Whamcloud - gitweb
LU-3963 libcfs: convert obdecho,obdclass code to atomics
[fs/lustre-release.git] / lustre / obdclass / obd_mount.c
index 1c99179..309080e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -46,8 +46,6 @@
 #define PRINT_CMD CDEBUG
 
 #include <obd.h>
-#include <lvfs.h>
-#include <lustre_fsfilt.h>
 #include <obd_class.h>
 #include <lustre/lustre_user.h>
 #include <linux/version.h>
@@ -281,7 +279,7 @@ int lustre_start_mgc(struct super_block *sb)
                         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)) {
@@ -337,36 +335,48 @@ int lustre_start_mgc(struct super_block *sb)
         sprintf(niduuid, "%s_%x", mgcname, i);
        if (IS_SERVER(lsi)) {
                ptr = lsi->lsi_lmd->lmd_mgs;
+               CDEBUG(D_MOUNT, "mgs nids %s.\n", ptr);
                if (IS_MGS(lsi)) {
-                        /* Use local nids (including LO) */
-                        lnet_process_id_t id;
-                        while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
-                                rc = do_lcfg(mgcname, id.nid,
-                                             LCFG_ADD_UUID, niduuid, 0,0,0);
-                        }
-                } else {
-                        /* Use mgsnode= nids */
+                       /* Use local nids (including LO) */
+                       lnet_process_id_t id;
+                       while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
+                               rc = do_lcfg(mgcname, id.nid, LCFG_ADD_UUID,
+                                            niduuid, 0, 0, 0);
+                       }
+               } else {
+                       /* Use mgsnode= nids */
                        /* mount -o mgsnode=nid */
                        if (lsi->lsi_lmd->lmd_mgs) {
                                ptr = lsi->lsi_lmd->lmd_mgs;
                        } else if (class_find_param(ptr, PARAM_MGSNODE,
                                                    &ptr) != 0) {
-                                CERROR("No MGS nids given.\n");
-                                GOTO(out_free, rc = -EINVAL);
-                        }
-                        while (class_parse_nid(ptr, &nid, &ptr) == 0) {
-                                rc = do_lcfg(mgcname, nid,
-                                             LCFG_ADD_UUID, niduuid, 0,0,0);
-                                i++;
-                        }
-                }
+                               CERROR("No MGS nids given.\n");
+                               GOTO(out_free, rc = -EINVAL);
+                       }
+                       /*
+                        * LU-3829.
+                        * Here we only take the first mgsnid as its primary
+                        * serving mgs node, the rest mgsnid will be taken as
+                        * failover mgs node, otherwise they would be takens
+                        * as multiple nids of a single mgs node.
+                        */
+                       while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+                               rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
+                                            niduuid, 0, 0, 0);
+                               if (rc == 0) {
+                                       i = 1;
+                                       break;
+                               }
+                       }
+               }
         } else { /* client */
                 /* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
                 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);
-                        i++;
+                       rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
+                                    niduuid, 0, 0, 0);
+                       if (rc == 0)
+                               ++i;
                         /* Stop at the first failover nid */
                         if (*ptr == ':')
                                 break;
@@ -395,20 +405,22 @@ int lustre_start_mgc(struct super_block *sb)
         i = 1;
        while (ptr && ((*ptr == ':' ||
               class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0))) {
-                /* New failover node */
-                sprintf(niduuid, "%s_%x", mgcname, i);
-                j = 0;
+               /* New failover node */
+               sprintf(niduuid, "%s_%x", mgcname, i);
+               j = 0;
                while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
-                        j++;
-                        rc = do_lcfg(mgcname, nid,
-                                     LCFG_ADD_UUID, niduuid, 0,0,0);
-                        if (*ptr == ':')
-                                break;
-                }
-                if (j > 0) {
-                        rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
-                                     niduuid, 0, 0, 0);
-                        i++;
+                       rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
+                                    niduuid, 0, 0, 0);
+                       if (rc == 0)
+                               ++j;
+                       if (*ptr == ':')
+                               break;
+               }
+               if (j > 0) {
+                       rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
+                                    niduuid, 0, 0, 0);
+                       if (rc == 0)
+                               ++i;
                 } else {
                         /* at ":/fsname" */
                         break;
@@ -430,7 +442,7 @@ int lustre_start_mgc(struct super_block *sb)
 
         /* 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);
+       atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
 
         /* Try all connections, but only once. */
         recov_bk = 1;
@@ -497,12 +509,12 @@ static int lustre_stop_mgc(struct super_block *sb)
         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);
         }
 
@@ -573,7 +585,7 @@ struct lustre_sb_info *lustre_init_lsi(struct super_block *sb)
         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;
@@ -590,7 +602,7 @@ static int lustre_free_lsi(struct super_block *sb)
         CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi);
 
         /* someone didn't call server_put_mount. */
-        LASSERT(cfs_atomic_read(&lsi->lsi_mounts) == 0);
+       LASSERT(atomic_read(&lsi->lsi_mounts) == 0);
 
         if (lsi->lsi_lmd != NULL) {
                 if (lsi->lsi_lmd->lmd_dev != NULL)
@@ -637,9 +649,12 @@ int lustre_put_lsi(struct super_block *sb)
 
         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;
+                       lsi->lsi_dt_dev = NULL;
                        obd_disconnect(lsi->lsi_osd_exp);
                        /* wait till OSD is gone */
                        obd_zombie_barrier();
@@ -650,6 +665,15 @@ int lustre_put_lsi(struct super_block *sb)
         RETURN(0);
 }
 
+/*** SERVER NAME ***
+ * <FSNAME><SEPERATOR><TYPE><INDEX>
+ * FSNAME is between 1 and 8 characters (inclusive).
+ *     Excluded characters are '/' and ':'
+ * SEPERATOR is either ':' or '-'
+ * TYPE: "OST", "MDT", etc.
+ * INDEX: Hex representation of the index
+ */
+
 /** Get the fsname ("lustre") from the server name ("lustre-OST003F").
  * @param [in] svname server name including type and index
  * @param [out] fsname Buffer to copy filesystem name prefix into.
@@ -659,22 +683,13 @@ int lustre_put_lsi(struct super_block *sb)
  */
 int server_name2fsname(const char *svname, char *fsname, const char **endptr)
 {
-       const char *dash = strrchr(svname, '-');
-       if (!dash) {
-               dash = strrchr(svname, ':');
-               if (!dash)
-                       return -EINVAL;
-       }
+       const char *dash;
 
-       /* interpret <fsname>-MDTXXXXX-mdc as mdt, the better way is to pass
-        * in the fsname, then determine the server index */
-       if (!strcmp(LUSTRE_MDC_NAME, dash + 1)) {
-               dash--;
-               for (; dash > svname && *dash != '-' && *dash != ':'; dash--)
-                       ;
-               if (dash == svname)
-                       return -EINVAL;
-       }
+       dash = svname + strnlen(svname, 8); /* max fsname length is 8 */
+       for (; dash > svname && *dash != '-' && *dash != ':'; dash--)
+               ;
+       if (dash == svname)
+               return -EINVAL;
 
        if (fsname != NULL) {
                strncpy(fsname, svname, dash - svname);
@@ -697,15 +712,15 @@ int server_name2svname(const char *label, char *svname, const char **endptr,
                       size_t svsize)
 {
        int rc;
-       const const char *dash;
+       const char *dash;
 
        /* We use server_name2fsname() just for parsing */
        rc = server_name2fsname(label, NULL, &dash);
        if (rc != 0)
                return rc;
 
-       if (*dash != '-')
-               return -1;
+       if (endptr != NULL)
+               *endptr = dash;
 
        if (strlcpy(svname, dash + 1, svsize) >= svsize)
                return -E2BIG;
@@ -714,27 +729,37 @@ int server_name2svname(const char *label, char *svname, const char **endptr,
 }
 EXPORT_SYMBOL(server_name2svname);
 
-
-/* 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)
+/**
+ * check server name is OST.
+ **/
+int server_name_is_ost(const char *svname)
 {
-       unsigned long index;
-       int rc;
        const char *dash;
+       int rc;
 
        /* We use server_name2fsname() just for parsing */
        rc = server_name2fsname(svname, NULL, &dash);
        if (rc != 0)
                return rc;
 
-       if (*dash != '-')
-               return -EINVAL;
-
        dash++;
 
+       if (strncmp(dash, "OST", 3) == 0)
+               return 1;
+       return 0;
+}
+EXPORT_SYMBOL(server_name_is_ost);
+
+/**
+ * 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;
+
        if (strncmp(dash, "MDT", 3) == 0)
                rc = LDD_F_SV_TYPE_MDT;
        else if (strncmp(dash, "OST", 3) == 0)
@@ -744,11 +769,42 @@ int server_name2index(const char *svname, __u32 *idx, const char **endptr)
 
        dash += 3;
 
-       if (strcmp(dash, "all") == 0)
+       if (strncmp(dash, "all", 3) == 0) {
+               if (endptr != NULL)
+                       *endptr = dash + 3;
                return rc | LDD_F_SV_ALL;
+       }
 
        index = simple_strtoul(dash, (char **)endptr, 16);
-       *idx = index;
+       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,
+                                     sizeof(LUSTRE_MDC_NAME)-1) == 0)
+               *endptr += sizeof(LUSTRE_MDC_NAME);
 
        return rc;
 }
@@ -839,55 +895,57 @@ int lustre_check_exclusion(struct super_block *sb, char *svname)
 static int lmd_make_exclusion(struct lustre_mount_data *lmd, const char *ptr)
 {
        const char *s1 = ptr, *s2;
-        __u32 index, *exclude_list;
-        int rc = 0, devmax;
-        ENTRY;
-
-        /* The shortest an ost name can be is 8 chars: -OST0000.
-           We don't actually know the fsname at this time, so in fact
-           a user could specify any fsname. */
-        devmax = strlen(ptr) / 8 + 1;
-
-        /* temp storage until we figure out how many we have */
-        OBD_ALLOC(exclude_list, sizeof(index) * devmax);
-        if (!exclude_list)
-                RETURN(-ENOMEM);
+       __u32 index, *exclude_list;
+       int rc = 0, devmax;
+       ENTRY;
+
+       /* The shortest an ost name can be is 8 chars: -OST0000.
+          We don't actually know the fsname at this time, so in fact
+          a user could specify any fsname. */
+       devmax = strlen(ptr) / 8 + 1;
+
+       /* temp storage until we figure out how many we have */
+       OBD_ALLOC(exclude_list, sizeof(index) * devmax);
+       if (!exclude_list)
+               RETURN(-ENOMEM);
 
-        /* we enter this fn pointing at the '=' */
-        while (*s1 && *s1 != ' ' && *s1 != ',') {
-                s1++;
-                rc = server_name2index(s1, &index, &s2);
-                if (rc < 0) {
-                        CERROR("Can't parse server name '%s'\n", s1);
-                        break;
-                }
-                if (rc == LDD_F_SV_TYPE_OST)
-                        exclude_list[lmd->lmd_exclude_count++] = index;
-                else
-                        CDEBUG(D_MOUNT, "ignoring exclude %.7s\n", s1);
-                s1 = s2;
-                /* now we are pointing at ':' (next exclude)
-                   or ',' (end of excludes) */
-                if (lmd->lmd_exclude_count >= devmax)
-                        break;
-        }
-        if (rc >= 0) /* non-err */
-                rc = 0;
-
-        if (lmd->lmd_exclude_count) {
-                /* permanent, freed in lustre_free_lsi */
-                OBD_ALLOC(lmd->lmd_exclude, sizeof(index) *
-                          lmd->lmd_exclude_count);
-                if (lmd->lmd_exclude) {
-                        memcpy(lmd->lmd_exclude, exclude_list,
-                               sizeof(index) * lmd->lmd_exclude_count);
-                } else {
-                        rc = -ENOMEM;
-                        lmd->lmd_exclude_count = 0;
-                }
-        }
-        OBD_FREE(exclude_list, sizeof(index) * devmax);
-        RETURN(rc);
+       /* we enter this fn pointing at the '=' */
+       while (*s1 && *s1 != ' ' && *s1 != ',') {
+               s1++;
+               rc = server_name2index(s1, &index, &s2);
+               if (rc < 0) {
+                       CERROR("Can't parse server name '%s': rc = %d\n",
+                              s1, rc);
+                       break;
+               }
+               if (rc == LDD_F_SV_TYPE_OST)
+                       exclude_list[lmd->lmd_exclude_count++] = index;
+               else
+                       CDEBUG(D_MOUNT, "ignoring exclude %.*s: type = %#x\n",
+                              (uint)(s2-s1), s1, rc);
+               s1 = s2;
+               /* now we are pointing at ':' (next exclude)
+                  or ',' (end of excludes) */
+               if (lmd->lmd_exclude_count >= devmax)
+                       break;
+       }
+       if (rc >= 0) /* non-err */
+               rc = 0;
+
+       if (lmd->lmd_exclude_count) {
+               /* permanent, freed in lustre_free_lsi */
+               OBD_ALLOC(lmd->lmd_exclude, sizeof(index) *
+                         lmd->lmd_exclude_count);
+               if (lmd->lmd_exclude) {
+                       memcpy(lmd->lmd_exclude, exclude_list,
+                              sizeof(index) * lmd->lmd_exclude_count);
+               } else {
+                       rc = -ENOMEM;
+                       lmd->lmd_exclude_count = 0;
+               }
+       }
+       OBD_FREE(exclude_list, sizeof(index) * devmax);
+       RETURN(rc);
 }
 
 static int lmd_parse_mgssec(struct lustre_mount_data *lmd, char *ptr)