From 94ad1c80e28f9700c84b4d28d1e5302ddf63a6fd Mon Sep 17 00:00:00 2001 From: Fred Isaman Date: Tue, 1 Mar 2011 01:34:14 +0000 Subject: NFSv4.1: coelesce across layout stripes Add a pg_test layout driver hook which is used to avoid coelescing I/O across layout stripes. Signed-off-by: Andy Adamson Signed-off-by: Andy Adamson Signed-off-by: Dean Hildebrand Signed-off-by: Fred Isaman Signed-off-by: Fred Isaman Signed-off-by: Benny Halevy Signed-off-by: Boaz Harrosh Signed-off-by: Oleg Drokin Signed-off-by: Tao Guo Signed-off-by: Trond Myklebust --- include/linux/nfs_page.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/nfs_page.h') diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index d55cee73f634..4eaf27a1282d 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -62,6 +62,8 @@ struct nfs_pageio_descriptor { int (*pg_doio)(struct inode *, struct list_head *, unsigned int, size_t, int); int pg_ioflags; int pg_error; + struct pnfs_layout_segment *pg_lseg; + int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); }; #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) -- cgit v1.2.2 From bae724ef95b0d0a1f4518f5451e7c8aabc41f820 Mon Sep 17 00:00:00 2001 From: Fred Isaman Date: Tue, 1 Mar 2011 01:34:15 +0000 Subject: NFSv4.1: shift pnfs_update_layout locations Move the pnfs_update_layout call location to nfs_pageio_do_add_request(). Grab the lseg sent in the doio function to nfs_read_rpcsetup and attach it to each nfs_read_data so it can be sent to the layout driver. Signed-off-by: Andy Adamson Signed-off-by: Andy Adamson Signed-off-by: Dean Hildebrand Signed-off-by: Fred Isaman Signed-off-by: Fred Isaman Signed-off-by: Benny Halevy Signed-off-by: Boaz Harrosh Signed-off-by: Oleg Drokin Signed-off-by: Tao Guo Signed-off-by: Trond Myklebust --- include/linux/nfs_page.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux/nfs_page.h') diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 4eaf27a1282d..ba88ff4f8186 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -59,7 +59,7 @@ struct nfs_pageio_descriptor { unsigned int pg_base; struct inode *pg_inode; - int (*pg_doio)(struct inode *, struct list_head *, unsigned int, size_t, int); + int (*pg_doio)(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *); int pg_ioflags; int pg_error; struct pnfs_layout_segment *pg_lseg; @@ -81,7 +81,7 @@ extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *dst, pgoff_t idx_start, unsigned int npages, int tag); extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc, struct inode *inode, - int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int), + int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *), size_t bsize, int how); extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *, -- cgit v1.2.2 From c76069bda0f17cd3e153e54d9ac01242909c6b15 Mon Sep 17 00:00:00 2001 From: Fred Isaman Date: Thu, 3 Mar 2011 15:13:48 +0000 Subject: NFSv4.1: rearrange ->doio args This will make it possible to clear the lseg pointer in the same function as it is put, instead of in the caller nfs_pageio_doio(). Signed-off-by: Fred Isaman Signed-off-by: Trond Myklebust --- include/linux/nfs_page.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux/nfs_page.h') diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index ba88ff4f8186..90907ada6d52 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -59,7 +59,7 @@ struct nfs_pageio_descriptor { unsigned int pg_base; struct inode *pg_inode; - int (*pg_doio)(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *); + int (*pg_doio)(struct nfs_pageio_descriptor *); int pg_ioflags; int pg_error; struct pnfs_layout_segment *pg_lseg; @@ -81,7 +81,7 @@ extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *dst, pgoff_t idx_start, unsigned int npages, int tag); extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc, struct inode *inode, - int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int, struct pnfs_layout_segment *), + int (*doio)(struct nfs_pageio_descriptor *desc), size_t bsize, int how); extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *, -- cgit v1.2.2 From b31268ac793fd300da66b9c28bbf0a200339ab96 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 21 Mar 2011 17:02:00 -0400 Subject: FS: Use stable writes when not doing a bulk flush If we're only doing a single write, and there are no other unstable writes being queued up, we might want to just flip to using a stable write RPC call. Reviewed-by: NeilBrown Signed-off-by: Trond Myklebust --- include/linux/nfs_page.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/nfs_page.h') diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 90907ada6d52..92d54c81f51e 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -57,6 +57,7 @@ struct nfs_pageio_descriptor { size_t pg_count; size_t pg_bsize; unsigned int pg_base; + char pg_moreio; struct inode *pg_inode; int (*pg_doio)(struct nfs_pageio_descriptor *); -- cgit v1.2.2 From a861a1e1c398fe34701569fd8ac9225dfe0a9a7e Mon Sep 17 00:00:00 2001 From: Fred Isaman Date: Wed, 23 Mar 2011 13:27:51 +0000 Subject: NFSv4.1: add generic layer hooks for pnfs COMMIT We create three major hooks for the pnfs code. pnfs_mark_request_commit() is called during writeback_done from nfs_mark_request_commit, which gives the driver an opportunity to claim it wants control over commiting a particular req. pnfs_choose_commit_list() is called from nfs_scan_list to choose which list a given req should be added to, based on where we intend to send it for COMMIT. It is up to the driver to have preallocated list headers for each destination it may need. pnfs_commit_list() is how the driver actually takes control, it is used instead of nfs_commit_list(). In order to pass information between the above functions, we create a union in nfs_page to hold a lseg (which is possible because the req is not on any list while in transition), and add some flags to indicate if we need to use the pnfs code. Signed-off-by: Fred Isaman Signed-off-by: Trond Myklebust --- include/linux/nfs_page.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux/nfs_page.h') diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 92d54c81f51e..8023e4e25133 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -33,11 +33,15 @@ enum { PG_CLEAN, PG_NEED_COMMIT, PG_NEED_RESCHED, + PG_PNFS_COMMIT, }; struct nfs_inode; struct nfs_page { - struct list_head wb_list; /* Defines state of page: */ + union { + struct list_head wb_list; /* Defines state of page: */ + struct pnfs_layout_segment *wb_commit_lseg; /* Used when PG_PNFS_COMMIT set */ + }; struct page *wb_page; /* page to read in/write out */ struct nfs_open_context *wb_context; /* File state context info */ struct nfs_lock_context *wb_lock_context; /* lock context info */ -- cgit v1.2.2 From 4d65c520fb4abed970069d18c119cfe85624f46d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 25 Mar 2011 14:15:11 -0400 Subject: NFS: Fix a hang in the writeback path Now that the inode scalability patches have been merged, it is no longer safe to call igrab() under the inode->i_lock. Now that we no longer call nfs_clear_request() until the nfs_page is being freed, we know that we are always holding a reference to the nfs_open_context, which again holds a reference to the path, and so the inode cannot be freed until the last nfs_page has been removed from the radix tree and freed. We can therefore skip the igrab()/iput() altogether. Signed-off-by: Trond Myklebust --- include/linux/nfs_page.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/nfs_page.h') diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 8023e4e25133..91af2e49fa3a 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -78,7 +78,6 @@ extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx, struct page *page, unsigned int offset, unsigned int count); -extern void nfs_clear_request(struct nfs_page *req); extern void nfs_release_request(struct nfs_page *req); -- cgit v1.2.2