diff --git a/config/kernel-bdi-setup-and-register.m4 b/config/kernel-bdi-setup-and-register.m4 index 6369409b8b..f13d1fe53d 100644 --- a/config/kernel-bdi-setup-and-register.m4 +++ b/config/kernel-bdi-setup-and-register.m4 @@ -1,22 +1,36 @@ dnl # -dnl # 2.6.34 API change -dnl # The bdi_setup_and_register() helper function is avaliable and -dnl # exported by the kernel. This is a trivial helper function but -dnl # using it significantly simplifies the code surrounding setting -dnl # up and tearing down the bdi structure. +dnl # 2.6.32 - 2.6.33, bdi_setup_and_register() is not exported. +dnl # 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments. +dnl # 4.0 - x.y, bdi_setup_and_register() takes 2 arguments. dnl # -AC_DEFUN([ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER], - [AC_MSG_CHECKING([whether bdi_setup_and_register() is available]) +AC_DEFUN([ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER], [ + AC_MSG_CHECKING([whether bdi_setup_and_register() wants 2 args]) ZFS_LINUX_TRY_COMPILE_SYMBOL([ #include ], [ - int r = bdi_setup_and_register(NULL, NULL, 0); - r = *(&r); + struct backing_dev_info bdi; + char *name = "bdi"; + (void) bdi_setup_and_register(&bdi, name); ], [bdi_setup_and_register], [mm/backing-dev.c], [ AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_BDI_SETUP_AND_REGISTER, 1, - [bdi_setup_and_register() is available]) + AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1, + [bdi_setup_and_register() wants 2 args]) ], [ AC_MSG_RESULT(no) + AC_MSG_CHECKING([whether bdi_setup_and_register() wants 3 args]) + ZFS_LINUX_TRY_COMPILE_SYMBOL([ + #include + ], [ + struct backing_dev_info bdi; + char *name = "bdi"; + unsigned int cap = BDI_CAP_MAP_COPY; + (void) bdi_setup_and_register(&bdi, name, cap); + ], [bdi_setup_and_register], [mm/backing-dev.c], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1, + [bdi_setup_and_register() wants 3 args]) + ], [ + AC_MSG_RESULT(no) + ]) ]) ]) diff --git a/config/kernel-bdi.m4 b/config/kernel-bdi.m4 deleted file mode 100644 index 00bd37539c..0000000000 --- a/config/kernel-bdi.m4 +++ /dev/null @@ -1,21 +0,0 @@ -dnl # -dnl # 2.6.32 API change -dnl # Private backing_device_info interfaces available -dnl # -AC_DEFUN([ZFS_AC_KERNEL_BDI], [ - AC_MSG_CHECKING([whether super_block has s_bdi]) - ZFS_LINUX_TRY_COMPILE([ - #include - - static const struct super_block - sb __attribute__ ((unused)) = { - .s_bdi = NULL, - }; - ],[ - ],[ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_BDI, 1, [struct super_block has s_bdi]) - ],[ - AC_MSG_RESULT(no) - ]) -]) diff --git a/config/kernel.m4 b/config/kernel.m4 index e0b7954224..ce10707e49 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -90,7 +90,6 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_SHRINK ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD ZFS_AC_KERNEL_S_D_OP - ZFS_AC_KERNEL_BDI ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER ZFS_AC_KERNEL_SET_NLINK ZFS_AC_KERNEL_ELEVATOR_CHANGE diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h index 6f5a9dc968..e8f8448410 100644 --- a/include/linux/vfs_compat.h +++ b/include/linux/vfs_compat.h @@ -65,25 +65,35 @@ truncate_setsize(struct inode *ip, loff_t new) } #endif /* HAVE_TRUNCATE_SETSIZE */ -#if defined(HAVE_BDI) && !defined(HAVE_BDI_SETUP_AND_REGISTER) /* - * 2.6.34 API change, - * Add bdi_setup_and_register() function if not yet provided by kernel. - * It is used to quickly initialize and register a BDI for the filesystem. + * 2.6.32 - 2.6.33, bdi_setup_and_register() is not available. + * 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments. + * 4.0 - x.y, bdi_setup_and_register() takes 2 arguments. */ +#if defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER) +static inline int +zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name) +{ + return (bdi_setup_and_register(bdi, name)); +} +#elif defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER) +static inline int +zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name) +{ + return (bdi_setup_and_register(bdi, name, BDI_CAP_MAP_COPY)); +} +#else extern atomic_long_t zfs_bdi_seq; static inline int -bdi_setup_and_register( - struct backing_dev_info *bdi, - char *name, - unsigned int cap) +zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name) { char tmp[32]; int error; bdi->name = name; - bdi->capabilities = cap; + bdi->capabilities = BDI_CAP_MAP_COPY; + error = bdi_init(bdi); if (error) return (error); @@ -98,7 +108,7 @@ bdi_setup_and_register( return (error); } -#endif /* HAVE_BDI && !HAVE_BDI_SETUP_AND_REGISTER */ +#endif /* * 2.6.38 API change, diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index a2dea89b7f..4df324a68f 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1198,9 +1198,10 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting) } EXPORT_SYMBOL(zfs_sb_teardown); -#if defined(HAVE_BDI) && !defined(HAVE_BDI_SETUP_AND_REGISTER) +#if !defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER) && \ + !defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER) atomic_long_t zfs_bdi_seq = ATOMIC_LONG_INIT(0); -#endif /* HAVE_BDI && !HAVE_BDI_SETUP_AND_REGISTER */ +#endif int zfs_domount(struct super_block *sb, void *data, int silent) @@ -1227,23 +1228,12 @@ zfs_domount(struct super_block *sb, void *data, int silent) sb->s_time_gran = 1; sb->s_blocksize = recordsize; sb->s_blocksize_bits = ilog2(recordsize); - -#ifdef HAVE_BDI - /* - * 2.6.32 API change, - * Added backing_device_info (BDI) per super block interfaces. A BDI - * must be configured when using a non-device backed filesystem for - * proper writeback. This is not required for older pdflush kernels. - * - * NOTE: Linux read-ahead is disabled in favor of zfs read-ahead. - */ zsb->z_bdi.ra_pages = 0; sb->s_bdi = &zsb->z_bdi; - error = -bdi_setup_and_register(&zsb->z_bdi, "zfs", BDI_CAP_MAP_COPY); + error = -zpl_bdi_setup_and_register(&zsb->z_bdi, "zfs"); if (error) goto out; -#endif /* HAVE_BDI */ /* Set callback operations for the file system. */ sb->s_op = &zpl_super_operations; @@ -1336,10 +1326,7 @@ zfs_umount(struct super_block *sb) VERIFY(zfs_sb_teardown(zsb, B_TRUE) == 0); os = zsb->z_os; - -#ifdef HAVE_BDI bdi_destroy(sb->s_bdi); -#endif /* HAVE_BDI */ /* * z_os will be NULL if there was an error in