diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-15 17:16:40 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-17 11:09:33 -0400 |
commit | 8dd3775889345850ecddd689b5c200cdd91bd8c9 (patch) | |
tree | ea697cfcac3f3a927e90d0048e9ed76b5a3ea8e5 /fs/nfs/pnfs.h | |
parent | 95a13f7b33be87d85d8e6652126a3f4d64d164db (diff) |
NFSv4.1: Clean ups and bugfixes for the pNFS read/writeback/commit code
Move more pnfs-isms out of the generic commit code.
Bugfixes:
- filelayout_scan_commit_lists doesn't need to get/put the lseg.
In fact since it is run under the inode->i_lock, the lseg_put()
can deadlock.
- Ensure that we distinguish between what needs to be done for
commit-to-data server and what needs to be done for commit-to-MDS
using the new flag PG_COMMIT_TO_DS. Otherwise we may end up calling
put_lseg() on a bucket for a struct nfs_page that got written
through the MDS.
- Fix a case where we were using list_del() on an nfs_page->wb_list
instead of list_del_init().
- filelayout_initiate_commit needs to call filelayout_commit_release
on error instead of the mds_ops->rpc_release(). Otherwise it won't
clear the commit lock.
Cleanups:
- Let the files layout manage the commit lists for the pNFS case.
Don't expose stuff like pnfs_choose_commit_list, and the fact
that the commit buckets hold references to the layout segment
in common code.
- Cast out the put_lseg() calls for the struct nfs_read/write_data->lseg
into the pNFS layer from whence they came.
- Let the pNFS layer manage the NFS_INO_PNFS_COMMIT bit.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Fred Isaman <iisaman@netapp.com>
Diffstat (limited to 'fs/nfs/pnfs.h')
-rw-r--r-- | fs/nfs/pnfs.h | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index ef92f676cf1e..e98ff3027d3a 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -94,9 +94,9 @@ struct pnfs_layoutdriver_type { | |||
94 | const struct nfs_pageio_ops *pg_read_ops; | 94 | const struct nfs_pageio_ops *pg_read_ops; |
95 | const struct nfs_pageio_ops *pg_write_ops; | 95 | const struct nfs_pageio_ops *pg_write_ops; |
96 | 96 | ||
97 | struct list_head * (*choose_commit_list) (struct nfs_page *req, | 97 | void (*mark_request_commit) (struct nfs_page *req, |
98 | struct pnfs_layout_segment *lseg); | 98 | struct pnfs_layout_segment *lseg); |
99 | struct pnfs_layout_segment *(*remove_commit_req) (struct nfs_page *req); | 99 | void (*clear_request_commit) (struct nfs_page *req); |
100 | int (*scan_commit_lists) (struct inode *inode, int max); | 100 | int (*scan_commit_lists) (struct inode *inode, int max); |
101 | int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how); | 101 | int (*commit_pagelist)(struct inode *inode, struct list_head *mds_pages, int how); |
102 | 102 | ||
@@ -269,39 +269,42 @@ pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how) | |||
269 | return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how); | 269 | return NFS_SERVER(inode)->pnfs_curr_ld->commit_pagelist(inode, mds_pages, how); |
270 | } | 270 | } |
271 | 271 | ||
272 | static inline struct list_head * | 272 | static inline bool |
273 | pnfs_choose_commit_list(struct nfs_page *req, struct pnfs_layout_segment *lseg) | 273 | pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg) |
274 | { | 274 | { |
275 | struct inode *inode = req->wb_context->dentry->d_inode; | 275 | struct inode *inode = req->wb_context->dentry->d_inode; |
276 | struct list_head *rv; | 276 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld; |
277 | 277 | ||
278 | if (lseg && NFS_SERVER(inode)->pnfs_curr_ld->choose_commit_list) | 278 | if (lseg == NULL || ld->mark_request_commit == NULL) |
279 | rv = NFS_SERVER(inode)->pnfs_curr_ld->choose_commit_list(req, lseg); | 279 | return false; |
280 | else | 280 | ld->mark_request_commit(req, lseg); |
281 | rv = &NFS_I(inode)->commit_list; | 281 | return true; |
282 | return rv; | ||
283 | } | 282 | } |
284 | 283 | ||
285 | static inline struct pnfs_layout_segment * | 284 | static inline bool |
286 | pnfs_clear_request_commit(struct nfs_page *req) | 285 | pnfs_clear_request_commit(struct nfs_page *req) |
287 | { | 286 | { |
288 | struct inode *inode = req->wb_context->dentry->d_inode; | 287 | struct inode *inode = req->wb_context->dentry->d_inode; |
288 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld; | ||
289 | 289 | ||
290 | if (NFS_SERVER(inode)->pnfs_curr_ld && | 290 | if (ld == NULL || ld->clear_request_commit == NULL) |
291 | NFS_SERVER(inode)->pnfs_curr_ld->remove_commit_req) | 291 | return false; |
292 | return NFS_SERVER(inode)->pnfs_curr_ld->remove_commit_req(req); | 292 | ld->clear_request_commit(req); |
293 | else | 293 | return true; |
294 | return NULL; | ||
295 | } | 294 | } |
296 | 295 | ||
297 | static inline int | 296 | static inline int |
298 | pnfs_scan_commit_lists(struct inode *inode, int max) | 297 | pnfs_scan_commit_lists(struct inode *inode, int max) |
299 | { | 298 | { |
300 | if (NFS_SERVER(inode)->pnfs_curr_ld && | 299 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld; |
301 | NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists) | 300 | int ret; |
302 | return NFS_SERVER(inode)->pnfs_curr_ld->scan_commit_lists(inode, max); | 301 | |
303 | else | 302 | if (ld == NULL || ld->scan_commit_lists == NULL) |
304 | return 0; | 303 | return 0; |
304 | ret = ld->scan_commit_lists(inode, max); | ||
305 | if (ret != 0) | ||
306 | set_bit(NFS_INO_PNFS_COMMIT, &NFS_I(inode)->flags); | ||
307 | return ret; | ||
305 | } | 308 | } |
306 | 309 | ||
307 | /* Should the pNFS client commit and return the layout upon a setattr */ | 310 | /* Should the pNFS client commit and return the layout upon a setattr */ |
@@ -403,18 +406,16 @@ pnfs_commit_list(struct inode *inode, struct list_head *mds_pages, int how) | |||
403 | return PNFS_NOT_ATTEMPTED; | 406 | return PNFS_NOT_ATTEMPTED; |
404 | } | 407 | } |
405 | 408 | ||
406 | static inline struct list_head * | 409 | static inline bool |
407 | pnfs_choose_commit_list(struct nfs_page *req, struct pnfs_layout_segment *lseg) | 410 | pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg) |
408 | { | 411 | { |
409 | struct inode *inode = req->wb_context->dentry->d_inode; | 412 | return false; |
410 | |||
411 | return &NFS_I(inode)->commit_list; | ||
412 | } | 413 | } |
413 | 414 | ||
414 | static inline struct pnfs_layout_segment * | 415 | static inline bool |
415 | pnfs_clear_request_commit(struct nfs_page *req) | 416 | pnfs_clear_request_commit(struct nfs_page *req) |
416 | { | 417 | { |
417 | return NULL; | 418 | return false; |
418 | } | 419 | } |
419 | 420 | ||
420 | static inline int | 421 | static inline int |