Whamcloud - gitweb
LU-11803 obd: replace class_uuid with linux kernel version.
[fs/lustre-release.git] / lustre / llite / llite_lib.c
index 456cb84..2548dbd 100644 (file)
 #define DEBUG_SUBSYSTEM S_LLITE
 
 #include <linux/module.h>
+#include <linux/random.h>
 #include <linux/statfs.h>
 #include <linux/time.h>
 #include <linux/types.h>
+#include <libcfs/linux/linux-uuid.h>
 #include <linux/version.h>
 #include <linux/mm.h>
 #include <linux/user_namespace.h>
@@ -71,7 +73,6 @@ static struct ll_sb_info *ll_init_sbi(void)
        unsigned long pages;
        unsigned long lru_page_max;
        struct sysinfo si;
-       class_uuid_t uuid;
        int i;
        ENTRY;
 
@@ -101,10 +102,6 @@ static struct ll_sb_info *ll_init_sbi(void)
        sbi->ll_ra_info.ra_max_pages = sbi->ll_ra_info.ra_max_pages_per_file;
        sbi->ll_ra_info.ra_max_read_ahead_whole_pages = -1;
 
-        ll_generate_random_uuid(uuid);
-        class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
-        CDEBUG(D_CONFIG, "generated uuid: %s\n", sbi->ll_sb_uuid.uuid);
-
         sbi->ll_flags |= LL_SBI_VERBOSE;
 #ifdef ENABLE_CHECKSUM
         sbi->ll_flags |= LL_SBI_CHECKSUM;
@@ -224,10 +221,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                  OBD_CONNECT_GRANT_PARAM |
                                  OBD_CONNECT_SHORTIO | OBD_CONNECT_FLAGS2;
 
-       data->ocd_connect_flags2 = OBD_CONNECT2_FLR |
-                                  OBD_CONNECT2_LOCK_CONVERT |
-                                  OBD_CONNECT2_DIR_MIGRATE |
+       data->ocd_connect_flags2 = OBD_CONNECT2_DIR_MIGRATE |
                                   OBD_CONNECT2_SUM_STATFS |
+                                  OBD_CONNECT2_FLR |
+                                  OBD_CONNECT2_LOCK_CONVERT |
                                   OBD_CONNECT2_ARCHIVE_ID_ARRAY |
                                   OBD_CONNECT2_LSOM;
 
@@ -594,9 +591,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
 
        sb->s_root = d_make_root(root);
        if (sb->s_root == NULL) {
-               CERROR("%s: can't make root dentry\n",
-                       ll_get_fsname(sb, NULL, 0));
-               GOTO(out_root, err = -ENOMEM);
+               err = -ENOMEM;
+               CERROR("%s: can't make root dentry: rc = %d\n",
+                      sbi->ll_fsname, err);
+               GOTO(out_root, err);
        }
 #ifdef HAVE_DCACHE_LOCK
        sb->s_root->d_op = &ll_d_ops;
@@ -624,7 +622,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                        sbi->ll_dt_obd->obd_type->typ_name);
                if (err < 0) {
                        CERROR("%s: could not register %s in llite: rc = %d\n",
-                              dt, ll_get_fsname(sb, NULL, 0), err);
+                              dt, sbi->ll_fsname, err);
                        err = 0;
                }
        }
@@ -635,7 +633,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                        sbi->ll_md_obd->obd_type->typ_name);
                if (err < 0) {
                        CERROR("%s: could not register %s in llite: rc = %d\n",
-                              md, ll_get_fsname(sb, NULL, 0), err);
+                              md, sbi->ll_fsname, err);
                        err = 0;
                }
        }
@@ -1030,6 +1028,7 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt)
        char name[MAX_STRING_SIZE];
        int md_len = 0;
        int dt_len = 0;
+       uuid_t uuid;
        char *ptr;
        int len;
        int err;
@@ -1054,31 +1053,50 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt)
        if (err)
                GOTO(out_free_cfg, err);
 
-       err = super_setup_bdi_name(sb, "lustre-%016lx", cfg_instance);
-       if (err)
-               GOTO(out_free_cfg, err);
-
 #ifndef HAVE_DCACHE_LOCK
        /* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */
        sb->s_d_op = &ll_d_ops;
 #endif
+       /* UUID handling */
+       generate_random_uuid(uuid.b);
+       snprintf(sbi->ll_sb_uuid.uuid, UUID_SIZE, "%pU", uuid.b);
+
+       CDEBUG(D_CONFIG, "llite sb uuid: %s\n", sbi->ll_sb_uuid.uuid);
+
        /* Get fsname */
        len = strlen(profilenm);
        ptr = strrchr(profilenm, '-');
        if (ptr && (strcmp(ptr, "-client") == 0))
                len -= 7;
 
+       if (len > LUSTRE_MAXFSNAME) {
+               if (unlikely(len >= MAX_STRING_SIZE))
+                       len = MAX_STRING_SIZE - 1;
+               strncpy(name, profilenm, len);
+               name[len] = '\0';
+               err = -ENAMETOOLONG;
+               CERROR("%s: fsname longer than %u characters: rc = %d\n",
+                      name, LUSTRE_MAXFSNAME, err);
+               GOTO(out_free_cfg, err);
+       }
+       strncpy(sbi->ll_fsname, profilenm, len);
+       sbi->ll_fsname[len] = '\0';
+
        /* Mount info */
-       snprintf(name, MAX_STRING_SIZE, "%.*s-%016lx", len,
+       snprintf(name, sizeof(name), "%.*s-%016lx", len,
                 profilenm, cfg_instance);
 
+       err = super_setup_bdi_name(sb, "%s", name);
+       if (err)
+               GOTO(out_free_cfg, err);
+
        /* Call ll_debugfs_register_super() before lustre_process_log()
         * so that "llite.*.*" params can be processed correctly.
         */
        err = ll_debugfs_register_super(sb, name);
        if (err < 0) {
                CERROR("%s: could not register mountpoint in llite: rc = %d\n",
-                      ll_get_fsname(sb, NULL, 0), err);
+                      sbi->ll_fsname, err);
                err = 0;
        }
 
@@ -1286,7 +1304,7 @@ static struct inode *ll_iget_anon_dir(struct super_block *sb,
        inode = iget_locked(sb, ino);
        if (inode == NULL) {
                CERROR("%s: failed get simple inode "DFID": rc = -ENOENT\n",
-                      ll_get_fsname(sb, NULL, 0), PFID(fid));
+                      sbi->ll_fsname, PFID(fid));
                RETURN(ERR_PTR(-ENOENT));
        }
 
@@ -1335,8 +1353,7 @@ static int ll_init_lsm_md(struct inode *inode, struct lustre_md *md)
        LASSERT(lsm != NULL);
 
        CDEBUG(D_INODE, "%s: "DFID" set dir layout:\n",
-               ll_get_fsname(inode->i_sb, NULL, 0),
-               PFID(&lli->lli_fid));
+              ll_i2sbi(inode)->ll_fsname, PFID(&lli->lli_fid));
        lsm_md_dump(D_INODE, lsm);
 
        /* XXX sigh, this lsm_root initialization should be in
@@ -1399,13 +1416,17 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
        /*
         * if dir layout mismatch, check whether version is increased, which
         * means layout is changed, this happens in dir migration and lfsck.
+        *
+        * foreign LMV should not change.
         */
-       if (lli->lli_lsm_md && !lsm_md_eq(lli->lli_lsm_md, lsm)) {
+       if (lli->lli_lsm_md &&
+           lli->lli_lsm_md->lsm_md_magic != LMV_MAGIC_FOREIGN &&
+          !lsm_md_eq(lli->lli_lsm_md, lsm)) {
                if (lsm->lsm_md_layout_version <=
                    lli->lli_lsm_md->lsm_md_layout_version) {
                        CERROR("%s: "DFID" dir layout mismatch:\n",
-                               ll_get_fsname(inode->i_sb, NULL, 0),
-                               PFID(&lli->lli_fid));
+                              ll_i2sbi(inode)->ll_fsname,
+                              PFID(&lli->lli_fid));
                        lsm_md_dump(D_ERROR, lli->lli_lsm_md);
                        lsm_md_dump(D_ERROR, lsm);
                        GOTO(unlock, rc = -EINVAL);
@@ -1421,6 +1442,15 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
        if (!lli->lli_lsm_md) {
                struct cl_attr  *attr;
 
+               if (lsm->lsm_md_magic == LMV_MAGIC_FOREIGN) {
+                       /* set md->lmv to NULL, so the following free lustre_md
+                        * will not free this lsm */
+                       md->lmv = NULL;
+                       lli->lli_lsm_md = lsm;
+                       up_write(&lli->lli_lsm_sem);
+                       RETURN(0);
+               }
+
                rc = ll_init_lsm_md(inode, md);
                up_write(&lli->lli_lsm_sem);
                if (rc != 0)
@@ -1611,7 +1641,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr,
 
        CDEBUG(D_VFSTRACE, "%s: setattr inode "DFID"(%p) from %llu to %llu, "
               "valid %x, hsm_import %d\n",
-              ll_get_fsname(inode->i_sb, NULL, 0), PFID(&lli->lli_fid),
+              ll_i2sbi(inode)->ll_fsname, PFID(&lli->lli_fid),
               inode, i_size_read(inode), attr->ia_size, attr->ia_valid,
               hsm_import);
 
@@ -2126,7 +2156,7 @@ void ll_delete_inode(struct inode *inode)
 
        LASSERTF(nrpages == 0, "%s: inode="DFID"(%p) nrpages=%lu, "
                 "see https://jira.whamcloud.com/browse/LU-118\n",
-                ll_get_fsname(inode->i_sb, NULL, 0),
+                ll_i2sbi(inode)->ll_fsname,
                 PFID(ll_inode2fid(inode)), inode, nrpages);
 
 #ifdef HAVE_SBOPS_EVICT_INODE
@@ -2355,8 +2385,7 @@ void ll_open_cleanup(struct super_block *sb, struct ptlrpc_request *open_req)
        OBD_ALLOC_PTR(op_data);
        if (op_data == NULL) {
                CWARN("%s: cannot allocate op_data to release open handle for "
-                     DFID"\n",
-                     ll_get_fsname(sb, NULL, 0), PFID(&body->mbo_fid1));
+                     DFID"\n", ll_s2sbi(sb)->ll_fsname, PFID(&body->mbo_fid1));
 
                RETURN_EXIT;
        }
@@ -2384,7 +2413,7 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
        rc = md_get_lustre_md(sbi->ll_md_exp, req, sbi->ll_dt_exp,
                              sbi->ll_md_exp, &md);
        if (rc != 0)
-               GOTO(cleanup, rc);
+               GOTO(out, rc);
 
        if (*inode) {
                rc = ll_update_inode(*inode, &md);
@@ -2399,7 +2428,7 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
                 */
                if (!fid_is_sane(&md.body->mbo_fid1)) {
                        CERROR("%s: Fid is insane "DFID"\n",
-                               ll_get_fsname(sb, NULL, 0),
+                               sbi->ll_fsname,
                                PFID(&md.body->mbo_fid1));
                        GOTO(out, rc = -EINVAL);
                }
@@ -2452,9 +2481,9 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
        GOTO(out, rc = 0);
 
 out:
+       /* cleanup will be done if necessary */
        md_free_lustre_md(sbi->ll_md_exp, &md);
 
-cleanup:
        if (rc != 0 && it != NULL && it->it_op & IT_OPEN)
                ll_open_cleanup(sb != NULL ? sb : (*inode)->i_sb, req);
 
@@ -2671,39 +2700,6 @@ int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg)
        RETURN(0);
 }
 
-/**
- * Get lustre file system name by \a sbi. If \a buf is provided(non-NULL), the
- * fsname will be returned in this buffer; otherwise, a static buffer will be
- * used to store the fsname and returned to caller.
- */
-char *ll_get_fsname(struct super_block *sb, char *buf, int buflen)
-{
-       static char fsname_static[MTI_NAME_MAXLEN];
-       struct lustre_sb_info *lsi = s2lsi(sb);
-       char *ptr;
-       int len;
-
-       if (buf == NULL) {
-               /* this means the caller wants to use static buffer
-                * and it doesn't care about race. Usually this is
-                * in error reporting path */
-               buf = fsname_static;
-               buflen = sizeof(fsname_static);
-       }
-
-       len = strlen(lsi->lsi_lmd->lmd_profile);
-       ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-');
-       if (ptr && (strcmp(ptr, "-client") == 0))
-               len -= 7;
-
-       if (unlikely(len >= buflen))
-               len = buflen - 1;
-       strncpy(buf, lsi->lsi_lmd->lmd_profile, len);
-       buf[len] = '\0';
-
-       return buf;
-}
-
 static char* ll_d_path(struct dentry *dentry, char *buf, int bufsize)
 {
        char *path = NULL;
@@ -2734,7 +2730,7 @@ void ll_dirty_page_discard_warn(struct page *page, int ioret)
 
        CDEBUG(D_WARNING,
               "%s: dirty page discard: %s/fid: "DFID"/%s may get corrupted "
-              "(rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0),
+              "(rc %d)\n", ll_i2sbi(inode)->ll_fsname,
               s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev,
               PFID(ll_inode2fid(inode)),
               (path && !IS_ERR(path)) ? path : "", ioret);