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

📄 journal.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 2 页
字号:
	    get_jp_journal_1st_block (sb_jp(sb)) != get_journal_start_must (fs) || 	    get_jp_journal_size (sb_jp(sb)) != 	    journal_default_size(fs->fs_super_bh->b_blocknr, fs->fs_blocksize))	{	    reiserfs_warning (stderr, 		"\nreiserfs_open_journal: wrong journal parameters found in the "		"super block. \nYou should run reiserfsck with --rebuild-sb to "		"check your superblock consistency.\n\n");			    return 1;	}    }	    if (memcmp(&j_head->jh_journal, sb_jp (sb), sizeof(struct journal_params))) {	if (!is_reiserfs_jr_magic_string (sb)) {	    reiserfs_warning (stderr, 		"\nreiserfs_open_journal: journal parameters from the superblock "		"does not match \nto the journal headers ones. It looks like that "		"you created your fs with old\nreiserfsprogs. Journal header is "		"fixed.\n\n", fs->fs_j_file_name);			    memcpy(&j_head->jh_journal, sb_jp(sb), sizeof(struct journal_params));	    mark_buffer_dirty(fs->fs_jh_bh);	    bwrite(fs->fs_jh_bh);	} else {	    reiserfs_warning (stderr,		"\nreiserfs_open_journal: journal parameters from the super block "		"does not match \nto journal parameters from the journal. You should "		"run  reiserfsck with --rebuild-sb to check your superblock consistency.\n\n");			    return 1;		}    }        return 0;}/* read journal header and make sure that it matches with the filesystem   opened */int reiserfs_open_journal (reiserfs_filsys_t * fs, char * j_filename, int flags) {    struct reiserfs_super_block * sb;    __u64 count;        sb = fs->fs_ondisk_sb;    if (!j_filename) {	/*        if (is_reiserfs_jr_magic_string (sb)) {            // create a special file to access journal            return 1;        } */		j_filename = fs->fs_file_name;    } else if (!is_reiserfs_jr_magic_string (sb)) {        /* make sure that name specified is a correct name */	if (strcmp (j_filename, fs->fs_file_name)) {	    reiserfs_warning (stderr, "Filesystem with standard journal found, "		"wrong name of specified journal device %s \n", j_filename);	    return 2;	}    }    fs->fs_journal_dev = open (j_filename, flags #if defined(O_LARGEFILE)			       | O_LARGEFILE#endif			       );    if (fs->fs_journal_dev == -1)         return -1;        asprintf (&fs->fs_j_file_name, "%s", j_filename);        if (get_jp_journal_size(sb_jp(sb)) < JOURNAL_MIN_SIZE) {	reiserfs_warning (stderr, "Journal of (%lu) block size found on "	    "specified journal device %s.\nMust be not less than (%lu).\n",	    get_jp_journal_size (sb_jp (sb)) + 1, j_filename, 	    JOURNAL_MIN_SIZE + 1);	close(fs->fs_journal_dev);	return 1;    }        if (!(count = count_blocks (j_filename, fs->fs_blocksize))) {	close(fs->fs_journal_dev);	return -1;    }    if (get_jp_journal_1st_block (sb_jp (sb)) + 	get_jp_journal_size (sb_jp (sb)) + 1 > count)     {	reiserfs_warning (stderr, "Detected journal on specified device %s "			  "does not fit to the device.\nStart block (%lu) + "			  "size (%lu) less than device size (%lu).\n", 			  j_filename, get_jp_journal_1st_block(sb_jp (sb)), 			  get_jp_journal_size(sb_jp (sb)) + 1, count);	close(fs->fs_journal_dev);	return 1;    }        /* read journal header */    fs->fs_jh_bh = bread (fs->fs_journal_dev, 			  get_jp_journal_1st_block (sb_jp (sb)) + 			  get_jp_journal_size (sb_jp (sb)), 			  fs->fs_blocksize);    if (!fs->fs_jh_bh) {	reiserfs_warning (stderr, "reiserfs_open_journal: bread failed "			  "reading journal  header.\n");	close(fs->fs_journal_dev);	return -1;    }    return 0;}/* initialize super block's journal related fields and journal header fields.  * If len is 0 - make journal of default size */int reiserfs_create_journal(    reiserfs_filsys_t * fs,     char * j_device,		/* journal device name */    unsigned long offset,	/* journal offset on the j_device */    unsigned long len,		/* including journal header */    int transaction_max_size){    struct stat st;    struct buffer_head * bh;    struct reiserfs_journal_header * jh;    struct reiserfs_super_block * sb;    unsigned long blocks;    sb = fs->fs_ondisk_sb;        if (!j_device || !strcmp (j_device, fs->fs_file_name)) {	/* Journal is to be on the host device, check the amount space for the 	 * journal on it. */	len = len ? len : journal_default_size(fs->fs_super_bh->b_blocknr, 	    fs->fs_blocksize) + 1;			offset = offset ? offset : get_journal_start_must(fs);		if (offset < get_journal_start_must(fs)) {	    reiserfs_warning (stderr, "reiserfs_create_journal: offset is "		"%lu, but it cannot be less then %llu on the device %s\n", 		offset, get_journal_start_must(fs), j_device);	    return 0;	}		if (!is_block_count_correct(offset, fs->fs_blocksize, 	    get_sb_block_count(sb), len)) 	{	    /* host device does not contain enough blocks */	    reiserfs_warning (stderr, "reiserfs_create_journal: cannot create "		"a journal of %lu blocks with %lu offset on %d blocks\n", 		len, offset, get_sb_block_count(sb));		return 0;	}		j_device = fs->fs_file_name;			st.st_rdev = 0;    } else {	/* journal is to be on separate device */	if (!(blocks = count_blocks (j_device, fs->fs_blocksize)))		return 0;	if (!len) {	    /* default size of a journal on a separate device is whole device */	    if (blocks < offset) {		reiserfs_warning (stderr, "reiserfs_create_journal: offset is "		    "%lu, blocks on device %lu\n", offset, blocks);		return 0;	    }	    len = blocks - offset;	}	if (len > journal_default_size (fs->fs_super_bh->b_blocknr, 	    fs->fs_blocksize) + 1) 	{	    fflush(stderr);	    	    reiserfs_warning (stdout, "NOTE: journal new size %lu is greater "		"than default size %lu:\nthis may slow down initializing and "		"mounting of the journal. Hope it is ok.\n\n", len, 		journal_default_size(fs->fs_super_bh->b_blocknr, 		fs->fs_blocksize) + 1);	}	if (blocks < offset + len) {	    reiserfs_warning (stderr, "reiserfs_create_journal: no enough "		"blocks on device %lu, needed %lu\n", blocks, offset + len);	    return 0;	}		if (stat (j_device, &st) == -1) {	    reiserfs_warning (stderr, "reiserfs_create_journal: stat %s failed"		": %s\n", j_device, strerror(errno));	    return 0;	}/*	if (!S_ISBLK (st.st_mode)) {		reiserfs_warning (stderr, "reiserfs_create_journal: "		"%s is not a block device (%x)\n", j_device, st.st_rdev);		return 0;	}*/    }    fs->fs_journal_dev = open (j_device, O_RDWR #if defined(O_LARGEFILE)			       | O_LARGEFILE#endif			       );    if (fs->fs_journal_dev == -1) {	reiserfs_warning (stderr, "reiserfs_create_journal: could not open "	    "%s: %s\n", j_device, strerror(errno));	return 0;    }    asprintf (&fs->fs_j_file_name, "%s", j_device);    if (len < JOURNAL_MIN_SIZE + 1) {	reiserfs_warning (stderr, "WARNING: Journal size (%u) is less, than "	    "minimal supported journal size (%u).\n", len, JOURNAL_MIN_SIZE + 1);        return 0;    }    /* get journal header */    bh = getblk (fs->fs_journal_dev, offset + len - 1, fs->fs_blocksize);    if (!bh) {	reiserfs_warning (stderr, "reiserfs_create_journal: getblk failed\n");	return 0;    }    /* fill journal header */    jh = (struct reiserfs_journal_header *)bh->b_data;    set_jp_journal_1st_block(&jh->jh_journal, offset);    set_jp_journal_dev(&jh->jh_journal, st.st_rdev);    set_jp_journal_magic(&jh->jh_journal, get_random());    set_jp_journal_size(&jh->jh_journal, len - 1);    set_jp_journal_max_trans_len(&jh->jh_journal, advise_journal_max_trans_len(	transaction_max_size, len - 1, fs->fs_blocksize, 1));    set_jp_journal_max_batch(&jh->jh_journal, advise_journal_max_batch(	get_jp_journal_max_trans_len(&jh->jh_journal)));    set_jp_journal_max_commit_age(&jh->jh_journal, 	advise_journal_max_commit_age());    set_jp_journal_max_trans_age(&jh->jh_journal, 	advise_journal_max_trans_age ());    mark_buffer_uptodate (bh, 1);    mark_buffer_dirty (bh);        fs->fs_jh_bh = bh;        /* make a copy of journal header in the super block */    memcpy (sb_jp (sb), &jh->jh_journal, sizeof (struct journal_params));    mark_buffer_dirty (fs->fs_super_bh);    return 1;}/* brelse journal header, flush all dirty buffers, close device, open, read   journal header */void reiserfs_reopen_journal (reiserfs_filsys_t * fs, int flag){    unsigned long jh_block;    if (!reiserfs_journal_opened (fs))	return;    jh_block = fs->fs_jh_bh->b_blocknr;    brelse (fs->fs_jh_bh);    flush_buffers (fs->fs_journal_dev);    invalidate_buffers (fs->fs_journal_dev);    if (close (fs->fs_journal_dev))	die ("reiserfs_reopen_journal: closed failed: %s", strerror(errno));    fs->fs_journal_dev = open (fs->fs_j_file_name, flag #if defined(O_LARGEFILE)			       | O_LARGEFILE#endif			       );    if (fs->fs_journal_dev == -1)	die ("reiserfs_reopen_journal: could not reopen journal device");    fs->fs_jh_bh = bread (fs->fs_journal_dev, jh_block, fs->fs_blocksize);    if (!fs->fs_jh_bh)	die ("reiserfs_reopen_journal: reading journal header failed");}int reiserfs_journal_opened (reiserfs_filsys_t * fs){    return fs->fs_jh_bh ? 1 : 0;}void reiserfs_flush_journal (reiserfs_filsys_t * fs){    if (!reiserfs_journal_opened (fs))		return;    flush_buffers (fs->fs_journal_dev);}void reiserfs_free_journal (reiserfs_filsys_t * fs){    if (!reiserfs_journal_opened (fs))		return;    brelse (fs->fs_jh_bh);    fs->fs_jh_bh = 0;    free (fs->fs_j_file_name);    fs->fs_j_file_name = 0;}void reiserfs_close_journal (reiserfs_filsys_t * fs){    reiserfs_flush_journal (fs);    reiserfs_free_journal (fs);}/* update journal header */static void update_journal_header (reiserfs_filsys_t * fs, 				   struct buffer_head * bh_jh, 				   reiserfs_trans_t *trans) {    struct reiserfs_journal_header * j_head;	    j_head = (struct reiserfs_journal_header *)(bh_jh->b_data);    /* update journal header */    set_jh_last_flushed (j_head, trans->trans_id);    set_jh_mount_id (j_head, trans->mount_id);    set_jh_replay_start_offset (j_head, trans->next_trans_offset);    mark_buffer_dirty (bh_jh);    bwrite (bh_jh);    fsync(fs->fs_journal_dev);}/* fixme: what should be done when not all transactions can be replayed in proper order? */int replay_journal (reiserfs_filsys_t * fs){    struct buffer_head * bh;    struct reiserfs_journal_header * j_head;    reiserfs_trans_t cur, newest, control;    int replayed, ret;    if (!reiserfs_journal_opened (fs))        reiserfs_panic ("replay_journal: journal is not opened");        if (!is_opened_rw (fs))        reiserfs_panic ("replay_journal: fs is not opened with write perms");    reiserfs_warning (stderr, "Replaying journal..\n");    bh = fs->fs_jh_bh;	    j_head = (struct reiserfs_journal_header *)(bh->b_data);    control.mount_id = get_jh_mount_id (j_head);    control.trans_id = get_jh_last_flushed (j_head);    control.desc_blocknr = get_jh_replay_start_offset (j_head);    if (!get_boundary_transactions (fs, &cur, &newest)) {	reiserfs_warning (stderr, "No transactions found\n");	return 0;    }    /*  Smth strange with journal header or journal. We cannot say for sure what was the last 	replaied transaction, but relying on JH data is preferable. */    replayed = 0;    ret = TRANS_FOUND;        /* Looking to the first valid not replayed transaction. */    while (1) {	if (cur.mount_id == control.mount_id && 	    cur.trans_id > control.trans_id)	    break;	if ((ret = next_transaction (fs, &cur, newest)) != TRANS_FOUND)	    break;    }        while (ret == TRANS_FOUND) {	/* If not the next transaction to be replayed, break out here. */	if ((cur.mount_id != control.mount_id) || 	    (cur.trans_id != control.trans_id + 1 && control.trans_id))	    break;		if (!transaction_check_content(fs, &cur)) {	    reiserfs_warning (stderr, "Trans broken: mountid %lu, transid %lu, desc %lu, "		"len %lu, commit %lu, next trans offset %lu\n", cur.mount_id, cur.trans_id, 		cur.desc_blocknr, cur.trans_len, cur.commit_blocknr, cur.next_trans_offset);	    break;	}        reiserfs_warning (stderr, "Trans replayed: mountid %lu, transid %lu, desc %lu, "            "len %lu, commit %lu, next trans offset %lu\n",	    cur.mount_id, cur.trans_id, cur.desc_blocknr, cur.trans_len,	    cur.commit_blocknr, cur.next_trans_offset);	replay_one_transaction (fs, &cur);	update_journal_header (fs, bh, &cur);	control = cur;        replayed ++;	ret = next_transaction (fs, &cur, newest);    }    reiserfs_warning (stderr, "Reiserfs journal '%s' in blocks [%u..%u]: %d "		      "transactions replayed\n", fs->fs_j_file_name, 		      get_jp_journal_1st_block(sb_jp(fs->fs_ondisk_sb)),		      get_jp_journal_1st_block(sb_jp(fs->fs_ondisk_sb)) + 		      get_jp_journal_size(sb_jp(fs->fs_ondisk_sb)) + 1,		      replayed);	    mark_buffer_dirty (fs->fs_super_bh);    bwrite (fs->fs_super_bh);	    update_journal_header (fs, bh, &newest);    return 0;}

⌨️ 快捷键说明

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