goto out;
}
+ if (unlikely(op_data->op_mea1)) {
+ /*
+ * This is only needed for striped dir to fill ..,
+ * see lmv_read_page
+ */
+ if (file_dentry(filp)->d_parent &&
+ file_dentry(filp)->d_parent->d_inode) {
+ __u64 ibits = MDS_INODELOCK_UPDATE;
+ struct inode *parent;
+
+ parent = file_dentry(filp)->d_parent->d_inode;
+ if (ll_have_md_lock(parent, &ibits, LCK_MINMODE))
+ op_data->op_fid3 = *ll_inode2fid(parent);
+ }
+
+ /*
+ * If it can not find in cache, do lookup .. on the master
+ * object
+ */
+ if (fid_is_zero(&op_data->op_fid3)) {
+ rc = ll_dir_get_parent_fid(inode, &op_data->op_fid3);
+ if (rc) {
+ ll_finish_md_op_data(op_data);
+ return rc;
+ }
+ }
+ }
ctx->pos = pos;
rc = ll_dir_read(inode, &pos, op_data, ctx);
pos = ctx->pos;
return ll_iget_for_nfs(sb, &nfs_fid->lnf_parent, NULL);
}
-static struct dentry *ll_get_parent(struct dentry *dchild)
+int ll_dir_get_parent_fid(struct inode *dir, struct lu_fid *parent_fid)
{
struct ptlrpc_request *req = NULL;
- struct inode *dir = d_inode(dchild);
struct ll_sb_info *sbi;
- struct dentry *result = NULL;
struct mdt_body *body;
- static char dotdot[] = "..";
+ static const char dotdot[] = "..";
struct md_op_data *op_data;
int rc;
int lmmsize;
rc = ll_get_default_mdsize(sbi, &lmmsize);
if (rc != 0)
- return ERR_PTR(rc);
+ return rc;
op_data = ll_prep_md_op_data(NULL, dir, NULL, dotdot,
strlen(dotdot), lmmsize,
LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
- return (void *)op_data;
+ return PTR_ERR(op_data);
rc = md_getattr_name(sbi->ll_md_exp, op_data, &req);
ll_finish_md_op_data(op_data);
CERROR("%s: failure inode "DFID" get parent: rc = %d\n",
ll_get_fsname(dir->i_sb, NULL, 0),
PFID(ll_inode2fid(dir)), rc);
- return ERR_PTR(rc);
+ return rc;
}
body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
/*
if (body->valid & OBD_MD_FLID) {
CDEBUG(D_INFO, "parent for " DFID " is " DFID "\n",
PFID(ll_inode2fid(dir)), PFID(&body->fid1));
+ *parent_fid = body->fid1;
}
- result = ll_iget_for_nfs(dir->i_sb, &body->fid1, NULL);
ptlrpc_req_finished(req);
- return result;
+ return 0;
+}
+
+static struct dentry *ll_get_parent(struct dentry *dchild)
+{
+ struct lu_fid parent_fid = { 0 };
+ struct dentry *dentry;
+ int rc;
+
+ rc = ll_dir_get_parent_fid(dchild->d_inode, &parent_fid);
+ if (rc)
+ return ERR_PTR(rc);
+
+ dentry = ll_iget_for_nfs(dchild->d_inode->i_sb, &parent_fid, NULL);
+
+ return dentry;
}
const struct export_operations lustre_export_operations = {