Whamcloud - gitweb
LU-13055 mdd: don't assert on unknown changelog lrh_type 10/43710/7
authorMikhail Pershin <mpershin@whamcloud.com>
Fri, 14 May 2021 17:01:43 +0000 (20:01 +0300)
committerOleg Drokin <green@whamcloud.com>
Tue, 10 Aug 2021 06:35:01 +0000 (06:35 +0000)
Supplemental patch for old server code to prevent assertion
on unknown/new changelog record and user record types

Test-Parameters: env=ONLY=160 testlist=sanity serverjob=lustre-master serverbuildno=0
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I5d45c6ef659feb2b143edf6286df9904378171ba
Reviewed-on: https://review.whamcloud.com/43710
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/mdd/mdd_device.c

index da92408..3bcc641 100644 (file)
@@ -2725,6 +2725,7 @@ enum llog_op_type {
        /* LLOG_JOIN_REC        = LLOG_OP_MAGIC | 0x50000, obsolete  1.8.0 */
        CHANGELOG_REC           = LLOG_OP_MAGIC | 0x60000,
        CHANGELOG_USER_REC      = LLOG_OP_MAGIC | 0x70000,
+       CHANGELOG_USER_REC2     = LLOG_OP_MAGIC | 0x70002,
        HSM_AGENT_REC           = LLOG_OP_MAGIC | 0x80000,
        UPDATE_REC              = LLOG_OP_MAGIC | 0xa0000,
        LLOG_HDR_MAGIC          = LLOG_OP_MAGIC | 0x45539,
index faf548d..53cc2fa 100644 (file)
@@ -185,11 +185,22 @@ static struct lu_device *mdd_device_fini(const struct lu_env *env,
 static int changelog_init_cb(const struct lu_env *env, struct llog_handle *llh,
                             struct llog_rec_hdr *hdr, void *data)
 {
-       struct mdd_device *mdd = (struct mdd_device *)data;
+       struct mdd_device *mdd = data;
        struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr;
 
-       LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
-       LASSERT(rec->cr_hdr.lrh_type == CHANGELOG_REC);
+       if (unlikely(!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN))) {
+               CWARN("%s: changelog "DFID" must be a plain llog\n",
+                     mdd2obd_dev(mdd)->obd_name,
+                     PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return -EINVAL;
+       }
+
+       if (rec->cr_hdr.lrh_type != CHANGELOG_REC) {
+               CWARN("%s: invalid record at index %#x in log "DFID"\n",
+                     mdd2obd_dev(mdd)->obd_name, hdr->lrh_index,
+                     PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return 0;
+       }
 
        CDEBUG(D_INFO,
               "seeing record at index %d/%d/%llu t=%x %.*s in log"
@@ -209,8 +220,20 @@ static int changelog_user_init_cb(const struct lu_env *env,
        struct llog_changelog_user_rec *rec =
                (struct llog_changelog_user_rec *)hdr;
 
-       LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
-       LASSERT(rec->cur_hdr.lrh_type == CHANGELOG_USER_REC);
+       if (unlikely(!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN))) {
+               CWARN("%s: changelog "DFID" must be a plain llog\n",
+                     mdd2obd_dev(mdd)->obd_name,
+                     PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return -EINVAL;
+       }
+
+       if (rec->cur_hdr.lrh_type != CHANGELOG_USER_REC &&
+           rec->cur_hdr.lrh_type != CHANGELOG_USER_REC2) {
+               CWARN("%s: unknown user type %x at index %u in log "DFID"\n",
+                     mdd2obd_dev(mdd)->obd_name, hdr->lrh_index,
+                     rec->cur_hdr.lrh_type, PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return 0;
+       }
 
        CDEBUG(D_INFO, "seeing user at index %d/%d id=%d endrec=%llu"
               " in log "DFID"\n", hdr->lrh_index, rec->cur_hdr.lrh_index,
@@ -241,7 +264,12 @@ static int changelog_detect_orphan_cb(const struct lu_env *env,
                                                      struct llog_changelog_rec,
                                                      cr_hdr);
 
-       LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+       if (unlikely(!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN))) {
+               CWARN("%s: changelog "DFID" must be a plain llog\n",
+                     mdd2obd_dev(mdd)->obd_name,
+                     PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return -EINVAL;
+       }
 
        if (rec->cr_hdr.lrh_type != CHANGELOG_REC) {
                CWARN("%s: invalid record at index %d in log "DFID"\n",
@@ -273,9 +301,15 @@ static int changelog_user_detect_orphan_cb(const struct lu_env *env,
                                                struct llog_changelog_user_rec,
                                                cur_hdr);
 
-       LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+       if (unlikely(!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN))) {
+               CWARN("%s: changelog "DFID" must be a plain llog\n",
+                     mdd2obd_dev(mdd)->obd_name,
+                     PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return -EINVAL;
+       }
 
-       if (rec->cur_hdr.lrh_type != CHANGELOG_USER_REC) {
+       if (rec->cur_hdr.lrh_type != CHANGELOG_USER_REC &&
+           rec->cur_hdr.lrh_type != CHANGELOG_USER_REC2) {
                CWARN("%s: invalid user at index %d in log "DFID"\n",
                      mdd2obd_dev(mdd)->obd_name, hdr->lrh_index,
                      PFID(&llh->lgh_id.lgl_oi.oi_fid));
@@ -315,7 +349,12 @@ static int llog_changelog_cancel_cb(const struct lu_env *env,
        ENTRY;
 
        /* This is always a (sub)log, not the catalog */
-       LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+       if (unlikely(!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN))) {
+               CWARN("%s: changelog "DFID" must be a plain llog\n",
+                     mdd2obd_dev(cl_cookie->mdd)->obd_name,
+                     PFID(&llh->lgh_id.lgl_oi.oi_fid));
+               return -EINVAL;
+       }
 
        /* if current context is GC-thread allow it to stop upon umount
         * remaining records cleanup will occur upon next mount
@@ -355,13 +394,19 @@ static int llog_changelog_cancel(const struct lu_env *env,
                                 struct llog_ctxt *ctxt,
                                 struct changelog_cancel_cookie *cookie)
 {
-       struct llog_handle      *cathandle = ctxt->loc_handle;
-       int                      rc;
+       struct llog_handle *cathandle = ctxt->loc_handle;
+       int rc;
 
        ENTRY;
 
        /* This should only be called with the catalog handle */
-       LASSERT(cathandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT);
+       if (unlikely(!(cathandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))) {
+               CWARN("%s: changelog "DFID" must be a catalog llog\n",
+                     mdd2obd_dev(cookie->mdd)->obd_name,
+                     PFID(&cathandle->lgh_id.lgl_oi.oi_fid));
+               return -EINVAL;
+       }
+
 
        rc = llog_cat_process(env, cathandle, llog_changelog_cancel_cb,
                              cookie, 0, 0);