diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2014-11-12 12:08:00 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-11-24 17:00:42 -0500 |
commit | cb1410c71e0b6b2eba8c1890645a76ff86169d24 (patch) | |
tree | 22fb6770fed66df7d51676e25e5a525bdd352abe /fs/nfs/write.c | |
parent | 6a74c0c9402b85647793da70edc9d6b097d54472 (diff) |
NFS: fix subtle change in COMMIT behavior
Recent work in the pgio layer made it possible for there to be more than one
request per page. This caused a subtle change in commit behavior, because
write.c:nfs_commit_unstable_pages compares the number of *pages* waiting for
writeback against the number of requests on a commit list to choose when to
send a COMMIT in a non-blocking flush.
This is probably hard to hit in normal operation - you have to be using
rsize/wsize < PAGE_SIZE, or pnfs with lots of boundaries that are not page
aligned to have a noticeable change in behavior.
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 | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f83b02dc9166..d489ff3f438f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -670,7 +670,8 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
670 | nfs_lock_request(req); | 670 | nfs_lock_request(req); |
671 | 671 | ||
672 | spin_lock(&inode->i_lock); | 672 | spin_lock(&inode->i_lock); |
673 | if (!nfsi->npages && NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) | 673 | if (!nfsi->nrequests && |
674 | NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) | ||
674 | inode->i_version++; | 675 | inode->i_version++; |
675 | /* | 676 | /* |
676 | * Swap-space should not get truncated. Hence no need to plug the race | 677 | * Swap-space should not get truncated. Hence no need to plug the race |
@@ -681,9 +682,11 @@ static void nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
681 | SetPagePrivate(req->wb_page); | 682 | SetPagePrivate(req->wb_page); |
682 | set_page_private(req->wb_page, (unsigned long)req); | 683 | set_page_private(req->wb_page, (unsigned long)req); |
683 | } | 684 | } |
684 | nfsi->npages++; | 685 | nfsi->nrequests++; |
685 | /* this a head request for a page group - mark it as having an | 686 | /* this a head request for a page group - mark it as having an |
686 | * extra reference so sub groups can follow suit */ | 687 | * extra reference so sub groups can follow suit. |
688 | * This flag also informs pgio layer when to bump nrequests when | ||
689 | * adding subrequests. */ | ||
687 | WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags)); | 690 | WARN_ON(test_and_set_bit(PG_INODE_REF, &req->wb_flags)); |
688 | kref_get(&req->wb_kref); | 691 | kref_get(&req->wb_kref); |
689 | spin_unlock(&inode->i_lock); | 692 | spin_unlock(&inode->i_lock); |
@@ -709,7 +712,11 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
709 | wake_up_page(head->wb_page, PG_private); | 712 | wake_up_page(head->wb_page, PG_private); |
710 | clear_bit(PG_MAPPED, &head->wb_flags); | 713 | clear_bit(PG_MAPPED, &head->wb_flags); |
711 | } | 714 | } |
712 | nfsi->npages--; | 715 | nfsi->nrequests--; |
716 | spin_unlock(&inode->i_lock); | ||
717 | } else { | ||
718 | spin_lock(&inode->i_lock); | ||
719 | nfsi->nrequests--; | ||
713 | spin_unlock(&inode->i_lock); | 720 | spin_unlock(&inode->i_lock); |
714 | } | 721 | } |
715 | 722 | ||
@@ -1735,7 +1742,7 @@ static int nfs_commit_unstable_pages(struct inode *inode, struct writeback_contr | |||
1735 | /* Don't commit yet if this is a non-blocking flush and there | 1742 | /* Don't commit yet if this is a non-blocking flush and there |
1736 | * are a lot of outstanding writes for this mapping. | 1743 | * are a lot of outstanding writes for this mapping. |
1737 | */ | 1744 | */ |
1738 | if (nfsi->commit_info.ncommit <= (nfsi->npages >> 1)) | 1745 | if (nfsi->commit_info.ncommit <= (nfsi->nrequests >> 1)) |
1739 | goto out_mark_dirty; | 1746 | goto out_mark_dirty; |
1740 | 1747 | ||
1741 | /* don't wait for the COMMIT response */ | 1748 | /* don't wait for the COMMIT response */ |