Whamcloud - gitweb
LU-9771 clio: no glimpse for data immutable file 84/29084/12
authorJinshan Xiong <jinshan.xiong@intel.com>
Fri, 14 Jul 2017 23:22:46 +0000 (16:22 -0700)
committerJinshan Xiong <jinshan.xiong@intel.com>
Fri, 17 Nov 2017 08:00:19 +0000 (08:00 +0000)
When merging a layout to an existing file as a mirror, client will
report the size and blocks to the MDT, which will be set to the MDT
object. In that case, if the MDT discovers a mirrored file in
READ_ONLY state, it will report the size and blocks. Clients should
take this advantage and skip glimpse.

Test-Parameters: testlist=sanity-flr
Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I60831689116e6c5dd0311dea62b91dd0ae3cfd56
Reviewed-on: https://review.whamcloud.com/29084
Tested-by: Jenkins
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/file.c
lustre/lov/lov_io.c
lustre/mdt/Makefile.in
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_open.c
lustre/mdt/mdt_som.c [new file with mode: 0644]
lustre/tests/sanity-flr.sh

index eaf53bd..3e8f706 100644 (file)
@@ -1093,6 +1093,7 @@ struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
 #define XATTR_TRUSTED_PREFIX    "trusted."
 #define XATTR_SECURITY_PREFIX   "security."
 
+#define XATTR_NAME_SOM         "trusted.som"
 #define XATTR_NAME_LOV          "trusted.lov"
 #define XATTR_NAME_LMA          "trusted.lma"
 #define XATTR_NAME_LMV          "trusted.lmv"
index cf3c908..314cb97 100644 (file)
@@ -274,6 +274,17 @@ struct lustre_ost_attrs {
  */
 #define LMA_OLD_SIZE (sizeof(struct lustre_mdt_attrs) + 5 * sizeof(__u64))
 
+enum {
+       LSOM_FL_VALID = 1 << 0,
+};
+
+struct lustre_som_attrs {
+       __u16   lsa_valid;
+       __u16   lsa_reserved[3];
+       __u64   lsa_size;
+       __u64   lsa_blocks;
+};
+
 /**
  * OST object IDentifier.
  */
index 701b647..7f43784 100644 (file)
@@ -145,6 +145,9 @@ static int ll_close_inode_openhandle(struct inode *inode,
        ll_prepare_close(inode, op_data, och);
        switch (bias) {
        case MDS_CLOSE_LAYOUT_MERGE:
+               /* merge blocks from the victim inode */
+               op_data->op_attr_blocks += ((struct inode *)data)->i_blocks;
+               op_data->op_attr.ia_valid |= ATTR_SIZE | ATTR_BLOCKS;
        case MDS_CLOSE_LAYOUT_SWAP:
                LASSERT(data != NULL);
                op_data->op_bias |= bias;
index 8cdfbf4..b100973 100644 (file)
@@ -263,6 +263,13 @@ static int lov_io_slice_init(struct lov_io *lio,
        }
 
        case CIT_GLIMPSE:
+               lio->lis_pos = 0;
+               lio->lis_endpos = OBD_OBJECT_EOF;
+
+               if ((obj->lo_lsm->lsm_flags & LCM_FL_FLR_MASK) == LCM_FL_RDONLY)
+                       RETURN(1); /* SoM is accurate, no need glimpse */
+               break;
+
         case CIT_MISC:
                 lio->lis_pos = 0;
                 lio->lis_endpos = OBD_OBJECT_EOF;
@@ -1127,21 +1134,23 @@ int lov_io_init_composite(const struct lu_env *env, struct cl_object *obj,
 {
        struct lov_io       *lio = lov_env_io(env);
        struct lov_object   *lov = cl2lov(obj);
-
+       int result;
        ENTRY;
+
        INIT_LIST_HEAD(&lio->lis_active);
-       io->ci_result = lov_io_slice_init(lio, lov, io);
-       if (io->ci_result != 0)
-               RETURN(io->ci_result);
-
-       if (io->ci_result == 0) {
-               io->ci_result = lov_io_subio_init(env, lio, io);
-               if (io->ci_result == 0) {
-                       cl_io_slice_add(io, &lio->lis_cl, obj, &lov_io_ops);
-                       atomic_inc(&lov->lo_active_ios);
-               }
+       result = lov_io_slice_init(lio, lov, io);
+       if (result)
+               GOTO(out, result);
+
+       result = lov_io_subio_init(env, lio, io);
+       if (!result) {
+               cl_io_slice_add(io, &lio->lis_cl, obj, &lov_io_ops);
+               atomic_inc(&lov->lo_active_ios);
        }
-       RETURN(io->ci_result);
+       EXIT;
+out:
+       io->ci_result = result < 0 ? result : 0;
+       return result;
 }
 
 int lov_io_init_empty(const struct lu_env *env, struct cl_object *obj,
index 0165cfe..ec054d7 100644 (file)
@@ -1,6 +1,6 @@
 MODULES := mdt
 mdt-objs := mdt_handler.o mdt_lib.o mdt_reint.o mdt_xattr.o mdt_recovery.o
-mdt-objs += mdt_open.o mdt_identity.o mdt_lproc.o mdt_fs.o
+mdt-objs += mdt_open.o mdt_identity.o mdt_lproc.o mdt_fs.o mdt_som.o
 mdt-objs += mdt_lvb.o mdt_hsm.o mdt_mds.o mdt_io.o
 mdt-objs += mdt_hsm_cdt_actions.o
 mdt-objs += mdt_hsm_cdt_requests.o
index 5ef06db..53fd951 100644 (file)
@@ -732,6 +732,8 @@ void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b,
                        else
                                b->mbo_blocks = 1;
                        b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
+               } else if (info->mti_som_valid) { /* som is valid */
+                       b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
                }
        }
 
@@ -992,6 +994,9 @@ int mdt_attr_get_complex(struct mdt_thread_info *info,
                rc = mo_attr_get(env, next, ma);
                if (rc)
                        GOTO(out, rc);
+
+               if (S_ISREG(mode))
+                       (void) mdt_get_som(info, o, &ma->ma_attr);
                ma->ma_valid |= MA_INODE;
        }
 
@@ -3282,6 +3287,7 @@ void mdt_thread_info_init(struct ptlrpc_request *req,
         info->mti_opdata = 0;
        info->mti_big_lmm_used = 0;
        info->mti_big_acl_used = 0;
+       info->mti_som_valid = 0;
 
         info->mti_spec.no_create = 0;
        info->mti_spec.sp_rm_entry = 0;
index ecd0a85..2054274 100644 (file)
@@ -398,7 +398,8 @@ struct mdt_thread_info {
                                   mti_cross_ref:1,
        /* big_lmm buffer was used and must be used in reply */
                                   mti_big_lmm_used:1,
-                                  mti_big_acl_used:1;
+                                  mti_big_acl_used:1,
+                                  mti_som_valid:1;
 
         /* opdata for mdt_reint_open(), has the same as
          * ldlm_reply:lock_policy_res1.  mdt_update_last_rcvd() stores this
@@ -468,6 +469,8 @@ struct mdt_thread_info {
        char                       mti_xattr_buf[128];
        struct ldlm_enqueue_info   mti_einfo;
        struct tg_reply_data      *mti_reply_data;
+
+       struct lustre_som_attrs    mti_som;
 };
 
 extern struct lu_context_key mdt_thread_key;
@@ -1111,6 +1114,12 @@ static inline enum ldlm_mode mdt_mdl_mode2dlm_mode(mdl_mode_t mode)
        return mdt_dlm_lock_modes[mode];
 }
 
+/* mdt_som.c */
+int mdt_set_som(struct mdt_thread_info *info, struct mdt_object *obj,
+               struct lu_attr *attr);
+int mdt_get_som(struct mdt_thread_info *info, struct mdt_object *obj,
+               struct lu_attr *attr);
+
 /* mdt_lvb.c */
 extern struct ldlm_valblock_ops mdt_lvbo;
 int mdt_dom_lvb_is_valid(struct ldlm_resource *res);
index 197b852..36bbad4 100644 (file)
@@ -2015,6 +2015,16 @@ int mdt_close_handle_layouts(struct mdt_thread_info *info,
                buf->lb_buf = mdt_object_child(o == o1 ? o2 : o1);
                rc = mo_xattr_set(info->mti_env, mdt_object_child(o), buf,
                                  XATTR_LUSTRE_LOV, LU_XATTR_MERGE);
+               if (rc == 0 && ma->ma_attr.la_valid & (LA_SIZE | LA_BLOCKS)) {
+                       int rc2;
+
+                       rc2 = mdt_set_som(info, o, &ma->ma_attr);
+                       if (rc2 < 0)
+                               CERROR(DFID": Setting i_blocks error: %d, "
+                                      "i_blocks will be reported wrongly and "
+                                      "can only be fixed in next resync\n",
+                                      PFID(mdt_object_fid(o)), rc2);
+               }
        }
        if (rc < 0)
                GOTO(out_unlock2, rc);
diff --git a/lustre/mdt/mdt_som.c b/lustre/mdt/mdt_som.c
new file mode 100644 (file)
index 0000000..f4c3306
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.  A copy is
+ * included in the COPYING file that accompanied this code.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2017, Intel Corporation.
+ */
+/*
+ * lustre/mdt/mdt_som.c
+ *
+ * Size on MDS revival
+ *
+ * Author: Jinshan Xiong <jinshan.xiong@intel.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include "mdt_internal.h"
+
+int mdt_get_som(struct mdt_thread_info *info, struct mdt_object *obj,
+               struct lu_attr *attr)
+{
+       struct lu_buf *buf = &info->mti_buf;
+       struct lustre_som_attrs *som;
+       int rc;
+
+       som = buf->lb_buf = info->mti_xattr_buf;
+       buf->lb_len = sizeof(info->mti_xattr_buf);
+       rc = mo_xattr_get(info->mti_env, mdt_object_child(obj), buf,
+                         XATTR_NAME_SOM);
+       if (rc >= (int)sizeof(*som) && (som->lsa_valid & LSOM_FL_VALID)) {
+               attr->la_valid |= LA_SIZE | LA_BLOCKS;
+               attr->la_size = som->lsa_size;
+               attr->la_blocks = som->lsa_blocks;
+
+               /* Size on MDS is valid and could be returned to client */
+               info->mti_som_valid = 1;
+
+               CDEBUG(D_INODE, DFID": Reading som attrs: "
+                      "valid: %x, size: %lld, blocks: %lld, rc: %d.\n",
+                      PFID(mdt_object_fid(obj)), som->lsa_valid,
+                      som->lsa_size, som->lsa_blocks, rc);
+       }
+
+       return (rc > 0 || rc == -ENODATA) ? 0 : rc;
+}
+
+int mdt_set_som(struct mdt_thread_info *info, struct mdt_object *obj,
+               struct lu_attr *attr)
+{
+       struct md_object *next = mdt_object_child(obj);
+       struct lu_buf *buf = &info->mti_buf;
+       struct lustre_som_attrs *som;
+       int rc;
+       ENTRY;
+
+       buf->lb_buf = info->mti_xattr_buf;
+       buf->lb_len = sizeof(info->mti_xattr_buf);
+       rc = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_SOM);
+       if (rc < 0 && rc != -ENODATA)
+               RETURN(rc);
+
+       som = buf->lb_buf;
+
+       CDEBUG(D_INODE,
+              DFID": Set som attrs: " "size: %lld, blocks: %lld, rc: %d\n",
+              PFID(mdt_object_fid(obj)), som->lsa_size, som->lsa_blocks, rc);
+
+       if (rc == -ENODATA)
+               memset(som, 0, sizeof(*som));
+       if (attr->la_valid & (LA_SIZE | LA_BLOCKS)) {
+               som->lsa_valid |= LSOM_FL_VALID;
+               som->lsa_size = attr->la_size;
+               som->lsa_blocks = attr->la_blocks;
+       }
+       buf->lb_len = sizeof(*som);
+       rc = mo_xattr_set(info->mti_env, next, buf, XATTR_NAME_SOM, 0);
+       RETURN(rc);
+}
index 94767b9..101a5ff 100644 (file)
@@ -152,6 +152,62 @@ test_3() {
 }
 run_test 3 "create components from files located on different MDTs"
 
+test_21() {
+       local tf=$DIR/$tfile
+       local tf2=$DIR/$tfile-2
+
+       [[ $OSTCOUNT -lt 2 ]] && skip "need >= 2 OSTs" && return
+
+       $LFS setstripe -E EOF -o 0 $tf
+       $LFS setstripe -E EOF -o 1 $tf2
+
+       local dd_count=$((RANDOM % 20 + 1))
+       dd if=/dev/zero of=$tf bs=1M count=$dd_count
+       dd if=/dev/zero of=$tf2 bs=1M count=1 seek=$((dd_count - 1))
+       cancel_lru_locks osc
+
+       local blocks=$(du -kc $tf $tf2 | awk '/total/{print $1}')
+
+       # add component
+       $LFS setstripe --component-add --mirror=$tf2 $tf
+
+       # cancel layout lock
+       cancel_lru_locks mdc
+
+       local new_blocks=$(du -k $tf | awk '{print $1}')
+       [ $new_blocks -eq $blocks ] ||
+       error "i_blocks error expected: $blocks, actual: $new_blocks"
+}
+run_test 21 "glimpse should report accurate i_blocks"
+
+test_22() {
+       local tf=$DIR/$tfile
+
+       $LFS setstripe -E EOF -o 0 $tf
+       dd if=/dev/zero of=$tf bs=1M count=$((RANDOM % 20 + 1))
+
+       # add component, two mirrors located on the same OST ;-)
+       $LFS setstripe --component-add --mirror -o 0 $tf
+
+       size_blocks=$(stat --format="%b %s" $tf)
+
+       cancel_lru_locks mdc
+       cancel_lru_locks osc
+
+       local new_size_blocks=$(stat --format="%b %s" $tf)
+
+       # make sure there is no lock cached
+       local lock_count=$($LCTL get_param -n \
+               ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count)
+       [ $lock_count -eq 0 ] || error "glimpse requests were sent"
+
+       [ "$new_size_blocks" = "$size_blocks" ] ||
+               echo "size expected: $size_blocks, actual: $new_size_blocks"
+
+       rm -f $tmpfile
+}
+run_test 22 "no glimpse to OSTs for READ_ONLY files"
+
 complete $SECONDS
 check_and_cleanup_lustre
 exit_status