Whamcloud - gitweb
LU-10773 obdclass: yield cpu during changelog_block_trim_ext
[fs/lustre-release.git] / lustre / obdclass / llog_osd.c
index c853433..f25126d 100644 (file)
@@ -793,6 +793,10 @@ static void changelog_block_trim_ext(struct llog_rec_hdr *hdr,
        enum changelog_rec_flags flags = CLF_SUPPORTED;
        enum changelog_rec_extra_flags extra_flags = CLFE_SUPPORTED;
 
+       if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_XATTR))
+               extra_flags &= ~CLFE_XATTR;
+       if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_OMODE))
+               extra_flags &= ~CLFE_OPEN;
        if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_NID))
                extra_flags &= ~CLFE_NID;
        if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
@@ -818,8 +822,26 @@ static void changelog_block_trim_ext(struct llog_rec_hdr *hdr,
                                extra_flags;
                }
 
+               if (unlikely(hdr->lrh_len == 0)) {
+                       /* It is corruption case, we cannot know the next rec,
+                        * jump to the last one directly to avoid dead loop. */
+                       LCONSOLE(D_WARNING, "Hit invalid llog record: "
+                                "idx %u, type %u, id %u\n",
+                                hdr->lrh_index, hdr->lrh_type, hdr->lrh_id);
+                       hdr = llog_rec_hdr_next(last_hdr);
+                       if (unlikely(hdr == last_hdr))
+                               LCONSOLE(D_WARNING, "The last record crashed: "
+                                        "idx %u, type %u, id %u\n",
+                                        hdr->lrh_index, hdr->lrh_type,
+                                        hdr->lrh_id);
+                       break;
+               }
+
                changelog_remap_rec(rec, rec->cr_flags & flags, xflag);
                hdr = llog_rec_hdr_next(hdr);
+               /* Yield CPU to avoid soft-lockup if there are too many records
+                * to be handled. */
+               cond_resched();
        } while ((char *)hdr <= (char *)last_hdr);
 }