* 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, 2015, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
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 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 : "";
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 {
/* 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;
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;
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);
+ LASSERT(lsi != NULL);
+ CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi);
- /* someone didn't call server_put_mount. */
+ /* 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_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 != 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);
if (lsi->lsi_lmd->lmd_params != NULL)
OBD_FREE(lsi->lsi_lmd->lmd_params, 4096);
- 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 -
}
/*** 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
*/
return 0;
}
+/**
+ * Find the first comma delimiter from the specified \a buf and make \a *endh
+ * point to the string starting with the comma. The commas in expression list
+ * [...] will be skipped.
+ *
+ * \param[in] buf a comma-separated string
+ * \param[in] endh a pointer to a pointer that will point to the string
+ * starting with the comma
+ *
+ * \retval 0 if comma delimiter is found
+ * \retval 1 if comma delimiter is not found
+ */
+static int lmd_find_comma(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 == ',' && skip == 0) {
+ if (endh != NULL)
+ *endh = c;
+ return 0;
+ }
+
+ c++;
+ }
+
+ return 1;
+}
+
+/**
+ * Find the first valid string delimited by comma 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 comma.
+ *
+ * \param[in] buf a comma-separated string
+ * \param[in] endh a pointer to a pointer that will point to the string
+ * starting with the comma
+ *
+ * \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_comma(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
}
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';
} 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;
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_comma(s1 + 6, &tail) != 0)
length = strlen(s1);
- } else {
- lnet_nid_t nid;
- char *param_str = tail + 1;
- int supplementary = 1;
-
- while (class_parse_nid_quiet(param_str, &nid,
- ¶m_str) == 0) {
+ 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) {
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);
+
+ 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);
+ }
+ }
/* Freed in lustre_free_lsi */
OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
* 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 (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_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 {
+ 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 };
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 };
}
#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");