@@ -1598,16 +1598,21 @@ pnfs_unhash_deviceid(struct pnfs_deviceid_cache *c,
{
struct pnfs_deviceid_node *d;
struct hlist_node *n;
- long h = nfs4_deviceid_hash(id);
+ long h;
+
+ spin_lock(&c->dc_lock);
+ h = nfs4_deviceid_hash(id);
dprintk("%s hash %ld\n", __func__, h);
hlist_for_each_entry_rcu(d, n, &c->dc_deviceids[h], de_node)
if (!memcmp(&d->de_id, id, sizeof(*id))) {
hlist_del_rcu(&d->de_node);
+ spin_unlock(&c->dc_lock);
synchronize_rcu();
return d;
}
+ spin_unlock(&c->dc_lock);
return NULL;
}
@@ -1620,11 +1625,10 @@ pnfs_put_deviceid(struct pnfs_deviceid_cache *c,
struct pnfs_deviceid_node *devid)
{
dprintk("%s [%d]\n", __func__, atomic_read(&devid->de_ref));
- if (!atomic_dec_and_lock(&devid->de_ref, &c->dc_lock))
+ if (!atomic_dec_and_test(&devid->de_ref))
return;
pnfs_unhash_deviceid(c, &devid->de_id);
- spin_unlock(&c->dc_lock);
c->dc_free_callback(devid);
}
@@ -1636,9 +1640,7 @@ pnfs_delete_deviceid(struct pnfs_deviceid_cache *c,
{
struct pnfs_deviceid_node *devid;
- spin_lock(&c->dc_lock);
devid = pnfs_unhash_deviceid(c, id);
- spin_unlock(&c->dc_lock);
dprintk("%s [%d]\n", __func__, atomic_read(&devid->de_ref));
if (atomic_dec_and_test(&devid->de_ref))