[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