📄 journal40_repair.c
字号:
if (ret) { /* Journal should be updated */ if (!jdata.cur_txh) { fsck_mess("Journal has broken list of transaction " "headers. Reinitialize the journal."); jdata.cur_txh = get_jf_last_flushed((journal40_footer_t *) journal->footer->data); } else { aal_block_t *tx_block = NULL; aal_device_t *device = NULL; /* jdata.cur_txh is the oldest problem transaction. Set the last_committed to the previous one. */ device = journal40_device((reiser4_journal_ent_t *)journal); if (device == NULL) { aal_error("Invalid device has been detected."); ret = -EINVAL; goto error_free_current; } tx_block = aal_block_load(device, journal->blksize, jdata.cur_txh); if (!tx_block) { aal_error("Can't read the block %llu while " "checking the journal. %s.", jdata.cur_txh, device->error); ret = -EIO; goto error_free_current; } txh = (journal40_tx_header_t *)tx_block->data; fsck_mess("Corrupted transaction (%llu) was found. " "The last valid transaction is (%llu).", jdata.cur_txh, get_th_prev_tx(txh)); jdata.cur_txh = get_th_prev_tx(txh); aal_block_free(tx_block); } header = (journal40_header_t *)journal->header->data; set_jh_last_commited(header, jdata.cur_txh); journal40_mkdirty(journal); } reiser4_bitmap_close(jdata.current_layout); reiser4_bitmap_close(jdata.journal_layout); return 0; error_free_current: reiser4_bitmap_close(jdata.current_layout); error_free_layout: reiser4_bitmap_close(jdata.journal_layout); return ret;}void journal40_invalidate(reiser4_journal_ent_t *entity) { journal40_t *journal = (journal40_t *)entity; journal40_footer_t *footer; journal40_header_t *header; aal_assert("vpf-1554", entity != NULL); footer = JFOOTER(journal->footer); header = JHEADER(journal->header); set_jh_last_commited(header, 0); set_jf_last_flushed(footer, 0); set_jf_free_blocks(footer, 0); set_jf_used_oids(footer, 0); set_jf_next_oid(footer, 0); journal40_mkdirty(journal);}/* Safely extracts string field from passed location. */static void extract_string(char *stor, char *orig, uint32_t max) { uint32_t i; for (i = 0; i < max; i++) { if (orig[i] == '\0') break; } aal_memcpy(stor, orig, i);}/* Helper function for printing transaction header. */static errno_t cb_print_txh(reiser4_journal_ent_t *entity, blk_t blk, void *data){ aal_block_t *block; journal40_t *journal; aal_stream_t *stream; char magic[TXH_MAGIC_SIZE]; journal40_tx_header_t *txh; if (blk == INVAL_BLK) return -EINVAL; stream = (aal_stream_t *)data; journal = (journal40_t *)entity; if (!(block = aal_block_load(journal->device, journal->blksize, blk))) { return -EIO; } txh = (journal40_tx_header_t *)block->data; aal_stream_format(stream, "Transaction header:\n"); aal_memset(magic, 0, sizeof(magic)); extract_string(magic, txh->magic, sizeof(magic)); aal_stream_format(stream, "magic:\t%s\n", magic); aal_stream_format(stream, "id: \t0x%llx\n", get_th_id(txh)); aal_stream_format(stream, "total:\t%lu\n", get_th_total(txh)); aal_stream_format(stream, "prev:\t%llu\n", get_th_prev_tx(txh)); aal_stream_format(stream, "next block:\t%llu\n", get_th_next_block(txh)); aal_stream_format(stream, "free blocks:\t%llu\n", get_th_free_blocks(txh)); aal_stream_format(stream, "used oids:\t%llu\n", get_th_used_oids(txh)); aal_stream_format(stream, "next oid:\t0x%llx\n\n", get_th_next_oid(txh)); aal_block_free(block); return 0;}/* Printing pair (wandered and original) blocks */static errno_t cb_print_par(reiser4_journal_ent_t *entity, aal_block_t *block, blk_t orig, void *data){ aal_stream_format((aal_stream_t *)data, "%llu -> %llu\n", orig, block->nr); return 0;}/* hellper function for printing log record. */static errno_t cb_print_lgr(reiser4_journal_ent_t *entity, aal_block_t *block, blk_t blk, journal40_block_t bel, void *data){ aal_stream_t *stream; char magic[LGR_MAGIC_SIZE]; journal40_lr_header_t *lgr; if (bel != JB_LGR) return 0; stream = (aal_stream_t *)data; lgr = (journal40_lr_header_t *)block->data; aal_stream_format(stream, "Log record:\n"); aal_memset(magic, 0, sizeof(magic)); extract_string(magic, lgr->magic, sizeof(magic)); aal_stream_format(stream, "magic:\t%s\n", magic); aal_stream_format(stream, "id: \t0x%llx\n", get_lh_id(lgr)); aal_stream_format(stream, "total:\t%lu\n", get_lh_total(lgr)); aal_stream_format(stream, "serial:\t0x%lx\n", get_lh_serial(lgr)); aal_stream_format(stream, "next block:\t%llu\n\n", get_lh_next_block(lgr)); return 0;}/* Prints journal structures into passed @stream */void journal40_print(reiser4_journal_ent_t *entity, aal_stream_t *stream, uint16_t options){ journal40_t *journal; journal40_footer_t *footer; journal40_header_t *header; aal_assert("umka-1465", entity != NULL); aal_assert("umka-1466", stream != NULL); journal = (journal40_t *)entity; /* Printing journal header and journal footer first */ header = JHEADER(journal->header); footer = JFOOTER(journal->footer); aal_stream_format(stream, "Journal:\n"); aal_stream_format(stream, "plugin: \t%s\n", entity->plug->p.label); aal_stream_format(stream, "description:\t%s\n\n", entity->plug->p.desc); aal_stream_format(stream, "Journal header block (%llu):\n", journal->header->nr); aal_stream_format(stream, "last commited:\t%llu\n\n", get_jh_last_commited(header)); aal_stream_format(stream, "Journal footer block (%llu):\n", journal->footer->nr); aal_stream_format(stream, "last flushed:\t%llu\n", get_jf_last_flushed(footer)); aal_stream_format(stream, "free blocks:\t%llu\n", get_jf_free_blocks(footer)); aal_stream_format(stream, "next oid:\t0x%llx\n", get_jf_next_oid(footer)); aal_stream_format(stream, "used oids:\t%llu\n", get_jf_used_oids(footer)); /* Print all transactions. */ journal40_traverse(entity, cb_print_txh, cb_print_par, cb_print_lgr, (void *)stream);}static errno_t journal40_block_pack(journal40_t *journal, aal_stream_t *stream, reiser4_bitmap_t *layout, uint64_t blk) { journal40_tx_header_t *txh; journal40_lr_header_t *lrh; journal40_lr_entry_t *lre; aal_block_t *block; uint32_t i, num; errno_t res; if (blk < journal->area.start || blk >= journal->area.len) return 0; if (reiser4_bitmap_test(layout, blk)) return 0; reiser4_bitmap_mark(layout, blk); if (!(block = aal_block_load(journal->device, journal->blksize, blk))) { aal_error("Can't read block %llu while traversing the journal." "%s.", blk, journal->device->error); return -EIO; } aal_stream_write(stream, BLOCK_PACK_SIGN, 4); aal_stream_write(stream, &block->nr, sizeof(block->nr)); aal_stream_write(stream, block->data, block->size); txh = (journal40_tx_header_t *)block->data; if (!aal_memcmp(txh->magic, TXH_MAGIC, TXH_MAGIC_SIZE)) { if ((res = journal40_block_pack(journal, stream, layout, get_th_next_block(txh)))) { goto done_block; } if ((res = journal40_block_pack(journal, stream, layout, get_th_prev_tx(txh)))) { goto done_block; } } lrh = (journal40_lr_header_t *)block->data; if (!aal_memcmp(lrh->magic, LGR_MAGIC, LGR_MAGIC_SIZE)) { lre = (journal40_lr_entry_t *)(lrh + 1); num = (journal->blksize - sizeof(*lrh)) / sizeof(*lre); for (i = 0; i < num; i++, lre++) { blk = get_le_wandered(lre); if (!blk) break; if ((res = journal40_block_pack(journal, stream, layout, blk))) { goto done_block; } } } aal_block_free(block); return 0; done_block: aal_block_free(block); return res;}errno_t journal40_pack(reiser4_journal_ent_t *entity, aal_stream_t *stream) { journal40_header_t *jheader; journal40_t *journal; reiser4_bitmap_t *layout; uint64_t blk; errno_t res; aal_assert("vpf-1745", entity != NULL); aal_assert("vpf-1746", stream != NULL); journal = (journal40_t *)entity; if (!(layout = reiser4_bitmap_create(journal->area.len))) { aal_error("Failed to allocate a control bitmap for " "journal layout."); return -ENOMEM; } jheader = (journal40_header_t *)journal->header->data; blk = get_jh_last_commited(jheader); aal_stream_write(stream, journal->header->data, journal->header->size); aal_stream_write(stream, journal->footer->data, journal->footer->size); /* Getting all blocks that are pointed by journal, do not control the journal structure. */ res = journal40_block_pack(journal, stream, layout, blk); reiser4_bitmap_close(layout); return res;}reiser4_journal_ent_t *journal40_unpack(aal_device_t *device, uint32_t blksize, reiser4_format_ent_t *format, reiser4_oid_ent_t *oid, uint64_t start, uint64_t blocks, aal_stream_t *stream) { journal40_t *journal; uint64_t read; blk_t jblk; aal_assert("vpf-1755", device != NULL); aal_assert("vpf-1756", format != NULL); aal_assert("vpf-1757", oid != NULL); /* Initializign journal entity. */ if (!(journal = aal_calloc(sizeof(*journal), 0))) return NULL; journal->state = 0; journal->format = format; journal->oid = oid; journal->device = device; journal->plug = &journal40_plug; journal->blksize = blksize; journal->area.len = blocks; journal->area.start = start; jblk = JOURNAL40_BLOCKNR(blksize); if (!(journal->header = aal_block_alloc(device, blksize, jblk))) { aal_error("Can't alloc journal header on block %llu.", jblk); goto error_free_journal; } if (!(journal->footer = aal_block_alloc(device, blksize, jblk + 1))) { aal_error("Can't alloc journal footer on block %llu.", jblk + 1); goto error_free_header; } read = aal_stream_read(stream, journal->header->data, blksize); journal->header->dirty = 1; if (read != blksize) { aal_error("Can't unpack journal header. Stream is over?"); goto error_free_footer; } read = aal_stream_read(stream, journal->footer->data, blksize); journal->footer->dirty = 1; if (read != blksize) { aal_error("Can't unpack journal footer. Stream is over?"); goto error_free_footer; } /* Other blocks are unpacked in reiser4_fs_unpack as usual blocks. */ journal40_mkdirty(journal); return (reiser4_journal_ent_t *)journal; error_free_footer: aal_block_free(journal->footer); error_free_header: aal_block_free(journal->header); error_free_journal: aal_free(journal); return NULL;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -