diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-21 17:02:00 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-21 21:08:17 -0400 |
commit | b31268ac793fd300da66b9c28bbf0a200339ab96 (patch) | |
tree | 910978e11c5e6d94fb5be82f38cbc6d3ef65c020 | |
parent | 8e26de238fd794c8ea56a5c98bf67c40cfeb051d (diff) |
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 <neilb@suse.de>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/pagelist.c | 3 | ||||
-rw-r--r-- | fs/nfs/write.c | 16 | ||||
-rw-r--r-- | include/linux/nfs_fs.h | 2 | ||||
-rw-r--r-- | include/linux/nfs_page.h | 1 |
4 files changed, 19 insertions, 3 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 23e794410669..fd85618149a1 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -223,6 +223,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
223 | desc->pg_count = 0; | 223 | desc->pg_count = 0; |
224 | desc->pg_bsize = bsize; | 224 | desc->pg_bsize = bsize; |
225 | desc->pg_base = 0; | 225 | desc->pg_base = 0; |
226 | desc->pg_moreio = 0; | ||
226 | desc->pg_inode = inode; | 227 | desc->pg_inode = inode; |
227 | desc->pg_doio = doio; | 228 | desc->pg_doio = doio; |
228 | desc->pg_ioflags = io_flags; | 229 | desc->pg_ioflags = io_flags; |
@@ -335,9 +336,11 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | |||
335 | struct nfs_page *req) | 336 | struct nfs_page *req) |
336 | { | 337 | { |
337 | while (!nfs_pageio_do_add_request(desc, req)) { | 338 | while (!nfs_pageio_do_add_request(desc, req)) { |
339 | desc->pg_moreio = 1; | ||
338 | nfs_pageio_doio(desc); | 340 | nfs_pageio_doio(desc); |
339 | if (desc->pg_error < 0) | 341 | if (desc->pg_error < 0) |
340 | return 0; | 342 | return 0; |
343 | desc->pg_moreio = 0; | ||
341 | } | 344 | } |
342 | return 1; | 345 | return 1; |
343 | } | 346 | } |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 47a3ad63e0d5..4d686ee53244 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -179,8 +179,8 @@ static int wb_priority(struct writeback_control *wbc) | |||
179 | if (wbc->for_reclaim) | 179 | if (wbc->for_reclaim) |
180 | return FLUSH_HIGHPRI | FLUSH_STABLE; | 180 | return FLUSH_HIGHPRI | FLUSH_STABLE; |
181 | if (wbc->for_kupdate || wbc->for_background) | 181 | if (wbc->for_kupdate || wbc->for_background) |
182 | return FLUSH_LOWPRI; | 182 | return FLUSH_LOWPRI | FLUSH_COND_STABLE; |
183 | return 0; | 183 | return FLUSH_COND_STABLE; |
184 | } | 184 | } |
185 | 185 | ||
186 | /* | 186 | /* |
@@ -863,7 +863,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
863 | data->args.context = get_nfs_open_context(req->wb_context); | 863 | data->args.context = get_nfs_open_context(req->wb_context); |
864 | data->args.lock_context = req->wb_lock_context; | 864 | data->args.lock_context = req->wb_lock_context; |
865 | data->args.stable = NFS_UNSTABLE; | 865 | data->args.stable = NFS_UNSTABLE; |
866 | if (how & FLUSH_STABLE) { | 866 | if (how & (FLUSH_STABLE | FLUSH_COND_STABLE)) { |
867 | data->args.stable = NFS_DATA_SYNC; | 867 | data->args.stable = NFS_DATA_SYNC; |
868 | if (!nfs_need_commit(NFS_I(inode))) | 868 | if (!nfs_need_commit(NFS_I(inode))) |
869 | data->args.stable = NFS_FILE_SYNC; | 869 | data->args.stable = NFS_FILE_SYNC; |
@@ -912,6 +912,12 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) | |||
912 | 912 | ||
913 | nfs_list_remove_request(req); | 913 | nfs_list_remove_request(req); |
914 | 914 | ||
915 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && | ||
916 | (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit || | ||
917 | desc->pg_count > wsize)) | ||
918 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; | ||
919 | |||
920 | |||
915 | nbytes = desc->pg_count; | 921 | nbytes = desc->pg_count; |
916 | do { | 922 | do { |
917 | size_t len = min(nbytes, wsize); | 923 | size_t len = min(nbytes, wsize); |
@@ -1002,6 +1008,10 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc) | |||
1002 | if ((!lseg) && list_is_singular(&data->pages)) | 1008 | if ((!lseg) && list_is_singular(&data->pages)) |
1003 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW); | 1009 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW); |
1004 | 1010 | ||
1011 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && | ||
1012 | (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) | ||
1013 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; | ||
1014 | |||
1005 | /* Set up the argument struct */ | 1015 | /* Set up the argument struct */ |
1006 | ret = nfs_write_rpcsetup(req, data, &nfs_write_full_ops, desc->pg_count, 0, lseg, desc->pg_ioflags); | 1016 | ret = nfs_write_rpcsetup(req, data, &nfs_write_full_ops, desc->pg_count, 0, lseg, desc->pg_ioflags); |
1007 | out: | 1017 | out: |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index f88522b10a38..cb2add401f25 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -33,6 +33,8 @@ | |||
33 | #define FLUSH_STABLE 4 /* commit to stable storage */ | 33 | #define FLUSH_STABLE 4 /* commit to stable storage */ |
34 | #define FLUSH_LOWPRI 8 /* low priority background flush */ | 34 | #define FLUSH_LOWPRI 8 /* low priority background flush */ |
35 | #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ | 35 | #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ |
36 | #define FLUSH_COND_STABLE 32 /* conditional stable write - only stable | ||
37 | * if everything fits in one RPC */ | ||
36 | 38 | ||
37 | #ifdef __KERNEL__ | 39 | #ifdef __KERNEL__ |
38 | 40 | ||
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 { | |||
57 | size_t pg_count; | 57 | size_t pg_count; |
58 | size_t pg_bsize; | 58 | size_t pg_bsize; |
59 | unsigned int pg_base; | 59 | unsigned int pg_base; |
60 | char pg_moreio; | ||
60 | 61 | ||
61 | struct inode *pg_inode; | 62 | struct inode *pg_inode; |
62 | int (*pg_doio)(struct nfs_pageio_descriptor *); | 63 | int (*pg_doio)(struct nfs_pageio_descriptor *); |