aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2009-06-05 12:35:15 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-06-15 21:14:57 -0400
commit48e03bc515cff75718de5460458680a230ae997e (patch)
treed8c3095c15e362e574b82b962ebf26f7589dc412 /fs
parent7eef4091a653c243a87e5375c54504cc03bec4d8 (diff)
nfsd: Use write gathering only with NFSv2
NFSv3 and above can use unstable writes whenever they are sending more than one write, rather than relying on the flaky write gathering heuristics. More often than not, write gathering is currently getting it wrong when the NFSv3 clients are sending a single write with FILE_SYNC for efficiency reasons. This patch turns off write gathering for NFSv3/v4, and ensures that it only applies to the one case that can actually benefit: namely NFSv2. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/vfs.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index b660435978d2..f30cc4eadb0a 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -975,6 +975,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
975 __be32 err = 0; 975 __be32 err = 0;
976 int host_err; 976 int host_err;
977 int stable = *stablep; 977 int stable = *stablep;
978 int use_wgather;
978 979
979#ifdef MSNFS 980#ifdef MSNFS
980 err = nfserr_perm; 981 err = nfserr_perm;
@@ -993,9 +994,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
993 * - the sync export option has been set, or 994 * - the sync export option has been set, or
994 * - the client requested O_SYNC behavior (NFSv3 feature). 995 * - the client requested O_SYNC behavior (NFSv3 feature).
995 * - The file system doesn't support fsync(). 996 * - The file system doesn't support fsync().
996 * When gathered writes have been configured for this volume, 997 * When NFSv2 gathered writes have been configured for this volume,
997 * flushing the data to disk is handled separately below. 998 * flushing the data to disk is handled separately below.
998 */ 999 */
1000 use_wgather = (rqstp->rq_vers == 2) && EX_WGATHER(exp);
999 1001
1000 if (!file->f_op->fsync) {/* COMMIT3 cannot work */ 1002 if (!file->f_op->fsync) {/* COMMIT3 cannot work */
1001 stable = 2; 1003 stable = 2;
@@ -1004,7 +1006,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1004 1006
1005 if (!EX_ISSYNC(exp)) 1007 if (!EX_ISSYNC(exp))
1006 stable = 0; 1008 stable = 0;
1007 if (stable && !EX_WGATHER(exp)) { 1009 if (stable && !use_wgather) {
1008 spin_lock(&file->f_lock); 1010 spin_lock(&file->f_lock);
1009 file->f_flags |= O_SYNC; 1011 file->f_flags |= O_SYNC;
1010 spin_unlock(&file->f_lock); 1012 spin_unlock(&file->f_lock);
@@ -1040,7 +1042,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1040 * nice and simple solution (IMHO), and it seems to 1042 * nice and simple solution (IMHO), and it seems to
1041 * work:-) 1043 * work:-)
1042 */ 1044 */
1043 if (EX_WGATHER(exp)) { 1045 if (use_wgather) {
1044 if (atomic_read(&inode->i_writecount) > 1 1046 if (atomic_read(&inode->i_writecount) > 1
1045 || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) { 1047 || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) {
1046 dprintk("nfsd: write defer %d\n", task_pid_nr(current)); 1048 dprintk("nfsd: write defer %d\n", task_pid_nr(current));