Whamcloud - gitweb
LU-11419 lfsck: lfsck_namespace_shrink_linkea() dead loop 52/33252/3
authorLai Siyao <lai.siyao@intel.com>
Thu, 30 Aug 2018 13:08:57 +0000 (21:08 +0800)
committerOleg Drokin <green@whamcloud.com>
Mon, 29 Oct 2018 16:02:17 +0000 (16:02 +0000)
lfsck_namespace_shrink_linkea() may fall in dead loop if it tries
to delete XATTR_NAME_LINK.

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: I43e6e7917f8f89eb2cc873c8521cd3fbb528f495
Reviewed-on: https://review.whamcloud.com/33252
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/lfsck/lfsck_namespace.c

index 6893b0c..d88a352 100644 (file)
@@ -1614,16 +1614,22 @@ again:
                lfsck_namespace_filter_linkea_entry(&ldata_new, cname, pfid,
                                                    true);
 
                lfsck_namespace_filter_linkea_entry(&ldata_new, cname, pfid,
                                                    true);
 
-       if (buflen < ldata_new.ld_leh->leh_len) {
+       /*
+        * linkea may change because it doesn't take lock in the first read, if
+        * it becomes larger, restart from beginning.
+        */
+       if ((ldata_new.ld_leh->leh_reccount > 0 ||
+            unlikely(ldata_new.ld_leh->leh_overflow_time)) &&
+           buflen < ldata_new.ld_leh->leh_len) {
                dt_write_unlock(env, obj);
                dt_trans_stop(env, dev, th);
                lfsck_buf_init(&linkea_buf, ldata_new.ld_buf->lb_buf,
                               ldata_new.ld_leh->leh_len);
                dt_write_unlock(env, obj);
                dt_trans_stop(env, dev, th);
                lfsck_buf_init(&linkea_buf, ldata_new.ld_buf->lb_buf,
                               ldata_new.ld_leh->leh_len);
+               buflen = linkea_buf.lb_len;
                goto again;
        }
 
                goto again;
        }
 
-       if (ldata_new.ld_leh->leh_reccount > 0 ||
-           unlikely(ldata->ld_leh->leh_overflow_time))
+       if (buflen)
                rc = lfsck_links_write(env, obj, &ldata_new, th);
        else
                rc = dt_xattr_del(env, obj, XATTR_NAME_LINK, th);
                rc = lfsck_links_write(env, obj, &ldata_new, th);
        else
                rc = dt_xattr_del(env, obj, XATTR_NAME_LINK, th);