+static int llog_cancel_rec_internal(const struct lu_env *env,
+ struct llog_handle *loghandle, int index)
+{
+ struct dt_device *dt;
+ struct llog_log_hdr *llh = loghandle->lgh_hdr;
+ struct thandle *th;
+ int rc;
+
+ ENTRY;
+
+ LASSERT(loghandle);
+ LASSERT(loghandle->lgh_ctxt);
+ LASSERT(loghandle->lgh_obj != NULL);
+
+ dt = lu2dt_dev(loghandle->lgh_obj->do_lu.lo_dev);
+
+ th = dt_trans_create(env, dt);
+ if (IS_ERR(th))
+ RETURN(PTR_ERR(th));
+
+ rc = llog_declare_write_rec(env, loghandle, &llh->llh_hdr, index, th);
+ if (rc < 0)
+ GOTO(out_trans, rc);
+
+ th->th_wait_submit = 1;
+ rc = dt_trans_start_local(env, dt, th);
+ if (rc < 0)
+ GOTO(out_trans, rc);
+
+ down_write(&loghandle->lgh_lock);
+ /* clear bitmap */
+ mutex_lock(&loghandle->lgh_hdr_mutex);
+ if (!ext2_clear_bit(index, LLOG_HDR_BITMAP(llh))) {
+ CDEBUG(D_RPCTRACE, "Catalog index %u already clear?\n", index);
+ GOTO(out_unlock, rc);
+ }
+ /* update header */
+ rc = llog_write_rec(env, loghandle, &llh->llh_hdr, NULL,
+ LLOG_HEADER_IDX, th);
+ if (rc == 0)
+ loghandle->lgh_hdr->llh_count--;
+ else
+ ext2_set_bit(index, LLOG_HDR_BITMAP(llh));
+out_unlock:
+ mutex_unlock(&loghandle->lgh_hdr_mutex);
+ up_write(&loghandle->lgh_lock);
+out_trans:
+ dt_trans_stop(env, dt, th);
+ RETURN(rc);
+}
+