From 7a789346afec87a89c4cde465faf9be4996db556 Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Mon, 6 Mar 2017 09:20:20 -0800 Subject: [PATCH] Fix loop device becomes read-only Commit 933ec99 removes read and write from f_op because the vfs layer will select iter_write or aio_write automatically. However, for Linux <= 4.0, loop_set_fd will actually check f_op->write and set read-only if not exists. This patch add them back and use the generic do_sync_{read,write} for aio_{read,write} and new_sync_{read,write} for {read,write}_iter. Reviewed-by: George Melikov Reviewed-by: Brian Behlendorf Signed-off-by: Chunwei Chen Closes #5776 Closes #5855 --- config/kernel-vfs-rw-iterate.m4 | 22 +++++++++++++++++++++- module/zfs/zpl_file.c | 6 ++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/config/kernel-vfs-rw-iterate.m4 b/config/kernel-vfs-rw-iterate.m4 index af44beb7b..9f8fe6559 100644 --- a/config/kernel-vfs-rw-iterate.m4 +++ b/config/kernel-vfs-rw-iterate.m4 @@ -1,5 +1,5 @@ dnl # -dnl # Linux 4.1.x API +dnl # Linux 3.16 API dnl # AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], [AC_MSG_CHECKING([whether fops->read/write_iter() are available]) @@ -21,6 +21,26 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_VFS_RW_ITERATE, 1, [fops->read/write_iter() are available]) + + ZFS_AC_KERNEL_NEW_SYNC_READ + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # Linux 4.1 API +dnl # +AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ], + [AC_MSG_CHECKING([whether new_sync_read() is available]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + new_sync_read(NULL, NULL, 0, NULL); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NEW_SYNC_READ, 1, + [new_sync_read() is available]) ],[ AC_MSG_RESULT(no) ]) diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index b625d8412..cdacdba27 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -856,9 +856,15 @@ const struct file_operations zpl_file_operations = { .release = zpl_release, .llseek = zpl_llseek, #ifdef HAVE_VFS_RW_ITERATE +#ifdef HAVE_NEW_SYNC_READ + .read = new_sync_read, + .write = new_sync_write, +#endif .read_iter = zpl_iter_read, .write_iter = zpl_iter_write, #else + .read = do_sync_read, + .write = do_sync_write, .aio_read = zpl_aio_read, .aio_write = zpl_aio_write, #endif