Whamcloud - gitweb
LU-13437 llite: pass name in getattr by FID 82/40482/2
authorLai Siyao <lai.siyao@whamcloud.com>
Mon, 12 Oct 2020 14:22:07 +0000 (22:22 +0800)
committerOleg Drokin <green@whamcloud.com>
Sat, 7 Nov 2020 04:15:59 +0000 (04:15 +0000)
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>
lustre/include/obd.h
lustre/llite/file.c
lustre/llite/llite_lib.c
lustre/lmv/lmv_intent.c
lustre/lmv/lmv_obd.c

index 8545fd4..f3dfd40 100644 (file)
@@ -822,6 +822,7 @@ enum md_op_flags {
        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 {
index 9284706..a9ca88a 100644 (file)
@@ -4356,23 +4356,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) {
index d200d2a..1e340ae 100644 (file)
@@ -2552,7 +2552,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);
        }
 
index ef780b4..c3e2ad7 100644 (file)
@@ -429,13 +429,29 @@ lmv_intent_lookup(struct obd_export *exp, struct md_op_data *op_data,
        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))
index f68835b..b94fa61 100644 (file)
@@ -1619,10 +1619,11 @@ __lmv_locate_tgt(struct lmv_obd *lmv, struct lmv_stripe_md *lsm,
  *
  * 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.