nfs: Provide a splice-read wrapper
[linux-block.git] / fs / nfs / file.c
index 2474cbc30712a8237e83ecd9770d6aefb8c181c2..3855f3ce8d2defd21e68a06d6c1bdcd0e37696c4 100644 (file)
@@ -178,6 +178,27 @@ nfs_file_read(struct kiocb *iocb, struct iov_iter *to)
 }
 EXPORT_SYMBOL_GPL(nfs_file_read);
 
+ssize_t
+nfs_file_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe,
+                    size_t len, unsigned int flags)
+{
+       struct inode *inode = file_inode(in);
+       ssize_t result;
+
+       dprintk("NFS: splice_read(%pD2, %zu@%llu)\n", in, len, *ppos);
+
+       nfs_start_io_read(inode);
+       result = nfs_revalidate_mapping(inode, in->f_mapping);
+       if (!result) {
+               result = filemap_splice_read(in, ppos, pipe, len, flags);
+               if (result > 0)
+                       nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, result);
+       }
+       nfs_end_io_read(inode);
+       return result;
+}
+EXPORT_SYMBOL_GPL(nfs_file_splice_read);
+
 int
 nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
 {
@@ -328,8 +349,8 @@ static int nfs_write_begin(struct file *file, struct address_space *mapping,
 start:
        folio = __filemap_get_folio(mapping, pos >> PAGE_SHIFT, FGP_WRITEBEGIN,
                                    mapping_gfp_mask(mapping));
-       if (!folio)
-               return -ENOMEM;
+       if (IS_ERR(folio))
+               return PTR_ERR(folio);
        *pagep = &folio->page;
 
        ret = nfs_flush_incompatible(file, folio);
@@ -879,7 +900,7 @@ const struct file_operations nfs_file_operations = {
        .fsync          = nfs_file_fsync,
        .lock           = nfs_lock,
        .flock          = nfs_flock,
-       .splice_read    = generic_file_splice_read,
+       .splice_read    = nfs_file_splice_read,
        .splice_write   = iter_file_splice_write,
        .check_flags    = nfs_check_flags,
        .setlease       = simple_nosetlease,