From 5b4d95e459f43e262d7c0a22e575e00136360a5b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 29 Jan 2010 16:44:25 -0500 Subject: [PATCH] --- yaml --- r: 186360 b: refs/heads/master c: aa696a6f349638428982bb52763f4cda851632fa h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/nfsd/vfs.c | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index ad0b6470fb32..a21be03804b3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 37498292aa97658a5d0a9bb84699ce8c1016bb74 +refs/heads/master: aa696a6f349638428982bb52763f4cda851632fa diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 79d216f276d9..ed024d329056 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1141,8 +1141,9 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, #ifdef CONFIG_NFSD_V3 /* * Commit all pending writes to stable storage. - * Strictly speaking, we could sync just the indicated file region here, - * but there's currently no way we can ask the VFS to do so. + * + * Note: we only guarantee that data that lies within the range specified + * by the 'offset' and 'count' parameters will be synced. * * Unfortunately we cannot lock the file to make sure we return full WCC * data to the client, as locking happens lower down in the filesystem. @@ -1152,23 +1153,32 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, unsigned long count) { struct file *file; - __be32 err; + loff_t end = LLONG_MAX; + __be32 err = nfserr_inval; - if ((u64)count > ~(u64)offset) - return nfserr_inval; + if (offset < 0) + goto out; + if (count != 0) { + end = offset + (loff_t)count - 1; + if (end < offset) + goto out; + } err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); if (err) - return err; + goto out; if (EX_ISSYNC(fhp->fh_export)) { - if (file->f_op && file->f_op->fsync) { - err = nfserrno(vfs_fsync(file, file->f_path.dentry, 0)); - } else { + int err2 = vfs_fsync_range(file, file->f_path.dentry, + offset, end, 0); + + if (err2 != -EINVAL) + err = nfserrno(err2); + else err = nfserr_notsupp; - } } nfsd_close(file); +out: return err; } #endif /* CONFIG_NFSD_V3 */