@@ -704,6 +704,7 @@ enum md_op_flags {
MF_MDC_CANCEL_FID3 = BIT(2),
MF_MDC_CANCEL_FID4 = BIT(3),
MF_GET_MDT_IDX = BIT(4),
+ MF_GETATTR_BY_FID = BIT(5),
};
enum md_cli_flags {
@@ -4587,22 +4587,29 @@ static int ll_inode_revalidate(struct dentry *dentry, enum ldlm_intent_flags op)
};
struct ptlrpc_request *req = NULL;
struct md_op_data *op_data;
+ const char *name = NULL;
+ size_t namelen = 0;
int rc = 0;
CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p),name=%pd\n",
PFID(ll_inode2fid(inode)), inode, dentry);
- if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID)
+ if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID) {
parent = dentry->d_parent->d_inode;
- else
+ name = dentry->d_name.name;
+ namelen = dentry->d_name.len;
+ } else {
parent = inode;
+ }
- /* Call getattr by fid, so do not provide name at all. */
- op_data = ll_prep_md_op_data(NULL, parent, inode, NULL, 0, 0,
+ op_data = ll_prep_md_op_data(NULL, parent, inode, name, namelen, 0,
LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
return PTR_ERR(op_data);
+ /* Call getattr by fid */
+ if (exp_connect_flags2(exp) & OBD_CONNECT2_GETATTR_PFID)
+ op_data->op_flags = MF_GETATTR_BY_FID;
rc = md_intent_lock(exp, op_data, &oit, &req, &ll_md_blocking_ast, 0);
ll_finish_md_op_data(op_data);
if (rc < 0) {
@@ -2811,7 +2811,9 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
if (namelen > ll_i2sbi(i1)->ll_namelen)
return ERR_PTR(-ENAMETOOLONG);
- if (!lu_name_is_valid_2(name, namelen))
+ /* "/" is not valid name, but it's allowed */
+ if (!lu_name_is_valid_2(name, namelen) &&
+ strncmp("/", name, namelen) != 0)
return ERR_PTR(-EINVAL);
}
@@ -448,13 +448,29 @@ static int lmv_intent_lookup(struct obd_export *exp,
}
retry:
- if (op_data->op_name) {
+ if (op_data->op_flags & MF_GETATTR_BY_FID) {
+ /* getattr by FID, replace fid1 with stripe FID */
+ LASSERT(op_data->op_name);
+ tgt = lmv_locate_tgt(lmv, op_data);
+ if (IS_ERR(tgt))
+ return PTR_ERR(tgt);
+
+ /* name is used to locate stripe target, clear it here
+ * to avoid packing name in request, so that MDS knows
+ * it's getattr by FID.
+ */
+ op_data->op_name = NULL;
+ op_data->op_namelen = 0;
+
+ /* getattr request is sent to MDT where fid2 inode is */
+ tgt = lmv_fid2tgt(lmv, &op_data->op_fid2);
+ } else if (op_data->op_name) {
+ /* getattr by name */
tgt = lmv_locate_tgt(lmv, op_data);
if (!fid_is_sane(&op_data->op_fid2))
fid_zero(&op_data->op_fid2);
- } else if (fid_is_sane(&op_data->op_fid2)) {
- tgt = lmv_fid2tgt(lmv, &op_data->op_fid2);
} else {
+ /* old way to getattr by FID, parent FID not packed */
tgt = lmv_fid2tgt(lmv, &op_data->op_fid1);
}
if (IS_ERR(tgt))
@@ -1513,6 +1513,9 @@ static struct lu_tgt_desc *lmv_locate_tgt_rr(struct lmv_obd *lmv, u32 *mdt)
return ERR_PTR(-ENODEV);
}
+/* locate MDT by file name, for striped directory, the file name hash decides
+ * which stripe its dirent is stored.
+ */
static struct lmv_tgt_desc *
lmv_locate_tgt_by_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm,
const char *name, int namelen, struct lu_fid *fid,
@@ -1564,8 +1567,9 @@ static struct lu_tgt_desc *lmv_locate_tgt_rr(struct lmv_obd *lmv, u32 *mdt)
* For plain direcotry, it just locate the MDT of op_data->op_fid1.
*
* @lmv: LMV device
- * @op_data: client MD stack parameters, name, namelen
- * mds_num etc.
+ * @op_data: client MD stack parameters, name, namelen etc,
+ * op_mds and op_fid1 will be updated if op_mea1
+ * indicates fid1 represents a striped directory.
*
* Returns: pointer to the lmv_tgt_desc if succeed.
* ERR_PTR(errno) if failed.