aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2011-06-15 17:52:40 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-12 13:40:29 -0400
commitc47abcf8ff4d0c56d20ce541e80d3e1c975f54b5 (patch)
tree9fc0bfddd899e415f9943a403b647ed7b05da71b
parenta56aaa02b1f723e28b41d339ddff02e958d32d43 (diff)
NFSv4.1: do not use deviceids after MDS clientid invalidation
Mark all deviceids established under an expired MDS clientid as invalid. Stop all new i/o through DS and send through the MDS. Don't use any new LAYOUTGETs that use the invalid deviceid. Purge all layouts established under the expired MDS clientid. Remove the MDS clientid deviceid and data servers reference Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4filelayout.c10
-rw-r--r--fs/nfs/nfs4filelayout.h6
-rw-r--r--fs/nfs/pnfs.c3
-rw-r--r--fs/nfs/pnfs.h8
-rw-r--r--fs/nfs/pnfs_dev.c20
5 files changed, 47 insertions, 0 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 51c19093022e..af9bf9eed4ca 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -334,6 +334,9 @@ filelayout_read_pagelist(struct nfs_read_data *data)
334 __func__, data->inode->i_ino, 334 __func__, data->inode->i_ino,
335 data->args.pgbase, (size_t)data->args.count, offset); 335 data->args.pgbase, (size_t)data->args.count, offset);
336 336
337 if (test_bit(NFS_DEVICEID_INVALID, &FILELAYOUT_DEVID_NODE(lseg)->flags))
338 return PNFS_NOT_ATTEMPTED;
339
337 /* Retrieve the correct rpc_client for the byte range */ 340 /* Retrieve the correct rpc_client for the byte range */
338 j = nfs4_fl_calc_j_index(lseg, offset); 341 j = nfs4_fl_calc_j_index(lseg, offset);
339 idx = nfs4_fl_calc_ds_index(lseg, j); 342 idx = nfs4_fl_calc_ds_index(lseg, j);
@@ -373,6 +376,9 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
373 struct nfs_fh *fh; 376 struct nfs_fh *fh;
374 int status; 377 int status;
375 378
379 if (test_bit(NFS_DEVICEID_INVALID, &FILELAYOUT_DEVID_NODE(lseg)->flags))
380 return PNFS_NOT_ATTEMPTED;
381
376 /* Retrieve the correct rpc_client for the byte range */ 382 /* Retrieve the correct rpc_client for the byte range */
377 j = nfs4_fl_calc_j_index(lseg, offset); 383 j = nfs4_fl_calc_j_index(lseg, offset);
378 idx = nfs4_fl_calc_ds_index(lseg, j); 384 idx = nfs4_fl_calc_ds_index(lseg, j);
@@ -456,6 +462,10 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
456 goto out; 462 goto out;
457 } else 463 } else
458 dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); 464 dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
465 /* Found deviceid is being reaped */
466 if (test_bit(NFS_DEVICEID_INVALID, &dsaddr->id_node.flags))
467 goto out_put;
468
459 fl->dsaddr = dsaddr; 469 fl->dsaddr = dsaddr;
460 470
461 if (fl->first_stripe_index < 0 || 471 if (fl->first_stripe_index < 0 ||
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index 68cce730b800..2e42284253fa 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -96,6 +96,12 @@ FILELAYOUT_LSEG(struct pnfs_layout_segment *lseg)
96 generic_hdr); 96 generic_hdr);
97} 97}
98 98
99static inline struct nfs4_deviceid_node *
100FILELAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg)
101{
102 return &FILELAYOUT_LSEG(lseg)->dsaddr->id_node;
103}
104
99extern struct nfs_fh * 105extern struct nfs_fh *
100nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); 106nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j);
101 107
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 5fc2e5d755a5..5b3cc3f4bb39 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -452,6 +452,9 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
452 struct pnfs_layout_hdr *lo; 452 struct pnfs_layout_hdr *lo;
453 LIST_HEAD(tmp_list); 453 LIST_HEAD(tmp_list);
454 454
455 nfs4_deviceid_mark_client_invalid(clp);
456 nfs4_deviceid_purge_client(clp);
457
455 spin_lock(&clp->cl_lock); 458 spin_lock(&clp->cl_lock);
456 rcu_read_lock(); 459 rcu_read_lock();
457 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 460 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 678c4c7b14d9..a59736eae6ec 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -192,12 +192,20 @@ struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
192 enum pnfs_iomode iomode, 192 enum pnfs_iomode iomode,
193 gfp_t gfp_flags); 193 gfp_t gfp_flags);
194 194
195void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp);
196
197/* nfs4_deviceid_flags */
198enum {
199 NFS_DEVICEID_INVALID = 0, /* set when MDS clientid recalled */
200};
201
195/* pnfs_dev.c */ 202/* pnfs_dev.c */
196struct nfs4_deviceid_node { 203struct nfs4_deviceid_node {
197 struct hlist_node node; 204 struct hlist_node node;
198 struct hlist_node tmpnode; 205 struct hlist_node tmpnode;
199 const struct pnfs_layoutdriver_type *ld; 206 const struct pnfs_layoutdriver_type *ld;
200 const struct nfs_client *nfs_client; 207 const struct nfs_client *nfs_client;
208 unsigned long flags;
201 struct nfs4_deviceid deviceid; 209 struct nfs4_deviceid deviceid;
202 atomic_t ref; 210 atomic_t ref;
203}; 211};
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c
index fb9498d91f6a..6fda5228ef56 100644
--- a/fs/nfs/pnfs_dev.c
+++ b/fs/nfs/pnfs_dev.c
@@ -156,6 +156,7 @@ nfs4_init_deviceid_node(struct nfs4_deviceid_node *d,
156 INIT_HLIST_NODE(&d->tmpnode); 156 INIT_HLIST_NODE(&d->tmpnode);
157 d->ld = ld; 157 d->ld = ld;
158 d->nfs_client = nfs_client; 158 d->nfs_client = nfs_client;
159 d->flags = 0;
159 d->deviceid = *id; 160 d->deviceid = *id;
160 atomic_set(&d->ref, 1); 161 atomic_set(&d->ref, 1);
161} 162}
@@ -253,3 +254,22 @@ nfs4_deviceid_purge_client(const struct nfs_client *clp)
253 for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) 254 for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++)
254 _deviceid_purge_client(clp, h); 255 _deviceid_purge_client(clp, h);
255} 256}
257
258/*
259 * Stop use of all deviceids associated with an nfs_client
260 */
261void
262nfs4_deviceid_mark_client_invalid(struct nfs_client *clp)
263{
264 struct nfs4_deviceid_node *d;
265 struct hlist_node *n;
266 int i;
267
268 rcu_read_lock();
269 for (i = 0; i < NFS4_DEVICE_ID_HASH_SIZE; i ++){
270 hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[i], node)
271 if (d->nfs_client == clp)
272 set_bit(NFS_DEVICEID_INVALID, &d->flags);
273 }
274 rcu_read_unlock();
275}