From: Lai Siyao Date: Mon, 12 Oct 2020 14:22:07 +0000 (+0800) Subject: LU-13437 llite: pass name in getattr by FID X-Git-Tag: 2.13.57~114 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=90ebab5833007defd91e86f5878f356ae5304a1b LU-13437 llite: pass name in getattr by FID 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. Fixes: 5f2c44bf6 ("LU-13437 llite: pack parent FID in getattr") Signed-off-by: Lai Siyao Change-Id: If8215667bcb10ea3c4c5cd2c9034d81fd1cda3b5 Reviewed-on: https://review.whamcloud.com/40219 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Mike Pershin Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/obd.h b/lustre/include/obd.h index f21b060..be04e32 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -838,6 +838,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 { diff --git a/lustre/llite/file.c b/lustre/llite/file.c index a48c0f8..abcbb6d 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -4710,23 +4710,30 @@ 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; 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) { diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 2547302..4aa1515 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2911,7 +2911,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); } diff --git a/lustre/lmv/lmv_intent.c b/lustre/lmv/lmv_intent.c index 7c75c75..9990a5f 100644 --- a/lustre/lmv/lmv_intent.c +++ b/lustre/lmv/lmv_intent.c @@ -443,13 +443,29 @@ lmv_intent_lookup(struct obd_export *exp, struct md_op_data *op_data, } 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)) diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 0b2428e..146f7b0 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1543,6 +1543,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, @@ -1593,9 +1596,10 @@ lmv_locate_tgt_by_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm, * * For plain direcotry, it just locate the MDT of op_data->op_fid1. * - * \param[in] lmv LMV device - * \param[in] op_data client MD stack parameters, name, namelen - * mds_num etc. + * \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. * * retval pointer to the lmv_tgt_desc if succeed. * ERR_PTR(errno) if failed.