From: wang di Date: Fri, 28 Feb 2014 15:52:58 +0000 (-0800) Subject: LU-4682 llite: a few fixes for migration. X-Git-Tag: 2.5.57~10 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=742d4ee68aaf3407ac4b8f86c9bddbece4beaa6e LU-4682 llite: a few fixes for migration. 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 Change-Id: I209079dfa07241412878b30fd02e8152046c95c7 Reviewed-on: http://review.whamcloud.com/9522 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond --- diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 270e302..c1ec562 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -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, diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index d658c60..45247f2 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -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; diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 5e8b891..a1ccfce 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -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); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index d0f978d..d66f8f2 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 19ec0e8..e94ff22 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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 diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index b394966..13ed111 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -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; diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 4ec2946..aeccd3b 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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); } diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index c1b0020..6c657da 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -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,