Skip to content

Commit

Permalink
NFSv4.1: use struct nfs_client to qualify deviceid
Browse files Browse the repository at this point in the history
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 ea8eecd
"NFSv4.1 move deviceid cache to filelayout driver"

Signed-off-by: Benny Halevy <bhalevy@panasas.com>
  • Loading branch information
Benny Halevy authored and Boaz Harrosh committed May 29, 2011
1 parent 3b6445a commit 67d51f6
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 7 deletions.
2 changes: 1 addition & 1 deletion fs/nfs/nfs4filelayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion fs/nfs/nfs4filelayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 4 additions & 5 deletions fs/nfs/nfs4filelayoutdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 67d51f6

Please sign in to comment.