Whamcloud - gitweb
LU-17863 hsm: add ioctl to set data version in HSM xattr 99/55599/9
authorNikitas Angelinas <nikitas.angelinas@hpe.com>
Mon, 1 Jul 2024 18:00:43 +0000 (21:00 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 30 Aug 2024 05:59:50 +0000 (05:59 +0000)
When migrating files to a Lustre filesystem (e.g. from another Lustre
filesystem), certain HSM solutions might prefer to bypass the Lustre
HSM subsystem, i.e. not use use llapi_hsm_import(), the Lustre HSM
coordinator and a copytool and instead just copy files to the
filesystem, as this enables a simpler workflow.

Since there already exists another copy of some of the files, users
might want to set the HS_EXISTS and HS_ARCHIVED HSM flags and perform
an HSM release operation to free disk space; however, the latter
operation fails in mdt_hsm_release(), as there is a data version
mismatch between the data version that is sent from the client, which
has been calculated from the OSTs and the data version in the HSM
xattr, as the latter hasn't been set appropriately via
hsm_cdt_request_completed(), as the Lustre HSM subsystem was bypassed
and the relevant HSM flags were force-set via llapi_hsm_state_set().

Add an ioctl to set the data version field in the HSM xattr to a
specified value and enable "lfs data_version" to synchronize it, to
the data version that is calculated from the OST objects.

HPE-bug-id: LUS-12152
Signed-off-by: Nikitas Angelinas <nikitas.angelinas@hpe.com>
Change-Id: Ic8538aa884c675e8561cbc4e2b1d83d64e23a67a
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55599
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andriy Skulysh <andriy.skulysh@hpe.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
21 files changed:
lustre/doc/lfs.1
lustre/include/lustre/lustreapi.h
lustre/include/lustre_req_layout.h
lustre/include/obd_support.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/file.c
lustre/lmv/lmv_obd.c
lustre/mdc/mdc_request.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_hsm.c
lustre/mdt/mdt_internal.h
lustre/ptlrpc/layout.c
lustre/ptlrpc/lproc_ptlrpc.c
lustre/ptlrpc/wiretest.c
lustre/target/tgt_handler.c
lustre/tests/sanity-hsm.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi_swap.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index de7ab1d..52d62a5 100644 (file)
@@ -9,7 +9,7 @@ lfs \- client utility for Lustre-specific file layout and other attributes
 .br
 .B lfs check \fR<\fBmgts\fR|\fBmdts\fR|\fBosts\fR|\fBall\fR> [\fIpath\fR]
 .br
-.B lfs data_version \fR[\fB-nrw\fR] \fB<\fIfilename\fR>
+.B lfs data_version \fR[\fB-nrws\fR] \fB<\fIfilename\fR>
 .br
 .B lfs df \fR[\fB-ihlv\fR] [\fB--pool\fR|\fB-p \fR<\fIfsname\fR>[.<\fIpool\fR>]] [\fIpath\fR]
 .br
@@ -155,14 +155,15 @@ Display the status of the MGTs, MDTs or OSTs (as specified in the command) or
 all the servers (MGTs, MDTs and OSTs). If \fBpath\fR is provided, display
 the status of the lustre file system mounted at specified \fBpath\fR only.
 .TP
-.B data_version [-nrw] <filename>
-Display the current version of file data. If -n is specified, the data version
-is read without taking a lock. As a consequence, the data version could be
-outdated if there are dirty caches on filesystem clients, but this option will
-not force data flushes and has less of an impact on the filesystem. If -r is
-specified, the data version is read after dirty pages on clients are flushed. If
--w is specified, the data version is read after all caching pages on clients are
-flushed.
+.B data_version [-nrws] <filename>
+Display the current version of file data and optionally set the data version
+stored in the HSM xattr. If -n is specified, the data version is read without
+taking a lock. As a consequence, the data version could be outdated if there are
+dirty caches on filesystem clients, but this option will not force data flushes
+and has less of an impact on the filesystem. If -r is specified, the data
+version is read after dirty pages on clients are flushed. If -w is specified,
+the data version is read after all caching pages on clients are flushed. If -s
+is specified, the data version that was read, is also written to the HSM xattr.
 
 Even with -r or -w, race conditions are possible and the data version should be
 checked before and after an operation to be confident the data did not change
index 94ec470..a84cfd8 100644 (file)
@@ -564,6 +564,7 @@ int llapi_get_version(char *buffer, int buffer_size, char **version)
 int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags);
 int llapi_file_flush(int fd);
 extern int llapi_get_ost_layout_version(int fd, __u32 *layout_version);
+int llapi_hsm_data_version_set(int fd, __u64 data_version);
 int llapi_hsm_state_get_fd(int fd, struct hsm_user_state *hus);
 int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus);
 int llapi_hsm_state_set_fd(int fd, __u64 setmask, __u64 clearmask,
index 0ed7e33..73ae677 100644 (file)
@@ -258,6 +258,7 @@ extern struct req_format RQF_MDS_HSM_PROGRESS;
 extern struct req_format RQF_MDS_HSM_CT_REGISTER;
 extern struct req_format RQF_MDS_HSM_CT_UNREGISTER;
 extern struct req_format RQF_MDS_HSM_REQUEST;
+extern struct req_format RQF_MDS_HSM_DATA_VERSION;
 /* OST req_format */
 extern struct req_format RQF_OST_CONNECT;
 extern struct req_format RQF_OST_DISCONNECT;
index 5eb436a..f063eeb 100644 (file)
@@ -276,6 +276,7 @@ extern bool obd_enable_health_write;
 #define OBD_FAIL_MDS_HSM_RESTORE_RACE   0x18b
 #define OBD_FAIL_MDS_CHANGELOG_ENOSPC   0x18c
 #define OBD_FAIL_MDS_BATCH_NET          0x18d
+#define OBD_FAIL_MDS_HSM_DATA_VERSION_NET 0x18e
 
 /* OI scrub */
 #define OBD_FAIL_OSD_SCRUB_DELAY                       0x190
index 874d677..28282f4 100644 (file)
@@ -1790,6 +1790,7 @@ enum mds_cmd {
        MDS_SWAP_LAYOUTS        = 61,
        MDS_RMFID               = 62,
        MDS_BATCH               = 63,
+       MDS_HSM_DATA_VERSION    = 64,
        MDS_LAST_OPC
 };
 
index d84697f..cf9998d 100644 (file)
@@ -655,6 +655,7 @@ struct ll_ioc_lease_id {
                                                struct lu_pcc_detach_fid)
 #define LL_IOC_PCC_STATE               _IOR('f', 252, struct lu_pcc_state)
 #define LL_IOC_PROJECT                 _IOW('f', 253, struct lu_project)
+#define LL_IOC_HSM_DATA_VERSION                _IOW('f', 254, struct ioc_data_version)
 
 #ifndef        FS_IOC_FSGETXATTR
 /*
index ca8e86a..9739eae 100644 (file)
@@ -3680,6 +3680,31 @@ int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss)
        RETURN(rc);
 }
 
+static int ll_hsm_data_version_sync(struct inode *inode, __u64 data_version)
+{
+       struct obd_export *exp = ll_i2mdexp(inode);
+       struct md_op_data *op_data;
+       int rc;
+       ENTRY;
+
+       if (!data_version)
+               RETURN(-EINVAL);
+
+       op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+                                    LUSTRE_OPC_ANY, NULL);
+       if (IS_ERR(op_data))
+               RETURN(PTR_ERR(op_data));
+
+       op_data->op_data_version = data_version;
+
+       rc = obd_iocontrol(LL_IOC_HSM_DATA_VERSION, exp, sizeof(*op_data),
+                          op_data, NULL);
+
+       ll_finish_md_op_data(op_data);
+
+       RETURN(rc);
+}
+
 static int ll_hsm_import(struct inode *inode, struct file *file,
                         struct hsm_user_import *hui)
 {
@@ -4687,6 +4712,16 @@ skip_copy:
                OBD_FREE_PTR(hca);
                RETURN(rc);
        }
+       case LL_IOC_HSM_DATA_VERSION: {
+               __u64 data_version;
+
+               if (get_user(data_version, (u64 __user *)arg))
+                       RETURN(-EFAULT);
+
+               rc = ll_hsm_data_version_sync(inode, data_version);
+
+               RETURN(rc);
+       }
        case LL_IOC_SET_LEASE_OLD: {
                struct ll_ioc_lease ioc = { .lil_mode = arg };
 
index 18ca4b6..03b257b 100644 (file)
@@ -1021,6 +1021,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
        }
        case LL_IOC_HSM_STATE_GET:
        case LL_IOC_HSM_STATE_SET:
+       case LL_IOC_HSM_DATA_VERSION:
        case LL_IOC_HSM_ACTION: {
                struct md_op_data *op_data = karg;
 
index 8251767..c0953cc 100644 (file)
@@ -2051,6 +2051,44 @@ out:
        return rc;
 }
 
+static int mdc_ioc_hsm_data_version(struct obd_export *exp,
+                                   struct md_op_data *op_data)
+{
+       struct ptlrpc_request   *req;
+       struct mdt_body         *b;
+       int                      rc;
+       ENTRY;
+
+       req = ptlrpc_request_alloc(class_exp2cliimp(exp),
+                                  &RQF_MDS_HSM_DATA_VERSION);
+       if (req == NULL)
+               RETURN(-ENOMEM);
+
+       rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_HSM_DATA_VERSION);
+       if (rc) {
+               ptlrpc_request_free(req);
+               RETURN(rc);
+       }
+
+       mdc_pack_body(&req->rq_pill, &op_data->op_fid1, 0, 0,
+                     op_data->op_suppgids[0], 0);
+
+       b = req_capsule_client_get(&req->rq_pill, &RMF_MDT_BODY);
+       LASSERT(b);
+
+       b->mbo_version = op_data->op_data_version;
+
+       ptlrpc_request_set_replen(req);
+
+       ptlrpc_get_mod_rpc_slot(req);
+       rc = ptlrpc_queue_wait(req);
+       ptlrpc_put_mod_rpc_slot(req);
+
+       GOTO(out, rc);
+out:
+       ptlrpc_req_put(req);
+       return rc;
+}
 static int mdc_ioc_hsm_ct_start(struct obd_export *exp,
                                 struct lustre_kernelcomm *lk);
 static int mdc_quotactl(struct obd_device *unused, struct obd_export *exp,
@@ -2260,6 +2298,9 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
        case LL_IOC_HSM_REQUEST:
                rc = mdc_ioc_hsm_request(exp, karg);
                GOTO(out, rc);
+       case LL_IOC_HSM_DATA_VERSION:
+               rc = mdc_ioc_hsm_data_version(exp, karg);
+               GOTO(out, rc);
        case OBD_IOC_CLIENT_RECOVER:
                rc = ptlrpc_recover_import(imp, data->ioc_inlbuf1, 0);
                if (rc < 0)
index 5a1d40b..b398af3 100644 (file)
@@ -6126,6 +6126,8 @@ TGT_MDT_HDL(HAS_BODY | HAS_REPLY, MDS_HSM_REQUEST,
 TGT_MDT_HDL(HAS_KEY | HAS_BODY | HAS_REPLY | IS_MUTABLE,
            MDS_SWAP_LAYOUTS,
            mdt_swap_layouts),
+TGT_MDT_HDL(HAS_BODY | HAS_REPLY | IS_MUTABLE, MDS_HSM_DATA_VERSION,
+           mdt_hsm_data_version),
 TGT_MDT_HDL(IS_MUTABLE,                MDS_RMFID,      mdt_rmfid),
 TGT_MDT_HDL(IS_MUTABLE,                MDS_BATCH,      mdt_batch),
 };
index 63b7c30..3c23dbd 100644 (file)
@@ -393,6 +393,69 @@ out:
 }
 
 /**
+ * Set the data version in the HSM xattr of a file.
+ *
+ * This is MDS_HSM_DATA_VERSION RPC handler.
+ */
+int mdt_hsm_data_version(struct tgt_session_info *tsi)
+{
+       struct mdt_thread_info  *info = tsi2mdt_info(tsi);
+       struct mdt_object       *obj = info->mti_object;
+       struct md_attr          *ma = &info->mti_attr;
+       struct mdt_lock_handle  *lh;
+       int                      rc;
+       ENTRY;
+
+       if (info->mti_body == NULL || obj == NULL)
+               GOTO(out, rc = -EPROTO);
+
+       /* Only valid if client is remote */
+       rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
+       if (rc < 0)
+               GOTO(out, rc = err_serious(rc));
+
+       lh = &info->mti_lh[MDT_LH_CHILD];
+       rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LOOKUP |
+                            MDS_INODELOCK_XATTR, LCK_PW);
+       if (rc < 0)
+               GOTO(out_ucred, rc);
+
+       /* Read current HSM info */
+       ma->ma_valid = 0;
+       ma->ma_need = MA_HSM;
+       rc = mdt_attr_get_complex(info, obj, ma);
+       if (rc)
+               GOTO(out_unlock, rc);
+
+       if (unlikely(!info->mti_body->mbo_version)) {
+               CDEBUG(D_HSM, "Can't set HSM xattr data version to zero "
+                      DFID"\n", PFID(&info->mti_body->mbo_fid1));
+               GOTO(out_unlock, rc = -EINVAL);
+       } else {
+               CDEBUG(D_HSM, "Setting HSM xattr data version to %llu "DFID"\n",
+                      info->mti_body->mbo_version,
+                      PFID(&info->mti_body->mbo_fid1));
+       }
+
+       ma->ma_hsm.mh_arch_ver = info->mti_body->mbo_version;
+
+       /* Save the data version */
+       rc = mdt_hsm_attr_set(info, obj, &ma->ma_hsm);
+       if (rc)
+               GOTO(out_unlock, rc);
+
+       EXIT;
+
+out_unlock:
+       mdt_object_unlock(info, obj, lh, 1);
+out_ucred:
+       mdt_exit_ucred(info);
+out:
+       mdt_thread_info_fini(info);
+       return rc;
+}
+
+/**
  * Retrieve undergoing HSM requests for the fid provided in RPC body.
  * Current requests are read from coordinator states.
  *
index 81d47b8..5730842 100644 (file)
@@ -1077,6 +1077,7 @@ int mdt_hsm_progress(struct tgt_session_info *tsi);
 int mdt_hsm_ct_register(struct tgt_session_info *tsi);
 int mdt_hsm_ct_unregister(struct tgt_session_info *tsi);
 int mdt_hsm_request(struct tgt_session_info *tsi);
+int mdt_hsm_data_version(struct tgt_session_info *tsi);
 
 /* mdt/mdt_hsm_cdt_actions.c */
 extern const struct file_operations mdt_hsm_actions_fops;
index 42e0fa3..7eb7716 100644 (file)
@@ -771,6 +771,11 @@ static const struct req_msg_field *mdt_hsm_request[] = {
        &RMF_GENERIC_DATA,
 };
 
+static const struct req_msg_field *mdt_hsm_data_version[] = {
+       &RMF_PTLRPC_BODY,
+       &RMF_MDT_BODY
+};
+
 static const struct req_msg_field *obd_lfsck_request[] = {
        &RMF_PTLRPC_BODY,
        &RMF_LFSCK_REQUEST,
@@ -849,6 +854,7 @@ static struct req_format *req_formats[] = {
        &RQF_MDS_HSM_STATE_SET,
        &RQF_MDS_HSM_ACTION,
        &RQF_MDS_HSM_REQUEST,
+       &RQF_MDS_HSM_DATA_VERSION,
        &RQF_MDS_SWAP_LAYOUTS,
        &RQF_MDS_RMFID,
 #ifdef HAVE_SERVER_SUPPORT
@@ -1708,6 +1714,10 @@ struct req_format RQF_MDS_HSM_REQUEST =
        DEFINE_REQ_FMT0("MDS_HSM_REQUEST", mdt_hsm_request, empty);
 EXPORT_SYMBOL(RQF_MDS_HSM_REQUEST);
 
+struct req_format RQF_MDS_HSM_DATA_VERSION =
+       DEFINE_REQ_FMT0("MDS_HSM_DATA_VERSION", mdt_hsm_data_version, empty);
+EXPORT_SYMBOL(RQF_MDS_HSM_DATA_VERSION);
+
 struct req_format RQF_MDS_SWAP_LAYOUTS =
        DEFINE_REQ_FMT0("MDS_SWAP_LAYOUTS",
                        mdt_swap_layouts, empty);
index e763e50..54b0e8d 100644 (file)
@@ -98,6 +98,7 @@ static struct ll_rpc_opcode {
        { MDS_SWAP_LAYOUTS,     "mds_swap_layouts" },
        { MDS_RMFID,        "mds_rmfid" },
        { MDS_BATCH,        "mds_batch" },
+       { MDS_HSM_DATA_VERSION, "mds_hsm_data_version" },
        { LDLM_ENQUEUE,     "ldlm_enqueue" },
        { LDLM_CONVERT,     "ldlm_convert" },
        { LDLM_CANCEL,      "ldlm_cancel" },
index 31b2839..7106bb4 100644 (file)
@@ -185,7 +185,9 @@ void lustre_assert_wire_constants(void)
                 (long long)MDS_RMFID);
        LASSERTF(MDS_BATCH == 63, "found %lld\n",
                 (long long)MDS_BATCH);
-       LASSERTF(MDS_LAST_OPC == 64, "found %lld\n",
+       LASSERTF(MDS_HSM_DATA_VERSION == 64, "found %lld\n",
+                (long long)MDS_HSM_DATA_VERSION);
+       LASSERTF(MDS_LAST_OPC == 65, "found %lld\n",
                 (long long)MDS_LAST_OPC);
        LASSERTF(REINT_SETATTR == 1, "found %lld\n",
                 (long long)REINT_SETATTR);
index 2297db5..62889c8 100644 (file)
@@ -538,6 +538,7 @@ static int tgt_filter_recovery_request(struct ptlrpc_request *req,
        case MDS_HSM_PROGRESS:
        case MDS_HSM_STATE_SET:
        case MDS_HSM_REQUEST:
+       case MDS_HSM_DATA_VERSION:
        case OST_FALLOCATE:
                *process = target_queue_recovery_request(req, obd);
                RETURN(0);
index 3d20fde..1fb02c7 100755 (executable)
@@ -5623,6 +5623,30 @@ test_409b()
 }
 run_test 409b "getattr released file with CDT stopped after remount"
 
+test_410()
+{
+       [ "$MDS1_VERSION" -lt $(version_code 2.15.3.2) ] &&
+               skip "need MDS version at least 2.15.3.2"
+
+       [ "$CLIENT_VERSION" -lt $(version_code 2.15.3.2) ] &&
+               skip "need client version at least 2.15.3.2"
+
+       mkdir_on_mdt0 $DIR/$tdir
+
+       local f=$DIR/$tdir/$tfile
+       local fid=$(create_small_file $f)
+
+       copytool setup
+
+       $LFS hsm_set --exists --archived $f ||
+               error "could not change hsm flags"
+       $LFS hsm_release $f 2>&1 > /dev/null && error "HSM release should fail"
+
+       $LFS data_version -ws $f 2>&1 > /dev/null
+       $LFS hsm_release $f || error "could not release file"
+}
+run_test 410 "lfs data_version -s allows release of force-archived file"
+
 test_500()
 {
        [ "$MDS1_VERSION" -lt $(version_code 2.6.92) ] &&
index 51bae69..abe0c56 100755 (executable)
@@ -498,8 +498,9 @@ command_t cmdlist[] = {
         "usage: path2fid [--parents] <path> ..."},
        {"rmfid", lfs_rmfid, 0, "Remove file(s) by FID(s)\n"
         "usage: rmfid <fsname|rootpath> <fid> ..."},
-       {"data_version", lfs_data_version, 0, "Display file data version for "
-        "a given path.\n" "usage: data_version [-n|-r|-w] <path>"},
+       {"data_version", lfs_data_version, 0, "Display file data version or "
+        "set the data version in the HSM xattr for a given path.\n"
+       "usage: data_version [-n|-r|-w|-s] <path>"},
        {"hsm_state", lfs_hsm_state, 0, "Display the HSM information (states, "
         "undergoing actions) for given files.\n usage: hsm_state <file> ..."},
        {"hsm_set", lfs_hsm_set, 0, "Set HSM user flag on specified files.\n"
@@ -10861,6 +10862,7 @@ static int lfs_data_version(int argc, char **argv)
        int data_version_flags = LL_DV_RD_FLUSH; /* Read by default */
        __u64 data_version;
        char *path;
+       bool hsm_sync = false;
        int fd;
        int rc;
        int c;
@@ -10871,7 +10873,7 @@ static int lfs_data_version(int argc, char **argv)
                return CMD_HELP;
        }
 
-       while ((c = getopt(argc, argv, "hnrw")) != -1) {
+       while ((c = getopt(argc, argv, "hnrws")) != -1) {
                switch (c) {
                case 'n':
                        data_version_flags = 0;
@@ -10882,6 +10884,9 @@ static int lfs_data_version(int argc, char **argv)
                case 'w':
                        data_version_flags |= LL_DV_WR_FLUSH;
                        break;
+               case 's':
+                       hsm_sync = true;
+                       break;
                default:
                        fprintf(stderr,
                                "%s data_version: unrecognized option '%s'\n",
@@ -10907,13 +10912,24 @@ static int lfs_data_version(int argc, char **argv)
        }
 
        rc = llapi_get_data_version(fd, &data_version, data_version_flags);
-       if (rc < 0)
+       if (rc < 0) {
                fprintf(stderr,
                        "%s data_version: cannot get version for '%s': %s\n",
                        progname, path, strerror(-rc));
-       else
+       } else {
                printf("%ju" "\n", (uintmax_t)data_version);
 
+               if (hsm_sync) {
+                       rc = llapi_hsm_data_version_set(fd, data_version);
+                       if (rc < 0)
+                               fprintf(stderr,
+                                       "%s data_version: cannot set version %llu for"
+                                       " '%s': %s\n", progname,
+                                       (unsigned long long)data_version, path,
+                                       strerror(-rc));
+               }
+       }
+
        close(fd);
        return rc;
 }
index 21b4d8d..1b50f2f 100644 (file)
@@ -91,6 +91,24 @@ int llapi_get_ost_layout_version(int fd, __u32 *layout_version)
        return rc;
 }
 
+/**
+ * Set the data version in the HSM xattr on the MDT inode of a file to a
+ * specific value.
+ *
+ * \retval 0 on success.
+ * \retval -errno on error.
+ */
+int llapi_hsm_data_version_set(int fd, __u64 data_version)
+{
+       int rc;
+
+       rc = ioctl(fd, LL_IOC_HSM_DATA_VERSION, &data_version);
+       if (rc)
+               rc = -errno;
+
+       return rc;
+}
+
 /*
  * Create a file without any name and open it for read/write
  *
index a23b87a..e35d771 100644 (file)
@@ -3424,6 +3424,7 @@ main(int argc, char **argv)
        CHECK_VALUE(MDS_SWAP_LAYOUTS);
        CHECK_VALUE(MDS_RMFID);
        CHECK_VALUE(MDS_BATCH);
+       CHECK_VALUE(MDS_HSM_DATA_VERSION);
        CHECK_VALUE(MDS_LAST_OPC);
 
        CHECK_VALUE(REINT_SETATTR);
index 9d283d6..e167360 100644 (file)
@@ -210,7 +210,9 @@ void lustre_assert_wire_constants(void)
                 (long long)MDS_RMFID);
        LASSERTF(MDS_BATCH == 63, "found %lld\n",
                 (long long)MDS_BATCH);
-       LASSERTF(MDS_LAST_OPC == 64, "found %lld\n",
+       LASSERTF(MDS_HSM_DATA_VERSION == 64, "found %lld\n",
+                (long long)MDS_BATCH);
+       LASSERTF(MDS_LAST_OPC == 65, "found %lld\n",
                 (long long)MDS_LAST_OPC);
        LASSERTF(REINT_SETATTR == 1, "found %lld\n",
                 (long long)REINT_SETATTR);