* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
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);
/* 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);
/* 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, 0, 53, 0)
data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
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
} 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;
clear++;
} else if (strncmp(s1, "param=", 6) == 0) {
size_t length, params_length;
- char *tail = strchr(s1 + 6, ',');
- if (tail == NULL) {
+ 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;
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);
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. */
.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");