📄 journal40.c
字号:
/* Copyright (C) 2001-2005 by Hans Reiser, licensing governed by reiser4progs/COPYING. journal40.c -- reiser4 journal plugin. */#ifndef ENABLE_MINIMAL#include "journal40.h"#include "journal40_repair.h"static uint32_t journal40_get_state(reiser4_journal_ent_t *entity) { aal_assert("umka-2081", entity != NULL); return PLUG_ENT(entity)->state;}static void journal40_set_state(reiser4_journal_ent_t *entity, uint32_t state){ aal_assert("umka-2082", entity != NULL); PLUG_ENT(entity)->state = state;}static errno_t journal40_valid(reiser4_journal_ent_t *entity) { aal_assert("umka-965", entity != NULL); return 0;}/* Journal enumerator function. */static errno_t journal40_layout(reiser4_journal_ent_t *entity, region_func_t region_func, void *data){ blk_t blk; aal_assert("umka-1040", entity != NULL); aal_assert("umka-1041", region_func != NULL); blk = JOURNAL40_BLOCKNR(PLUG_ENT(entity)->blksize); return region_func(blk, 2, data);}aal_device_t *journal40_device(reiser4_journal_ent_t *entity) { aal_assert("vpf-455", entity != NULL); return PLUG_ENT(entity)->device;}/* Helper function fetching journal footer and header. */static errno_t cb_fetch_journal(blk_t start, count_t width, void *data) { journal40_t *journal = (journal40_t *)data; /* Load journal header. */ if (!(journal->header = aal_block_load(journal->device, journal->blksize, start))) { aal_error("Can't read journal header from block " "%llu. %s.", start, journal->device->error); return -EIO; } /* Load journal footer. */ if (!(journal->footer = aal_block_load(journal->device, journal->blksize, start + 1))) { aal_error("Can't read journal footer from block %llu. %s.", start + 1, journal->device->error); aal_block_free(journal->header); return -EIO; } return 0;}/* Open journal on passed @format entity, @start and @blocks. Uses passed @desc for getting device journal is working on and fs block size. */static reiser4_journal_ent_t *journal40_open(aal_device_t *device, uint32_t blksize, reiser4_format_ent_t *format, reiser4_oid_ent_t *oid, uint64_t start, uint64_t blocks){ journal40_t *journal; aal_assert("umka-409", device != NULL); aal_assert("umka-1692", format != 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; /* Calling journal enumerator in order to fetch journal header and footer. */ if (journal40_layout((reiser4_journal_ent_t *)journal, cb_fetch_journal, journal)) { aal_error("Can't open journal header/footer."); goto error_free_journal; } return (reiser4_journal_ent_t *)journal; error_free_journal: aal_free(journal); return NULL;}/* Helper function for creating empty journal header and footer. Used in journal create time. */static errno_t cb_alloc_journal(blk_t start, count_t width, void *data) { journal40_t *journal = (journal40_t *)data; if (!(journal->header = aal_block_alloc(journal->device, journal->blksize, start))) { aal_error("Can't alloc journal header on " "block %llu.", start); return -ENOMEM; } if (!(journal->footer = aal_block_alloc(journal->device, journal->blksize, start + 1))) { aal_error("Can't alloc journal footer " "on block %llu.", start + 1); aal_block_free(journal->header); return -ENOMEM; } aal_block_fill(journal->header, 0); aal_block_fill(journal->footer, 0); return 0;}/* Create journal entity on passed params. Return create instance to caller. */static reiser4_journal_ent_t *journal40_create(aal_device_t *device, uint32_t blksize, reiser4_format_ent_t *format, reiser4_oid_ent_t *oid, uint64_t start, uint64_t blocks){ journal40_t *journal; aal_assert("umka-1057", device != NULL); aal_assert("umka-1691", format != NULL); /* Initializing journal entity. Making it dirty. Setting up all fields. */ if (!(journal = aal_calloc(sizeof(*journal), 0))) return NULL; journal->format = format; journal->oid = oid; journal->area.len = blocks; journal->area.start = start; journal->device = device; journal->plug = &journal40_plug; journal->blksize = blksize; journal40_mkdirty(journal); /* Create journal header and footer. */ if (journal40_layout((reiser4_journal_ent_t *)journal, cb_alloc_journal, journal)) { aal_error("Can't create journal header/footer."); goto error_free_journal; } return (reiser4_journal_ent_t *)journal; error_free_journal: aal_free(journal); return NULL;}/* Helper function for save jopurnal header and footer to device journal is working on. */static errno_t cb_sync_journal(blk_t start, count_t width, void *data) { journal40_t *journal = (journal40_t *)data; if (aal_block_write(journal->header)) { aal_error("Can't write journal header. %s.", journal->device->error); return -EIO; } if (aal_block_write(journal->footer)) { aal_error("Can't write journal footer. %s.", journal->device->error); return -EIO; } return 0;}/* Save journal metadata to device. */static errno_t journal40_sync(reiser4_journal_ent_t *entity) { errno_t res; aal_assert("umka-410", entity != NULL); if ((res = journal40_layout(entity, cb_sync_journal, entity))) return res; journal40_mkclean(entity); return 0;}/* Update header/footer fields. Used from journal40_replay() and from fsck related stuff. */static errno_t journal40_update(journal40_t *journal) { errno_t res = 0; aal_device_t *device; aal_block_t *tx_block; journal40_footer_t *footer; journal40_header_t *header; journal40_tx_header_t *tx_header; uint64_t last_commited_tx, last_flushed_tx; aal_assert("vpf-450", journal != NULL); aal_assert("vpf-451", journal->footer != NULL); aal_assert("vpf-452", journal->footer->data != NULL); aal_assert("vpf-453", journal->header != NULL); aal_assert("vpf-504", journal->header->data != NULL); aal_assert("vpf-454", journal->device != NULL); footer = JFOOTER(journal->footer); header = JHEADER(journal->header); last_commited_tx = get_jh_last_commited(header); last_flushed_tx = get_jf_last_flushed(footer); if (last_flushed_tx == last_commited_tx) return 0; device = journal->device; if (!(tx_block = aal_block_load(device, journal->blksize, last_commited_tx))) { aal_error("Can't read block %llu while updating " "the journal. %s.", last_commited_tx, device->error); return -EIO; } tx_header = (journal40_tx_header_t *)tx_block->data; if (aal_memcmp(tx_header->magic, TXH_MAGIC, TXH_MAGIC_SIZE)) { aal_error("Invalid transaction header has been detected."); res = -EINVAL; goto error_free_tx_block; } /* Updating journal footer */ set_jf_last_flushed(footer, last_commited_tx); set_jf_free_blocks(footer, get_th_free_blocks(tx_header)); set_jf_used_oids(footer, get_th_used_oids(tx_header)); set_jf_next_oid(footer, get_th_next_oid(tx_header)); journal40_mkdirty(journal); error_free_tx_block: aal_block_free(tx_block); return res;}static errno_t journal40_update_format(journal40_t *journal) { journal40_footer_t *footer; aal_assert("vpf-1582", journal != NULL); aal_assert("vpf-1583", journal->format != NULL); aal_assert("vpf-1584", journal->footer != NULL); aal_assert("vpf-1585", journal->footer->data != NULL); footer = JFOOTER(journal->footer); /* If there is no valid info, return. */ if (!get_jf_last_flushed(footer)) return 0; /* Some transaction passed, update format accordingly to the footer info. */ entcall(journal->format, set_free, get_jf_free_blocks(footer)); entcall(journal->oid, set_next, get_jf_next_oid(footer)); entcall(journal->oid, set_used, get_jf_used_oids(footer)); return 0;}/* Traverses one journal transaction. This is used for transactions replaying, checking, etc. */errno_t journal40_traverse_trans( reiser4_journal_ent_t *entity, /* journal object to be traversed */ aal_block_t *tx_block, /* trans header of a transaction */ journal40_han_func_t han_func, /* wandered/original pair callback */ journal40_sec_func_t sec_func, /* secondary blocks callback */ void *data) { errno_t res; uint64_t log_blk; uint32_t i, capacity; aal_device_t *device; journal40_t *journal;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -