Whamcloud - gitweb
LU-4682 llite: a few fixes for migration. 22/9522/5
authorwang di <di.wang@intel.com>
Fri, 28 Feb 2014 15:52:58 +0000 (07:52 -0800)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 12 Mar 2014 15:17:27 +0000 (15:17 +0000)
1. Clear the client dentry cache before migrating file/directory
to the remote MDT.

2. Do not return stripe information to client, it did not get
Layout lock.

3. A few cleanups from the review of 6662.

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: I209079dfa07241412878b30fd02e8152046c95c7
Reviewed-on: http://review.whamcloud.com/9522
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
lustre/include/md_object.h
lustre/lfsck/lfsck_layout.c
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/lov/lov_object.c
lustre/mdd/mdd_dir.c
lustre/mdt/mdt_reint.c

index 270e302..c1ec562 100644 (file)
@@ -303,7 +303,7 @@ struct md_dir_operations {
                          struct md_attr *ma, int no_name);
 
        int (*mdo_migrate)(const struct lu_env *env, struct md_object *pobj,
-                          const struct lu_fid *lf, const struct lu_name *lname,
+                          struct md_object *sobj, const struct lu_name *lname,
                           struct md_object *tobj, struct md_attr *ma);
         /** This method is used to compare a requested layout to an existing
          * layout (struct lov_mds_md_v1/3 vs struct lov_mds_md_v1/3) */
@@ -749,13 +749,13 @@ static inline int mdo_rename(const struct lu_env *env,
 
 static inline int mdo_migrate(const struct lu_env *env,
                             struct md_object *pobj,
-                            const struct lu_fid *lf,
+                            struct md_object *sobj,
                             const struct lu_name *lname,
                             struct md_object *tobj,
                             struct md_attr *ma)
 {
        LASSERT(pobj->mo_dir_ops->mdo_migrate);
-       return pobj->mo_dir_ops->mdo_migrate(env, pobj, lf, lname, tobj, ma);
+       return pobj->mo_dir_ops->mdo_migrate(env, pobj, sobj, lname, tobj, ma);
 }
 
 static inline int mdo_is_subdir(const struct lu_env *env,
index d658c60..45247f2 100644 (file)
@@ -1049,7 +1049,8 @@ lfsck_layout_lastid_store(const struct lu_env *env,
                lastid = cpu_to_le64(lls->lls_lastid);
                rc = dt_declare_record_write(env, lls->lls_lastid_obj,
                                             lfsck_buf_get(env, &lastid,
-                                            sizeof(lastid)), pos, th);
+                                                          sizeof(lastid)),
+                                            pos, th);
                if (rc != 0)
                        goto stop;
 
index 5e8b891..a1ccfce 100644 (file)
@@ -1035,39 +1035,29 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                 return 0;
         }
         case IOC_MDC_LOOKUP: {
-                struct ptlrpc_request *request = NULL;
-                int namelen, len = 0;
-                char *buf = NULL;
-                char *filename;
-                struct md_op_data *op_data;
-
-                rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
-                if (rc)
-                        RETURN(rc);
-                data = (void *)buf;
-
-                filename = data->ioc_inlbuf1;
-                namelen = strlen(filename);
+               int namelen, len = 0;
+               char *buf = NULL;
+               char *filename;
 
-                if (namelen < 1) {
-                        CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n");
-                        GOTO(out_free, rc = -EINVAL);
-                }
+               rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
+               if (rc != 0)
+                       RETURN(rc);
+               data = (void *)buf;
 
-                op_data = ll_prep_md_op_data(NULL, inode, NULL, filename, namelen,
-                                             0, LUSTRE_OPC_ANY, NULL);
-                if (IS_ERR(op_data))
-                        GOTO(out_free, rc = PTR_ERR(op_data));
+               filename = data->ioc_inlbuf1;
+               namelen = strlen(filename);
+               if (namelen < 1) {
+                       CDEBUG(D_INFO, "IOC_MDC_LOOKUP missing filename\n");
+                       GOTO(out_free, rc = -EINVAL);
+               }
 
-                op_data->op_valid = OBD_MD_FLID;
-                rc = md_getattr_name(sbi->ll_md_exp, op_data, &request);
-                ll_finish_md_op_data(op_data);
-                if (rc < 0) {
-                        CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
-                        GOTO(out_free, rc);
-                }
-                ptlrpc_req_finished(request);
-                EXIT;
+               rc = ll_get_fid_by_name(inode, filename, namelen, NULL);
+               if (rc < 0) {
+                       CERROR("%s: lookup %.*s failed: rc = %d\n",
+                              ll_get_fsname(inode->i_sb, NULL, 0), namelen,
+                              filename, rc);
+                       GOTO(out_free, rc);
+               }
 out_free:
                 obd_ioctl_freedata(buf, len);
                 return rc;
@@ -1769,14 +1759,15 @@ out_rmdir:
 
                filename = data->ioc_inlbuf1;
                namelen = data->ioc_inllen1;
-               if (namelen < 1)
+               /* \0 is packed at the end of filename */
+               if (namelen < 1 || namelen != strlen(filename) + 1)
                        GOTO(migrate_free, rc = -EINVAL);
 
                if (data->ioc_inllen2 != sizeof(mdtidx))
                        GOTO(migrate_free, rc = -EINVAL);
                mdtidx = *(int *)data->ioc_inlbuf2;
 
-               rc = ll_migrate(inode, file, mdtidx, filename, namelen);
+               rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
 migrate_free:
                obd_ioctl_freedata(buf, len);
 
index d0f978d..d66f8f2 100644 (file)
@@ -3000,48 +3000,48 @@ int ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
         RETURN(rc);
 }
 
-static int ll_get_fid_by_name(struct inode *parent, const char *name,
-                             int namelen, struct lu_fid *fid)
+int ll_get_fid_by_name(struct inode *parent, const char *name,
+                      int namelen, struct lu_fid *fid)
 {
        struct md_op_data       *op_data = NULL;
        struct mdt_body         *body;
        struct ptlrpc_request   *req;
        int                     rc;
+       ENTRY;
 
        op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen, 0,
                                     LUSTRE_OPC_ANY, NULL);
        if (IS_ERR(op_data))
-               return PTR_ERR(op_data);
+               RETURN(PTR_ERR(op_data));
 
        op_data->op_valid = OBD_MD_FLID;
        rc = md_getattr_name(ll_i2sbi(parent)->ll_md_exp, op_data, &req);
+       ll_finish_md_op_data(op_data);
        if (rc < 0)
-               GOTO(out_free, rc);
+               RETURN(rc);
 
        body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
        if (body == NULL)
                GOTO(out_req, rc = -EFAULT);
-
-       *fid = body->fid1;
+       if (fid != NULL)
+               *fid = body->fid1;
 out_req:
        ptlrpc_req_finished(req);
-out_free:
-       if (op_data != NULL)
-               ll_finish_md_op_data(op_data);
-       return rc;
+       RETURN(rc);
 }
 
 int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
               const char *name, int namelen)
 {
        struct dentry         *dchild = NULL;
+       struct inode          *child_inode = NULL;
        struct md_op_data     *op_data;
        struct ptlrpc_request *request = NULL;
        struct qstr           qstr;
        int                    rc;
        ENTRY;
 
-       CDEBUG(D_VFSTRACE, "migrate %s under"DFID" to MDT%d\n",
+       CDEBUG(D_VFSTRACE, "migrate %s under "DFID" to MDT%04x\n",
               name, PFID(ll_inode2fid(parent)), mdtidx);
 
        op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen,
@@ -3056,8 +3056,13 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
        dchild = d_lookup(file->f_dentry, &qstr);
        if (dchild != NULL && dchild->d_inode != NULL) {
                op_data->op_fid3 = *ll_inode2fid(dchild->d_inode);
+               if (dchild->d_inode != NULL) {
+                       child_inode = igrab(dchild->d_inode);
+                       ll_invalidate_aliases(child_inode);
+               }
+               dput(dchild);
        } else {
-               rc = ll_get_fid_by_name(parent, name, strnlen(name, namelen),
+               rc = ll_get_fid_by_name(parent, name, namelen,
                                        &op_data->op_fid3);
                if (rc != 0)
                        GOTO(out_free, rc);
@@ -3067,7 +3072,7 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
                CERROR("%s: migrate %s , but fid "DFID" is insane\n",
                       ll_get_fsname(parent->i_sb, NULL, 0), name,
                       PFID(&op_data->op_fid3));
-               GOTO(out_free, rc);
+               GOTO(out_free, rc = -EINVAL);
        }
 
        rc = ll_get_mdt_idx_by_fid(ll_i2sbi(parent), &op_data->op_fid3);
@@ -3083,8 +3088,7 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
        op_data->op_mds = mdtidx;
        op_data->op_cli_flags = CLI_MIGRATE;
        rc = md_rename(ll_i2sbi(parent)->ll_md_exp, op_data, name,
-                      strnlen(name, namelen), name, strnlen(name, namelen),
-                      &request);
+                      namelen, name, namelen, &request);
        if (rc == 0)
                ll_update_times(request, parent);
 
@@ -3093,10 +3097,9 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
                GOTO(out_free, rc);
 
 out_free:
-       if (dchild != NULL) {
-               if (dchild->d_inode != NULL)
-                       ll_delete_inode(dchild->d_inode);
-               dput(dchild);
+       if (child_inode != NULL) {
+               clear_nlink(child_inode);
+               iput(child_inode);
        }
 
        ll_finish_md_op_data(op_data);
index 19ec0e8..e94ff22 100644 (file)
@@ -833,6 +833,8 @@ struct ll_file_data *ll_file_data_get(void);
 struct posix_acl * ll_get_acl(struct inode *inode, int type);
 int ll_migrate(struct inode *parent, struct file *file, int mdtidx,
               const char *name, int namelen);
+int ll_get_fid_by_name(struct inode *parent, const char *name,
+                      int namelen, struct lu_fid *fid);
 #ifdef HAVE_GENERIC_PERMISSION_4ARGS
 int ll_inode_permission(struct inode *inode, int mask, unsigned int flags);
 #else
index b394966..13ed111 100644 (file)
@@ -232,6 +232,8 @@ static int lov_init_raid0(const struct lu_env *env,
        r0->lo_nr  = lsm->lsm_stripe_count;
        LASSERT(r0->lo_nr <= lov_targets_nr(dev));
 
+       lov->lo_layout_invalid = true;
+
        OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof r0->lo_sub[0]);
        if (r0->lo_sub != NULL) {
                int psz = 0;
index 4ec2946..aeccd3b 100644 (file)
@@ -2869,7 +2869,7 @@ static int mdd_linkea_update_child_internal(const struct lu_env *env,
                linkea_entry_unpack(ldata.ld_lee, &ldata.ld_reclen,
                                    &lname, &fid);
 
-               if (strncmp(lname.ln_name, name, namelen) ||
+               if (strncmp(lname.ln_name, name, namelen) != 0 ||
                    lu_fid_eq(&fid, mdd_object_fid(parent))) {
                        ldata.ld_lee = (struct link_ea_entry *)
                                       ((char *)ldata.ld_lee +
@@ -3730,6 +3730,11 @@ static int mdd_migrate_update_name(const struct lu_env *env,
        if (is_dir)
                mdo_ref_del(env, mdd_sobj, handle);
 
+       /* Get the attr again after ref_del */
+       rc = mdd_la_get(env, mdd_sobj, so_attr,
+                       mdd_object_capa(env, mdd_sobj));
+       if (rc != 0)
+               GOTO(stop_trans, rc);
        ma->ma_attr = *so_attr;
        ma->ma_valid |= MA_INODE;
        rc = mdd_finish_unlink(env, mdd_sobj, ma, handle);
@@ -3860,22 +3865,18 @@ static int mdd_migrate_sanity_check(const struct lu_env *env,
 }
 
 static int mdd_migrate(const struct lu_env *env, struct md_object *pobj,
-                      const struct lu_fid *lf, const struct lu_name *lname,
+                      struct md_object *sobj, const struct lu_name *lname,
                       struct md_object *tobj, struct md_attr *ma)
 {
        struct mdd_object       *mdd_pobj = md2mdd_obj(pobj);
        struct mdd_device       *mdd = mdo2mdd(pobj);
-       struct mdd_object       *mdd_sobj = NULL;
+       struct mdd_object       *mdd_sobj = md2mdd_obj(sobj);
        struct mdd_object       *mdd_tobj = NULL;
        struct lu_attr          *so_attr = MDD_ENV_VAR(env, cattr);
        struct lu_attr          *pattr = MDD_ENV_VAR(env, pattr);
        int                     rc;
 
        ENTRY;
-       /* object has to be locked by mdt, so it must exist */
-       mdd_sobj = mdd_object_find(env, mdd, lf);
-       LASSERT(mdd_sobj != NULL);
-
        /* If the file will being migrated, it will check whether
         * the file is being opened by someone else right now */
        mdd_read_lock(env, mdd_sobj, MOR_SRC_CHILD);
@@ -3955,9 +3956,6 @@ static int mdd_migrate(const struct lu_env *env, struct md_object *pobj,
        if (rc != 0)
                GOTO(put, rc);
 put:
-       if (mdd_sobj)
-               mdd_object_put(env, mdd_sobj);
-
        RETURN(rc);
 }
 
index c1b0020..6c657da 100644 (file)
@@ -1125,18 +1125,29 @@ static int mdt_pdir_hash_lock(struct mdt_thread_info *info,
        return rc;
 }
 
+enum mdt_rename_lock {
+       MRL_RENAME,
+       MRL_MIGRATE,
+};
+
+/**
+ * Get BFL lock for rename or migrate process, right now, it does not support
+ * cross-MDT rename, so we only need global rename lock during migration.
+ **/
 static int mdt_rename_lock(struct mdt_thread_info *info,
-                          struct lustre_handle *lh, bool rename)
+                          struct lustre_handle *lh,
+                          enum mdt_rename_lock rename_lock)
 {
        struct ldlm_namespace   *ns = info->mti_mdt->mdt_namespace;
-       __u64                   flags = 0;
-       int                     rc;
        ldlm_policy_data_t      *policy = &info->mti_policy;
        struct ldlm_res_id      *res_id = &info->mti_res_id;
+       __u64                   flags = 0;
+       int                     rc;
        ENTRY;
 
        /* XXX only do global rename lock for migration */
-       if (mdt_seq_site(info->mti_mdt)->ss_node_id != 0 && !rename) {
+       if (mdt_seq_site(info->mti_mdt)->ss_node_id != 0 &&
+           rename_lock == MRL_MIGRATE) {
                struct lu_fid *fid = &info->mti_tmp_fid1;
                struct mdt_object *obj;
 
@@ -1468,8 +1479,9 @@ static int mdt_reint_migrate_internal(struct mdt_thread_info *info,
                if (IS_ERR(mnew))
                        GOTO(out_unlock_child, rc = PTR_ERR(mnew));
                if (!mdt_object_remote(mnew)) {
-                       CERROR("%s: Migration "DFID" is on this MDT !\n",
-                              mdt_obd_name(info->mti_mdt), PFID(rr->rr_fid2));
+                       CERROR("%s: Migration "DFID" is on this MDT:"
+                              " rc = %d\n", mdt_obd_name(info->mti_mdt),
+                              PFID(rr->rr_fid2), -EXDEV);
                        GOTO(out_put_new, rc = -EXDEV);
                }
        }
@@ -1481,7 +1493,8 @@ static int mdt_reint_migrate_internal(struct mdt_thread_info *info,
                       OBD_FAIL_MDS_REINT_RENAME_WRITE);
 
        rc = mdo_migrate(info->mti_env, mdt_object_child(msrcdir),
-                        old_fid, &rr->rr_name, mdt_object_child(mnew), ma);
+                        mdt_object_child(mold), &rr->rr_name,
+                        mdt_object_child(mnew), ma);
        if (rc != 0)
                GOTO(out_unlock_new, rc);
 out_unlock_new:
@@ -1754,7 +1767,7 @@ out_unlock_source:
 
 static int mdt_reint_rename_or_migrate(struct mdt_thread_info *info,
                                       struct mdt_lock_handle *lhc,
-                                      bool  rename)
+                                      enum mdt_rename_lock rename_lock)
 {
        struct mdt_reint_record *rr = &info->mti_rr;
        struct ptlrpc_request   *req = mdt_info_req(info);
@@ -1769,14 +1782,14 @@ static int mdt_reint_rename_or_migrate(struct mdt_thread_info *info,
            fid_is_obf(rr->rr_fid2) || fid_is_dot_lustre(rr->rr_fid2))
                RETURN(-EPERM);
 
-       rc = mdt_rename_lock(info, &rename_lh, rename);
+       rc = mdt_rename_lock(info, &rename_lh, rename_lock);
        if (rc != 0) {
                CERROR("%s: can't lock FS for rename: rc  = %d\n",
                       mdt_obd_name(info->mti_mdt), rc);
                RETURN(rc);
        }
 
-       if (rename)
+       if (rename_lock == MRL_RENAME)
                rc = mdt_reint_rename_internal(info, lhc);
        else
                rc = mdt_reint_migrate_internal(info, lhc);
@@ -1790,13 +1803,13 @@ static int mdt_reint_rename_or_migrate(struct mdt_thread_info *info,
 static int mdt_reint_rename(struct mdt_thread_info *info,
                            struct mdt_lock_handle *lhc)
 {
-       return mdt_reint_rename_or_migrate(info, lhc, true);
+       return mdt_reint_rename_or_migrate(info, lhc, MRL_RENAME);
 }
 
 static int mdt_reint_migrate(struct mdt_thread_info *info,
                            struct mdt_lock_handle *lhc)
 {
-       return mdt_reint_rename_or_migrate(info, lhc, false);
+       return mdt_reint_rename_or_migrate(info, lhc, MRL_MIGRATE);
 }
 
 typedef int (*mdt_reinter)(struct mdt_thread_info *info,