From: Oleg Drokin Date: Fri, 9 Jun 2017 20:51:56 +0000 (-0400) Subject: LU-20 osd-ldiskfs: Make readonly patches optional X-Git-Tag: 2.10.0-RC1~19 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=0f0a43b4ba6660a88f7922aadaba1a69c297142c;ds=sidebyside LU-20 osd-ldiskfs: Make readonly patches optional If CONFIG_KALLSYMS is enabled, see if there are dev_set/check_rdonly functions present and use them if so. Otherwise assume the functionality is unavailable. This should allow using osd_ldiskfs module on both patched and unpatched kernels with no modifications thanks to weak updates. Change-Id: I274db77cf76abc63ad6a5643a98c521778f294b3 Signed-off-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/27549 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Andreas Dilger --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index c6f2377..b9b8a6d 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -74,19 +74,6 @@ AC_CHECK_FUNCS([name_to_handle_at], ]) # LC_GLIBC_SUPPORT_FHANDLES # -# LC_FUNC_DEV_SET_RDONLY -# -# check whether dev_set_rdonly is exported. This is needed until we -# have another mechanism to fence IO from the underlying device. -# -AC_DEFUN([LC_FUNC_DEV_SET_RDONLY], [ -LB_CHECK_EXPORT([dev_set_rdonly], [block/ll_rw_block.c block/blk-core.c], - [AC_DEFINE(HAVE_DEV_SET_RDONLY, 1, - [kernel exports dev_set_rdonly])], - [AC_MSG_WARN([kernel missing dev_set_rdonly patch for testing])]) -]) # LC_FUNC_DEV_SET_RDONLY - -# # LC_STACK_SIZE # # Ensure the stack size is at least 8k in Lustre server (all kernels) @@ -2694,7 +2681,6 @@ AC_DEFUN([LC_PROG_LINUX], [ # AS_IF([test "x$enable_server" != xno], [ - LC_FUNC_DEV_SET_RDONLY LC_STACK_SIZE LC_QUOTA64 LC_QUOTA_CONFIG diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index c0030b2..4e98210 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2161,44 +2161,47 @@ static int osd_commit_async(const struct lu_env *env, RETURN(s->s_op->sync_fs(s, 0)); } +/* Our own copy of the set readonly functions if present, or NU if not. */ +static int (*priv_dev_set_rdonly)(struct block_device *bdev); +static int (*priv_dev_check_rdonly)(struct block_device *bdev); +/* static int (*priv_dev_clear_rdonly)(struct block_device *bdev); */ + /* * Concurrency: shouldn't matter. */ - static int osd_ro(const struct lu_env *env, struct dt_device *d) { struct super_block *sb = osd_sb(osd_dt_dev(d)); struct block_device *dev = sb->s_bdev; -#ifdef HAVE_DEV_SET_RDONLY - struct block_device *jdev = LDISKFS_SB(sb)->journal_bdev; - int rc = 0; -#else int rc = -EOPNOTSUPP; -#endif ENTRY; -#ifdef HAVE_DEV_SET_RDONLY - CERROR("*** setting %s read-only ***\n", osd_dt_dev(d)->od_svname); + if (priv_dev_set_rdonly) { + struct block_device *jdev = LDISKFS_SB(sb)->journal_bdev; - if (sb->s_op->freeze_fs) { - rc = sb->s_op->freeze_fs(sb); - if (rc) - goto out; - } + rc = 0; + CERROR("*** setting %s read-only ***\n", + osd_dt_dev(d)->od_svname); - if (jdev && (jdev != dev)) { - CDEBUG(D_IOCTL | D_HA, "set journal dev %lx rdonly\n", - (long)jdev); - dev_set_rdonly(jdev); - } - CDEBUG(D_IOCTL | D_HA, "set dev %lx rdonly\n", (long)dev); - dev_set_rdonly(dev); + if (sb->s_op->freeze_fs) { + rc = sb->s_op->freeze_fs(sb); + if (rc) + goto out; + } + + if (jdev && (jdev != dev)) { + CDEBUG(D_IOCTL | D_HA, "set journal dev %lx rdonly\n", + (long)jdev); + priv_dev_set_rdonly(jdev); + } + CDEBUG(D_IOCTL | D_HA, "set dev %lx rdonly\n", (long)dev); + priv_dev_set_rdonly(dev); - if (sb->s_op->unfreeze_fs) - sb->s_op->unfreeze_fs(sb); + if (sb->s_op->unfreeze_fs) + sb->s_op->unfreeze_fs(sb); + } out: -#endif if (rc) CERROR("%s: %lx CANNOT BE SET READONLY: rc = %d\n", osd_dt_dev(d)->od_svname, (long)dev, rc); @@ -6968,25 +6971,23 @@ static int osd_mount(const struct lu_env *env, } if (lmd_flags & LMD_FLG_DEV_RDONLY) { -#ifdef HAVE_DEV_SET_RDONLY - dev_set_rdonly(osd_sb(o)->s_bdev); - o->od_dt_dev.dd_rdonly = 1; - LCONSOLE_WARN("%s: set dev_rdonly on this device\n", name); -#else - LCONSOLE_WARN("%s: not support dev_rdonly on this device", - name); - - GOTO(out_mnt, rc = -EOPNOTSUPP); -#endif - } else { -#ifdef HAVE_DEV_SET_RDONLY - if (dev_check_rdonly(osd_sb(o)->s_bdev)) { - CERROR("%s: underlying device %s is marked as " - "read-only. Setup failed\n", name, dev); + if (priv_dev_set_rdonly) { + priv_dev_set_rdonly(osd_sb(o)->s_bdev); + o->od_dt_dev.dd_rdonly = 1; + LCONSOLE_WARN("%s: set dev_rdonly on this device\n", + name); + } else { + LCONSOLE_WARN("%s: not support dev_rdonly on this device", + name); - GOTO(out_mnt, rc = -EROFS); + GOTO(out_mnt, rc = -EOPNOTSUPP); } -#endif + } else if (priv_dev_check_rdonly && + priv_dev_check_rdonly(osd_sb(o)->s_bdev)) { + CERROR("%s: underlying device %s is marked as " + "read-only. Setup failed\n", name, dev); + + GOTO(out_mnt, rc = -EROFS); } if (!LDISKFS_HAS_COMPAT_FEATURE(o->od_mnt->mnt_sb, @@ -7404,6 +7405,13 @@ static int __init osd_init(void) if (rc) return rc; +#ifdef CONFIG_KALLSYMS + priv_dev_set_rdonly = (void *)kallsyms_lookup_name("dev_set_rdonly"); + priv_dev_check_rdonly = (void *)kallsyms_lookup_name("dev_check_rdonly"); + /* Clear readonly is unused at this time */ + /*priv_dev_clear_rdonly = (void *)kallsyms_lookup_name("dev_clear_rdonly");*/ +#endif + rc = class_register_type(&osd_obd_device_ops, NULL, true, lprocfs_osd_module_vars, LUSTRE_OSD_LDISKFS_NAME, &osd_device_type);