#include <obd.h>
#include <obd_class.h>
+#include <linux/random.h>
+#include <libcfs/linux/linux-uuid.h>
#include <linux/version.h>
#include <lustre_log.h>
#include <lustre_disk.h>
#include <uapi/linux/lustre/lustre_param.h>
-static int (*client_fill_super)(struct super_block *sb,
- struct vfsmount *mnt);
+static DEFINE_SPINLOCK(client_lock);
+static struct module *client_mod;
+static int (*client_fill_super)(struct super_block *sb);
static void (*kill_super_cb)(struct super_block *sb);
struct obd_device *obd;
struct obd_export *exp;
struct obd_uuid *uuid = NULL;
- class_uuid_t uuidc;
+ uuid_t uuidc;
lnet_nid_t nid;
char nidstr[LNET_NIDSTR_SIZE];
char *mgcname = NULL, *niduuid = NULL, *mgssec = NULL;
if (uuid == NULL)
GOTO(out_free, rc = -ENOMEM);
- ll_generate_random_uuid(uuidc);
- class_uuid_unparse(uuidc, uuid);
+ generate_random_uuid(uuidc.b);
+ snprintf(uuid->uuid, UUID_SIZE, "%pU", uuidc.b);
/* Start the MGC */
rc = lustre_start_simple(mgcname, LUSTRE_MGC_NAME,
OBD_CONNECT_LVB_TYPE |
OBD_CONNECT_BULK_MBITS | OBD_CONNECT_BARRIER;
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
- data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
-#endif
-
if (lmd_is_client(lsi->lsi_lmd) &&
lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)
data->ocd_connect_flags &= ~OBD_CONNECT_IMP_RECOV;
RETURN(rc);
}
-/*
- * Appended to obdname to form "obdname_XXXX".
- */
-#define MGC_IDX_LEN sizeof("_XXXX")
-
static int lustre_stop_mgc(struct super_block *sb)
{
struct lustre_sb_info *lsi = s2lsi(sb);
}
/*
- * Save the obdname for cleaning the NID uuids, which are
+ * Save the obdname for cleaning the nid uuids, which are
* obdname_XX
*/
- len = strlen(obd->obd_name) + MGC_IDX_LEN;
+ len = strlen(obd->obd_name) + 6;
OBD_ALLOC(niduuid, len);
if (niduuid) {
- strlcpy(niduuid, obd->obd_name, len);
+ strcpy(niduuid, obd->obd_name);
ptr = niduuid + strlen(niduuid);
}
if (rc)
GOTO(out, rc);
- /* Clean the NID uuids */
+ /* Clean the nid uuids */
if (!niduuid)
GOTO(out, rc = -ENOMEM);
for (i = 0; i < lsi->lsi_lmd->lmd_mgs_failnodes; i++) {
- snprintf(ptr, MGC_IDX_LEN, "_%x", i);
+ sprintf(ptr, "_%x", i);
rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_DEL_UUID,
niduuid, NULL, NULL, NULL);
if (rc)
/* Default umount style */
lsi->lsi_flags = LSI_UMOUNT_FAILOVER;
INIT_LIST_HEAD(&lsi->lsi_lwp_list);
- spin_lock_init(&lsi->lsi_lwp_lock);
+ mutex_init(&lsi->lsi_lwp_mutex);
RETURN(lsi);
}
return rc | LDD_F_SV_ALL;
}
- if (idx) {
- if (!(kstrtoul(dash, 16, &index)))
- *idx = index;
- else
- rc = -EINVAL;
- }
+ index = simple_strtoul(dash, (char **)endptr, 16);
+ if (idx != NULL)
+ *idx = index;
+
+ if (index > 0xffff)
+ return -ERANGE;
return rc;
}
*/
static int lmd_parse_nidlist(char *buf, char **endh)
{
- struct list_head nidlist;
+ LIST_HEAD(nidlist);
char *endp = buf;
char tmp;
int rc = 0;
tmp = *endp;
*endp = '\0';
- INIT_LIST_HEAD(&nidlist);
if (cfs_parse_nidlist(buf, strlen(buf), &nidlist) <= 0)
rc = 1;
cfs_free_nidlist(&nidlist);
/**
* Parse mount line options
* e.g. mount -v -t lustre -o abort_recov uml1:uml2:/lustre-client /mnt/lustre
- * dev is passed as device=uml1:/lustre by mount.lustre
+ * dev is passed as device=uml1:/lustre by mount.lustre_tgt
*/
static int lmd_parse(char *options, struct lustre_mount_data *lmd)
{
LASSERT(lmd);
if (!options) {
LCONSOLE_ERROR_MSG(0x162,
- "Missing mount data: check /sbin/mount.lustre is installed.\n");
+ "Missing mount data: check /sbin/mount.lustre_tgt is installed.\n");
RETURN(-EINVAL);
}
/* Options should be a string - try to detect old lmd data */
if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) {
LCONSOLE_ERROR_MSG(0x163,
- "Using an old version of /sbin/mount lustre. Please install version %s\n",
+ "Using an old version of /sbin/mount.lustre. Please install version %s\n",
LUSTRE_VERSION_STRING);
RETURN(-EINVAL);
}
while (*s1) {
int clear = 0;
int time_min = OBD_RECOVERY_TIME_MIN;
- unsigned long result;
char *s3;
/* Skip whitespace and extra commas */
lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
clear++;
} else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
- rc = kstrtoul(s1 + 19, 10, &result);
- if (rc)
- goto invalid;
- lmd->lmd_recovery_time_soft = max_t(int, result,
- time_min);
+ lmd->lmd_recovery_time_soft =
+ max_t(int, simple_strtoul(s1 + 19, NULL, 10),
+ time_min);
clear++;
} else if (strncmp(s1, "recovery_time_hard=", 19) == 0) {
- rc = kstrtoul(s1 + 19, 10, &result);
- if (rc)
- goto invalid;
- lmd->lmd_recovery_time_hard = max_t(int, result,
- time_min);
+ lmd->lmd_recovery_time_hard =
+ max_t(int, simple_strtoul(s1 + 19, NULL, 10),
+ time_min);
+ clear++;
+ } else if (strncmp(s1, "no_precreate", 12) == 0) {
+ lmd->lmd_flags |= LMD_FLG_NO_PRECREATE;
clear++;
} else if (strncmp(s1, "noir", 4) == 0) {
lmd->lmd_flags |= LMD_FLG_NOIR; /* test purpose only. */
strlcat(lmd->lmd_params, " ", LMD_PARAMS_MAXLEN);
s3 = s1 + 6 + length;
clear++;
+ } else if (strncmp(s1, "localrecov", 10) == 0) {
+ lmd->lmd_flags |= LMD_FLG_LOCAL_RECOV;
+ clear++;
} else if (strncmp(s1, "osd=", 4) == 0) {
rc = lmd_parse_string(&lmd->lmd_osd_type, s1 + 4);
if (rc)
RETURN(-EINVAL);
}
-struct lustre_mount_data2 {
- void *lmd2_data;
- struct vfsmount *lmd2_mnt;
-};
-
/**
* This is the entry point for the mount call into Lustre.
* This is called when a server or client is mounted,
* and this is where we start setting things up.
* @param data Mount options (e.g. -o flock,abort_recov)
*/
-static int lustre_fill_super(struct super_block *sb, void *data, int silent)
+static int lustre_fill_super(struct super_block *sb, void *lmd2_data,
+ int silent)
{
struct lustre_mount_data *lmd;
- struct lustre_mount_data2 *lmd2 = data;
struct lustre_sb_info *lsi;
int rc;
obd_zombie_barrier();
/* Figure out the lmd from the mount options */
- if (lmd_parse((char *)(lmd2->lmd2_data), lmd)) {
+ if (lmd_parse(lmd2_data, lmd)) {
lustre_put_lsi(sb);
GOTO(out, rc = -EINVAL);
}
if (lmd_is_client(lmd)) {
+ bool have_client = false;
+
CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
- if (client_fill_super == NULL)
+ if (!client_fill_super)
request_module("lustre");
- if (client_fill_super == NULL) {
+ spin_lock(&client_lock);
+ if (client_fill_super && try_module_get(client_mod))
+ have_client = true;
+ spin_unlock(&client_lock);
+ if (!have_client) {
LCONSOLE_ERROR_MSG(0x165,
"Nothing registered for client mount! Is the 'lustre' module loaded?\n");
lustre_put_lsi(sb);
}
/* Connect and start */
/* (should always be ll_fill_super) */
- rc = (*client_fill_super)(sb, lmd2->lmd2_mnt);
- /* c_f_s will call lustre_common_put_super on failure */
+ rc = (*client_fill_super)(sb);
+ /* c_f_s will call lustre_common_put_super on failure,
+ * which takes care of the module reference.
+ */
}
} else {
#ifdef HAVE_SERVER_SUPPORT
* We can't call ll_fill_super by name because it lives in a module that
* must be loaded after this one.
*/
-void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb,
- struct vfsmount *mnt))
+void lustre_register_super_ops(struct module *mod,
+ int (*cfs)(struct super_block *sb),
+ void (*ksc)(struct super_block *sb))
{
+ spin_lock(&client_lock);
+ client_mod = mod;
client_fill_super = cfs;
+ kill_super_cb = ksc;
+ spin_unlock(&client_lock);
}
-EXPORT_SYMBOL(lustre_register_client_fill_super);
-
-void lustre_register_kill_super_cb(void (*cfs)(struct super_block *sb))
-{
- kill_super_cb = cfs;
-}
-EXPORT_SYMBOL(lustre_register_kill_super_cb);
+EXPORT_SYMBOL(lustre_register_super_ops);
/***************** FS registration ******************/
-#ifdef HAVE_FSTYPE_MOUNT
static struct dentry *lustre_mount(struct file_system_type *fs_type, int flags,
const char *devname, void *data)
{
- struct lustre_mount_data2 lmd2 = {
- .lmd2_data = data,
- };
-
- return mount_nodev(fs_type, flags, &lmd2, lustre_fill_super);
-}
-#else
-static int lustre_get_sb(struct file_system_type *fs_type, int flags,
- const char *devname, void *data, struct vfsmount *mnt)
-{
- struct lustre_mount_data2 lmd2 = {
- .lmd2_data = data,
- .lmd2_mnt = mnt,
- };
-
- return get_sb_nodev(fs_type, flags, &lmd2, lustre_fill_super, mnt);
+ return mount_nodev(fs_type, flags, data, lustre_fill_super);
}
-#endif
static void lustre_kill_super(struct super_block *sb)
{
kill_anon_super(sb);
}
-/* Register the "lustre" fs type */
-static struct file_system_type lustre_fs_type = {
- .owner = THIS_MODULE,
- .name = "lustre",
-#ifdef HAVE_FSTYPE_MOUNT
- .mount = lustre_mount,
+#ifdef HAVE_SERVER_SUPPORT
+/* Register the "lustre_tgt" fs type.
+ *
+ * Right now this isn't any different than the normal "lustre" filesystem
+ * type, but it is added so that there is some compatibility to allow
+ * changing documentation and scripts to start using the "lustre_tgt" type
+ * at mount time. That will simplify test interop, and in case of upgrades
+ * that change to the new type and then need to roll back for some reason.
+ *
+ * The long-term goal is to disentangle the client and server mount code.
+ */
+static struct file_system_type lustre_fs_type_tgt = {
+ .owner = THIS_MODULE,
+ .name = "lustre_tgt",
+ .mount = lustre_mount,
+ .kill_sb = lustre_kill_super,
+ .fs_flags = FS_REQUIRES_DEV | FS_RENAME_DOES_D_MOVE,
+};
+MODULE_ALIAS_FS("lustre_tgt");
+
+#define register_filesystem_tgt(fstype) \
+do { \
+ int _rc; \
+ \
+ _rc = register_filesystem(fstype); \
+ if (_rc && _rc != -EBUSY) { \
+ /* Don't fail if server code also registers "lustre_tgt" */ \
+ CERROR("obdclass: register fstype '%s' failed: rc = %d\n", \
+ (fstype)->name, _rc); \
+ return _rc; \
+ } \
+} while (0)
+#define unregister_filesystem_tgt(fstype) unregister_filesystem(fstype)
#else
- .get_sb = lustre_get_sb,
+#define register_filesystem_tgt(fstype) do {} while (0)
+#define unregister_filesystem_tgt(fstype) do {} while (0)
#endif
- .kill_sb = lustre_kill_super,
- .fs_flags = FS_REQUIRES_DEV | FS_HAS_FIEMAP | FS_RENAME_DOES_D_MOVE,
+
+/* Register the "lustre" fs type */
+static struct file_system_type lustre_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "lustre",
+ .mount = lustre_mount,
+ .kill_sb = lustre_kill_super,
+ .fs_flags = FS_RENAME_DOES_D_MOVE,
};
MODULE_ALIAS_FS("lustre");
int lustre_register_fs(void)
{
+ register_filesystem_tgt(&lustre_fs_type_tgt);
+
return register_filesystem(&lustre_fs_type);
}
int lustre_unregister_fs(void)
{
+ unregister_filesystem_tgt(&lustre_fs_type_tgt);
+
return unregister_filesystem(&lustre_fs_type);
}