Whamcloud - gitweb
LU-17914 lnet: Fix erroneous net set error
[fs/lustre-release.git] / lustre / target / tgt_mount.c
index 442e289..0ca65ed 100644 (file)
  *
  * Author: Nathan Rutman <nathan@clusterfs.com>
  */
-
-
 #define DEBUG_SUBSYSTEM S_CLASS
 #define D_MOUNT (D_SUPER | D_CONFIG /* | D_WARNING */)
-#define PRINT_CMD CDEBUG
-#define PRINT_MASK (D_SUPER | D_CONFIG)
 
 #include <linux/types.h>
+#include <linux/generic-radix-tree.h>
 #ifdef HAVE_LINUX_SELINUX_IS_ENABLED
 #include <linux/selinux.h>
 #endif
 #include <linux/statfs.h>
 #include <linux/version.h>
 #include <linux/delay.h>
+#include <linux/file.h>
+#ifdef HAVE_FSMAP_H
+#include <linux/fsmap.h>
+#endif
 
 #include <llog_swab.h>
 #include <lustre_disk.h>
@@ -57,6 +58,8 @@
 #include <obd.h>
 #include <obd_class.h>
 
+#include "tgt_internal.h"
+
 /*********** mount lookup *********/
 
 static DEFINE_MUTEX(lustre_mount_info_lock);
@@ -140,7 +143,7 @@ static int server_deregister_mount(const char *name)
        OBD_FREE(lmi, sizeof(*lmi));
        mutex_unlock(&lustre_mount_info_lock);
 
-       OBD_RACE(OBD_FAIL_MDS_LLOG_UMOUNT_RACE);
+       CFS_RACE(OBD_FAIL_MDS_LLOG_UMOUNT_RACE);
        RETURN(0);
 }
 
@@ -163,10 +166,10 @@ struct lustre_mount_info *server_get_mount(const char *name)
        }
        lsi = s2lsi(lmi->lmi_sb);
 
-       atomic_inc(&lsi->lsi_mounts);
+       kref_get(&lsi->lsi_mounts);
 
        CDEBUG(D_MOUNT, "get mount %p from %s, refs=%d\n", lmi->lmi_sb,
-              name, atomic_read(&lsi->lsi_mounts));
+              name, kref_read(&lsi->lsi_mounts));
 
        RETURN(lmi);
 }
@@ -200,7 +203,7 @@ int server_put_mount(const char *name, bool dereg_mnt)
        lsi = s2lsi(lmi->lmi_sb);
 
        CDEBUG(D_MOUNT, "put mount %p from %s, refs=%d\n",
-              lmi->lmi_sb, name, atomic_read(&lsi->lsi_mounts));
+              lmi->lmi_sb, name, kref_read(&lsi->lsi_mounts));
 
        if (lustre_put_lsi(lmi->lmi_sb))
                CDEBUG(D_MOUNT, "Last put of mount %p from %s\n",
@@ -228,8 +231,7 @@ static int server_start_mgs(struct super_block *sb)
        lmi = server_find_mount(LUSTRE_MGS_OBDNAME);
        if (lmi) {
                lsi = s2lsi(lmi->lmi_sb);
-               LCONSOLE_ERROR_MSG(0x15d,
-                                  "The MGS service was already started from server\n");
+               LCONSOLE_ERROR("The MGS service was already started from server\n");
                RETURN(-EALREADY);
        }
 
@@ -251,9 +253,8 @@ static int server_start_mgs(struct super_block *sb)
        if (rc < 0) {
                server_deregister_mount(LUSTRE_MGS_OBDNAME);
 report_err:
-               LCONSOLE_ERROR_MSG(0x15e,
-                                  "Failed to start MGS '%s' (%d). Is the 'mgs' module loaded?\n",
-                                  LUSTRE_MGS_OBDNAME, rc);
+               LCONSOLE_ERROR("Failed to start MGS '%s' (%d). Is the 'mgs' module loaded?\n",
+                              LUSTRE_MGS_OBDNAME, rc);
        }
        RETURN(rc);
 }
@@ -640,11 +641,18 @@ static int lustre_lwp_setup(struct lustre_cfg *lcfg, struct lustre_sb_info *lsi,
        struct obd_device *obd;
        char *lwpname = NULL;
        char *lwpuuid = NULL;
+       struct lnet_nid nid;
        int rc;
 
        ENTRY;
-       rc = class_add_uuid(lustre_cfg_string(lcfg, 1),
-                           lcfg->lcfg_nid);
+       if (lcfg->lcfg_nid)
+               lnet_nid4_to_nid(lcfg->lcfg_nid, &nid);
+       else {
+               rc = libcfs_strnid(&nid, lustre_cfg_string(lcfg, 2));
+               if (rc)
+                       RETURN(rc);
+       }
+       rc = class_add_uuid(lustre_cfg_string(lcfg, 1), &nid);
        if (rc != 0) {
                CERROR("%s: Can't add uuid: rc =%d\n", lsi->lsi_svname, rc);
                RETURN(rc);
@@ -869,8 +877,17 @@ static int client_lwp_config_process(const struct lu_env *env,
                         */
                        cfg->cfg_flags |= CFG_F_SKIP;
                } else if (cfg->cfg_flags == (CFG_F_MARKER | CFG_F_SKIP)) {
-                       rc = class_add_uuid(lustre_cfg_string(lcfg, 1),
-                                           lcfg->lcfg_nid);
+                       struct lnet_nid nid;
+
+                       rc = 0;
+                       if (lcfg->lcfg_nid)
+                               lnet_nid4_to_nid(lcfg->lcfg_nid, &nid);
+                       else
+                               rc = libcfs_strnid(&nid,
+                                                  lustre_cfg_string(lcfg, 2));
+                       if (!rc)
+                               rc = class_add_uuid(lustre_cfg_string(lcfg, 1),
+                                                   &nid);
                        if (rc < 0)
                                CERROR("%s: Fail to add uuid, rc:%d\n",
                                       lsi->lsi_svname, rc);
@@ -990,7 +1007,8 @@ static int lustre_disconnect_lwp(struct super_block *sb)
                                                        lwp->obd_lu_dev, lcfg);
                OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount,
                                              lcfg->lcfg_buflens));
-               if (rc != 0 && rc != -ETIMEDOUT) {
+               if (rc != 0 && rc != -ETIMEDOUT && rc != -ENODEV &&
+                   rc != -ENOTCONN && rc != -ESHUTDOWN) {
                        CERROR("%s: fail to disconnect LWP: rc = %d\n",
                               lwp->obd_name, rc);
                        rc1 = rc;
@@ -1024,8 +1042,8 @@ static int lustre_stop_lwp(struct super_block *sb)
        ENTRY;
        mutex_lock(&lsi->lsi_lwp_mutex);
        while (!list_empty(&lsi->lsi_lwp_list)) {
-               lwp = list_entry(lsi->lsi_lwp_list.next, struct obd_device,
-                                obd_lwp_list);
+               lwp = list_first_entry(&lsi->lsi_lwp_list, struct obd_device,
+                                      obd_lwp_list);
                list_del_init(&lwp->obd_lwp_list);
                lwp->obd_force = 1;
                mutex_unlock(&lsi->lsi_lwp_mutex);
@@ -1140,43 +1158,89 @@ static int server_stop_servers(int lsiflags)
 
 int server_mti_print(const char *title, struct mgs_target_info *mti)
 {
-       PRINT_CMD(PRINT_MASK, "mti %s\n", title);
-       PRINT_CMD(PRINT_MASK, "server: %s\n", mti->mti_svname);
-       PRINT_CMD(PRINT_MASK, "fs:     %s\n", mti->mti_fsname);
-       PRINT_CMD(PRINT_MASK, "uuid:   %s\n", mti->mti_uuid);
-       PRINT_CMD(PRINT_MASK, "ver: %d  flags: %#x\n",
-                 mti->mti_config_ver, mti->mti_flags);
+       CDEBUG(D_MOUNT, "mti - %s\n", title);
+       CDEBUG(D_MOUNT, "server: %s\n", mti->mti_svname);
+       CDEBUG(D_MOUNT, "fs:     %s\n", mti->mti_fsname);
+       CDEBUG(D_MOUNT, "uuid:   %s\n", mti->mti_uuid);
+       CDEBUG(D_MOUNT, "ver:    %d\n", mti->mti_config_ver);
+       CDEBUG(D_MOUNT, "flags:\n");
+       if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
+               CDEBUG(D_MOUNT, "        LDD_F_SV_TYPE_MDT\n");
+       if (mti->mti_flags & LDD_F_SV_TYPE_OST)
+               CDEBUG(D_MOUNT, "        LDD_F_SV_TYPE_OST\n");
+       if (mti->mti_flags & LDD_F_SV_TYPE_MGS)
+               CDEBUG(D_MOUNT, "        LDD_F_SV_TYPE_MGS\n");
+       if (mti->mti_flags & LDD_F_SV_ALL)
+               CDEBUG(D_MOUNT, "        LDD_F_SV_ALL\n");
+       if (mti->mti_flags & LDD_F_NEED_INDEX)
+               CDEBUG(D_MOUNT, "        LDD_F_NEED_INDEX\n");
+       if (mti->mti_flags & LDD_F_VIRGIN)
+               CDEBUG(D_MOUNT, "        LDD_F_VIRIGIN\n");
+       if (mti->mti_flags & LDD_F_UPDATE)
+               CDEBUG(D_MOUNT, "        LDD_F_UPDATE\n");
+       if (mti->mti_flags & LDD_F_REWRITE_LDD)
+               CDEBUG(D_MOUNT, "        LDD_F_REWRITE_LDD\n");
+       if (mti->mti_flags & LDD_F_WRITECONF)
+               CDEBUG(D_MOUNT, "        LDD_F_WRITECONF\n");
+       if (mti->mti_flags & LDD_F_PARAM)
+               CDEBUG(D_MOUNT, "        LDD_F_PARAM\n");
+       if (mti->mti_flags & LDD_F_NO_PRIMNODE)
+               CDEBUG(D_MOUNT, "        LDD_F_NO_PRIMNODE\n");
+       if (mti->mti_flags & LDD_F_IR_CAPABLE)
+               CDEBUG(D_MOUNT, "        LDD_F_IR_CAPABLE\n");
+       if (mti->mti_flags & LDD_F_ERROR)
+               CDEBUG(D_MOUNT, "        LDD_F_ERROR\n");
+       if (mti->mti_flags & LDD_F_PARAM2)
+               CDEBUG(D_MOUNT, "        LDD_F_PARAM2\n");
+       if (mti->mti_flags & LDD_F_NO_LOCAL_LOGS)
+               CDEBUG(D_MOUNT, "        LDD_F_NO_LOCAL_LOGS\n");
+
+       /* Upper 16 bits for target registering */
+       if (target_supports_large_nid(mti))
+               CDEBUG(D_MOUNT, "        LDD_F_LARGE_NID\n");
+       if (mti->mti_flags & LDD_F_OPC_REG)
+               CDEBUG(D_MOUNT, "        LDD_F_OPC_REG\n");
+       if (mti->mti_flags & LDD_F_OPC_UNREG)
+               CDEBUG(D_MOUNT, "        LDD_F_OPC_UNREG\n");
+       if (mti->mti_flags & LDD_F_OPC_READY)
+               CDEBUG(D_MOUNT, "        LDD_F_OPC_READY\n");
+
        return 0;
 }
+EXPORT_SYMBOL(server_mti_print);
 
 /* Generate data for registration */
-static int server_lsi2mti(struct lustre_sb_info *lsi,
-                         struct mgs_target_info *mti)
+static struct mgs_target_info *server_lsi2mti(struct lustre_sb_info *lsi)
 {
-       struct lnet_processid id;
+       size_t len = offsetof(struct mgs_target_info, mti_nidlist);
+       GENRADIX(struct lnet_processid) plist;
+       struct lnet_processid id, *tmp;
+       struct mgs_target_info *mti;
+       bool large_nid = false;
+       int nid_count = 0;
        int rc, i = 0;
        int cplen = 0;
 
        ENTRY;
        if (!IS_SERVER(lsi))
-               RETURN(-EINVAL);
+               RETURN(ERR_PTR(-EINVAL));
+
+       if (exp_connect_flags2(lsi->lsi_mgc->u.cli.cl_mgc_mgsexp) &
+           OBD_CONNECT2_LARGE_NID)
+               large_nid = true;
 
-       if (strlcpy(mti->mti_svname, lsi->lsi_svname, sizeof(mti->mti_svname))
-           >= sizeof(mti->mti_svname))
-               RETURN(-E2BIG);
+       genradix_init(&plist);
 
-       mti->mti_nid_count = 0;
-       while (LNetGetId(i++, &id) != -ENOENT) {
+       while (LNetGetId(i++, &id, large_nid) != -ENOENT) {
                if (nid_is_lo0(&id.nid))
                        continue;
 
                /* server use --servicenode param, only allow specified
                 * nids be registered
                 */
-               if ((lsi->lsi_lmd->lmd_flags & LMD_FLG_NO_PRIMNODE) != 0 &&
+               if (test_bit(LMD_FLG_NO_PRIMNODE, lsi->lsi_lmd->lmd_flags) &&
                    class_match_nid(lsi->lsi_lmd->lmd_params,
-                                   PARAM_FAILNODE,
-                                   lnet_nid_to_nid4(&id.nid)) < 1)
+                                   PARAM_FAILNODE, &id.nid) < 1)
                        continue;
 
                if (!class_find_param(lsi->lsi_lmd->lmd_params,
@@ -1186,7 +1250,7 @@ static int server_lsi2mti(struct lustre_sb_info *lsi,
                                       " on this node. 'network' option used in"
                                       " mkfs.lustre cannot be taken into"
                                       " account.\n");
-                               RETURN(-EINVAL);
+                               GOTO(free_list, mti = ERR_PTR(-EINVAL));
                        }
                }
 
@@ -1195,42 +1259,72 @@ static int server_lsi2mti(struct lustre_sb_info *lsi,
                                     PARAM_NETWORK, LNET_NID_NET(&id.nid)))
                        continue;
 
-               mti->mti_nids[mti->mti_nid_count] = lnet_nid_to_nid4(&id.nid);
-               mti->mti_nid_count++;
-               if (mti->mti_nid_count >= MTI_NIDS_MAX) {
-                       CWARN("Only using first %d nids for %s\n",
-                             mti->mti_nid_count, mti->mti_svname);
-                       break;
-               }
+               tmp = genradix_ptr_alloc(&plist, nid_count++, GFP_KERNEL);
+               if (!tmp)
+                       GOTO(free_list, mti = ERR_PTR(-ENOMEM));
+
+               if (large_nid)
+                       len += LNET_NIDSTR_SIZE;
+               *tmp = id;
        }
 
-       if (mti->mti_nid_count == 0) {
+       if (nid_count == 0) {
                CERROR("Failed to get NID for server %s, please check whether the target is specifed with improper --servicenode or --network options.\n",
-                      mti->mti_svname);
-               RETURN(-EINVAL);
+                      lsi->lsi_svname);
+               GOTO(free_list, mti = ERR_PTR(-EINVAL));
        }
 
+       OBD_ALLOC(mti, len);
+       if (!mti)
+               GOTO(free_list, mti = ERR_PTR(-ENOMEM));
+
+       rc = strscpy(mti->mti_svname, lsi->lsi_svname, sizeof(mti->mti_svname));
+       if (rc < 0)
+               GOTO(free_mti, rc);
+
+       mti->mti_nid_count = nid_count;
+       for (i = 0; i < mti->mti_nid_count; i++) {
+               tmp = genradix_ptr(&plist, i);
+
+               if (large_nid)
+                       libcfs_nidstr_r(&tmp->nid, mti->mti_nidlist[i],
+                                       sizeof(mti->mti_nidlist[i]));
+               else
+                       mti->mti_nids[i] = lnet_nid_to_nid4(&tmp->nid);
+       }
        mti->mti_lustre_ver = LUSTRE_VERSION_CODE;
        mti->mti_config_ver = 0;
 
        rc = server_name2fsname(lsi->lsi_svname, mti->mti_fsname, NULL);
-       if (rc != 0)
-               return rc;
+       if (rc < 0)
+               GOTO(free_mti, rc);
 
        rc = server_name2index(lsi->lsi_svname, &mti->mti_stripe_index, NULL);
        if (rc < 0)
-               return rc;
+               GOTO(free_mti, rc);
+
        /* Orion requires index to be set */
        LASSERT(!(rc & LDD_F_NEED_INDEX));
        /* keep only LDD flags */
        mti->mti_flags = lsi->lsi_flags & LDD_F_MASK;
        if (mti->mti_flags & (LDD_F_WRITECONF | LDD_F_VIRGIN))
                mti->mti_flags |= LDD_F_UPDATE;
-       cplen = strlcpy(mti->mti_params, lsi->lsi_lmd->lmd_params,
+       /* use NID strings instead */
+       if (large_nid)
+               mti->mti_flags |= LDD_F_LARGE_NID;
+       cplen = strscpy(mti->mti_params, lsi->lsi_lmd->lmd_params,
                        sizeof(mti->mti_params));
        if (cplen >= sizeof(mti->mti_params))
-               return -E2BIG;
-       return 0;
+               rc = -E2BIG;
+free_mti:
+       if (rc < 0) {
+               OBD_FREE(mti, len);
+               mti = ERR_PTR(rc);
+       }
+free_list:
+       genradix_free(&plist);
+
+       return mti;
 }
 
 /* Register an old or new target with the MGS. If needed MGS will construct
@@ -1240,47 +1334,40 @@ static int server_register_target(struct lustre_sb_info *lsi)
 {
        struct obd_device *mgc = lsi->lsi_mgc;
        struct mgs_target_info *mti = NULL;
+       size_t mti_len = sizeof(*mti);
        bool must_succeed;
        int rc;
        int tried = 0;
 
        ENTRY;
        LASSERT(mgc);
-
-       if (!IS_SERVER(lsi))
-               RETURN(-EINVAL);
-
-       OBD_ALLOC_PTR(mti);
-       if (!mti)
-               RETURN(-ENOMEM);
-
-       rc = server_lsi2mti(lsi, mti);
-       if (rc < 0)
-               GOTO(out, rc);
+       mti = server_lsi2mti(lsi);
+       if (IS_ERR(mti))
+               GOTO(out, rc = PTR_ERR(mti));
 
        CDEBUG(D_MOUNT, "Registration %s, fs=%s, %s, index=%04x, flags=%#x\n",
-              mti->mti_svname, mti->mti_fsname,
-              libcfs_nid2str(mti->mti_nids[0]), mti->mti_stripe_index,
-              mti->mti_flags);
+              mti->mti_svname, mti->mti_fsname, mti->mti_nidlist[0],
+              mti->mti_stripe_index, mti->mti_flags);
 
        /* we cannot ignore registration failure if MGS logs must be updated. */
        must_succeed = !!(lsi->lsi_flags &
                    (LDD_F_NEED_INDEX | LDD_F_UPDATE | LDD_F_WRITECONF |
                     LDD_F_VIRGIN));
        mti->mti_flags |= LDD_F_OPC_REG;
-
+       if (target_supports_large_nid(mti))
+               mti_len += mti->mti_nid_count * LNET_NIDSTR_SIZE;
+       server_mti_print("server_register_target", mti);
 again:
        /* Register the target */
        /* FIXME use mgc_process_config instead */
        rc = obd_set_info_async(NULL, mgc->u.cli.cl_mgc_mgsexp,
                                sizeof(KEY_REGISTER_TARGET),
                                KEY_REGISTER_TARGET,
-                               sizeof(*mti), mti, NULL);
+                               mti_len, mti, NULL);
        if (rc < 0) {
                if (mti->mti_flags & LDD_F_ERROR) {
-                       LCONSOLE_ERROR_MSG(0x160,
-                                          "%s: the MGS refuses to allow this server to start: rc = %d. Please see messages on the MGS.\n",
-                                          lsi->lsi_svname, rc);
+                       LCONSOLE_ERROR("%s: the MGS refuses to allow this server to start: rc = %d. Please see messages on the MGS.\n",
+                                      lsi->lsi_svname, rc);
                } else if (must_succeed) {
                        if ((rc == -ESHUTDOWN || rc == -EIO) && ++tried < 5) {
                                /* The connection with MGS is not established.
@@ -1291,9 +1378,8 @@ again:
                                        goto again;
                        }
 
-                       LCONSOLE_ERROR_MSG(0x15f,
-                                          "%s: cannot register this server with the MGS: rc = %d. Is the MGS running?\n",
-                                          lsi->lsi_svname, rc);
+                       LCONSOLE_ERROR("%s: cannot register this server with the MGS: rc = %d. Is the MGS running?\n",
+                                      lsi->lsi_svname, rc);
                } else {
                        CDEBUG(D_HA,
                               "%s: error registering with the MGS: rc = %d (not fatal)\n",
@@ -1301,12 +1387,10 @@ again:
                        /* reset the error code for non-fatal error. */
                        rc = 0;
                }
-               GOTO(out, rc);
        }
 
+       OBD_FREE(mti, mti_len);
 out:
-       if (mti)
-               OBD_FREE_PTR(mti);
        RETURN(rc);
 }
 
@@ -1319,40 +1403,35 @@ static int server_notify_target(struct super_block *sb, struct obd_device *obd)
        struct lustre_sb_info *lsi = s2lsi(sb);
        struct obd_device *mgc = lsi->lsi_mgc;
        struct mgs_target_info *mti = NULL;
+       size_t mti_len = sizeof(*mti);
        int rc;
 
        ENTRY;
        LASSERT(mgc);
-
-       if (!(IS_SERVER(lsi)))
-               RETURN(-EINVAL);
-
-       OBD_ALLOC_PTR(mti);
-       if (!mti)
-               RETURN(-ENOMEM);
-       rc = server_lsi2mti(lsi, mti);
-       if (rc < 0)
-               GOTO(out, rc);
+       mti = server_lsi2mti(lsi);
+       if (IS_ERR(mti))
+               GOTO(out, rc = PTR_ERR(mti));
 
        mti->mti_instance = obd2obt(obd)->obt_instance;
        mti->mti_flags |= LDD_F_OPC_READY;
+       if (target_supports_large_nid(mti))
+               mti_len += mti->mti_nid_count * LNET_NIDSTR_SIZE;
+       server_mti_print("server_notify_target", mti);
 
        /* FIXME use mgc_process_config instead */
        rc = obd_set_info_async(NULL, mgc->u.cli.cl_mgc_mgsexp,
                                sizeof(KEY_REGISTER_TARGET),
                                KEY_REGISTER_TARGET,
-                               sizeof(*mti), mti, NULL);
+                               mti_len, mti, NULL);
 
        /* Imperative recovery: if the mgs informs us to use IR? */
        if (!rc && !(mti->mti_flags & LDD_F_ERROR) &&
            (mti->mti_flags & LDD_F_IR_CAPABLE))
                lsi->lsi_flags |= LDD_F_IR_CAPABLE;
 
+       OBD_FREE(mti, mti_len);
 out:
-       if (mti)
-               OBD_FREE_PTR(mti);
        RETURN(rc);
-
 }
 
 /* Start server targets: MDTs and OSTs */
@@ -1405,9 +1484,9 @@ static int server_start_targets(struct super_block *sb)
        }
        lsi->lsi_server_started = 1;
        mutex_unlock(&server_start_lock);
-       if (OBD_FAIL_PRECHECK(OBD_FAIL_OBD_STOP_MDS_RACE) &&
+       if (CFS_FAIL_PRECHECK(OBD_FAIL_OBD_STOP_MDS_RACE) &&
            IS_MDT(lsi)) {
-               OBD_RACE(OBD_FAIL_OBD_STOP_MDS_RACE);
+               CFS_RACE(OBD_FAIL_OBD_STOP_MDS_RACE);
                msleep(2 * MSEC_PER_SEC);
        }
 
@@ -1494,12 +1573,15 @@ static int server_start_targets(struct super_block *sb)
        /* abort recovery only on the complete stack:
         * many devices can be involved
         */
-       if ((lsi->lsi_lmd->lmd_flags &
-            (LMD_FLG_ABORT_RECOV | LMD_FLG_ABORT_RECOV_MDT)) &&
-           (OBP(obd, iocontrol))) {
-               struct obd_ioctl_data karg = {
-                       .ioc_type = lsi->lsi_lmd->lmd_flags,
-               };
+       if ((test_bit(LMD_FLG_ABORT_RECOV, lsi->lsi_lmd->lmd_flags) ||
+           (test_bit(LMD_FLG_ABORT_RECOV_MDT, lsi->lsi_lmd->lmd_flags))) &&
+           (obd->obd_type->typ_dt_ops->o_iocontrol)) {
+               struct obd_ioctl_data karg;
+
+               if (test_bit(LMD_FLG_ABORT_RECOV, lsi->lsi_lmd->lmd_flags))
+                       karg.ioc_type = OBD_FLG_ABORT_RECOV_OST;
+               else
+                       karg.ioc_type = OBD_FLG_ABORT_RECOV_MDT;
 
                obd_iocontrol(OBD_IOC_ABORT_RECOVERY, obd->obd_self_export, 0,
                              &karg, NULL);
@@ -1549,21 +1631,21 @@ static int lsi_prepare(struct lustre_sb_info *lsi)
            strlen(fstype) >= sizeof(lsi->lsi_fstype))
                RETURN(-ENAMETOOLONG);
 
-       strlcpy(lsi->lsi_svname, lsi->lsi_lmd->lmd_profile,
+       strscpy(lsi->lsi_svname, lsi->lsi_lmd->lmd_profile,
                sizeof(lsi->lsi_svname));
-       strlcpy(lsi->lsi_osd_type, osd_type, sizeof(lsi->lsi_osd_type));
+       strscpy(lsi->lsi_osd_type, osd_type, sizeof(lsi->lsi_osd_type));
        /* XXX: a temp. solution for components using ldiskfs
         *      to be removed in one of the subsequent patches
         */
-       strlcpy(lsi->lsi_fstype, fstype, sizeof(lsi->lsi_fstype));
+       strscpy(lsi->lsi_fstype, fstype, sizeof(lsi->lsi_fstype));
 
        /* Determine server type */
        rc = server_name2index(lsi->lsi_svname, &index, NULL);
        if (rc < 0) {
-               if (lsi->lsi_lmd->lmd_flags & LMD_FLG_MGS) {
+               if (test_bit(LMD_FLG_MGS, lsi->lsi_lmd->lmd_flags)) {
                        /* Assume we're a bare MGS */
                        rc = 0;
-                       lsi->lsi_lmd->lmd_flags |= LMD_FLG_NOSVC;
+                       set_bit(LMD_FLG_NOSVC, lsi->lsi_lmd->lmd_flags);
                } else {
                        LCONSOLE_ERROR("Can't determine server type of '%s'\n",
                                       lsi->lsi_svname);
@@ -1575,18 +1657,18 @@ static int lsi_prepare(struct lustre_sb_info *lsi)
        /* Add mount line flags that used to be in ldd:
         * writeconf, mgs, anything else?
         */
-       lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_WRITECONF) ?
-               LDD_F_WRITECONF : 0;
-       lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_NO_LOCAL_LOGS) ?
-               LDD_F_NO_LOCAL_LOGS : 0;
-       lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_VIRGIN) ?
-               LDD_F_VIRGIN : 0;
-       lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_UPDATE) ?
-               LDD_F_UPDATE : 0;
-       lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_MGS) ?
-               LDD_F_SV_TYPE_MGS : 0;
-       lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_NO_PRIMNODE) ?
-               LDD_F_NO_PRIMNODE : 0;
+       lsi->lsi_flags |= test_bit(LMD_FLG_WRITECONF, lsi->lsi_lmd->lmd_flags) ?
+                         LDD_F_WRITECONF : 0;
+       lsi->lsi_flags |= test_bit(LMD_FLG_NO_LOCAL_LOGS, lsi->lsi_lmd->lmd_flags) ?
+                         LDD_F_NO_LOCAL_LOGS : 0;
+       lsi->lsi_flags |= test_bit(LMD_FLG_VIRGIN, lsi->lsi_lmd->lmd_flags) ?
+                         LDD_F_VIRGIN : 0;
+       lsi->lsi_flags |= test_bit(LMD_FLG_UPDATE, lsi->lsi_lmd->lmd_flags) ?
+                         LDD_F_UPDATE : 0;
+       lsi->lsi_flags |= test_bit(LMD_FLG_MGS, lsi->lsi_lmd->lmd_flags) ?
+                         LDD_F_SV_TYPE_MGS : 0;
+       lsi->lsi_flags |= test_bit(LMD_FLG_NO_PRIMNODE, lsi->lsi_lmd->lmd_flags) ?
+                         LDD_F_NO_PRIMNODE : 0;
 
        RETURN(0);
 }
@@ -1611,7 +1693,7 @@ static void server_put_super(struct super_block *sb)
        OBD_ALLOC(tmpname, tmpname_sz);
        memcpy(tmpname, lsi->lsi_svname, tmpname_sz);
        CDEBUG(D_MOUNT, "server put_super %s\n", tmpname);
-       if (IS_MDT(lsi) && (lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC))
+       if (IS_MDT(lsi) && test_bit(LMD_FLG_NOSVC, lsi->lsi_lmd->lmd_flags))
                snprintf(tmpname, tmpname_sz, "MGS");
 
        /* disconnect the lwp first to drain off the inflight request */
@@ -1619,14 +1701,14 @@ static void server_put_super(struct super_block *sb)
                int     rc;
 
                rc = lustre_disconnect_lwp(sb);
-               if (rc != 0 && rc != -ETIMEDOUT &&
+               if (rc != 0 && rc != -ETIMEDOUT && rc != -ENODEV &&
                    rc != -ENOTCONN && rc != -ESHUTDOWN)
                        CWARN("%s: failed to disconnect lwp: rc= %d\n",
                              tmpname, rc);
        }
 
        /* Stop the target */
-       if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC) &&
+       if (!test_bit(LMD_FLG_NOSVC, lsi->lsi_lmd->lmd_flags) &&
            (IS_MDT(lsi) || IS_OST(lsi))) {
                struct lustre_profile *lprof = NULL;
 
@@ -1657,13 +1739,13 @@ static void server_put_super(struct super_block *sb)
                         */
                        obd->obd_force = 1;
                        class_manual_cleanup(obd);
-                       if (OBD_FAIL_PRECHECK(OBD_FAIL_OBD_STOP_MDS_RACE)) {
+                       if (CFS_FAIL_PRECHECK(OBD_FAIL_OBD_STOP_MDS_RACE)) {
                                int idx;
 
                                server_name2index(lsi->lsi_svname, &idx, NULL);
                                /* sleeping for MDT0001 */
                                if (idx == 1)
-                                       OBD_RACE(OBD_FAIL_OBD_STOP_MDS_RACE);
+                                       CFS_RACE(OBD_FAIL_OBD_STOP_MDS_RACE);
                        }
                } else {
                        CERROR("no obd %s\n", lsi->lsi_svname);
@@ -1677,7 +1759,7 @@ static void server_put_super(struct super_block *sb)
        lustre_stop_mgc(sb);
        if (IS_MGS(lsi)) {
                /* if MDS start with --nomgs, don't stop MGS then */
-               if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS))
+               if (!test_bit(LMD_FLG_NOMGS, lsi->lsi_lmd->lmd_flags))
                        server_stop_mgs(sb);
        }
 
@@ -1713,7 +1795,7 @@ static void server_put_super(struct super_block *sb)
                OBD_FREE(extraname, strlen(extraname) + 1);
        }
 
-       LCONSOLE_WARN("server umount %s complete\n", tmpname);
+       LCONSOLE(D_WARNING, "server umount %s complete\n", tmpname);
        OBD_FREE(tmpname, tmpname_sz);
        EXIT;
 }
@@ -1762,7 +1844,7 @@ static int server_statfs(struct dentry *dentry, struct kstatfs *buf)
        RETURN(0);
 }
 
-int server_show_options(struct seq_file *seq, struct dentry *dentry)
+static int server_show_options(struct seq_file *seq, struct dentry *dentry)
 {
        struct lustre_sb_info *lsi;
        struct lustre_mount_data *lmd;
@@ -1788,8 +1870,7 @@ int server_show_options(struct seq_file *seq, struct dentry *dentry)
                         * Also, if server is mounted with "rdonly_dev"
                         * (LMD_FLG_DEV_RDONLY) then force flag to be 'ro'
                         */
-
-                       if (!(lmd->lmd_flags & LMD_FLG_DEV_RDONLY) &&
+                       if (!test_bit(LMD_FLG_DEV_RDONLY, lmd->lmd_flags) &&
                            !(osfs.os_state & OS_STATFS_READONLY))
                                sb->s_flags &= ~SB_RDONLY;
                }
@@ -1797,27 +1878,28 @@ int server_show_options(struct seq_file *seq, struct dentry *dentry)
 
        seq_printf(seq, ",svname=%s", lmd->lmd_profile);
 
-       if  (lmd->lmd_flags & LMD_FLG_ABORT_RECOV)
+       if (test_bit(LMD_FLG_ABORT_RECOV, lmd->lmd_flags))
                seq_puts(seq, ",abort_recov");
 
-       if (lmd->lmd_flags & LMD_FLG_NOIR)
+       if (test_bit(LMD_FLG_NOIR, lmd->lmd_flags))
                seq_puts(seq, ",noir");
 
-       if (lmd->lmd_flags & LMD_FLG_NOSVC)
+       if (test_bit(LMD_FLG_NOSVC, lmd->lmd_flags))
                seq_puts(seq, ",nosvc");
 
-       if (lmd->lmd_flags & LMD_FLG_NOMGS)
+       if (test_bit(LMD_FLG_NOMGS, lmd->lmd_flags))
                seq_puts(seq, ",nomgs");
 
-       if (lmd->lmd_flags & LMD_FLG_NOSCRUB)
+       if (test_bit(LMD_FLG_NOSCRUB, lmd->lmd_flags))
                seq_puts(seq, ",noscrub");
-       if (lmd->lmd_flags & LMD_FLG_SKIP_LFSCK)
+
+       if (test_bit(LMD_FLG_SKIP_LFSCK, lmd->lmd_flags))
                seq_puts(seq, ",skip_lfsck");
 
-       if (lmd->lmd_flags & LMD_FLG_DEV_RDONLY)
+       if (test_bit(LMD_FLG_DEV_RDONLY, lmd->lmd_flags))
                seq_puts(seq, ",rdonly_dev");
 
-       if (lmd->lmd_flags & LMD_FLG_MGS)
+       if (test_bit(LMD_FLG_MGS, lmd->lmd_flags))
                seq_puts(seq, ",mgs");
 
        if (lmd->lmd_mgs)
@@ -1844,11 +1926,53 @@ static const struct super_operations server_ops = {
        .show_options   = server_show_options,
 };
 
+#if defined(HAVE_USER_NAMESPACE_ARG)
+# define IDMAP_ARG idmap,
+#else
+# define IDMAP_ARG
+# ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#  define server_getattr(ns, path, st, rq, fl) server_getattr(path, st, rq, fl)
+# endif
+#endif
+
 /*
- * Xattr support for Lustre servers
+ * inode operations for Lustre server mountpoints
  */
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+static int server_getattr(struct mnt_idmap *idmap,
+                         const struct path *path, struct kstat *stat,
+                         u32 request_mask, unsigned int flags)
+{
+       struct inode *inode = d_inode(path->dentry);
+#else
+static int server_getattr(struct vfsmount *mnt, struct dentry *de,
+                         struct kstat *stat)
+{
+       struct inode *inode = de->d_inode;
+#endif
+       struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
+       struct vfsmount *root_mnt;
+       struct inode *root_inode;
+
+       root_mnt = dt_mnt_get(lsi->lsi_dt_dev);
+       if (IS_ERR(root_mnt))
+               root_inode = igrab(inode);
+       else
+               root_inode = igrab(root_mnt->mnt_sb->s_root->d_inode);
+       if (!root_inode)
+               return -EACCES;
+
+       CDEBUG(D_SUPER, "%s: root_inode from %s ino=%lu, dev=%x\n",
+              lsi->lsi_svname, root_inode == inode ? "lsi" : "vfsmnt",
+              root_inode->i_ino, root_inode->i_rdev);
+       generic_fillattr(IDMAP_ARG RQMASK_ARG root_inode, stat);
+       iput(root_inode);
+
+       return 0;
+}
+
 #ifdef HAVE_IOP_XATTR
-static ssize_t lustre_getxattr(struct dentry *dentry, const char *name,
+static ssize_t server_getxattr(struct dentry *dentry, const char *name,
                                void *buffer, size_t size)
 {
        if (!selinux_is_enabled())
@@ -1856,24 +1980,32 @@ static ssize_t lustre_getxattr(struct dentry *dentry, const char *name,
        return -ENODATA;
 }
 
-static int lustre_setxattr(struct dentry *dentry, const char *name,
+static int server_setxattr(struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags)
 {
        return -EOPNOTSUPP;
 }
 #endif
 
-static ssize_t lustre_listxattr(struct dentry *d_entry, char *name,
+static ssize_t server_listxattr(struct dentry *d_entry, char *name,
                                size_t size)
 {
        return -EOPNOTSUPP;
 }
 
-static bool is_cmd_supported(unsigned int command)
+static bool is_cmd_supported(unsigned int cmd)
 {
-       switch (command) {
+       CDEBUG(D_SUPER, "ioctl cmd=%x\n", cmd);
+
+       switch (cmd) {
        case FITRIM:
                return true;
+       case LL_IOC_RESIZE_FS:
+               return true;
+#ifdef HAVE_FSMAP_H
+       case FS_IOC_GETFSMAP:
+               return true;
+#endif
        default:
                return false;
        }
@@ -1881,37 +2013,41 @@ static bool is_cmd_supported(unsigned int command)
        return false;
 }
 
-static long server_ioctl(struct file *filp, unsigned int command,
-                        unsigned long arg)
+static long server_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-       struct file active_filp;
-       struct inode *inode = file_inode(filp);
-       struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
-       struct super_block *dd_sb = dt_mnt_sb_get(lsi->lsi_dt_dev);
-       struct inode *active_inode;
-       int err = -EOPNOTSUPP;
+       struct lustre_sb_info *lsi = s2lsi(file_inode(filp)->i_sb);
+       struct vfsmount *root_mnt;
+       struct file *root_filp;
+       struct inode *root_inode;
+       int err = -ENOTTY;
+
+       if (!is_cmd_supported(cmd))
+               return err;
 
-       if (IS_ERR(dd_sb) || !is_cmd_supported(command))
+       root_mnt = dt_mnt_get(lsi->lsi_dt_dev);
+       if (IS_ERR(root_mnt))
                return err;
 
-       active_inode = igrab(dd_sb->s_root->d_inode);
-       if (!active_inode)
+       root_inode = igrab(root_mnt->mnt_root->d_inode);
+       if (!root_inode)
                return -EACCES;
 
-       active_filp.f_inode = active_inode;
-       if (active_inode->i_fop && active_inode->i_fop->unlocked_ioctl)
-               err = active_inode->i_fop->unlocked_ioctl(&active_filp,
-                                                         command, arg);
-       iput(active_inode);
+       root_filp = alloc_file_pseudo(root_inode, root_mnt, "/",
+                                     O_RDWR | O_NOATIME, root_inode->i_fop);
+       if (root_inode->i_fop && root_inode->i_fop->unlocked_ioctl)
+               err = root_inode->i_fop->unlocked_ioctl(root_filp, cmd, arg);
+       fput(root_filp);
+
        return err;
 }
 
 static const struct inode_operations server_inode_operations = {
+       .getattr        = server_getattr,
 #ifdef HAVE_IOP_XATTR
-       .setxattr       = lustre_setxattr,
-       .getxattr       = lustre_getxattr,
+       .setxattr       = server_setxattr,
+       .getxattr       = server_getxattr,
 #endif
-       .listxattr      = lustre_listxattr,
+       .listxattr      = server_listxattr,
 };
 
 static const struct file_operations server_file_operations = {
@@ -1962,6 +2098,7 @@ static int osd_start(struct lustre_sb_info *lsi, unsigned long mflags)
        struct obd_device *obd;
        struct dt_device_param p;
        char flagstr[20 + 1 + 10 + 1];
+       u32 lmd_flags;
        int rc;
 
        ENTRY;
@@ -1972,7 +2109,8 @@ static int osd_start(struct lustre_sb_info *lsi, unsigned long mflags)
        sprintf(lsi->lsi_osd_obdname, "%s-osd", lsi->lsi_svname);
        strcpy(lsi->lsi_osd_uuid, lsi->lsi_osd_obdname);
        strcat(lsi->lsi_osd_uuid, "_UUID");
-       snprintf(flagstr, sizeof(flagstr), "%lu:%u", mflags, lmd->lmd_flags);
+       bitmap_to_arr32(&lmd_flags, lmd->lmd_flags, LMD_FLG_NUM_FLAGS);
+       snprintf(flagstr, sizeof(flagstr), "%lu:%u", mflags, lmd_flags);
 
        obd = class_name2obd(lsi->lsi_osd_obdname);
        if (!obd) {
@@ -1990,10 +2128,10 @@ static int osd_start(struct lustre_sb_info *lsi, unsigned long mflags)
                /* but continue setup to allow special case of MDT and internal
                 * MGT being started separately.
                 */
-               if (!((IS_MGS(lsi) && (lsi->lsi_lmd->lmd_flags &
-                                     LMD_FLG_NOMGS)) ||
-                    (IS_MDT(lsi) && (lsi->lsi_lmd->lmd_flags &
-                                     LMD_FLG_NOSVC))))
+               if (!((IS_MGS(lsi) &&
+                      test_bit(LMD_FLG_NOMGS, lsi->lsi_lmd->lmd_flags)) ||
+                    (IS_MDT(lsi) &&
+                     test_bit(LMD_FLG_NOSVC, lsi->lsi_lmd->lmd_flags))))
                        RETURN(-EALREADY);
        }
 
@@ -2033,7 +2171,7 @@ int server_fill_super(struct super_block *sb)
 
        ENTRY;
        /* to simulate target mount race */
-       OBD_RACE(OBD_FAIL_TGT_MOUNT_RACE);
+       CFS_RACE(OBD_FAIL_TGT_MOUNT_RACE);
 
        rc = lsi_prepare(lsi);
        if (rc < 0) {
@@ -2054,15 +2192,14 @@ int server_fill_super(struct super_block *sb)
               lsi->lsi_svname, lsi->lsi_lmd->lmd_dev);
 
        if (class_name2obd(lsi->lsi_svname)) {
-               LCONSOLE_ERROR_MSG(0x161,
-                                  "The target named %s is already running. Double-mount may have compromised the disk journal.\n",
-                                  lsi->lsi_svname);
+               LCONSOLE_ERROR("The target named %s is already running. Double-mount may have compromised the disk journal.\n",
+                              lsi->lsi_svname);
                lustre_put_lsi(sb);
                RETURN(-EALREADY);
        }
 
        /* Start MGS before MGC */
-       if (IS_MGS(lsi) && !(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS)) {
+       if (IS_MGS(lsi) && !test_bit(LMD_FLG_NOMGS, lsi->lsi_lmd->lmd_flags)) {
                rc = server_start_mgs(sb);
                if (rc < 0)
                        GOTO(out_mnt, rc);
@@ -2074,7 +2211,7 @@ int server_fill_super(struct super_block *sb)
                GOTO(out_mnt, rc);
 
        /* Set up all obd devices for service */
-       if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC) &&
+       if (!test_bit(LMD_FLG_NOSVC, lsi->lsi_lmd->lmd_flags) &&
            (IS_OST(lsi) || IS_MDT(lsi))) {
                rc = server_start_targets(sb);
                if (rc < 0) {
@@ -2128,7 +2265,7 @@ void server_calc_timeout(struct lustre_sb_info *lsi, struct obd_device *obd)
        if (lmd) {
                soft   = lmd->lmd_recovery_time_soft;
                hard   = lmd->lmd_recovery_time_hard;
-               has_ir = has_ir && !(lmd->lmd_flags & LMD_FLG_NOIR);
+               has_ir = has_ir && !test_bit(LMD_FLG_NOIR, lmd->lmd_flags);
                obd->obd_no_ir = !has_ir;
        }