+struct changelog_orphan_data {
+ __u64 clod_index;
+ struct mdd_device *clod_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 changelog_orphan_data *clod = data;
+ struct mdd_device *mdd = clod->clod_mdd;
+ struct llog_changelog_rec *rec;
+
+ LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+
+ rec = container_of(hdr, typeof(*rec), cr_hdr);
+ 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: 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));
+
+ clod->clod_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 changelog_orphan_data *clod = data;
+ struct mdd_device *mdd = clod->clod_mdd;
+ struct llog_changelog_user_rec2 *rec;
+ char user_name[CHANGELOG_USER_NAMELEN_FULL];
+
+ LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
+
+ rec = container_of(hdr, typeof(*rec), cur_hdr);
+ if (rec->cur_hdr.lrh_type != CHANGELOG_USER_REC &&
+ rec->cur_hdr.lrh_type != CHANGELOG_USER_REC2) {
+ CWARN("%s: unknown user type %u 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));
+ /* 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: user %s at index %u/%u endrec=%llu in log "DFID"\n",
+ mdd2obd_dev(mdd)->obd_name, mdd_chlg_username(rec, user_name,
+ sizeof(user_name)),
+ hdr->lrh_index, rec->cur_hdr.lrh_index,
+ rec->cur_endrec, PFID(&llh->lgh_id.lgl_oi.oi_fid));
+
+ clod->clod_index = min_t(__u64, clod->clod_index, rec->cur_endrec);
+
+ return 0;
+}
+
+struct changelog_cancel_cookie {
+ long long endrec;
+ struct mdd_device *mdd;
+};
+