NFSv4.1: use layout driver in global device cache
authorBenny Halevy <bhalevy@panasas.com>
Tue, 24 May 2011 15:04:02 +0000 (18:04 +0300)
committerBoaz Harrosh <bharrosh@panasas.com>
Sun, 29 May 2011 17:52:31 +0000 (20:52 +0300)
pnfs deviceids are unique per server, per layout type.
struct nfs_client is currently used to distinguish deviceids from
different nfs servers, yet these may clash between different layout
types on the same server.  Therefore, use the layout driver associated
with each deviceid at insertion time to look it up, unhash, or
delete it.

Signed-off-by: Benny Halevy <bhalevy@panasas.com>
fs/nfs/callback_proc.c
fs/nfs/nfs4filelayout.c
fs/nfs/pnfs.h
fs/nfs/pnfs_dev.c

index fb5e5b9a97ae2b3e3c4d523100a19a2ec6bb5bec..c73e7b2fb8e26553da51bdc0b92933e8e3d7fe2c 100644 (file)
@@ -278,7 +278,7 @@ __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args,
                if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE)
                        dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, "
                                "deleting instead\n", __func__);
-               nfs4_delete_deviceid(clp, &dev->cbd_dev_id);
+               nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id);
        }
 
 out:
index cd289d9b7de7fa3e44f9d74740e57b5200390dd6..501a9b86b318d0997a680ea1c007c99deebf5c66 100644 (file)
@@ -441,7 +441,8 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
        }
 
        /* find and reference the deviceid */
-       d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id);
+       d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld,
+                                  NFS_SERVER(lo->plh_inode)->nfs_client, id);
        if (d == NULL) {
                dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
                if (dsaddr == NULL)
index fbd3f7cd9e7156356ce51259f1ad9d3a1ca6cf86..5b083d29533434ee46c4664e818936899eadfd4e 100644 (file)
@@ -171,9 +171,9 @@ struct nfs4_deviceid_node {
 };
 
 void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
-struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
-struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
-void nfs4_delete_deviceid(const struct nfs_client *, const struct nfs4_deviceid *);
+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 *,
                             const struct nfs_client *,
index 8fd3839df299c1f48c2bc1ae5629100717ec323e..c65e133ce9c071d17e26729fe767b23f4271b445 100644 (file)
@@ -67,14 +67,16 @@ nfs4_deviceid_hash(const struct nfs4_deviceid *id)
 }
 
 static struct nfs4_deviceid_node *
-_lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
+_lookup_deviceid(const struct pnfs_layoutdriver_type *ld,
+                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 (d->ld == ld && d->nfs_client == clp &&
+                   !memcmp(&d->deviceid, id, sizeof(*id))) {
                        if (atomic_read(&d->ref))
                                return d;
                        else
@@ -90,13 +92,14 @@ _lookup_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
  * @id deviceid to look up
  */
 struct nfs4_deviceid_node *
-_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
+_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
+                  const struct nfs_client *clp, const struct nfs4_deviceid *id,
                   long hash)
 {
        struct nfs4_deviceid_node *d;
 
        rcu_read_lock();
-       d = _lookup_deviceid(clp, id, hash);
+       d = _lookup_deviceid(ld, clp, id, hash);
        if (d && !atomic_inc_not_zero(&d->ref))
                d = NULL;
        rcu_read_unlock();
@@ -104,9 +107,10 @@ _find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id,
 }
 
 struct nfs4_deviceid_node *
-nfs4_find_get_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
+nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
+                      const struct nfs_client *clp, const struct nfs4_deviceid *id)
 {
-       return _find_get_deviceid(clp, id, nfs4_deviceid_hash(id));
+       return _find_get_deviceid(ld, clp, id, nfs4_deviceid_hash(id));
 }
 EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
 
@@ -119,13 +123,14 @@ EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
  * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
  */
 struct nfs4_deviceid_node *
-nfs4_unhash_put_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
+nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
+                        const struct nfs_client *clp, const struct nfs4_deviceid *id)
 {
        struct nfs4_deviceid_node *d;
 
        spin_lock(&nfs4_deviceid_lock);
        rcu_read_lock();
-       d = _lookup_deviceid(clp, id, nfs4_deviceid_hash(id));
+       d = _lookup_deviceid(ld, clp, id, nfs4_deviceid_hash(id));
        rcu_read_unlock();
        if (!d) {
                spin_unlock(&nfs4_deviceid_lock);
@@ -150,11 +155,12 @@ EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid);
  * @id deviceid to delete
  */
 void
-nfs4_delete_deviceid(const struct nfs_client *clp, const struct nfs4_deviceid *id)
+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(clp, id);
+       d = nfs4_unhash_put_deviceid(ld, clp, id);
        if (!d)
                return;
        d->ld->free_deviceid_node(d);
@@ -194,7 +200,7 @@ nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new)
 
        spin_lock(&nfs4_deviceid_lock);
        hash = nfs4_deviceid_hash(&new->deviceid);
-       d = _find_get_deviceid(new->nfs_client, &new->deviceid, hash);
+       d = _find_get_deviceid(new->ld, new->nfs_client, &new->deviceid, hash);
        if (d) {
                spin_unlock(&nfs4_deviceid_lock);
                return d;