diff options
author | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-01-19 14:37:30 -0500 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-05-17 15:47:55 -0400 |
commit | 67911c8f18b595040f5c2df0550c69a7c9397891 (patch) | |
tree | 11583f0793161d5bb0632ff1c45d14b81b24c89a /fs/nfs/write.c | |
parent | c2985d001d2fb77357aeae675545893b61c50044 (diff) |
NFS: Add nfs_commit_file()
Copy will use this to set up a commit request for a generic range. I
don't want to allocate a new pagecache entry for the file, so I needed
to change parts of the commit path to handle requests with a null
wb_page.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 9283a96b9fb8..e18a97aab275 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -737,7 +737,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
737 | head = req->wb_head; | 737 | head = req->wb_head; |
738 | 738 | ||
739 | spin_lock(&inode->i_lock); | 739 | spin_lock(&inode->i_lock); |
740 | if (likely(!PageSwapCache(head->wb_page))) { | 740 | if (likely(head->wb_page && !PageSwapCache(head->wb_page))) { |
741 | set_page_private(head->wb_page, 0); | 741 | set_page_private(head->wb_page, 0); |
742 | ClearPagePrivate(head->wb_page); | 742 | ClearPagePrivate(head->wb_page); |
743 | smp_mb__after_atomic(); | 743 | smp_mb__after_atomic(); |
@@ -759,7 +759,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
759 | static void | 759 | static void |
760 | nfs_mark_request_dirty(struct nfs_page *req) | 760 | nfs_mark_request_dirty(struct nfs_page *req) |
761 | { | 761 | { |
762 | __set_page_dirty_nobuffers(req->wb_page); | 762 | if (req->wb_page) |
763 | __set_page_dirty_nobuffers(req->wb_page); | ||
763 | } | 764 | } |
764 | 765 | ||
765 | /* | 766 | /* |
@@ -835,7 +836,8 @@ nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo) | |||
835 | spin_lock(&cinfo->inode->i_lock); | 836 | spin_lock(&cinfo->inode->i_lock); |
836 | nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo); | 837 | nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo); |
837 | spin_unlock(&cinfo->inode->i_lock); | 838 | spin_unlock(&cinfo->inode->i_lock); |
838 | nfs_mark_page_unstable(req->wb_page, cinfo); | 839 | if (req->wb_page) |
840 | nfs_mark_page_unstable(req->wb_page, cinfo); | ||
839 | } | 841 | } |
840 | EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); | 842 | EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); |
841 | 843 | ||
@@ -1724,6 +1726,36 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how, | |||
1724 | return -ENOMEM; | 1726 | return -ENOMEM; |
1725 | } | 1727 | } |
1726 | 1728 | ||
1729 | int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf) | ||
1730 | { | ||
1731 | struct inode *inode = file_inode(file); | ||
1732 | struct nfs_open_context *open; | ||
1733 | struct nfs_commit_info cinfo; | ||
1734 | struct nfs_page *req; | ||
1735 | int ret; | ||
1736 | |||
1737 | open = get_nfs_open_context(nfs_file_open_context(file)); | ||
1738 | req = nfs_create_request(open, NULL, NULL, 0, i_size_read(inode)); | ||
1739 | if (!req) { | ||
1740 | ret = -ENOMEM; | ||
1741 | goto out_put; | ||
1742 | } | ||
1743 | |||
1744 | nfs_init_cinfo_from_inode(&cinfo, inode); | ||
1745 | |||
1746 | memcpy(&req->wb_verf, verf, sizeof(struct nfs_write_verifier)); | ||
1747 | nfs_request_add_commit_list(req, &cinfo); | ||
1748 | ret = nfs_commit_inode(inode, FLUSH_SYNC); | ||
1749 | if (ret > 0) | ||
1750 | ret = 0; | ||
1751 | |||
1752 | nfs_free_request(req); | ||
1753 | out_put: | ||
1754 | put_nfs_open_context(open); | ||
1755 | return ret; | ||
1756 | } | ||
1757 | EXPORT_SYMBOL_GPL(nfs_commit_file); | ||
1758 | |||
1727 | /* | 1759 | /* |
1728 | * COMMIT call returned | 1760 | * COMMIT call returned |
1729 | */ | 1761 | */ |
@@ -1748,7 +1780,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) | |||
1748 | while (!list_empty(&data->pages)) { | 1780 | while (!list_empty(&data->pages)) { |
1749 | req = nfs_list_entry(data->pages.next); | 1781 | req = nfs_list_entry(data->pages.next); |
1750 | nfs_list_remove_request(req); | 1782 | nfs_list_remove_request(req); |
1751 | nfs_clear_page_commit(req->wb_page); | 1783 | if (req->wb_page) |
1784 | nfs_clear_page_commit(req->wb_page); | ||
1752 | 1785 | ||
1753 | dprintk("NFS: commit (%s/%llu %d@%lld)", | 1786 | dprintk("NFS: commit (%s/%llu %d@%lld)", |
1754 | req->wb_context->dentry->d_sb->s_id, | 1787 | req->wb_context->dentry->d_sb->s_id, |