nfs: add support for splice writes
Subsystems (2)
PATCH RESEND 1/1 nfs: add support for splice writes
Adds support for splice writes. It effectively calls generic_file_splice_write() to do the writes.
We need not worry about O_APPEND case as the combination of splice() writes and O_APPEND is disallowed. This patch propagates NFS write errors back to the caller. The number of bytes written via splice are being added to NFSIO_NORMALWRITTENBYTES as these are effectively cached writes.
--- fs/nfs/file.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)
fs/nfs/file.c +31 -0
@@ -48,6 +48,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos, size_t count, unsigned int flags);static ssize_t nfs_file_read (struct kiocb *,const struct iovec *iov,unsigned long nr_segs,loff_t pos); +static ssize_t nfs_file_splice_write (struct pipe_inode_info *pipe, +struct file *filp,loff_t *ppos, +size_t count,unsigned int flags);static ssize_t nfs_file_write (struct kiocb *,const struct iovec *iov,unsigned long nr_segs,loff_t pos);static int nfs_file_flush (struct file *,fl_owner_t id);
@@ -73,6 +76,7 @@ const struct file_operations nfs_file_operations = { .lock = nfs_lock, .flock = nfs_flock, .splice_read = nfs_file_splice_read, + .splice_write = nfs_file_splice_write, .check_flags = nfs_check_flags, .setlease = nfs_setlease, };
@@ -587,6 +591,33 @@ out_swapfile: goto out; } +static ssize_t nfs_file_splice_write (struct pipe_inode_info *pipe, +struct file *filp,loff_t *ppos, +size_t count,unsigned int flags) +{ +struct dentry *dentry = filp->f_path.dentry; +struct inode *inode = dentry->d_inode; +ssize_t ret; + +dprintk ("NFS splice_write(%s/%s, %lu@%llu)\n" , + dentry->d_parent->d_name.name, dentry->d_name.name, + (unsigned long ) count, (unsigned long long ) *ppos); + +/* +* The combination of splice and an O_APPEND destination is disallowed. +*/ + +nfs_add_stats (inode,NFSIOS_NORMALWRITTENBYTES , count); + + ret =generic_file_splice_write (pipe, filp, ppos, count, flags); +if (ret >=0 &&nfs_need_sync_write (filp, inode)) { +int err =nfs_do_fsync (nfs_file_open_context (filp), inode); +if (err <0 ) + ret = err; + } +return ret; +} +static int do_getlk (struct file *filp,int cmd,struct file_lock *fl) {struct inode *inode = filp->f_mapping->host;
Quoted 60 lines · Suresh Jayaraman
Adds support for splice writes. It effectively calls
generic_file_splice_write()to do the writes.We need not worry about
O_APPENDcase as the combination ofsplice()writes andO_APPENDis disallowed. This patch propagates NFS write errors back to the caller. The number of bytes written via splice are being added toNFSIO_NORMALWRITTENBYTESas these are effectively cached writes.Signed-off-by Suresh Jayaraman <[email protected]>--- fs/nfs/file.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)fs/nfs/file.c +24
-0@@ -48,6 +48,9 @@ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos, size_t count, unsigned int flags);static ssize_t nfs_file_read (struct kiocb *,const struct iovec *iov,unsigned long nr_segs,loff_t pos); +static ssize_t nfs_file_splice_write (struct pipe_inode_info *pipe, +struct file *filp,loff_t *ppos, +size_t count,unsigned int flags);static ssize_t nfs_file_write (struct kiocb *,const struct iovec *iov,unsigned long nr_segs,loff_t pos);static int nfs_file_flush (struct file *,fl_owner_t id);@@ -73,6 +76,7 @@ const struct file_operations nfs_file_operations = { .lock = nfs_lock, .flock = nfs_flock, .splice_read = nfs_file_splice_read, + .splice_write = nfs_file_splice_write, .check_flags = nfs_check_flags, .setlease = nfs_setlease, };@@ -587,6 +591,33 @@ out_swapfile: goto out; } +static ssize_t nfs_file_splice_write (struct pipe_inode_info *pipe, +struct file *filp,loff_t *ppos, +size_t count,unsigned int flags) +{ +struct dentry *dentry = filp->f_path.dentry; +struct inode *inode = dentry->d_inode; +ssize_t ret; + +dprintk ("NFS splice_write(%s/%s, %lu@%llu)\n" , + dentry->d_parent->d_name.name, dentry->d_name.name, + (unsigned long ) count, (unsigned long long ) *ppos); + +/* +* The combination of splice and an O_APPEND destination is disallowed. +*/ + +nfs_add_stats (inode,NFSIOS_NORMALWRITTENBYTES , count); + + ret =generic_file_splice_write (pipe, filp, ppos, count, flags); +if (ret >=0 &&nfs_need_sync_write (filp, inode)) {
fs/nfs/file.c out_swapfile: · line 623
Quoted 10 lines
fs/nfs/file.c +7
-0+int err =nfs_do_fsync (nfs_file_open_context (filp), inode); +if (err <0 ) + ret = err; + } +return ret; +} +static int do_getlk (struct file *filp,int cmd,struct file_lock *fl) {struct inode *inode = filp->f_mapping->host;
Thanks Suresh! That patch looks good...
Cheers
Trond
Signature · 6 lines
Trond Myklebust Linux NFS client maintainer NetApp [email protected] www.netapp.com