diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayout.h | 6 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 3 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 8 | ||||
-rw-r--r-- | fs/nfs/pnfs_dev.c | 20 |
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 | ||
99 | static inline struct nfs4_deviceid_node * | ||
100 | FILELAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg) | ||
101 | { | ||
102 | return &FILELAYOUT_LSEG(lseg)->dsaddr->id_node; | ||
103 | } | ||
104 | |||
99 | extern struct nfs_fh * | 105 | extern struct nfs_fh * |
100 | nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); | 106 | nfs4_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 | ||
195 | void nfs4_deviceid_mark_client_invalid(struct nfs_client *clp); | ||
196 | |||
197 | /* nfs4_deviceid_flags */ | ||
198 | enum { | ||
199 | NFS_DEVICEID_INVALID = 0, /* set when MDS clientid recalled */ | ||
200 | }; | ||
201 | |||
195 | /* pnfs_dev.c */ | 202 | /* pnfs_dev.c */ |
196 | struct nfs4_deviceid_node { | 203 | struct 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 | */ | ||
261 | void | ||
262 | nfs4_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 | } | ||