NFSv4.1: Clean ups for the device id cache
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 14 Jun 2011 16:18:11 +0000 (12:18 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 12 Jul 2011 17:40:28 +0000 (13:40 -0400)
The fact that the global device id cache holds a reference to the
nfs4_deviceid_node until it is invisible to rcu lookups implies that
we can always assume that the reference count is non-zero in
_find_get_deviceid.

Also clean up nfs4_put_deviceid_node and the removal of the device id
from the cache.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/pnfs.h
fs/nfs/pnfs_dev.c

index dd54351..1cfc96f 100644 (file)
@@ -198,7 +198,6 @@ struct nfs4_deviceid_node {
 
 void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
 struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
-struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
 void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
 void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
                             const struct pnfs_layoutdriver_type *,
index f0f8e1e..fb9498d 100644 (file)
@@ -100,8 +100,8 @@ _find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
 
        rcu_read_lock();
        d = _lookup_deviceid(ld, clp, id, hash);
-       if (d && !atomic_inc_not_zero(&d->ref))
-               d = NULL;
+       if (d != NULL)
+               atomic_inc(&d->ref);
        rcu_read_unlock();
        return d;
 }
@@ -115,15 +115,15 @@ nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
 EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
 
 /*
- * Unhash and put deviceid
+ * Remove a deviceid from cache
  *
  * @clp nfs_client associated with deviceid
  * @id the deviceid to unhash
  *
  * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
  */
-struct nfs4_deviceid_node *
-nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
+void
+nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
                         const struct nfs_client *clp, const struct nfs4_deviceid *id)
 {
        struct nfs4_deviceid_node *d;
@@ -134,7 +134,7 @@ nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
        rcu_read_unlock();
        if (!d) {
                spin_unlock(&nfs4_deviceid_lock);
-               return NULL;
+               return;
        }
        hlist_del_init_rcu(&d->node);
        spin_unlock(&nfs4_deviceid_lock);
@@ -142,28 +142,7 @@ nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
 
        /* balance the initial ref set in pnfs_insert_deviceid */
        if (atomic_dec_and_test(&d->ref))
-               return d;
-
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid);
-
-/*
- * Delete a deviceid from cache
- *
- * @clp struct nfs_client qualifying the deviceid
- * @id deviceid to delete
- */
-void
-nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
-                    const struct nfs_client *clp, const struct nfs4_deviceid *id)
-{
-       struct nfs4_deviceid_node *d;
-
-       d = nfs4_unhash_put_deviceid(ld, clp, id);
-       if (!d)
-               return;
-       d->ld->free_deviceid_node(d);
+               d->ld->free_deviceid_node(d);
 }
 EXPORT_SYMBOL_GPL(nfs4_delete_deviceid);
 
@@ -221,16 +200,15 @@ EXPORT_SYMBOL_GPL(nfs4_insert_deviceid_node);
  *
  * @d deviceid node to put
  *
- * @ret true iff the node was deleted
+ * return true iff the node was deleted
+ * Note that since the test for d->ref == 0 is sufficient to establish
+ * that the node is no longer hashed in the global device id cache.
  */
 bool
 nfs4_put_deviceid_node(struct nfs4_deviceid_node *d)
 {
-       if (!atomic_dec_and_lock(&d->ref, &nfs4_deviceid_lock))
+       if (!atomic_dec_and_test(&d->ref))
                return false;
-       hlist_del_init_rcu(&d->node);
-       spin_unlock(&nfs4_deviceid_lock);
-       synchronize_rcu();
        d->ld->free_deviceid_node(d);
        return true;
 }