aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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 51c19093022..af9bf9eed4c 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 68cce730b80..2e42284253f 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 5fc2e5d755a..5b3cc3f4bb3 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 678c4c7b14d..a59736eae6e 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 fb9498d91f6..6fda5228ef5 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}