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
1 changed files with 20 additions and 10 deletions
|
@ -1141,8 +1141,9 @@ out:
|
||||||
#ifdef CONFIG_NFSD_V3
|
#ifdef CONFIG_NFSD_V3
|
||||||
/*
|
/*
|
||||||
* Commit all pending writes to stable storage.
|
* 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
|
* 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.
|
* 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)
|
loff_t offset, unsigned long count)
|
||||||
{
|
{
|
||||||
struct file *file;
|
struct file *file;
|
||||||
__be32 err;
|
loff_t end = LLONG_MAX;
|
||||||
|
__be32 err = nfserr_inval;
|
||||||
|
|
||||||
if ((u64)count > ~(u64)offset)
|
if (offset < 0)
|
||||||
return nfserr_inval;
|
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);
|
err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto out;
|
||||||
if (EX_ISSYNC(fhp->fh_export)) {
|
if (EX_ISSYNC(fhp->fh_export)) {
|
||||||
if (file->f_op && file->f_op->fsync) {
|
int err2 = vfs_fsync_range(file, file->f_path.dentry,
|
||||||
err = nfserrno(vfs_fsync(file, file->f_path.dentry, 0));
|
offset, end, 0);
|
||||||
} else {
|
|
||||||
|
if (err2 != -EINVAL)
|
||||||
|
err = nfserrno(err2);
|
||||||
|
else
|
||||||
err = nfserr_notsupp;
|
err = nfserr_notsupp;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nfsd_close(file);
|
nfsd_close(file);
|
||||||
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NFSD_V3 */
|
#endif /* CONFIG_NFSD_V3 */
|
||||||
|
|
Loading…
Add table
Reference in a new issue