[PATCH 2/2] NFS: Record file size changes when doing O_DIRECT writes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Ensure that we do update the file size when doing O_DIRECT writes
rather than relying on attribute updates. Those may not be
immediately forthcoming if this is a delegated file and/or we
are doing pNFS.

Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
---
 fs/nfs/direct.c   |  1 +
 fs/nfs/internal.h |  1 +
 fs/nfs/write.c    | 14 +++++---------
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 621c517b325c..aae35f87d4d0 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -938,6 +938,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
 		return result < 0 ? result : -EIO;
 	}
 
+	nfs_grow_file(inode, dreq->io_start, requested_bytes);
 	if (put_dreq(dreq))
 		nfs_direct_write_complete(dreq);
 	return requested_bytes;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 8357ff69962f..51ecc634f79a 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -474,6 +474,7 @@ extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
 			const struct nfs_pgio_completion_ops *compl_ops);
 extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
 extern void nfs_commit_free(struct nfs_commit_data *p);
+void nfs_grow_file(struct inode *inode, loff_t offset, unsigned int count);
 extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
 extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
 extern int nfs_initiate_commit(struct rpc_clnt *clnt,
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 7428a669d7a7..93460f1cf5a4 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -216,18 +216,13 @@ static struct nfs_page *nfs_page_find_head_request(struct page *page)
 }
 
 /* Adjust the file length if we're writing beyond the end */
-static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count)
+void nfs_grow_file(struct inode *inode, loff_t offset, unsigned int count)
 {
-	struct inode *inode = page_file_mapping(page)->host;
-	loff_t end, i_size;
-	pgoff_t end_index;
+	loff_t end = offset + count;
+	loff_t i_size;
 
 	spin_lock(&inode->i_lock);
 	i_size = i_size_read(inode);
-	end_index = (i_size - 1) >> PAGE_SHIFT;
-	if (i_size > 0 && page_index(page) < end_index)
-		goto out;
-	end = page_file_offset(page) + ((loff_t)offset+count);
 	if (i_size >= end)
 		goto out;
 	i_size_write(inode, end);
@@ -1170,13 +1165,14 @@ static struct nfs_page * nfs_setup_write_request(struct nfs_open_context* ctx,
 static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
 		unsigned int offset, unsigned int count)
 {
+	struct inode *inode = page_file_mapping(page)->host;
 	struct nfs_page	*req;
 
 	req = nfs_setup_write_request(ctx, page, offset, count);
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 	/* Update file length */
-	nfs_grow_file(page, offset, count);
+	nfs_grow_file(inode, req_offset(req), req->wb_bytes);
 	nfs_mark_uptodate(req);
 	nfs_mark_request_dirty(req);
 	nfs_unlock_and_release_request(req);
-- 
2.14.3

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux