nfsd: Use vfs_fsync_range() in nfsd_commit
The NFS COMMIT operation allows the client to specify the exact byte range that it wishes to sync to disk in order to optimise server performance. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
37498292aa
commit
aa696a6f34
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user