+struct changelog_orphan_data {
+ __u64 index;
+ struct mdd_device *mdd;
+};
+
+/* find oldest changelog record index */
+static int changelog_detect_orphan_cb(const struct lu_env *env,
+ struct llog_handle *llh,
+ struct llog_rec_hdr *hdr, void *data)
+{
+ struct mdd_device *mdd = ((struct changelog_orphan_data *)data)->mdd;
+ struct llog_changelog_rec *rec = container_of(hdr,
+ struct llog_changelog_rec,
+ cr_hdr);
+
+ LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+
+ if (rec->cr_hdr.lrh_type != CHANGELOG_REC) {
+ CWARN("%s: invalid record at index %d in log "DFID"\n",
+ mdd2obd_dev(mdd)->obd_name, hdr->lrh_index,
+ PFID(&llh->lgh_id.lgl_oi.oi_fid));
+ /* try to find some next valid record and thus allow to recover
+ * from a corrupted LLOG, instead to assert and force a crash
+ */
+ return 0;
+ }
+
+ CDEBUG(D_INFO, "%s: seeing record at index %d/%d/%llu t=%x %.*s in log "
+ DFID"\n", mdd2obd_dev(mdd)->obd_name, hdr->lrh_index,
+ rec->cr_hdr.lrh_index, rec->cr.cr_index, rec->cr.cr_type,
+ rec->cr.cr_namelen, changelog_rec_name(&rec->cr),
+ PFID(&llh->lgh_id.lgl_oi.oi_fid));
+
+ ((struct changelog_orphan_data *)data)->index = rec->cr.cr_index;
+ return LLOG_PROC_BREAK;
+}
+
+/* find oldest changelog user index */
+static int changelog_user_detect_orphan_cb(const struct lu_env *env,
+ struct llog_handle *llh,
+ struct llog_rec_hdr *hdr, void *data)
+{
+ struct mdd_device *mdd = ((struct changelog_orphan_data *)data)->mdd;
+ struct llog_changelog_user_rec *rec = container_of(hdr,
+ struct llog_changelog_user_rec,
+ cur_hdr);
+
+ LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+
+ if (rec->cur_hdr.lrh_type != CHANGELOG_USER_REC) {
+ 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));
+ /* try to find some next valid record and thus allow to recover
+ * from a corrupted LLOG, instead to assert and force a crash
+ */
+ return 0;
+ }
+
+ CDEBUG(D_INFO, "%s: seeing user at index %d/%d id=%d endrec=%llu in "
+ "log "DFID"\n", mdd2obd_dev(mdd)->obd_name, hdr->lrh_index,
+ rec->cur_hdr.lrh_index, rec->cur_id, rec->cur_endrec,
+ PFID(&llh->lgh_id.lgl_oi.oi_fid));
+
+ if (((struct changelog_orphan_data *)data)->index == 0 ||
+ rec->cur_endrec < ((struct changelog_orphan_data *)data)->index)
+ ((struct changelog_orphan_data *)data)->index = rec->cur_endrec;
+
+ return 0;
+}
+
+struct changelog_cancel_cookie {
+ long long endrec;
+ struct mdd_device *mdd;
+};
+