Message ID | 237db7dc485834d3d359b5765f07ebf7c3514f3a.1629234193.git.osandov@fb.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: add ioctls and send/receive support for reading/writing compressed data | expand |
On 18.08.21 г. 0:06, Omar Sandoval wrote: > From: Omar Sandoval <osandov@fb.com> > > Encoded I/O in Btrfs needs to check a write with a given logical size > without an iov_iter that matches that size (because the iov_iter we have > is for the compressed data). So, factor out the parts of > generic_write_check() that expect an iov_iter into a new > __generic_write_checks() function and export that. > > Signed-off-by: Omar Sandoval <osandov@fb.com> > --- > fs/read_write.c | 40 ++++++++++++++++++++++------------------ > include/linux/fs.h | 1 + > 2 files changed, 23 insertions(+), 18 deletions(-) > > diff --git a/fs/read_write.c b/fs/read_write.c > index 0029ff2b0ca8..3bddd5ee7f64 100644 > --- a/fs/read_write.c > +++ b/fs/read_write.c > @@ -1633,6 +1633,26 @@ int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count) > return 0; > } > > +/* Like generic_write_checks(), but takes size of write instead of iter. */ > +int __generic_write_checks(struct kiocb *iocb, loff_t *count) > +{ > + struct file *file = iocb->ki_filp; > + struct inode *inode = file->f_mapping->host; > + > + if (IS_SWAPFILE(inode)) > + return -ETXTBSY; Missing 'if(!count) return 0' from original code ? <snip>
On Fri, Aug 20, 2021 at 10:59:28AM +0300, Nikolay Borisov wrote: > > > On 18.08.21 г. 0:06, Omar Sandoval wrote: > > From: Omar Sandoval <osandov@fb.com> > > > > Encoded I/O in Btrfs needs to check a write with a given logical size > > without an iov_iter that matches that size (because the iov_iter we have > > is for the compressed data). So, factor out the parts of > > generic_write_check() that expect an iov_iter into a new > > __generic_write_checks() function and export that. > > > > Signed-off-by: Omar Sandoval <osandov@fb.com> > > --- > > fs/read_write.c | 40 ++++++++++++++++++++++------------------ > > include/linux/fs.h | 1 + > > 2 files changed, 23 insertions(+), 18 deletions(-) > > > > diff --git a/fs/read_write.c b/fs/read_write.c > > index 0029ff2b0ca8..3bddd5ee7f64 100644 > > --- a/fs/read_write.c > > +++ b/fs/read_write.c > > @@ -1633,6 +1633,26 @@ int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count) > > return 0; > > } > > > > +/* Like generic_write_checks(), but takes size of write instead of iter. */ > > +int __generic_write_checks(struct kiocb *iocb, loff_t *count) > > +{ > > + struct file *file = iocb->ki_filp; > > + struct inode *inode = file->f_mapping->host; > > + > > + if (IS_SWAPFILE(inode)) > > + return -ETXTBSY; > > Missing 'if(!count) return 0' from original code ? Good catch, thanks.
diff --git a/fs/read_write.c b/fs/read_write.c index 0029ff2b0ca8..3bddd5ee7f64 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1633,6 +1633,26 @@ int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count) return 0; } +/* Like generic_write_checks(), but takes size of write instead of iter. */ +int __generic_write_checks(struct kiocb *iocb, loff_t *count) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; + + if (IS_SWAPFILE(inode)) + return -ETXTBSY; + + /* FIXME: this is for backwards compatibility with 2.4 */ + if (iocb->ki_flags & IOCB_APPEND) + iocb->ki_pos = i_size_read(inode); + + if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) + return -EINVAL; + + return generic_write_check_limits(iocb->ki_filp, iocb->ki_pos, count); +} +EXPORT_SYMBOL(__generic_write_checks); + /* * Performs necessary checks before doing a write * @@ -1642,26 +1662,10 @@ int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count) */ ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) { - struct file *file = iocb->ki_filp; - struct inode *inode = file->f_mapping->host; - loff_t count; + loff_t count = iov_iter_count(from); int ret; - if (IS_SWAPFILE(inode)) - return -ETXTBSY; - - if (!iov_iter_count(from)) - return 0; - - /* FIXME: this is for backwards compatibility with 2.4 */ - if (iocb->ki_flags & IOCB_APPEND) - iocb->ki_pos = i_size_read(inode); - - if ((iocb->ki_flags & IOCB_NOWAIT) && !(iocb->ki_flags & IOCB_DIRECT)) - return -EINVAL; - - count = iov_iter_count(from); - ret = generic_write_check_limits(file, iocb->ki_pos, &count); + ret = __generic_write_checks(iocb, &count); if (ret) return ret; diff --git a/include/linux/fs.h b/include/linux/fs.h index 0de4d75339b9..b206814da181 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3227,6 +3227,7 @@ extern int sb_min_blocksize(struct super_block *, int); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); extern ssize_t generic_write_checks(struct kiocb *, struct iov_iter *); +extern int __generic_write_checks(struct kiocb *iocb, loff_t *count); extern int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count); extern int generic_file_rw_checks(struct file *file_in, struct file *file_out);