}
int ll_get_fid_by_name(struct inode *parent, const char *name,
- int namelen, struct lu_fid *fid)
+ int namelen, struct lu_fid *fid,
+ struct inode **inode)
{
struct md_op_data *op_data = NULL;
struct mdt_body *body;
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
- op_data->op_valid = OBD_MD_FLID;
+ op_data->op_valid = OBD_MD_FLID | OBD_MD_FLTYPE;
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_req, rc = -EFAULT);
if (fid != NULL)
*fid = body->mbo_fid1;
+
+ if (inode != NULL)
+ rc = ll_prep_inode(inode, req, parent->i_sb, NULL);
out_req:
ptlrpc_req_finished(req);
RETURN(rc);
struct inode *child_inode = NULL;
struct md_op_data *op_data;
struct ptlrpc_request *request = NULL;
+ struct obd_client_handle *och = NULL;
struct qstr qstr;
+ struct mdt_body *body;
int rc;
+ __u64 data_version = 0;
ENTRY;
CDEBUG(D_VFSTRACE, "migrate %s under "DFID" to MDT%04x\n",
qstr.len = namelen;
dchild = d_lookup(file->f_path.dentry, &qstr);
if (dchild != NULL) {
- if (dchild->d_inode != NULL) {
+ if (dchild->d_inode != NULL)
child_inode = igrab(dchild->d_inode);
- if (child_inode != NULL) {
- mutex_lock(&child_inode->i_mutex);
- op_data->op_fid3 = *ll_inode2fid(child_inode);
- ll_invalidate_aliases(child_inode);
- }
- }
dput(dchild);
- } else {
+ }
+
+ if (child_inode == NULL) {
rc = ll_get_fid_by_name(parent, name, namelen,
- &op_data->op_fid3);
+ &op_data->op_fid3, &child_inode);
if (rc != 0)
GOTO(out_free, rc);
}
+ if (child_inode == NULL)
+ GOTO(out_free, rc = -EINVAL);
+
+ mutex_lock(&child_inode->i_mutex);
+ op_data->op_fid3 = *ll_inode2fid(child_inode);
if (!fid_is_sane(&op_data->op_fid3)) {
CERROR("%s: migrate %s , but fid "DFID" is insane\n",
ll_get_fsname(parent->i_sb, NULL, 0), name,
PFID(&op_data->op_fid3), mdtidx);
GOTO(out_free, rc = 0);
}
+again:
+ if (S_ISREG(child_inode->i_mode)) {
+ och = ll_lease_open(child_inode, NULL, FMODE_WRITE, 0);
+ if (IS_ERR(och)) {
+ rc = PTR_ERR(och);
+ och = NULL;
+ GOTO(out_free, rc);
+ }
+
+ rc = ll_data_version(child_inode, &data_version,
+ LL_DV_WR_FLUSH);
+ if (rc != 0)
+ GOTO(out_free, rc);
+
+ op_data->op_handle = och->och_fh;
+ op_data->op_data = och->och_mod;
+ op_data->op_data_version = data_version;
+ op_data->op_lease_handle = och->och_lease_handle;
+ op_data->op_bias |= MDS_RENAME_MIGRATE;
+ }
op_data->op_mds = mdtidx;
op_data->op_cli_flags = CLI_MIGRATE;
if (rc == 0)
ll_update_times(request, parent);
- ptlrpc_req_finished(request);
- if (rc != 0)
- GOTO(out_free, rc);
+ body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
+ if (body == NULL)
+ GOTO(out_free, rc = -EPROTO);
+
+ /* If the server does release layout lock, then we cleanup
+ * the client och here, otherwise release it in out_free: */
+ if (och != NULL && body->mbo_valid & OBD_MD_CLOSE_INTENT_EXECED) {
+ obd_mod_put(och->och_mod);
+ md_clear_open_replay_data(ll_i2sbi(parent)->ll_md_exp, och);
+ och->och_fh.cookie = DEAD_HANDLE_MAGIC;
+ OBD_FREE_PTR(och);
+ och = NULL;
+ }
+ ptlrpc_req_finished(request);
+ /* Try again if the file layout has changed. */
+ if (rc == -EAGAIN && S_ISREG(child_inode->i_mode))
+ goto again;
out_free:
if (child_inode != NULL) {
+ if (och != NULL) /* close the file */
+ ll_lease_close(och, child_inode, NULL);
clear_nlink(child_inode);
mutex_unlock(&child_inode->i_mutex);
iput(child_inode);