Now parent FID is packed in getattr_by_FID request
(see https://review.whamcloud.com/39290), it should also pass in name
from llite, so that lmv can replace fid1 with stripe FID, otherwise
MDS may treat sub files under striped directory as remote object.
Note, the name is not packed in request, because if it's packed, MDS
will getattr by name instead of FID.
Lustre-change: https://review.whamcloud.com/40219
Lustre-commit:
90ebab5833007defd91e86f5878f356ae5304a1b
Fixes:
5f2c44bf6 ("LU-13437 llite: pack parent FID in getattr")
Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: If8215667bcb10ea3c4c5cd2c9034d81fd1cda3b5
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/40482
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
MF_MDC_CANCEL_FID3 = 1 << 2,
MF_MDC_CANCEL_FID4 = 1 << 3,
MF_GET_MDT_IDX = 1 << 4,
+ MF_GETATTR_BY_FID = 1 << 5,
};
enum md_cli_flags {
};
struct ptlrpc_request *req = NULL;
struct md_op_data *op_data;
+ const char *name = NULL;
+ size_t namelen = 0;
int rc = 0;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p),name=%s\n",
PFID(ll_inode2fid(inode)), inode, dentry->d_name.name);
- 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) {
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);
}
ENTRY;
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, &op_data->op_fid1);
+ 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_find_target(lmv, &op_data->op_fid2);
+ } else if (op_data->op_name) {
+ /* getattr by name */
tgt = lmv_locate_tgt(lmv, op_data, &op_data->op_fid1);
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_find_target(lmv, &op_data->op_fid2);
} else {
+ /* old way to getattr by FID, parent FID not packed */
tgt = lmv_find_target(lmv, &op_data->op_fid1);
}
if (IS_ERR(tgt))
*
* For normal direcotry, it will locate MDS by FID directly.
*
- * \param[in] lmv LMV device
- * \param[in] op_data client MD stack parameters, name, namelen
- * mds_num etc.
- * \param[in] fid object FID used to locate MDS.
+ * \param[in] lmv LMV device
+ * \param[in/out] 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.
+ * \param[out] fid object FID used to locate MDS.
*
* retval pointer to the lmv_tgt_desc if succeed.
* ERR_PTR(errno) if failed.