diff options
author | Trond Myklebust <trond.myklebust@fys.uio.no> | 2009-06-05 12:35:15 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-06-15 21:14:57 -0400 |
commit | 48e03bc515cff75718de5460458680a230ae997e (patch) | |
tree | d8c3095c15e362e574b82b962ebf26f7589dc412 /fs/nfsd | |
parent | 7eef4091a653c243a87e5375c54504cc03bec4d8 (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/nfsd')
-rw-r--r-- | fs/nfsd/vfs.c | 8 |
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)); |