Whamcloud - gitweb
LU-9994 obdclass: fix llog_cat_id2handle() error handling 70/29370/3
authorBruno Faccini <bruno.faccini@intel.com>
Mon, 9 Oct 2017 15:21:50 +0000 (17:21 +0200)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 3 Nov 2017 04:25:56 +0000 (04:25 +0000)
Patch for LU-9153 ("llog: consolidate common error checking") has
introduced a regression in llog_cat_id2handle() error handling
path by adding llog_cat_process_common() common routine additional
call in sequence and allowing it to return zero even when catalog
entry was invalid and it had cleared it instead to populate
llog_handle, thus causing an exception when handle was later
dereferenced in llog_process_thread().

Signed-off-by: Bruno Faccini <bruno.faccini@intel.com>
Change-Id: I50153b931e3c1567bfe9c15564ba29fabe3a2d4c
Reviewed-on: https://review.whamcloud.com/29370
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
lustre/obdclass/llog_cat.c

index 0d57ce3..8771d68 100644 (file)
@@ -806,9 +806,8 @@ static int llog_cat_process_common(const struct lu_env *env,
                 * deletion are not atomic. So we end up with an index but no
                 * actual record. Destroy the index and move on. */
                if (rc == -ENOENT || rc == -ESTALE)
                 * deletion are not atomic. So we end up with an index but no
                 * actual record. Destroy the index and move on. */
                if (rc == -ENOENT || rc == -ESTALE)
-                       rc = llog_cat_cleanup(env, cat_llh, NULL,
-                                             rec->lrh_index);
-               if (rc)
+                       rc = LLOG_DEL_RECORD;
+               else if (rc)
                        CWARN("%s: can't find llog handle "DFID":%x: rc = %d\n",
                              cat_llh->lgh_ctxt->loc_obd->obd_name,
                              PFID(&lir->lid_id.lgl_oi.oi_fid),
                        CWARN("%s: can't find llog handle "DFID":%x: rc = %d\n",
                              cat_llh->lgh_ctxt->loc_obd->obd_name,
                              PFID(&lir->lid_id.lgl_oi.oi_fid),
@@ -866,9 +865,14 @@ static int llog_cat_process_cb(const struct lu_env *env,
 
 out:
        /* The empty plain log was destroyed while processing */
 
 out:
        /* The empty plain log was destroyed while processing */
-       if (rc == LLOG_DEL_PLAIN)
+       if (rc == LLOG_DEL_PLAIN) {
                rc = llog_cat_cleanup(env, cat_llh, llh,
                                      llh->u.phd.phd_cookie.lgc_index);
                rc = llog_cat_cleanup(env, cat_llh, llh,
                                      llh->u.phd.phd_cookie.lgc_index);
+       } else if (rc == LLOG_DEL_RECORD) {
+               /* clear wrong catalog entry */
+               rc = llog_cat_cleanup(env, cat_llh, NULL, rec->lrh_index);
+       }
+
        if (llh)
                llog_handle_put(llh);
 
        if (llh)
                llog_handle_put(llh);
 
@@ -938,13 +942,14 @@ static int llog_cat_size_cb(const struct lu_env *env,
 
        ENTRY;
        rc = llog_cat_process_common(env, cat_llh, rec, &llh);
 
        ENTRY;
        rc = llog_cat_process_common(env, cat_llh, rec, &llh);
-       if (llh == NULL)
-               RETURN(0);
 
        if (rc == LLOG_DEL_PLAIN) {
                /* empty log was deleted, don't count it */
                rc = llog_cat_cleanup(env, cat_llh, llh,
                                      llh->u.phd.phd_cookie.lgc_index);
 
        if (rc == LLOG_DEL_PLAIN) {
                /* empty log was deleted, don't count it */
                rc = llog_cat_cleanup(env, cat_llh, llh,
                                      llh->u.phd.phd_cookie.lgc_index);
+       } else if (rc == LLOG_DEL_RECORD) {
+               /* clear wrong catalog entry */
+               rc = llog_cat_cleanup(env, cat_llh, NULL, rec->lrh_index);
        } else {
                size = llog_size(env, llh);
                *cum_size += size;
        } else {
                size = llog_size(env, llh);
                *cum_size += size;
@@ -953,7 +958,8 @@ static int llog_cat_size_cb(const struct lu_env *env,
                       PFID(&llh->lgh_id.lgl_oi.oi_fid), size, *cum_size);
        }
 
                       PFID(&llh->lgh_id.lgl_oi.oi_fid), size, *cum_size);
        }
 
-       llog_handle_put(llh);
+       if (llh != NULL)
+               llog_handle_put(llh);
 
        RETURN(0);
 }
 
        RETURN(0);
 }
@@ -979,6 +985,15 @@ static int llog_cat_reverse_process_cb(const struct lu_env *env,
 
        ENTRY;
        rc = llog_cat_process_common(env, cat_llh, rec, &llh);
 
        ENTRY;
        rc = llog_cat_process_common(env, cat_llh, rec, &llh);
+
+       /* The empty plain log was destroyed while processing */
+       if (rc == LLOG_DEL_PLAIN) {
+               rc = llog_cat_cleanup(env, cat_llh, llh,
+                                     llh->u.phd.phd_cookie.lgc_index);
+       } else if (rc == LLOG_DEL_RECORD) {
+               /* clear wrong catalog entry */
+               rc = llog_cat_cleanup(env, cat_llh, NULL, rec->lrh_index);
+       }
        if (rc)
                RETURN(rc);
 
        if (rc)
                RETURN(rc);