[pnfs] [PATCH 25/28] pnfs: pnfs_write_end

Fred Isaman iisaman at citi.umich.edu
Tue Mar 11 15:32:06 EDT 2008


Add hooks in the nfs_write_end path, giving a driver the potential to
post-copy manipulation of page.

Signed-off-by: Fred Isaman <iisaman at citi.umich.edu>
---
 fs/nfs/file.c             |    7 +++++++
 fs/nfs/pnfs.c             |   20 ++++++++++++++++++++
 fs/nfs/pnfs.h             |    2 ++
 fs/nfs/write.c            |    2 +-
 include/linux/nfs4_pnfs.h |    3 +++
 5 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index a7c37e4..815cbc9 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -375,10 +375,17 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
 	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
 	int status;
 
+#ifdef CONFIG_PNFS
+	/* CAREFUL - what happens if copied < len??? */
+	status = pnfs_write_end(file, page, pos, len, copied, fsdata);
+	if (status)
+		goto out;
+#endif
 	lock_kernel();
 	status = nfs_updatepage(file, page, offset, copied, fsdata);
 	unlock_kernel();
 
+ out:
 	unlock_page(page);
 	page_cache_release(page);
 #ifdef CONFIG_PNFS
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 4c4927f..4fa54ed 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1594,6 +1594,26 @@ int pnfs_write_begin(struct file *filp, struct page *page,
 	return status;
 }
 
+/* Return 0 on succes, negative on failure */
+/* CAREFUL - what happens if copied < len??? */
+int pnfs_write_end(struct file *filp, struct page *page,
+		   loff_t pos, unsigned len, unsigned copied, void *fsdata)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct nfs_server *nfss = NFS_SERVER(inode);
+	struct pnfs_layout_segment *lseg;
+	int status;
+
+	if (!nfss->pnfs_curr_ld || !nfss->pnfs_curr_ld->ld_io_ops ||
+	    !nfss->pnfs_curr_ld->ld_io_ops->write_begin)
+		return 0;
+	lseg = pnfs_find_get_lseg(inode, pos, len, IOMODE_RW);
+	status = nfss->pnfs_curr_ld->ld_io_ops->write_end(inode, page,
+						pos, len, copied, fsdata);
+	put_lseg(lseg);
+	return status;
+}
+
 /* Given an nfs request, determine if it should be flushed before proceeding.
  * It should default to returning False, returning True only if there is a
  * specific reason to flush.
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 9824f78..1509fb7 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -31,6 +31,8 @@ int pnfs_use_write(struct inode *inode, ssize_t count);
 int pnfs_try_to_write_data(struct nfs_write_data *, const struct rpc_call_ops *, int);
 int pnfs_write_begin(struct file *filp, struct page *page, loff_t pos,
 		     unsigned len, unsigned flags, void **fsdata);
+int pnfs_write_end(struct file *filp, struct page *page,
+		   loff_t pos, unsigned len, unsigned copied, void *fsdata);
 int pnfs_do_flush(struct nfs_page *req, void *fsdata);
 int pnfs_try_to_read_data(struct nfs_read_data *data, const struct rpc_call_ops *call_ops);
 int pnfs_initialize(void);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 24bfcb5..575c067 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -656,7 +656,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
 	rqend = req->wb_offset + req->wb_bytes;
 	if (req->wb_context != ctx
 	    || req->wb_page != page
-	    || !nfs_dirty_request(req)
+	    || !nfs_dirty_request(req) || pnfs_do_flush(req, fsdata)
 	    || offset > rqend || end < req->wb_offset) {
 		nfs_unlock_request(req);
 		return ERR_PTR(-EBUSY);
diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
index 000e9eb..9ac366f 100644
--- a/include/linux/nfs4_pnfs.h
+++ b/include/linux/nfs4_pnfs.h
@@ -141,6 +141,9 @@ struct layoutdriver_io_operations {
 	int (*write_begin) (struct pnfs_layout_segment *lseg, struct page *page,
 			    loff_t pos, unsigned count,
 			    struct pnfs_fsdata **fsdata);
+	int (*write_end)(struct inode *inode, struct page *page, loff_t pos,
+			 unsigned count, unsigned copied,
+			 struct pnfs_fsdata *fsdata);
 	/* Hook into nfs_create_request, for setting wb_private */
 	void (*new_request)(struct pnfs_layout_segment *lseg,
 			    struct nfs_page *req, loff_t pos, unsigned count,
-- 
1.5.3.3



More information about the pNFS mailing list