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) */
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,
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;
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;
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);
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,
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);
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);
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);
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);
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
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;
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 +
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);
}
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);
if (rc != 0)
GOTO(put, rc);
put:
- if (mdd_sobj)
- mdd_object_put(env, mdd_sobj);
-
RETURN(rc);
}
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;
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);
}
}
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:
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);
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);
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,