diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2014-07-17 20:42:19 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-08-03 17:05:26 -0400 |
commit | 411a99adffb4f993eee29759f744de01487044ac (patch) | |
tree | cea4af52189a179a8001d5ae5c2d5ed28bd5f7d7 /fs/nfs/write.c | |
parent | e6cf82d1830f5e16a10d566f58db70f297ba5da8 (diff) |
nfs: clear_request_commit while holding i_lock
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ba417692b80d..1065de26190b 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -404,8 +404,6 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list, | |||
404 | subreq->wb_head = subreq; | 404 | subreq->wb_head = subreq; |
405 | subreq->wb_this_page = subreq; | 405 | subreq->wb_this_page = subreq; |
406 | 406 | ||
407 | nfs_clear_request_commit(subreq); | ||
408 | |||
409 | /* subreq is now totally disconnected from page group or any | 407 | /* subreq is now totally disconnected from page group or any |
410 | * write / commit lists. last chance to wake any waiters */ | 408 | * write / commit lists. last chance to wake any waiters */ |
411 | nfs_unlock_request(subreq); | 409 | nfs_unlock_request(subreq); |
@@ -515,7 +513,7 @@ try_again: | |||
515 | * Commit list removal accounting is done after locks are dropped */ | 513 | * Commit list removal accounting is done after locks are dropped */ |
516 | subreq = head; | 514 | subreq = head; |
517 | do { | 515 | do { |
518 | nfs_list_remove_request(subreq); | 516 | nfs_clear_request_commit(subreq); |
519 | subreq = subreq->wb_this_page; | 517 | subreq = subreq->wb_this_page; |
520 | } while (subreq != head); | 518 | } while (subreq != head); |
521 | 519 | ||
@@ -545,15 +543,11 @@ try_again: | |||
545 | 543 | ||
546 | nfs_page_group_unlock(head); | 544 | nfs_page_group_unlock(head); |
547 | 545 | ||
548 | /* drop lock to clear_request_commit the head req and clean up | 546 | /* drop lock to clean uprequests on destroy list */ |
549 | * requests on destroy list */ | ||
550 | spin_unlock(&inode->i_lock); | 547 | spin_unlock(&inode->i_lock); |
551 | 548 | ||
552 | nfs_destroy_unlinked_subrequests(destroy_list, head); | 549 | nfs_destroy_unlinked_subrequests(destroy_list, head); |
553 | 550 | ||
554 | /* clean up commit list state */ | ||
555 | nfs_clear_request_commit(head); | ||
556 | |||
557 | /* still holds ref on head from nfs_page_find_head_request_locked | 551 | /* still holds ref on head from nfs_page_find_head_request_locked |
558 | * and still has lock on head from lock loop */ | 552 | * and still has lock on head from lock loop */ |
559 | return head; | 553 | return head; |
@@ -837,6 +831,7 @@ nfs_clear_page_commit(struct page *page) | |||
837 | dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE); | 831 | dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE); |
838 | } | 832 | } |
839 | 833 | ||
834 | /* Called holding inode (/cinfo) lock */ | ||
840 | static void | 835 | static void |
841 | nfs_clear_request_commit(struct nfs_page *req) | 836 | nfs_clear_request_commit(struct nfs_page *req) |
842 | { | 837 | { |
@@ -846,9 +841,7 @@ nfs_clear_request_commit(struct nfs_page *req) | |||
846 | 841 | ||
847 | nfs_init_cinfo_from_inode(&cinfo, inode); | 842 | nfs_init_cinfo_from_inode(&cinfo, inode); |
848 | if (!pnfs_clear_request_commit(req, &cinfo)) { | 843 | if (!pnfs_clear_request_commit(req, &cinfo)) { |
849 | spin_lock(cinfo.lock); | ||
850 | nfs_request_remove_commit_list(req, &cinfo); | 844 | nfs_request_remove_commit_list(req, &cinfo); |
851 | spin_unlock(cinfo.lock); | ||
852 | } | 845 | } |
853 | nfs_clear_page_commit(req->wb_page); | 846 | nfs_clear_page_commit(req->wb_page); |
854 | } | 847 | } |
@@ -1061,9 +1054,9 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, | |||
1061 | else | 1054 | else |
1062 | req->wb_bytes = rqend - req->wb_offset; | 1055 | req->wb_bytes = rqend - req->wb_offset; |
1063 | out_unlock: | 1056 | out_unlock: |
1064 | spin_unlock(&inode->i_lock); | ||
1065 | if (req) | 1057 | if (req) |
1066 | nfs_clear_request_commit(req); | 1058 | nfs_clear_request_commit(req); |
1059 | spin_unlock(&inode->i_lock); | ||
1067 | return req; | 1060 | return req; |
1068 | out_flushme: | 1061 | out_flushme: |
1069 | spin_unlock(&inode->i_lock); | 1062 | spin_unlock(&inode->i_lock); |