⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 journal.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2002-2004 by Hans Reiser, licensing governed by  * reiserfsprogs/README */#define _GNU_SOURCE#include "includes.h"/* compares description block with commit block. returns 0 if they differ, 1   if they match */static int does_desc_match_commit (struct buffer_head *d_bh, 			    struct buffer_head *c_bh) {    return (get_commit_trans_id (c_bh) == get_desc_trans_id (d_bh) &&	    get_commit_trans_len (c_bh) == get_desc_trans_len (d_bh));}/* d_bh is descriptor, return number of block where commit block of this   transaction is to be */unsigned long commit_expected (reiserfs_filsys_t * fs, struct buffer_head * d_bh){    unsigned long offset;    struct journal_params * sb_jp;    sb_jp = sb_jp (fs->fs_ondisk_sb);    //desc = (struct reiserfs_journal_desc *)d_bh->b_data;    offset = d_bh->b_blocknr - get_jp_journal_1st_block (sb_jp);    return get_jp_journal_1st_block (sb_jp) + 	((offset + get_desc_trans_len (d_bh) + 1) % get_jp_journal_size (sb_jp));}/* d_bh contains journal descriptor, returns number of block where descriptor   block of next transaction should be */unsigned long next_desc_expected (reiserfs_filsys_t * fs, struct buffer_head * d_bh){    unsigned long offset;    struct journal_params * sb_jp;    sb_jp = sb_jp (fs->fs_ondisk_sb);    //desc = (struct reiserfs_journal_desc *)d_bh->b_data;    offset = d_bh->b_blocknr - get_jp_journal_1st_block (sb_jp);    return get_jp_journal_1st_block (sb_jp) + 	((offset + get_desc_trans_len (d_bh) + 2) % get_jp_journal_size (sb_jp));}/* common checks for validness of a transaction */int transaction_check_content (reiserfs_filsys_t * fs, reiserfs_trans_t * trans) {    struct buffer_head *d_bh, *c_bh;    struct reiserfs_journal_desc * desc;    struct reiserfs_journal_commit * commit;    unsigned long block;    unsigned int trans_half, i;    d_bh = bread (fs->fs_journal_dev, trans->desc_blocknr, fs->fs_blocksize);    if (!d_bh || who_is_this (d_bh->b_data, d_bh->b_size) != THE_JDESC)	goto error_desc_brelse;    /* read expected commit block and compare with descriptor block */    c_bh = bread (fs->fs_journal_dev, commit_expected (fs, d_bh), fs->fs_blocksize);    if (!c_bh)	goto error_desc_brelse;     if (!does_desc_match_commit (d_bh, c_bh)) 	goto error_commit_brelse;    /* Check that all target blocks are journalable */    desc = (struct reiserfs_journal_desc *)(d_bh->b_data);    commit = (struct reiserfs_journal_commit *)(c_bh->b_data);    trans_half = journal_trans_half (d_bh->b_size);    for (i = 0; i < get_desc_trans_len(d_bh); i++) {	if (i < trans_half)	    block = le32_to_cpu (desc->j2_realblock[i]);	else	    block = le32_to_cpu (commit->j3_realblock[i - trans_half]);	if (not_journalable(fs, block)) 	    goto error_commit_brelse;    }        brelse (d_bh);    brelse (c_bh);    return 1;    error_commit_brelse:    brelse (c_bh);error_desc_brelse:    brelse(d_bh);    return 0;}/* common checks for validness of a transaction */int transaction_check_desc(reiserfs_filsys_t * fs, struct buffer_head * d_bh) {    struct buffer_head * c_bh;    int ret = 1;    if (!d_bh || who_is_this (d_bh->b_data, d_bh->b_size) != THE_JDESC)	return 0;    /* read expected commit block and compare with descriptor block */    c_bh = bread (fs->fs_journal_dev, commit_expected (fs, d_bh), fs->fs_blocksize);    if (!c_bh)	return 0;     if (!does_desc_match_commit (d_bh, c_bh)) 	ret = 0;    brelse (c_bh);    return ret;}/* read the journal and find the oldest and newest transactions, return number   of transactions found */int get_boundary_transactions (reiserfs_filsys_t * fs,			       reiserfs_trans_t * oldest,			       reiserfs_trans_t * newest){    struct reiserfs_super_block * sb;    unsigned long j_cur;    unsigned long j_start;    unsigned long j_size;    struct buffer_head * d_bh;    __u32 newest_trans_id, oldest_trans_id, trans_id;    int trans_nr;    sb = fs->fs_ondisk_sb;        j_start = get_jp_journal_1st_block (sb_jp (sb));    j_size = get_jp_journal_size (sb_jp (sb));        oldest_trans_id = 0xffffffff;    newest_trans_id = 0;    trans_nr = 0;    for (j_cur = 0; j_cur < j_size; j_cur ++) {	d_bh = bread (fs->fs_journal_dev, j_start + j_cur, fs->fs_blocksize);	if (!transaction_check_desc (fs, d_bh)) {	    brelse (d_bh);	    continue;	}	trans_nr ++;	trans_id = get_desc_trans_id (d_bh);	if (trans_id < oldest_trans_id) {	    oldest_trans_id = trans_id;	    oldest->mount_id = get_desc_mount_id (d_bh);	    oldest->trans_id = get_desc_trans_id (d_bh);	    oldest->desc_blocknr = d_bh->b_blocknr;	    oldest->trans_len = get_desc_trans_len (d_bh);	    oldest->commit_blocknr = commit_expected (fs, d_bh);	    oldest->next_trans_offset = next_desc_expected (fs, d_bh) - j_start;	}	if (trans_id > newest_trans_id) {	    newest_trans_id = trans_id;	    newest->mount_id = get_desc_mount_id (d_bh);	    newest->trans_id = get_desc_trans_id (d_bh);	    newest->desc_blocknr = d_bh->b_blocknr;	    newest->trans_len = get_desc_trans_len (d_bh);	    newest->commit_blocknr = commit_expected (fs, d_bh);	    newest->next_trans_offset = next_desc_expected (fs, d_bh) - j_start;	}	j_cur += get_desc_trans_len (d_bh) + 1;	brelse (d_bh);    }    return trans_nr;}#define TRANS_FOUND     1#define TRANS_NOT_FOUND 0/* trans is a valid transaction. Look for valid transaction with smallest   trans id which is greater than the id of the current one */int next_transaction (reiserfs_filsys_t * fs, reiserfs_trans_t * trans, reiserfs_trans_t break_trans){    struct buffer_head * d_bh, * next_d_bh;    int found;    unsigned long j_start;    unsigned long j_offset;    unsigned long block;    j_start = get_jp_journal_1st_block (sb_jp (fs->fs_ondisk_sb));    found = TRANS_NOT_FOUND;    if (trans->trans_id == break_trans.trans_id)	return found;	    /* make sure that 'trans' is a valid transaction */    d_bh = bread (fs->fs_journal_dev, trans->desc_blocknr, fs->fs_blocksize);    if (!transaction_check_desc (fs, d_bh))	die ("next_transaction: valid transaction is expected");    block = next_desc_expected (fs, d_bh);    j_offset = block - j_start;    while (1) {	next_d_bh = bread (fs->fs_journal_dev, block, fs->fs_blocksize);	if (transaction_check_desc (fs, next_d_bh))	    break;	brelse (next_d_bh);	j_offset ++;	block = j_start + (j_offset % get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)));    }    //next_desc = (struct reiserfs_journal_desc *)next_d_bh->b_data;        if (break_trans.trans_id >= get_desc_trans_id (next_d_bh)) {	/* found transaction is newer */	trans->mount_id = get_desc_mount_id (next_d_bh);	trans->trans_id = get_desc_trans_id (next_d_bh);	trans->desc_blocknr = next_d_bh->b_blocknr;	trans->trans_len = get_desc_trans_len (next_d_bh);	trans->commit_blocknr = commit_expected (fs, next_d_bh);	trans->next_trans_offset = next_desc_expected (fs, next_d_bh) - j_start;	found = TRANS_FOUND;    }    brelse (d_bh);    brelse (next_d_bh);    return found;}static void read_journal_write_in_place (reiserfs_filsys_t * fs, reiserfs_trans_t * trans, unsigned int index,                                          unsigned long in_journal, unsigned long in_place){    struct buffer_head * j_bh, * bh;    j_bh = bread (fs->fs_journal_dev, in_journal, fs->fs_blocksize);    if (!j_bh) {	fprintf (stderr, "replay_one_transaction: transaction %lu: reading %lu block failed\n",		 trans->trans_id, in_journal);	return;    }    if (not_journalable (fs, in_place)) {	fprintf (stderr, "replay_one_transaction: transaction %lu: block %ld should not be journalled (%lu)\n",		 trans->trans_id, in_journal, in_place);	brelse (j_bh);	return;    }    bh = getblk (fs->fs_dev, in_place, fs->fs_blocksize);        memcpy (bh->b_data, j_bh->b_data, bh->b_size);    mark_buffer_dirty (bh);    mark_buffer_uptodate (bh, 1);    bwrite (bh);    brelse (bh);    brelse (j_bh);    }/* go through all blocks of transaction and call 'action' each of them */void for_each_block (reiserfs_filsys_t * fs, reiserfs_trans_t * trans,		     action_on_block_t action){    struct buffer_head * d_bh, * c_bh;    struct reiserfs_journal_desc * desc;    struct reiserfs_journal_commit * commit;    unsigned long j_start, j_offset, j_size;    unsigned int i, trans_half;    unsigned long block;     d_bh = bread (fs->fs_journal_dev, trans->desc_blocknr, fs->fs_blocksize);    if (!d_bh) {	reiserfs_warning (stdout, "reading descriptor block %lu failed\n", trans->desc_blocknr);	return;    }    c_bh = bread (fs->fs_journal_dev, trans->commit_blocknr, fs->fs_blocksize);    if (!c_bh) {	reiserfs_warning (stdout, "reading commit block %lu failed\n", trans->commit_blocknr);	brelse (d_bh);	return;    }    desc = (struct reiserfs_journal_desc *)(d_bh->b_data);    commit = (struct reiserfs_journal_commit *)(c_bh->b_data);    /* first block of journal and size of journal */    j_start = get_jp_journal_1st_block (sb_jp (fs->fs_ondisk_sb));    j_size = get_jp_journal_size (sb_jp (fs->fs_ondisk_sb));    /* offset in the journal where the transaction starts */    j_offset = trans->desc_blocknr - j_start + 1;    trans_half = journal_trans_half (d_bh->b_size);    for (i = 0; i < trans->trans_len; i ++, j_offset ++) {	if (i < trans_half)	    block = le32_to_cpu (desc->j2_realblock[i]);	else	    block = le32_to_cpu (commit->j3_realblock[i - trans_half]);	action (fs, trans, i, j_start + (j_offset % j_size), block);    }    brelse (d_bh);    brelse (c_bh);}/* transaction is supposed to be valid */int replay_one_transaction (reiserfs_filsys_t * fs,			    reiserfs_trans_t * trans){    for_each_block (fs, trans, read_journal_write_in_place);    fsync(fs->fs_dev);    return 0;}void for_each_transaction (reiserfs_filsys_t * fs, action_on_trans_t action){    reiserfs_trans_t oldest, newest;    int ret = 0;    if (!get_boundary_transactions (fs, &oldest, &newest))	return;    while (1) {	action (fs, &oldest);		if ((ret = next_transaction (fs, &oldest, newest)) == TRANS_NOT_FOUND)	    break;    }}unsigned long get_size_of_journal_or_reserved_area(    struct reiserfs_super_block * sb){	if (is_reiserfs_jr_magic_string (sb))		return get_sb_reserved_for_journal (sb);	/* with standard journal */	return get_jp_journal_size (sb_jp (sb)) + 1;}__u32 advise_journal_max_trans_len (__u32 desired, __u32 journal_size /* no j_header */,     int blocksize, int verbose){    __u32 saved;    __u32 ratio = 1;    if (blocksize < 4096)	ratio = 4096/blocksize;	    saved = desired;    if (!desired)		desired = JOURNAL_TRANS_MAX/ratio;        if (journal_size / desired < JOURNAL_MIN_RATIO)		desired = journal_size / JOURNAL_MIN_RATIO;        if (desired > JOURNAL_TRANS_MAX/ratio)		desired = JOURNAL_TRANS_MAX/ratio;        if (desired < JOURNAL_TRANS_MIN/ratio)		desired = JOURNAL_TRANS_MIN/ratio;    if (verbose) {	if (saved && saved != desired)		reiserfs_warning (stderr,		    "WARNING: wrong transaction max size (%u). Changed to %u\n", 		    saved, desired);    }    return desired;}#if 0    __u32 ret_val;    ret_val = 0;    if (!desired)                   ret_val = JOURNAL_TRANS_MAX;    if (desired<journal_size/8)     ret_val = journal_size/8;    if (desired>journal_size/2)     ret_val = journal_size/2;    if (desired>JOURNAL_TRANS_MAX)  ret_val = JOURNAL_TRANS_MAX;    if (ret_val) {        reiserfs_warning (stderr, "WARNING: Journal max trans length is wrong seting: %u, resetting to available possible %u\n",                          desired, ret_val);    } else {        ret_val = desired;    }    return ret_val;}#endif__u32 advise_journal_max_batch (unsigned long journal_trans_max){    return journal_trans_max*JOURNAL_MAX_BATCH/JOURNAL_TRANS_MAX;}__u32 advise_journal_max_commit_age (void){    return JOURNAL_MAX_COMMIT_AGE;}__u32 advise_journal_max_trans_age (void){    return JOURNAL_MAX_TRANS_AGE;}int reiserfs_journal_params_check (reiserfs_filsys_t * fs) {    struct reiserfs_journal_header * j_head;    struct reiserfs_super_block * sb = fs->fs_ondisk_sb;        j_head = (struct reiserfs_journal_header *)(fs->fs_jh_bh->b_data);	    /* Check the superblock's journal parameters. */    if (!is_reiserfs_jr_magic_string (sb)) {    	if (get_jp_journal_dev (sb_jp(sb)) != 0 || 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -