*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2013, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
lustre_cfg_bufs_set(bufs, 2, cfg, sizeof(*cfg));
lustre_cfg_bufs_set(bufs, 3, &sb, sizeof(sb));
lcfg = lustre_cfg_new(LCFG_LOG_START, bufs);
- rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
- lustre_cfg_free(lcfg);
-
+ if (lcfg == NULL)
+ GOTO(out, rc = -ENOMEM);
+ rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
+ lustre_cfg_free(lcfg);
+out:
OBD_FREE_PTR(bufs);
if (rc == -EINVAL)
"client and the MGS are running compatible "
"versions of Lustre.\n",
mgc->obd_name, logname, rc);
-
- if (rc)
+ else if (rc != 0)
LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' "
"failed (%d). This may be the result of "
"communication errors between this node and "
if (cfg)
lustre_cfg_bufs_set(&bufs, 2, cfg, sizeof(*cfg));
lcfg = lustre_cfg_new(LCFG_LOG_END, &bufs);
+ if (lcfg == NULL)
+ RETURN(-ENOMEM);
rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
lustre_cfg_free(lcfg);
RETURN(rc);
lustre_cfg_bufs_set_string(&bufs, 4, s4);
lcfg = lustre_cfg_new(cmd, &bufs);
+ if (lcfg == NULL)
+ return -ENOMEM;
lcfg->lcfg_nid = nid;
rc = class_process_config(lcfg);
lustre_cfg_free(lcfg);
return(rc);
}
-EXPORT_SYMBOL(do_lcfg);
/** Call class_attach and class_setup. These methods in turn call
* obd type-specific methods.
int rc;
CDEBUG(D_MOUNT, "Starting obd %s (typ=%s)\n", obdname, type);
- rc = do_lcfg(obdname, 0, LCFG_ATTACH, type, uuid, 0, 0);
+ rc = do_lcfg(obdname, 0, LCFG_ATTACH, type, uuid, NULL, NULL);
if (rc) {
CERROR("%s attach error %d\n", obdname, rc);
return rc;
rc = do_lcfg(obdname, 0, LCFG_SETUP, s1, s2, s3, s4);
if (rc) {
CERROR("%s setup error %d\n", obdname, rc);
- do_lcfg(obdname, 0, LCFG_DETACH, 0, 0, 0, 0);
+ do_lcfg(obdname, 0, LCFG_DETACH, NULL, NULL, NULL, NULL);
}
return rc;
}
-DEFINE_MUTEX(mgc_start_lock);
+static DEFINE_MUTEX(mgc_start_lock);
/** Set up a mgc obd to process startup logs
*
struct obd_uuid *uuid;
class_uuid_t uuidc;
lnet_nid_t nid;
+ char nidstr[LNET_NIDSTR_SIZE];
char *mgcname = NULL, *niduuid = NULL, *mgssec = NULL;
char *ptr;
- int recov_bk;
- int rc = 0, i = 0, j, len;
- ENTRY;
+ int rc = 0, i = 0, j;
+ size_t len;
+ ENTRY;
- LASSERT(lsi->lsi_lmd);
+ LASSERT(lsi->lsi_lmd);
- /* Find the first non-lo MGS nid for our MGC name */
+ /* Find the first non-lo MGS nid for our MGC name */
if (IS_SERVER(lsi)) {
/* mount -o mgsnode=nid */
ptr = lsi->lsi_lmd->lmd_mgs;
mutex_lock(&mgc_start_lock);
- len = strlen(LUSTRE_MGC_OBDNAME) + strlen(libcfs_nid2str(nid)) + 1;
- OBD_ALLOC(mgcname, len);
- OBD_ALLOC(niduuid, len + 2);
- if (!mgcname || !niduuid)
- GOTO(out_free, rc = -ENOMEM);
- sprintf(mgcname, "%s%s", LUSTRE_MGC_OBDNAME, libcfs_nid2str(nid));
+ libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
+ len = strlen(LUSTRE_MGC_OBDNAME) + strlen(nidstr) + 1;
+ OBD_ALLOC(mgcname, len);
+ OBD_ALLOC(niduuid, len + 2);
+ if (mgcname == NULL || niduuid == NULL)
+ GOTO(out_free, rc = -ENOMEM);
+ snprintf(mgcname, len, "%s%s", LUSTRE_MGC_OBDNAME, nidstr);
mgssec = lsi->lsi_lmd->lmd_mgssec ? lsi->lsi_lmd->lmd_mgssec : "";
obd = class_name2obd(mgcname);
if (obd && !obd->obd_stopping) {
+ int recov_bk;
+
rc = obd_set_info_async(NULL, obd->obd_self_export,
strlen(KEY_MGSSEC), KEY_MGSSEC,
strlen(mgssec), mgssec, NULL);
GOTO(out_free, rc);
/* Re-using an existing MGC */
- cfs_atomic_inc(&obd->u.cli.cl_mgc_refcount);
+ atomic_inc(&obd->u.cli.cl_mgc_refcount);
/* IR compatibility check, only for clients */
if (lmd_is_client(lsi->lsi_lmd)) {
int vallen = sizeof(*data);
__u32 *flags = &lsi->lsi_lmd->lmd_flags;
- rc = obd_get_info(NULL, obd->obd_self_export,
- strlen(KEY_CONN_DATA), KEY_CONN_DATA,
- &vallen, data, NULL);
+ rc = obd_get_info(NULL, obd->obd_self_export,
+ strlen(KEY_CONN_DATA), KEY_CONN_DATA,
+ &vallen, data);
LASSERT(rc == 0);
has_ir = OCD_HAS_FLAG(data, IMP_RECOV);
if (has_ir ^ !(*flags & LMD_FLG_NOIR)) {
/* Add the primary nids for the MGS */
i = 0;
- sprintf(niduuid, "%s_%x", mgcname, i);
+ snprintf(niduuid, len + 2, "%s_%x", mgcname, i);
if (IS_SERVER(lsi)) {
ptr = lsi->lsi_lmd->lmd_mgs;
CDEBUG(D_MOUNT, "mgs nids %s.\n", ptr);
lnet_process_id_t id;
while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
rc = do_lcfg(mgcname, id.nid, LCFG_ADD_UUID,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
}
} else {
/* Use mgsnode= nids */
*/
while (class_parse_nid(ptr, &nid, &ptr) == 0) {
rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
if (rc == 0) {
i = 1;
break;
ptr = lsi->lsi_lmd->lmd_dev;
while (class_parse_nid(ptr, &nid, &ptr) == 0) {
rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
if (rc == 0)
++i;
/* Stop at the first failover nid */
/* Random uuid for MGC allows easier reconnects */
OBD_ALLOC_PTR(uuid);
+ if (uuid == NULL)
+ GOTO(out_free, rc = -ENOMEM);
+
ll_generate_random_uuid(uuidc);
class_uuid_unparse(uuidc, uuid);
/* Start the MGC */
rc = lustre_start_simple(mgcname, LUSTRE_MGC_NAME,
(char *)uuid->uuid, LUSTRE_MGS_OBDNAME,
- niduuid, 0, 0);
+ niduuid, NULL, NULL);
OBD_FREE_PTR(uuid);
if (rc)
GOTO(out_free, rc);
j = 0;
while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
if (rc == 0)
++j;
if (*ptr == ':')
}
if (j > 0) {
rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
if (rc == 0)
++i;
} else {
/* Keep a refcount of servers/clients who started with "mount",
so we know when we can get rid of the mgc. */
- cfs_atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
-
- /* Try all connections, but only once. */
- recov_bk = 1;
- rc = obd_set_info_async(NULL, obd->obd_self_export,
- sizeof(KEY_INIT_RECOV_BACKUP),
- KEY_INIT_RECOV_BACKUP,
- sizeof(recov_bk), &recov_bk, NULL);
- if (rc)
- /* nonfatal */
- CWARN("can't set %s %d\n", KEY_INIT_RECOV_BACKUP, rc);
+ atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
/* We connect to the MGS at setup, and don't disconnect until cleanup */
data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
- OBD_CONNECT_LVB_TYPE;
+ OBD_CONNECT_LVB_TYPE | OBD_CONNECT_BULK_MBITS;
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
-#else
-#warning "LU-1644: Remove old OBD_CONNECT_MNE_SWAB fixup and imp_need_mne_swab"
#endif
if (lmd_is_client(lsi->lsi_lmd) &&
{
struct lustre_sb_info *lsi = s2lsi(sb);
struct obd_device *obd;
- char *niduuid = 0, *ptr = 0;
+ char *niduuid = NULL, *ptr = NULL;
int i, rc = 0, len = 0;
ENTRY;
lsi->lsi_mgc = NULL;
mutex_lock(&mgc_start_lock);
- LASSERT(cfs_atomic_read(&obd->u.cli.cl_mgc_refcount) > 0);
- if (!cfs_atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) {
+ LASSERT(atomic_read(&obd->u.cli.cl_mgc_refcount) > 0);
+ if (!atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) {
/* This is not fatal, every client that stops
will call in here. */
CDEBUG(D_MOUNT, "mgc still has %d references.\n",
- cfs_atomic_read(&obd->u.cli.cl_mgc_refcount));
+ atomic_read(&obd->u.cli.cl_mgc_refcount));
GOTO(out, rc = -EBUSY);
}
for (i = 0; i < lsi->lsi_lmd->lmd_mgs_failnodes; i++) {
sprintf(ptr, "_%x", i);
rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_DEL_UUID,
- niduuid, 0, 0, 0);
+ niduuid, NULL, NULL, NULL);
if (rc)
CERROR("del MDC UUID %s failed: rc = %d\n",
niduuid, rc);
/***************** lustre superblock **************/
-struct lustre_sb_info *lustre_init_lsi(struct super_block *sb)
+static struct lustre_sb_info *lustre_init_lsi(struct super_block *sb)
{
struct lustre_sb_info *lsi;
ENTRY;
lsi->lsi_lmd->lmd_recovery_time_hard = 0;
s2lsi_nocast(sb) = lsi;
/* we take 1 extra ref for our setup */
- cfs_atomic_set(&lsi->lsi_mounts, 1);
+ atomic_set(&lsi->lsi_mounts, 1);
/* Default umount style */
lsi->lsi_flags = LSI_UMOUNT_FAILOVER;
+ INIT_LIST_HEAD(&lsi->lsi_lwp_list);
+ spin_lock_init(&lsi->lsi_lwp_lock);
- RETURN(lsi);
+ RETURN(lsi);
}
static int lustre_free_lsi(struct super_block *sb)
{
- struct lustre_sb_info *lsi = s2lsi(sb);
- ENTRY;
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ ENTRY;
- LASSERT(lsi != NULL);
- CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi);
-
- /* someone didn't call server_put_mount. */
- LASSERT(cfs_atomic_read(&lsi->lsi_mounts) == 0);
-
- if (lsi->lsi_lmd != NULL) {
- if (lsi->lsi_lmd->lmd_dev != NULL)
- OBD_FREE(lsi->lsi_lmd->lmd_dev,
- strlen(lsi->lsi_lmd->lmd_dev) + 1);
- if (lsi->lsi_lmd->lmd_profile != NULL)
- OBD_FREE(lsi->lsi_lmd->lmd_profile,
- strlen(lsi->lsi_lmd->lmd_profile) + 1);
- if (lsi->lsi_lmd->lmd_mgssec != NULL)
- OBD_FREE(lsi->lsi_lmd->lmd_mgssec,
- strlen(lsi->lsi_lmd->lmd_mgssec) + 1);
- if (lsi->lsi_lmd->lmd_opts != NULL)
- OBD_FREE(lsi->lsi_lmd->lmd_opts,
- strlen(lsi->lsi_lmd->lmd_opts) + 1);
- if (lsi->lsi_lmd->lmd_exclude_count)
- OBD_FREE(lsi->lsi_lmd->lmd_exclude,
- sizeof(lsi->lsi_lmd->lmd_exclude[0]) *
- lsi->lsi_lmd->lmd_exclude_count);
+ LASSERT(lsi != NULL);
+ CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi);
+
+ /* someone didn't call server_put_mount. */
+ LASSERT(atomic_read(&lsi->lsi_mounts) == 0);
+
+ if (lsi->lsi_lmd != NULL) {
+ if (lsi->lsi_lmd->lmd_dev != NULL)
+ OBD_FREE(lsi->lsi_lmd->lmd_dev,
+ strlen(lsi->lsi_lmd->lmd_dev) + 1);
+ if (lsi->lsi_lmd->lmd_profile != NULL)
+ OBD_FREE(lsi->lsi_lmd->lmd_profile,
+ strlen(lsi->lsi_lmd->lmd_profile) + 1);
+ if (lsi->lsi_lmd->lmd_fileset != NULL)
+ OBD_FREE(lsi->lsi_lmd->lmd_fileset,
+ strlen(lsi->lsi_lmd->lmd_fileset) + 1);
+ if (lsi->lsi_lmd->lmd_mgssec != NULL)
+ OBD_FREE(lsi->lsi_lmd->lmd_mgssec,
+ strlen(lsi->lsi_lmd->lmd_mgssec) + 1);
+ if (lsi->lsi_lmd->lmd_opts != NULL)
+ OBD_FREE(lsi->lsi_lmd->lmd_opts,
+ strlen(lsi->lsi_lmd->lmd_opts) + 1);
+ if (lsi->lsi_lmd->lmd_exclude_count)
+ OBD_FREE(lsi->lsi_lmd->lmd_exclude,
+ sizeof(lsi->lsi_lmd->lmd_exclude[0]) *
+ lsi->lsi_lmd->lmd_exclude_count);
if (lsi->lsi_lmd->lmd_mgs != NULL)
OBD_FREE(lsi->lsi_lmd->lmd_mgs,
strlen(lsi->lsi_lmd->lmd_mgs) + 1);
strlen(lsi->lsi_lmd->lmd_osd_type) + 1);
if (lsi->lsi_lmd->lmd_params != NULL)
OBD_FREE(lsi->lsi_lmd->lmd_params, 4096);
+ if (lsi->lsi_lmd->lmd_nidnet != NULL)
+ OBD_FREE(lsi->lsi_lmd->lmd_nidnet,
+ strlen(lsi->lsi_lmd->lmd_nidnet) + 1);
- OBD_FREE(lsi->lsi_lmd, sizeof(*lsi->lsi_lmd));
- }
+ OBD_FREE_PTR(lsi->lsi_lmd);
+ }
- LASSERT(lsi->lsi_llsbi == NULL);
- OBD_FREE(lsi, sizeof(*lsi));
- s2lsi_nocast(sb) = NULL;
+ LASSERT(lsi->lsi_llsbi == NULL);
+ OBD_FREE_PTR(lsi);
+ s2lsi_nocast(sb) = NULL;
- RETURN(0);
+ RETURN(0);
}
/* The lsi has one reference for every server that is using the disk -
e.g. MDT, MGS, and potentially MGC */
int lustre_put_lsi(struct super_block *sb)
{
- struct lustre_sb_info *lsi = s2lsi(sb);
- ENTRY;
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ ENTRY;
- LASSERT(lsi != NULL);
+ LASSERT(lsi != NULL);
- CDEBUG(D_MOUNT, "put %p %d\n", sb, cfs_atomic_read(&lsi->lsi_mounts));
- if (cfs_atomic_dec_and_test(&lsi->lsi_mounts)) {
+ CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts));
+ if (atomic_dec_and_test(&lsi->lsi_mounts)) {
if (IS_SERVER(lsi) && lsi->lsi_osd_exp) {
lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev);
lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL;
/* wait till OSD is gone */
obd_zombie_barrier();
}
- lustre_free_lsi(sb);
- RETURN(1);
- }
- RETURN(0);
+ lustre_free_lsi(sb);
+ RETURN(1);
+ }
+ RETURN(0);
}
/*** SERVER NAME ***
- * <FSNAME><SEPERATOR><TYPE><INDEX>
+ * <FSNAME><SEPARATOR><TYPE><INDEX>
* FSNAME is between 1 and 8 characters (inclusive).
* Excluded characters are '/' and ':'
- * SEPERATOR is either ':' or '-'
+ * SEPARATOR is either ':' or '-'
* TYPE: "OST", "MDT", etc.
* INDEX: Hex representation of the index
*/
}
EXPORT_SYMBOL(server_name_is_ost);
-/* Get the index from the obd name.
- rc = server type, or
- rc < 0 on error
- if endptr isn't NULL it is set to end of name */
-int server_name2index(const char *svname, __u32 *idx, const char **endptr)
+/**
+ * Get the index from the target name MDTXXXX/OSTXXXX
+ * rc = server type, or rc < 0 on error
+ **/
+int target_name2index(const char *tgtname, __u32 *idx, const char **endptr)
{
+ const char *dash = tgtname;
unsigned long index;
int rc;
- const char *dash;
-
- /* We use server_name2fsname() just for parsing */
- rc = server_name2fsname(svname, NULL, &dash);
- if (rc != 0)
- return rc;
-
- dash++;
if (strncmp(dash, "MDT", 3) == 0)
rc = LDD_F_SV_TYPE_MDT;
index = simple_strtoul(dash, (char **)endptr, 16);
if (idx != NULL)
*idx = index;
+ return rc;
+}
+EXPORT_SYMBOL(target_name2index);
+
+/* Get the index from the obd name.
+ rc = server type, or
+ rc < 0 on error
+ if endptr isn't NULL it is set to end of name */
+int server_name2index(const char *svname, __u32 *idx, const char **endptr)
+{
+ const char *dash;
+ int rc;
+
+ /* We use server_name2fsname() just for parsing */
+ rc = server_name2fsname(svname, NULL, &dash);
+ if (rc != 0)
+ return rc;
+
+ dash++;
+ rc = target_name2index(dash, idx, endptr);
+ if (rc < 0)
+ return rc;
/* Account for -mdc after index that is possible when specifying mdt */
if (endptr != NULL && strncmp(LUSTRE_MDC_NAME, *endptr + 1,
}
/* Drop a ref to the mounted disk */
lustre_put_lsi(sb);
- lu_types_stop();
- RETURN(rc);
+
+ RETURN(rc);
}
EXPORT_SYMBOL(lustre_common_put_super);
static int lmd_make_exclusion(struct lustre_mount_data *lmd, const char *ptr)
{
const char *s1 = ptr, *s2;
- __u32 index, *exclude_list;
+ __u32 *exclude_list;
+ __u32 index = 0;
int rc = 0, devmax;
ENTRY;
return 0;
}
+static int lmd_parse_network(struct lustre_mount_data *lmd, char *ptr)
+{
+ char *tail;
+ int length;
+
+ if (lmd->lmd_nidnet != NULL) {
+ OBD_FREE(lmd->lmd_nidnet, strlen(lmd->lmd_nidnet) + 1);
+ lmd->lmd_nidnet = NULL;
+ }
+
+ tail = strchr(ptr, ',');
+ if (tail == NULL)
+ length = strlen(ptr);
+ else
+ length = tail - ptr;
+
+ OBD_ALLOC(lmd->lmd_nidnet, length + 1);
+ if (lmd->lmd_nidnet == NULL)
+ return -ENOMEM;
+
+ memcpy(lmd->lmd_nidnet, ptr, length);
+ lmd->lmd_nidnet[length] = '\0';
+ return 0;
+}
+
static int lmd_parse_string(char **handle, char *ptr)
{
char *tail;
return 0;
}
+/**
+ * Find the first delimiter (comma or colon) from the specified \a buf and
+ * make \a *endh point to the string starting with the delimiter. The commas
+ * in expression list [...] will be skipped.
+ *
+ * \param[in] buf a delimiter-separated string
+ * \param[in] endh a pointer to a pointer that will point to the string
+ * starting with the delimiter
+ *
+ * \retval 0 if delimiter is found
+ * \retval 1 if delimiter is not found
+ */
+static int lmd_find_delimiter(char *buf, char **endh)
+{
+ char *c = buf;
+ int skip = 0;
+
+ if (buf == NULL)
+ return 1;
+
+ while (*c != '\0') {
+ if (*c == '[')
+ skip++;
+ else if (*c == ']')
+ skip--;
+
+ if ((*c == ',' || *c == ':') && skip == 0) {
+ if (endh != NULL)
+ *endh = c;
+ return 0;
+ }
+
+ c++;
+ }
+
+ return 1;
+}
+
+/**
+ * Find the first valid string delimited by comma or colon from the specified
+ * \a buf and parse it to see whether it's a valid nid list. If yes, \a *endh
+ * will point to the next string starting with the delimiter.
+ *
+ * \param[in] buf a delimiter-separated string
+ * \param[in] endh a pointer to a pointer that will point to the string
+ * starting with the delimiter
+ *
+ * \retval 0 if the string is a valid nid list
+ * \retval 1 if the string is not a valid nid list
+ */
+static int lmd_parse_nidlist(char *buf, char **endh)
+{
+ struct list_head nidlist;
+ char *endp = buf;
+ char tmp;
+ int rc = 0;
+
+ if (buf == NULL)
+ return 1;
+ while (*buf == ',' || *buf == ':')
+ buf++;
+ if (*buf == ' ' || *buf == '/' || *buf == '\0')
+ return 1;
+
+ if (lmd_find_delimiter(buf, &endp) != 0)
+ endp = buf + strlen(buf);
+
+ tmp = *endp;
+ *endp = '\0';
+
+ INIT_LIST_HEAD(&nidlist);
+ if (cfs_parse_nidlist(buf, strlen(buf), &nidlist) <= 0)
+ rc = 1;
+ cfs_free_nidlist(&nidlist);
+
+ *endp = tmp;
+ if (rc != 0)
+ return rc;
+ if (endh != NULL)
+ *endh = endp;
+ return 0;
+}
+
/** 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
*/
static int lmd_parse(char *options, struct lustre_mount_data *lmd)
{
- char *s1, *s2, *devname = NULL;
- struct lustre_mount_data *raw = (struct lustre_mount_data *)options;
- int rc = 0;
- ENTRY;
+ char *s1, *s2, *devname = NULL;
+ struct lustre_mount_data *raw = (struct lustre_mount_data *)options;
+ int rc = 0;
+ ENTRY;
- LASSERT(lmd);
- if (!options) {
- LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that "
- "/sbin/mount.lustre is installed.\n");
- RETURN(-EINVAL);
- }
+ LASSERT(lmd);
+ if (!options) {
+ LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that "
+ "/sbin/mount.lustre 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, "You're using an old version of "
- "/sbin/mount.lustre. Please install "
- "version %s\n", LUSTRE_VERSION_STRING);
- RETURN(-EINVAL);
- }
- lmd->lmd_magic = LMD_MAGIC;
+ /* Options should be a string - try to detect old lmd data */
+ if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) {
+ LCONSOLE_ERROR_MSG(0x163, "You're using an old version of "
+ "/sbin/mount.lustre. Please install "
+ "version %s\n", LUSTRE_VERSION_STRING);
+ RETURN(-EINVAL);
+ }
+ lmd->lmd_magic = LMD_MAGIC;
- OBD_ALLOC(lmd->lmd_params, 4096);
+ OBD_ALLOC(lmd->lmd_params, LMD_PARAMS_MAXLEN);
if (lmd->lmd_params == NULL)
RETURN(-ENOMEM);
lmd->lmd_params[0] = '\0';
- /* Set default flags here */
-
- s1 = options;
- while (*s1) {
- int clear = 0;
- int time_min = OBD_RECOVERY_TIME_MIN;
-
- /* Skip whitespace and extra commas */
- while (*s1 == ' ' || *s1 == ',')
- s1++;
-
- /* Client options are parsed in ll_options: eg. flock,
- user_xattr, acl */
-
- /* Parse non-ldiskfs options here. Rather than modifying
- ldiskfs, we just zero these out here */
- if (strncmp(s1, "abort_recov", 11) == 0) {
- lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
- clear++;
- } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
- 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) {
- lmd->lmd_recovery_time_hard = max_t(int,
- simple_strtoul(s1 + 19, NULL, 10), time_min);
- clear++;
- } else if (strncmp(s1, "noir", 4) == 0) {
- lmd->lmd_flags |= LMD_FLG_NOIR; /* test purpose only. */
- clear++;
- } else if (strncmp(s1, "nosvc", 5) == 0) {
- lmd->lmd_flags |= LMD_FLG_NOSVC;
- clear++;
- } else if (strncmp(s1, "nomgs", 5) == 0) {
- lmd->lmd_flags |= LMD_FLG_NOMGS;
- clear++;
+ /* Set default flags here */
+
+ s1 = options;
+ while (*s1) {
+ int clear = 0;
+ int time_min = OBD_RECOVERY_TIME_MIN;
+ char *s3;
+
+ /* Skip whitespace and extra commas */
+ while (*s1 == ' ' || *s1 == ',')
+ s1++;
+ s3 = s1;
+
+ /* Client options are parsed in ll_options: eg. flock,
+ user_xattr, acl */
+
+ /* Parse non-ldiskfs options here. Rather than modifying
+ ldiskfs, we just zero these out here */
+ if (strncmp(s1, "abort_recov", 11) == 0) {
+ lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
+ clear++;
+ } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
+ 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) {
+ lmd->lmd_recovery_time_hard =
+ max_t(int, simple_strtoul(s1 + 19, NULL, 10),
+ time_min);
+ clear++;
+ } else if (strncmp(s1, "noir", 4) == 0) {
+ lmd->lmd_flags |= LMD_FLG_NOIR; /* test purpose only. */
+ clear++;
+ } else if (strncmp(s1, "nosvc", 5) == 0) {
+ lmd->lmd_flags |= LMD_FLG_NOSVC;
+ clear++;
+ } else if (strncmp(s1, "nomgs", 5) == 0) {
+ lmd->lmd_flags |= LMD_FLG_NOMGS;
+ clear++;
} else if (strncmp(s1, "noscrub", 7) == 0) {
lmd->lmd_flags |= LMD_FLG_NOSCRUB;
clear++;
+ } else if (strncmp(s1, "skip_lfsck", 10) == 0) {
+ lmd->lmd_flags |= LMD_FLG_SKIP_LFSCK;
+ clear++;
} else if (strncmp(s1, PARAM_MGSNODE,
sizeof(PARAM_MGSNODE) - 1) == 0) {
s2 = s1 + sizeof(PARAM_MGSNODE) - 1;
rc = lmd_parse_mgs(lmd, &s2);
if (rc)
goto invalid;
+ s3 = s2;
+ clear++;
+ } else if (strncmp(s1, "writeconf", 9) == 0) {
+ lmd->lmd_flags |= LMD_FLG_WRITECONF;
clear++;
- } else if (strncmp(s1, "writeconf", 9) == 0) {
- lmd->lmd_flags |= LMD_FLG_WRITECONF;
- clear++;
} else if (strncmp(s1, "update", 6) == 0) {
lmd->lmd_flags |= LMD_FLG_UPDATE;
clear++;
} else if (strncmp(s1, "noprimnode", 10) == 0) {
lmd->lmd_flags |= LMD_FLG_NO_PRIMNODE;
clear++;
- } else if (strncmp(s1, "mgssec=", 7) == 0) {
- rc = lmd_parse_mgssec(lmd, s1 + 7);
- if (rc)
- goto invalid;
- clear++;
- /* ost exclusion list */
- } else if (strncmp(s1, "exclude=", 8) == 0) {
- rc = lmd_make_exclusion(lmd, s1 + 7);
- if (rc)
- goto invalid;
- clear++;
+ } else if (strncmp(s1, "mgssec=", 7) == 0) {
+ rc = lmd_parse_mgssec(lmd, s1 + 7);
+ if (rc)
+ goto invalid;
+ clear++;
+ /* ost exclusion list */
+ } else if (strncmp(s1, "exclude=", 8) == 0) {
+ rc = lmd_make_exclusion(lmd, s1 + 7);
+ if (rc)
+ goto invalid;
+ clear++;
} else if (strncmp(s1, "mgs", 3) == 0) {
/* We are an MGS */
lmd->lmd_flags |= LMD_FLG_MGS;
goto invalid;
clear++;
} else if (strncmp(s1, "param=", 6) == 0) {
- int length;
- char *tail = strchr(s1 + 6, ',');
- if (tail == NULL)
+ size_t length, params_length;
+ char *tail = s1;
+ if (lmd_find_delimiter(s1 + 6, &tail) != 0)
length = strlen(s1);
- else
- length = tail - s1;
+ else {
+ char *param_str = tail + 1;
+ int supplementary = 1;
+ while (lmd_parse_nidlist(param_str,
+ ¶m_str) == 0) {
+ supplementary = 0;
+ }
+ length = param_str - s1 - supplementary;
+ }
length -= 6;
+ params_length = strlen(lmd->lmd_params);
+ if (params_length + length + 1 >= LMD_PARAMS_MAXLEN)
+ RETURN(-E2BIG);
strncat(lmd->lmd_params, s1 + 6, length);
- strcat(lmd->lmd_params, " ");
+ lmd->lmd_params[params_length + length] = '\0';
+ strlcat(lmd->lmd_params, " ", LMD_PARAMS_MAXLEN);
+ s3 = s1 + 6 + length;
clear++;
} else if (strncmp(s1, "osd=", 4) == 0) {
rc = lmd_parse_string(&lmd->lmd_osd_type, s1 + 4);
if (rc)
goto invalid;
clear++;
- }
- /* Linux 2.4 doesn't pass the device, so we stuck it at the
- end of the options. */
- else if (strncmp(s1, "device=", 7) == 0) {
- devname = s1 + 7;
- /* terminate options right before device. device
- must be the last one. */
- *s1 = '\0';
- break;
- }
+ }
+ /* Linux 2.4 doesn't pass the device, so we stuck it at the
+ end of the options. */
+ else if (strncmp(s1, "device=", 7) == 0) {
+ devname = s1 + 7;
+ /* terminate options right before device. device
+ must be the last one. */
+ *s1 = '\0';
+ break;
+ } else if (strncmp(s1, "network=", 8) == 0) {
+ rc = lmd_parse_network(lmd, s1 + 8);
+ if (rc)
+ goto invalid;
+ clear++;
+ }
- /* Find next opt */
- s2 = strchr(s1, ',');
- if (s2 == NULL) {
- if (clear)
- *s1 = '\0';
- break;
- }
- s2++;
- if (clear)
- memmove(s1, s2, strlen(s2) + 1);
- else
- s1 = s2;
- }
+ /* Find next opt */
+ s2 = strchr(s3, ',');
+ if (s2 == NULL) {
+ if (clear)
+ *s1 = '\0';
+ break;
+ }
+ s2++;
+ if (clear)
+ memmove(s1, s2, strlen(s2) + 1);
+ else
+ s1 = s2;
+ }
- if (!devname) {
- LCONSOLE_ERROR_MSG(0x164, "Can't find the device name "
- "(need mount option 'device=...')\n");
- goto invalid;
- }
+ if (!devname) {
+ LCONSOLE_ERROR_MSG(0x164, "Can't find the device name "
+ "(need mount option 'device=...')\n");
+ goto invalid;
+ }
- s1 = strstr(devname, ":/");
- if (s1) {
- ++s1;
- lmd->lmd_flags |= LMD_FLG_CLIENT;
- /* Remove leading /s from fsname */
- while (*++s1 == '/') ;
- /* Freed in lustre_free_lsi */
- OBD_ALLOC(lmd->lmd_profile, strlen(s1) + 8);
- if (!lmd->lmd_profile)
- RETURN(-ENOMEM);
- sprintf(lmd->lmd_profile, "%s-client", s1);
- }
+ s1 = strstr(devname, ":/");
+ if (s1) {
+ ++s1;
+ lmd->lmd_flags |= LMD_FLG_CLIENT;
+ /* Remove leading /s from fsname */
+ while (*++s1 == '/')
+ ;
+ s2 = s1;
+ while (*s2 != '/' && *s2 != '\0')
+ s2++;
+ /* Freed in lustre_free_lsi */
+ OBD_ALLOC(lmd->lmd_profile, s2 - s1 + 8);
+ if (!lmd->lmd_profile)
+ RETURN(-ENOMEM);
+
+ strncat(lmd->lmd_profile, s1, s2 - s1);
+ strncat(lmd->lmd_profile, "-client", 7);
- /* Freed in lustre_free_lsi */
- OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
- if (!lmd->lmd_dev)
- RETURN(-ENOMEM);
- strcpy(lmd->lmd_dev, devname);
-
- /* Save mount options */
- s1 = options + strlen(options) - 1;
- while (s1 >= options && (*s1 == ',' || *s1 == ' '))
- *s1-- = 0;
- if (*options != 0) {
- /* Freed in lustre_free_lsi */
- OBD_ALLOC(lmd->lmd_opts, strlen(options) + 1);
- if (!lmd->lmd_opts)
- RETURN(-ENOMEM);
- strcpy(lmd->lmd_opts, options);
- }
+ s1 = s2;
+ s2 = s1 + strlen(s1) - 1;
+ /* Remove padding /s from fileset */
+ while (*s2 == '/')
+ s2--;
+ if (s2 > s1) {
+ OBD_ALLOC(lmd->lmd_fileset, s2 - s1 + 2);
+ if (lmd->lmd_fileset == NULL) {
+ OBD_FREE(lmd->lmd_profile,
+ strlen(lmd->lmd_profile) + 1);
+ RETURN(-ENOMEM);
+ }
+ strncat(lmd->lmd_fileset, s1, s2 - s1 + 1);
+ }
+ } else {
+ /* server mount */
+ if (lmd->lmd_nidnet != NULL) {
+ /* 'network=' mount option forbidden for server */
+ OBD_FREE(lmd->lmd_nidnet, strlen(lmd->lmd_nidnet) + 1);
+ lmd->lmd_nidnet = NULL;
+ rc = -EINVAL;
+ CERROR("%s: option 'network=' not allowed for Lustre "
+ "servers: rc = %d\n", devname, rc);
+ RETURN(rc);
+ }
+ }
- lmd_print(lmd);
- lmd->lmd_magic = LMD_MAGIC;
+ /* Freed in lustre_free_lsi */
+ OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
+ if (!lmd->lmd_dev)
+ RETURN(-ENOMEM);
+ strncpy(lmd->lmd_dev, devname, strlen(devname)+1);
+
+ /* Save mount options */
+ s1 = options + strlen(options) - 1;
+ while (s1 >= options && (*s1 == ',' || *s1 == ' '))
+ *s1-- = 0;
+ if (*options != 0) {
+ /* Freed in lustre_free_lsi */
+ OBD_ALLOC(lmd->lmd_opts, strlen(options) + 1);
+ if (!lmd->lmd_opts)
+ RETURN(-ENOMEM);
+ strncpy(lmd->lmd_opts, options, strlen(options)+1);
+ }
- RETURN(rc);
+ lmd_print(lmd);
+ lmd->lmd_magic = LMD_MAGIC;
+
+ RETURN(rc);
invalid:
- CERROR("Bad mount options %s\n", options);
- RETURN(-EINVAL);
+ CERROR("Bad mount options %s\n", options);
+ RETURN(-EINVAL);
}
struct lustre_mount_data2 {
* and this is where we start setting things up.
* @param data Mount options (e.g. -o flock,abort_recov)
*/
-int lustre_fill_super(struct super_block *sb, void *data, int silent)
+static int lustre_fill_super(struct super_block *sb, void *data, int silent)
{
struct lustre_mount_data *lmd;
struct lustre_mount_data2 *lmd2 = data;
GOTO(out, rc = -EINVAL);
}
- if (lmd_is_client(lmd)) {
- CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
- if (!client_fill_super) {
- LCONSOLE_ERROR_MSG(0x165, "Nothing registered for "
- "client mount! Is the 'lustre' "
- "module loaded?\n");
- lustre_put_lsi(sb);
- rc = -ENODEV;
- } else {
- rc = lustre_start_mgc(sb);
- if (rc) {
- lustre_put_lsi(sb);
- GOTO(out, rc);
- }
- /* 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 */
- }
- } else {
+ if (lmd_is_client(lmd)) {
+ CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
+ if (client_fill_super == NULL)
+ request_module("lustre");
+ if (client_fill_super == NULL) {
+ LCONSOLE_ERROR_MSG(0x165, "Nothing registered for "
+ "client mount! Is the 'lustre' "
+ "module loaded?\n");
+ lustre_put_lsi(sb);
+ rc = -ENODEV;
+ } else {
+ rc = lustre_start_mgc(sb);
+ if (rc) {
+ lustre_common_put_super(sb);
+ GOTO(out, rc);
+ }
+ /* 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 */
+ }
+ } else {
#ifdef HAVE_SERVER_SUPPORT
CDEBUG(D_MOUNT, "Mounting server from %s\n", lmd->lmd_dev);
rc = server_fill_super(sb);
"cannot handle server mount.\n");
rc = -EINVAL;
#endif
- }
+ }
/* If error happens in fill_super() call, @lsi will be killed there.
* This is why we do not put it here. */
/***************** FS registration ******************/
#ifdef HAVE_FSTYPE_MOUNT
-struct dentry *lustre_mount(struct file_system_type *fs_type, int flags,
- const char *devname, void *data)
+static struct dentry *lustre_mount(struct file_system_type *fs_type, int flags,
+ const char *devname, void *data)
{
- struct lustre_mount_data2 lmd2 = { data, NULL };
+ struct lustre_mount_data2 lmd2 = {
+ .lmd2_data = data,
+ };
return mount_nodev(fs_type, flags, &lmd2, lustre_fill_super);
}
#else
-int lustre_get_sb(struct file_system_type *fs_type, int flags,
- const char *devname, void * data, struct vfsmount *mnt)
+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 = { data, mnt };
+ struct lustre_mount_data2 lmd2 = {
+ .lmd2_data = data,
+ .lmd2_mnt = mnt,
+ };
return get_sb_nodev(fs_type, flags, &lmd2, lustre_fill_super, mnt);
}
#endif
-void lustre_kill_super(struct super_block *sb)
+static void lustre_kill_super(struct super_block *sb)
{
struct lustre_sb_info *lsi = s2lsi(sb);
/** Register the "lustre" fs type
*/
-struct file_system_type lustre_fs_type = {
+static struct file_system_type lustre_fs_type = {
.owner = THIS_MODULE,
.name = "lustre",
#ifdef HAVE_FSTYPE_MOUNT
.get_sb = lustre_get_sb,
#endif
.kill_sb = lustre_kill_super,
- .fs_flags = FS_BINARY_MOUNTDATA | FS_REQUIRES_DEV |
- FS_HAS_FIEMAP | FS_RENAME_DOES_D_MOVE,
+ .fs_flags = FS_REQUIRES_DEV | FS_HAS_FIEMAP | FS_RENAME_DOES_D_MOVE,
};
+MODULE_ALIAS_FS("lustre");
int lustre_register_fs(void)
{