From a9a6d78a9b8dec10bb5fe82245325481ef371963 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Sun, 4 Aug 2024 10:28:38 +1000 Subject: [PATCH] config: remove HAVE_VFS_RW_ITERATE Sponsored-by: https://despairlabs.com/sponsor/ Reviewed-by: Brian Behlendorf Reviewed-by: Tony Hutter Reviewed-by: Tino Reichardt Signed-off-by: Rob Norris Closes #16479 --- config/kernel-vfs-new-sync-rw.m4 | 29 ++++++ config/kernel-vfs-rw-iterate.m4 | 56 ----------- config/kernel.m4 | 4 +- module/os/linux/zfs/zpl_file.c | 161 ++++--------------------------- 4 files changed, 51 insertions(+), 199 deletions(-) create mode 100644 config/kernel-vfs-new-sync-rw.m4 delete mode 100644 config/kernel-vfs-rw-iterate.m4 diff --git a/config/kernel-vfs-new-sync-rw.m4 b/config/kernel-vfs-new-sync-rw.m4 new file mode 100644 index 000000000..c7332f373 --- /dev/null +++ b/config/kernel-vfs-new-sync-rw.m4 @@ -0,0 +1,29 @@ +dnl # +dnl # Linux 4.1 API +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_NEW_SYNC_RW], [ + ZFS_LINUX_TEST_SRC([new_sync_rw], [ + #include + ],[ + ssize_t ret __attribute__ ((unused)); + struct file *filp = NULL; + char __user *rbuf = NULL; + const char __user *wbuf = NULL; + size_t len = 0; + loff_t ppos; + + ret = new_sync_read(filp, rbuf, len, &ppos); + ret = new_sync_write(filp, wbuf, len, &ppos); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_VFS_NEW_SYNC_RW], [ + AC_MSG_CHECKING([whether new_sync_read/write() are available]) + ZFS_LINUX_TEST_RESULT([new_sync_rw], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NEW_SYNC_READ, 1, + [new_sync_read()/new_sync_write() are available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4 deleted file mode 100644 index 7c568e94f..000000000 --- a/config/kernel-vfs-rw-iterate.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl # -dnl # Linux 3.16 API -dnl # -AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE], [ - ZFS_LINUX_TEST_SRC([file_operations_rw], [ - #include - - static ssize_t test_read(struct kiocb *kiocb, struct iov_iter *to) - { return 0; } - static ssize_t test_write(struct kiocb *kiocb, struct iov_iter *from) - { return 0; } - - static const struct file_operations - fops __attribute__ ((unused)) = { - .read_iter = test_read, - .write_iter = test_write, - }; - ],[]) - - ZFS_LINUX_TEST_SRC([new_sync_rw], [ - #include - ],[ - ssize_t ret __attribute__ ((unused)); - struct file *filp = NULL; - char __user *rbuf = NULL; - const char __user *wbuf = NULL; - size_t len = 0; - loff_t ppos; - - ret = new_sync_read(filp, rbuf, len, &ppos); - ret = new_sync_write(filp, wbuf, len, &ppos); - ]) -]) - -AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], [ - AC_MSG_CHECKING([whether fops->read/write_iter() are available]) - ZFS_LINUX_TEST_RESULT([file_operations_rw], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_VFS_RW_ITERATE, 1, - [fops->read/write_iter() are available]) - - dnl # - dnl # Linux 4.1 API - dnl # - AC_MSG_CHECKING([whether new_sync_read/write() are available]) - ZFS_LINUX_TEST_RESULT([new_sync_rw], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_NEW_SYNC_READ, 1, - [new_sync_read()/new_sync_write() are available]) - ],[ - AC_MSG_RESULT(no) - ]) - ],[ - AC_MSG_RESULT(no) - ]) -]) diff --git a/config/kernel.m4 b/config/kernel.m4 index c7fa69bee..b5de5ab46 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -102,7 +102,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO ZFS_AC_KERNEL_SRC_VFS_READPAGES ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS - ZFS_AC_KERNEL_SRC_VFS_RW_ITERATE + ZFS_AC_KERNEL_SRC_VFS_NEW_SYNC_RW ZFS_AC_KERNEL_SRC_VFS_IOV_ITER ZFS_AC_KERNEL_SRC_VFS_COPY_FILE_RANGE ZFS_AC_KERNEL_SRC_VFS_GENERIC_COPY_FILE_RANGE @@ -241,7 +241,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_VFS_DIRECT_IO ZFS_AC_KERNEL_VFS_READPAGES ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS - ZFS_AC_KERNEL_VFS_RW_ITERATE + ZFS_AC_KERNEL_VFS_NEW_SYNC_RW ZFS_AC_KERNEL_VFS_IOV_ITER ZFS_AC_KERNEL_VFS_COPY_FILE_RANGE ZFS_AC_KERNEL_VFS_GENERIC_COPY_FILE_RANGE diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c index d0eaa6289..0c9e6f94e 100644 --- a/module/os/linux/zfs/zpl_file.c +++ b/module/os/linux/zfs/zpl_file.c @@ -240,8 +240,6 @@ zpl_file_accessed(struct file *filp) } } -#if defined(HAVE_VFS_RW_ITERATE) - /* * When HAVE_VFS_IOV_ITER is defined the iov_iter structure supports * iovecs, kvevs, bvecs and pipes, plus all the required interfaces to @@ -277,14 +275,14 @@ zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to) crhold(cr); cookie = spl_fstrans_mark(); - int error = -zfs_read(ITOZ(filp->f_mapping->host), &uio, + ssize_t ret = -zfs_read(ITOZ(filp->f_mapping->host), &uio, filp->f_flags | zfs_io_flags(kiocb), cr); spl_fstrans_unmark(cookie); crfree(cr); - if (error < 0) - return (error); + if (ret < 0) + return (ret); ssize_t read = count - uio.uio_resid; kiocb->ki_pos += read; @@ -327,14 +325,14 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from) crhold(cr); cookie = spl_fstrans_mark(); - int error = -zfs_write(ITOZ(ip), &uio, + ret = -zfs_write(ITOZ(ip), &uio, filp->f_flags | zfs_io_flags(kiocb), cr); spl_fstrans_unmark(cookie); crfree(cr); - if (error < 0) - return (error); + if (ret < 0) + return (ret); ssize_t wrote = count - uio.uio_resid; kiocb->ki_pos += wrote; @@ -342,154 +340,41 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from) return (wrote); } -#else /* !HAVE_VFS_RW_ITERATE */ - static ssize_t -zpl_aio_read(struct kiocb *kiocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) +zpl_direct_IO_impl(void) { - cred_t *cr = CRED(); - fstrans_cookie_t cookie; - struct file *filp = kiocb->ki_filp; - size_t count; - ssize_t ret; - - ret = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE); - if (ret) - return (ret); - - zfs_uio_t uio; - zfs_uio_iovec_init(&uio, iov, nr_segs, kiocb->ki_pos, UIO_USERSPACE, - count, 0); - - crhold(cr); - cookie = spl_fstrans_mark(); - - int error = -zfs_read(ITOZ(filp->f_mapping->host), &uio, - filp->f_flags | zfs_io_flags(kiocb), cr); - - spl_fstrans_unmark(cookie); - crfree(cr); - - if (error < 0) - return (error); - - ssize_t read = count - uio.uio_resid; - kiocb->ki_pos += read; - - zpl_file_accessed(filp); - - return (read); + /* + * All O_DIRECT requests should be handled by + * zpl_{iter/aio}_{write/read}(). There is no way kernel generic code + * should call the direct_IO address_space_operations function. We set + * this code path to be fatal if it is executed. + */ + PANIC(0); + return (0); } -static ssize_t -zpl_aio_write(struct kiocb *kiocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) -{ - cred_t *cr = CRED(); - fstrans_cookie_t cookie; - struct file *filp = kiocb->ki_filp; - struct inode *ip = filp->f_mapping->host; - size_t count; - ssize_t ret; - - ret = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); - if (ret) - return (ret); - - ret = generic_write_checks(filp, &pos, &count, S_ISBLK(ip->i_mode)); - if (ret) - return (ret); - - kiocb->ki_pos = pos; - - zfs_uio_t uio; - zfs_uio_iovec_init(&uio, iov, nr_segs, kiocb->ki_pos, UIO_USERSPACE, - count, 0); - - crhold(cr); - cookie = spl_fstrans_mark(); - - int error = -zfs_write(ITOZ(ip), &uio, - filp->f_flags | zfs_io_flags(kiocb), cr); - - spl_fstrans_unmark(cookie); - crfree(cr); - - if (error < 0) - return (error); - - ssize_t wrote = count - uio.uio_resid; - kiocb->ki_pos += wrote; - - return (wrote); -} -#endif /* HAVE_VFS_RW_ITERATE */ - -#if defined(HAVE_VFS_RW_ITERATE) -static ssize_t -zpl_direct_IO_impl(int rw, struct kiocb *kiocb, struct iov_iter *iter) -{ - if (rw == WRITE) - return (zpl_iter_write(kiocb, iter)); - else - return (zpl_iter_read(kiocb, iter)); -} #if defined(HAVE_VFS_DIRECT_IO_ITER) static ssize_t zpl_direct_IO(struct kiocb *kiocb, struct iov_iter *iter) { - return (zpl_direct_IO_impl(iov_iter_rw(iter), kiocb, iter)); + return (zpl_direct_IO_impl()); } #elif defined(HAVE_VFS_DIRECT_IO_ITER_OFFSET) static ssize_t zpl_direct_IO(struct kiocb *kiocb, struct iov_iter *iter, loff_t pos) { - ASSERT3S(pos, ==, kiocb->ki_pos); - return (zpl_direct_IO_impl(iov_iter_rw(iter), kiocb, iter)); + return (zpl_direct_IO_impl()); } #elif defined(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET) static ssize_t zpl_direct_IO(int rw, struct kiocb *kiocb, struct iov_iter *iter, loff_t pos) { - ASSERT3S(pos, ==, kiocb->ki_pos); - return (zpl_direct_IO_impl(rw, kiocb, iter)); + return (zpl_direct_IO_impl()); } #else -#error "Unknown direct IO interface" +#error "Unknown Direct I/O interface" #endif -#else /* HAVE_VFS_RW_ITERATE */ - -#if defined(HAVE_VFS_DIRECT_IO_IOVEC) -static ssize_t -zpl_direct_IO(int rw, struct kiocb *kiocb, const struct iovec *iov, - loff_t pos, unsigned long nr_segs) -{ - if (rw == WRITE) - return (zpl_aio_write(kiocb, iov, nr_segs, pos)); - else - return (zpl_aio_read(kiocb, iov, nr_segs, pos)); -} -#elif defined(HAVE_VFS_DIRECT_IO_ITER_RW_OFFSET) -static ssize_t -zpl_direct_IO(int rw, struct kiocb *kiocb, struct iov_iter *iter, loff_t pos) -{ - const struct iovec *iovp = iov_iter_iovec(iter); - unsigned long nr_segs = iter->nr_segs; - - ASSERT3S(pos, ==, kiocb->ki_pos); - if (rw == WRITE) - return (zpl_aio_write(kiocb, iovp, nr_segs, pos)); - else - return (zpl_aio_read(kiocb, iovp, nr_segs, pos)); -} -#else -#error "Unknown direct IO interface" -#endif - -#endif /* HAVE_VFS_RW_ITERATE */ - static loff_t zpl_llseek(struct file *filp, loff_t offset, int whence) { @@ -570,6 +455,7 @@ zpl_mmap(struct file *filp, struct vm_area_struct *vma) error = -zfs_map(ip, vma->vm_pgoff, (caddr_t *)vma->vm_start, (size_t)(vma->vm_end - vma->vm_start), vma->vm_flags); spl_fstrans_unmark(cookie); + if (error) return (error); @@ -1255,7 +1141,6 @@ const struct file_operations zpl_file_operations = { .open = zpl_open, .release = zpl_release, .llseek = zpl_llseek, -#ifdef HAVE_VFS_RW_ITERATE #ifdef HAVE_NEW_SYNC_READ .read = new_sync_read, .write = new_sync_write, @@ -1269,12 +1154,6 @@ const struct file_operations zpl_file_operations = { .splice_read = generic_file_splice_read, #endif .splice_write = iter_file_splice_write, -#endif -#else - .read = do_sync_read, - .write = do_sync_write, - .aio_read = zpl_aio_read, - .aio_write = zpl_aio_write, #endif .mmap = zpl_mmap, .fsync = zpl_fsync,