int llog_cancel_rec(const struct lu_env *env, struct llog_handle *loghandle,
int index)
{
+ struct llog_thread_info *lgi = llog_info(env);
struct dt_device *dt;
struct llog_log_hdr *llh = loghandle->lgh_hdr;
struct thandle *th;
CDEBUG(D_RPCTRACE, "Catalog index %u already clear?\n", index);
GOTO(out_unlock, rc);
}
+
+ loghandle->lgh_hdr->llh_count--;
+ /* Pass this index to llog_osd_write_rec(), which will use the index
+ * to only update the necesary bitmap. */
+ lgi->lgi_cookie.lgc_index = index;
/* update header */
- rc = llog_write_rec(env, loghandle, &llh->llh_hdr, NULL,
+ rc = llog_write_rec(env, loghandle, &llh->llh_hdr, &lgi->lgi_cookie,
LLOG_HEADER_IDX, th);
- if (rc == 0)
- loghandle->lgh_hdr->llh_count--;
- else
+ if (rc != 0) {
+ loghandle->lgh_hdr->llh_count++;
ext2_set_bit(index, LLOG_HDR_BITMAP(llh));
+ GOTO(out_unlock, rc);
+ }
if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) &&
(llh->llh_count == 1) &&
if (idx == LLOG_HEADER_IDX) {
/* llog header update */
+ __u32 *bitmap = LLOG_HDR_BITMAP(llh);
+
lgi->lgi_off = 0;
- lgi->lgi_buf.lb_len = reclen;
- lgi->lgi_buf.lb_buf = rec;
+
+ /* If it does not indicate the bitmap index
+ * (reccookie == NULL), then it means update
+ * the whole update header. Otherwise only
+ * update header and bits needs to be updated,
+ * and in DNE cases, it will signaficantly
+ * shrink the RPC size.
+ * see distribute_txn_cancel_records()*/
+ if (reccookie == NULL) {
+ lgi->lgi_buf.lb_len = reclen;
+ lgi->lgi_buf.lb_buf = rec;
+ rc = dt_record_write(env, o, &lgi->lgi_buf,
+ &lgi->lgi_off, th);
+ RETURN(rc);
+ }
+
+ /* update the header */
+ lgi->lgi_buf.lb_len = llh->llh_bitmap_offset;
+ lgi->lgi_buf.lb_buf = llh;
rc = dt_record_write(env, o, &lgi->lgi_buf,
&lgi->lgi_off, th);
+ if (rc != 0)
+ RETURN(rc);
+
+ /* update the bitmap */
+ index = reccookie->lgc_index;
+ lgi->lgi_off = llh->llh_bitmap_offset +
+ (index / (sizeof(*bitmap) * 8)) *
+ sizeof(*bitmap);
+ lgi->lgi_buf.lb_len = sizeof(*bitmap);
+ lgi->lgi_buf.lb_buf =
+ &bitmap[index/(sizeof(*bitmap)*8)];
+ rc = dt_record_write(env, o, &lgi->lgi_buf,
+ &lgi->lgi_off, th);
+
RETURN(rc);
} else if (loghandle->lgh_cur_idx > 0) {
/**