NFSv4.1: use struct nfs_client to qualify deviceid
authorBenny Halevy <bhalevy@panasas.com>
Fri, 20 May 2011 08:45:05 +0000 (10:45 +0200)
committerBoaz Harrosh <bharrosh@panasas.com>
Sun, 29 May 2011 09:09:47 +0000 (12:09 +0300)
deviceids are unique per server, per layout type.
Therefore, in the global cache in the files layout driver
deviceids from different servers may clash so we need
to qualify them with a struct nfs_client that represents
the nfs server that returned the deviceid.

Introduced in 2.6.39 commit ea8eecdd
"NFSv4.1 move deviceid cache to filelayout driver"

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

index dd6ccf0076734067b3615e6a5f24fdfc18473f7e..571c1b032e9de8274b9c5773adff1b7a3bf73d7a 100644 (file)
@@ -440,7 +440,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
        }
 
        /* find and reference the deviceid */
-       dsaddr = nfs4_fl_find_get_deviceid(id);
+       dsaddr = nfs4_fl_find_get_deviceid(NFS_SERVER(lo->plh_inode)->nfs_client, id);
        if (dsaddr == NULL) {
                dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
                if (dsaddr == NULL)
index 2b461d77b43a9efa1c8235a955c18941ee8f56b5..301b95568bd2000102885497d13516e244198bd2 100644 (file)
@@ -60,6 +60,7 @@ struct nfs4_pnfs_ds {
 
 struct nfs4_file_layout_dsaddr {
        struct hlist_node               node;
+       struct nfs_client               *nfs_client;
        struct nfs4_deviceid            deviceid;
        atomic_t                        ref;
        unsigned long                   flags;
@@ -101,7 +102,7 @@ u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j);
 struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg,
                                        u32 ds_idx);
 extern struct nfs4_file_layout_dsaddr *
-nfs4_fl_find_get_deviceid(struct nfs4_deviceid *dev_id);
+nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id);
 extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
 struct nfs4_file_layout_dsaddr *
 get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
index db07c7af139519a3b938e44e0042a8d91102434c..42e32663727150e9bab13fc4972e19984d78bd33 100644 (file)
@@ -431,7 +431,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
        dsaddr->stripe_indices = stripe_indices;
        stripe_indices = NULL;
        dsaddr->ds_num = num;
-
+       dsaddr->nfs_client = NFS_SERVER(ino)->nfs_client;
        memcpy(&dsaddr->deviceid, &pdev->dev_id, sizeof(pdev->dev_id));
 
        for (i = 0; i < dsaddr->ds_num; i++) {
@@ -516,7 +516,7 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
        }
 
        spin_lock(&filelayout_deviceid_lock);
-       d = nfs4_fl_find_get_deviceid(&new->deviceid);
+       d = nfs4_fl_find_get_deviceid(new->nfs_client, &new->deviceid);
        if (d) {
                spin_unlock(&filelayout_deviceid_lock);
                nfs4_fl_free_deviceid(new);
@@ -610,16 +610,15 @@ nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
 }
 
 struct nfs4_file_layout_dsaddr *
-nfs4_fl_find_get_deviceid(struct nfs4_deviceid *id)
+nfs4_fl_find_get_deviceid(struct nfs_client *clp, struct nfs4_deviceid *id)
 {
        struct nfs4_file_layout_dsaddr *d;
        struct hlist_node *n;
        long hash = nfs4_fl_deviceid_hash(id);
 
-
        rcu_read_lock();
        hlist_for_each_entry_rcu(d, n, &filelayout_deviceid_cache[hash], node) {
-               if (!memcmp(&d->deviceid, id, sizeof(*id))) {
+               if (d->nfs_client == clp && !memcmp(&d->deviceid, id, sizeof(*id))) {
                        if (!atomic_inc_not_zero(&d->ref))
                                goto fail;
                        rcu_read_unlock();