@@ -752,6 +752,44 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
752
752
return ret ;
753
753
}
754
754
755
+ static ssize_t zonefs_file_splice_read (struct file * in , loff_t * ppos ,
756
+ struct pipe_inode_info * pipe ,
757
+ size_t len , unsigned int flags )
758
+ {
759
+ struct inode * inode = file_inode (in );
760
+ struct zonefs_inode_info * zi = ZONEFS_I (inode );
761
+ struct zonefs_zone * z = zonefs_inode_zone (inode );
762
+ loff_t isize ;
763
+ ssize_t ret = 0 ;
764
+
765
+ /* Offline zones cannot be read */
766
+ if (unlikely (IS_IMMUTABLE (inode ) && !(inode -> i_mode & 0777 )))
767
+ return - EPERM ;
768
+
769
+ if (* ppos >= z -> z_capacity )
770
+ return 0 ;
771
+
772
+ inode_lock_shared (inode );
773
+
774
+ /* Limit read operations to written data */
775
+ mutex_lock (& zi -> i_truncate_mutex );
776
+ isize = i_size_read (inode );
777
+ if (* ppos >= isize )
778
+ len = 0 ;
779
+ else
780
+ len = min_t (loff_t , len , isize - * ppos );
781
+ mutex_unlock (& zi -> i_truncate_mutex );
782
+
783
+ if (len > 0 ) {
784
+ ret = filemap_splice_read (in , ppos , pipe , len , flags );
785
+ if (ret == - EIO )
786
+ zonefs_io_error (inode , false);
787
+ }
788
+
789
+ inode_unlock_shared (inode );
790
+ return ret ;
791
+ }
792
+
755
793
/*
756
794
* Write open accounting is done only for sequential files.
757
795
*/
@@ -896,7 +934,7 @@ const struct file_operations zonefs_file_operations = {
896
934
.llseek = zonefs_file_llseek ,
897
935
.read_iter = zonefs_file_read_iter ,
898
936
.write_iter = zonefs_file_write_iter ,
899
- .splice_read = generic_file_splice_read ,
937
+ .splice_read = zonefs_file_splice_read ,
900
938
.splice_write = iter_file_splice_write ,
901
939
.iopoll = iocb_bio_iopoll ,
902
940
};
0 commit comments