Signed-off-by: Benny Halevy <bhalevy@xxxxxxxxxxx> --- fs/nfs/pnfs_dev.c | 49 +++++++++++++++++++++++++++---------------------- 1 files changed, 27 insertions(+), 22 deletions(-) diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c index d205b18..374fa66 100644 --- a/fs/nfs/pnfs_dev.c +++ b/fs/nfs/pnfs_dev.c @@ -66,6 +66,23 @@ nfs4_deviceid_hash(const struct nfs4_deviceid *id) return x & NFS4_DEVICE_ID_HASH_MASK; } +static struct nfs4_deviceid_node * +_lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id, + long hash) +{ + struct nfs4_deviceid_node *d; + struct hlist_node *n; + + hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) + if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) { + if (atomic_read(&d->ref)) + return d; + else + continue; + } + return NULL; +} + /* * Lookup a deviceid in cache and get a reference count on it if found * @@ -76,21 +93,13 @@ struct nfs4_deviceid_node * nfs4_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id) { struct nfs4_deviceid_node *d; - struct hlist_node *n; - long hash = nfs4_deviceid_hash(id); rcu_read_lock(); - hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) { - if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) { - if (!atomic_inc_not_zero(&d->ref)) - goto fail; - rcu_read_unlock(); - return d; - } - } -fail: + d = _lookup_deviceid(clp, id, nfs4_deviceid_hash(id)); + if (!atomic_inc_not_zero(&d->ref)) + d = NULL; rcu_read_unlock(); - return NULL; + return d; } EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid); @@ -106,19 +115,15 @@ struct nfs4_deviceid_node * nfs4_unhash_put_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id) { struct nfs4_deviceid_node *d; - struct hlist_node *n; - long hash = nfs4_deviceid_hash(id); + spin_lock(&nfs4_deviceid_lock); rcu_read_lock(); - hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) - if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) - goto found; + d = _lookup_deviceid(clp, id, nfs4_deviceid_hash(id)); rcu_read_unlock(); - return NULL; - -found: - rcu_read_unlock(); - spin_lock(&nfs4_deviceid_lock); + if (!d) { + spin_unlock(&nfs4_deviceid_lock); + return NULL; + } hlist_del_init_rcu(&d->node); spin_unlock(&nfs4_deviceid_lock); synchronize_rcu(); -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html