Imported reiserfsprogs-3.6.9
This commit is contained in:
1 parent
99c89460c3
commit
cccefa4d84
86 files changed
+13393
-6954
No files matched your search
+297
-185
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2002 Hans Reiser
|
||||
* Copyright 2002-2003 by Hans Reiser, licensing governed by
|
||||
* reiserfsprogs/README
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@@ -53,12 +54,57 @@ unsigned long next_desc_expected (reiserfs_filsys_t * fs, struct buffer_head * d
|
||||
((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;
|
||||
|
||||
/**/
|
||||
int is_valid_transaction (reiserfs_filsys_t * fs, struct buffer_head * d_bh)
|
||||
{
|
||||
struct buffer_head * c_bh;
|
||||
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;
|
||||
@@ -67,13 +113,12 @@ int is_valid_transaction (reiserfs_filsys_t * fs, struct buffer_head * d_bh)
|
||||
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)) {
|
||||
brelse (c_bh);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!does_desc_match_commit (d_bh, c_bh))
|
||||
ret = 0;
|
||||
|
||||
brelse (c_bh);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +147,7 @@ int get_boundary_transactions (reiserfs_filsys_t * fs,
|
||||
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 (!is_valid_transaction (fs, d_bh)) {
|
||||
if (!transaction_check_desc (fs, d_bh)) {
|
||||
brelse (d_bh);
|
||||
continue;
|
||||
}
|
||||
@@ -158,9 +203,12 @@ int next_transaction (reiserfs_filsys_t * fs, reiserfs_trans_t * trans, reiserfs
|
||||
|
||||
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 (!is_valid_transaction (fs, d_bh))
|
||||
if (!transaction_check_desc (fs, d_bh))
|
||||
die ("next_transaction: valid transaction is expected");
|
||||
|
||||
block = next_desc_expected (fs, d_bh);
|
||||
@@ -168,7 +216,7 @@ int next_transaction (reiserfs_filsys_t * fs, reiserfs_trans_t * trans, reiserfs
|
||||
|
||||
while (1) {
|
||||
next_d_bh = bread (fs->fs_journal_dev, block, fs->fs_blocksize);
|
||||
if (is_valid_transaction (fs, next_d_bh))
|
||||
if (transaction_check_desc (fs, next_d_bh))
|
||||
break;
|
||||
|
||||
brelse (next_d_bh);
|
||||
@@ -196,7 +244,7 @@ int next_transaction (reiserfs_filsys_t * fs, reiserfs_trans_t * trans, reiserfs
|
||||
return found;
|
||||
}
|
||||
|
||||
static void read_journal_write_in_place (reiserfs_filsys_t * fs, reiserfs_trans_t * trans, int index,
|
||||
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;
|
||||
@@ -234,11 +282,9 @@ void for_each_block (reiserfs_filsys_t * fs, reiserfs_trans_t * trans,
|
||||
struct reiserfs_journal_desc * desc;
|
||||
struct reiserfs_journal_commit * commit;
|
||||
unsigned long j_start, j_offset, j_size;
|
||||
int i;
|
||||
unsigned int i, trans_half;
|
||||
unsigned long block;
|
||||
int trans_half;
|
||||
|
||||
|
||||
|
||||
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);
|
||||
@@ -295,31 +341,16 @@ void for_each_transaction (reiserfs_filsys_t * fs, action_on_trans_t action)
|
||||
|
||||
while (1) {
|
||||
action (fs, &oldest);
|
||||
if ((ret == TRANS_LAST) || ((ret = next_transaction (fs, &oldest, newest)) == TRANS_NOT_FOUND) )
|
||||
if (ret == TRANS_LAST)
|
||||
break;
|
||||
ret = next_transaction (fs, &oldest, newest);
|
||||
if (ret == TRANS_NOT_FOUND)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* user is allowed to specify journal size and ratio between journal size and
|
||||
max trans len. Max batch is calculated as 9/10 of max trans len. Max commit
|
||||
and trans ages are not tunable so far */
|
||||
static __u32 advise_journal_length (reiserfs_filsys_t * fs, __u32 desired)
|
||||
{
|
||||
if (!desired)
|
||||
return journal_default_size (fs->fs_super_bh->b_blocknr, fs->fs_blocksize);
|
||||
|
||||
if (desired < JOURNAL_MIN_SIZE + 1) {
|
||||
reiserfs_warning (stderr, "WARNING: Journal length is too small %u, resetting to minimal possible %u\n",
|
||||
desired, JOURNAL_MIN_SIZE + 1);
|
||||
return JOURNAL_MIN_SIZE;
|
||||
}
|
||||
|
||||
return desired;
|
||||
}
|
||||
|
||||
|
||||
unsigned long get_size_of_journal_or_reserved_area (struct reiserfs_super_block * sb)
|
||||
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);
|
||||
@@ -329,13 +360,14 @@ unsigned long get_size_of_journal_or_reserved_area (struct reiserfs_super_block
|
||||
}
|
||||
|
||||
|
||||
__u32 advise_journal_max_trans_len (__u32 desired, __u32 journal_size, int blocksize)
|
||||
__u32 advise_journal_max_trans_len (__u32 desired, __u32 journal_size /* no j_header */,
|
||||
int blocksize, int verbose)
|
||||
{
|
||||
__u32 saved;
|
||||
__u32 ratio = 1;
|
||||
__u32 ratio = 1;
|
||||
|
||||
if (blocksize < 4096)
|
||||
ratio = 4096/blocksize;
|
||||
if (blocksize < 4096)
|
||||
ratio = 4096/blocksize;
|
||||
|
||||
saved = desired;
|
||||
if (!desired)
|
||||
@@ -350,10 +382,13 @@ __u32 advise_journal_max_trans_len (__u32 desired, __u32 journal_size, int block
|
||||
if (desired < JOURNAL_TRANS_MIN/ratio)
|
||||
desired = JOURNAL_TRANS_MIN/ratio;
|
||||
|
||||
if (saved && saved != desired)
|
||||
if (verbose) {
|
||||
if (saved && saved != desired)
|
||||
reiserfs_warning (stderr,
|
||||
"WARNING: wrong transaction "
|
||||
"max size (%u). Changed to %u\n", saved, desired);
|
||||
"WARNING: wrong transaction max size (%u). Changed to %u\n",
|
||||
saved, desired);
|
||||
}
|
||||
|
||||
return desired;
|
||||
}
|
||||
#if 0
|
||||
@@ -391,21 +426,64 @@ __u32 advise_journal_max_trans_age (void)
|
||||
}
|
||||
|
||||
|
||||
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 ||
|
||||
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 buffer_head * bh;
|
||||
struct reiserfs_journal_header * j_head;
|
||||
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 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
j_filename = fs->fs_file_name;
|
||||
@@ -414,58 +492,55 @@ int reiserfs_open_journal (reiserfs_filsys_t * fs, char * j_filename, int flags)
|
||||
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 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
fs->fs_journal_dev = open (j_filename, flags | O_LARGEFILE);
|
||||
if (fs->fs_journal_dev == -1)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
|
||||
asprintf (&fs->fs_j_file_name, "%s", j_filename);
|
||||
|
||||
/* read journal header */
|
||||
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 (!bh) {
|
||||
reiserfs_warning (stderr, "reiserfs_open_journal: bread failed reading "
|
||||
"journal header\n");
|
||||
return 0;
|
||||
|
||||
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).\nRun --rebuild-sb to rebuild journal "
|
||||
"parameters.\n", get_jp_journal_size (sb_jp (sb)) + 1, j_filename,
|
||||
JOURNAL_MIN_SIZE + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
j_head = (struct reiserfs_journal_header *)(bh->b_data);
|
||||
|
||||
if (is_reiserfs_jr_magic_string (sb)) {
|
||||
if (get_jp_journal_1st_block (&j_head->jh_journal) != get_jp_journal_1st_block (sb_jp (sb)) ||
|
||||
get_jp_journal_dev (&j_head->jh_journal) != get_jp_journal_dev (sb_jp (sb)) ||
|
||||
get_jp_journal_size (&j_head->jh_journal) != get_jp_journal_size (sb_jp (sb)))
|
||||
{
|
||||
reiserfs_warning (stderr, "reiserfs_open_journal: no journal found on %s\n", j_filename);
|
||||
brelse (bh);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (get_jp_journal_dev (sb_jp(sb)) != 0 ||
|
||||
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, "reiserfs_open_journal: wrong journal parameters found in the super block.\n");
|
||||
brelse (bh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
count = count_blocks (j_filename, fs->fs_blocksize);
|
||||
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"
|
||||
"Run --rebuild-sb to rebuild journal parameters.\n",
|
||||
get_jp_journal_1st_block(sb_jp (sb)), get_jp_journal_size(sb_jp (sb)) + 1,
|
||||
count);
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs->fs_jh_bh = bh;
|
||||
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_filename,
|
||||
unsigned long offset,
|
||||
unsigned long len, /* journal size including journal header */
|
||||
int transaction_max_size)
|
||||
/* 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;
|
||||
@@ -473,113 +548,126 @@ int reiserfs_create_journal (reiserfs_filsys_t * fs, char * j_filename,
|
||||
struct reiserfs_super_block * sb;
|
||||
unsigned long blocks;
|
||||
|
||||
|
||||
sb = fs->fs_ondisk_sb;
|
||||
|
||||
|
||||
if (!j_filename || !strcmp (j_filename, fs->fs_file_name)) {
|
||||
/* journal is to be on a host device, make sure that there is enough
|
||||
space for it */
|
||||
if (!len)
|
||||
len = journal_default_size (fs->fs_super_bh->b_blocknr, fs->fs_blocksize) + 1;
|
||||
|
||||
if (!is_block_count_correct (
|
||||
fs->fs_super_bh->b_blocknr, fs->fs_blocksize, get_sb_block_count (sb), len - 1)) {
|
||||
// if (get_sb_block_count (sb) < min_block_amount (fs->fs_blocksize, len)) {
|
||||
/* host device does not contain enough blocks */
|
||||
reiserfs_warning (stderr, "reiserfs_create_journal: "
|
||||
"cannot create filesystem on %d blocks\n",
|
||||
get_sb_block_count (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_filename = fs->fs_file_name;
|
||||
|
||||
/* journal is not on a separate device starts after super block and first
|
||||
bitmap. offset is ignored */
|
||||
offset = get_journal_start_must (fs);
|
||||
|
||||
j_device = fs->fs_file_name;
|
||||
|
||||
|
||||
st.st_rdev = 0;
|
||||
} else {
|
||||
/* journal is to be on separate device */
|
||||
blocks = count_blocks (j_filename, fs->fs_blocksize);
|
||||
blocks = count_blocks (j_device, fs->fs_blocksize);
|
||||
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;
|
||||
/* 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)
|
||||
reiserfs_warning (stderr,
|
||||
"NOTE: journal new size %lu is greater than default size %lu:\n"
|
||||
"this may slow down journal initializing and mounting. Hope it is ok.\n\n",
|
||||
len, journal_default_size (fs->fs_super_bh->b_blocknr, fs->fs_blocksize) + 1);
|
||||
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;
|
||||
reiserfs_warning (stderr, "reiserfs_create_journal: no enough "
|
||||
"blocks on device %lu, needed %lu\n", blocks, offset + len);
|
||||
return 0;
|
||||
}
|
||||
if (stat (j_filename, &st) == -1) {
|
||||
reiserfs_warning (stderr, "reiserfs_create_journal: "
|
||||
"stat %s failed: %m\n", j_filename);
|
||||
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_filename, st.st_rdev);
|
||||
"%s is not a block device (%x)\n", j_device, st.st_rdev);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
fs->fs_journal_dev = open (j_filename, O_RDWR | O_LARGEFILE);
|
||||
fs->fs_journal_dev = open (j_device, O_RDWR | O_LARGEFILE);
|
||||
if (fs->fs_journal_dev == -1) {
|
||||
reiserfs_warning (stderr, "reiserfs_create_journal: could not open %s: %m\n",
|
||||
j_filename);
|
||||
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_filename);
|
||||
|
||||
len = advise_journal_length (fs, len - 1) + 1;
|
||||
asprintf (&fs->fs_j_file_name, "%s", j_device);
|
||||
|
||||
if (len < JOURNAL_MIN_SIZE) {
|
||||
reiserfs_warning (stderr, "WARNING: Journal size (%u) is less, than "
|
||||
"minimal supported journal size (%u).", 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");
|
||||
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_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));
|
||||
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 ());
|
||||
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;
|
||||
@@ -601,7 +689,7 @@ void reiserfs_reopen_journal (reiserfs_filsys_t * fs, int flag)
|
||||
flush_buffers (fs->fs_journal_dev);
|
||||
invalidate_buffers (fs->fs_journal_dev);
|
||||
if (close (fs->fs_journal_dev))
|
||||
die ("reiserfs_reopen_journal: closed failed: %m");
|
||||
die ("reiserfs_reopen_journal: closed failed: %s", strerror(errno));
|
||||
|
||||
fs->fs_journal_dev = open (fs->fs_j_file_name, flag | O_LARGEFILE);
|
||||
if (fs->fs_journal_dev == -1)
|
||||
@@ -665,7 +753,7 @@ 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 = 0;
|
||||
int replayed, ret;
|
||||
|
||||
if (!reiserfs_journal_opened (fs))
|
||||
reiserfs_panic ("replay_journal: journal is not opened");
|
||||
@@ -686,29 +774,53 @@ int replay_journal (reiserfs_filsys_t * fs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (control.mount_id != newest.mount_id) {
|
||||
reiserfs_warning (stderr, "Journal header's mountid: %lu\n"
|
||||
"latest transaction found is of mountid %lu\n", control.mount_id, newest.mount_id);
|
||||
if (user_confirmed (stderr, "Should those transactions be replayed?(Y/n)[n]", "Y\n")) {
|
||||
control.mount_id = newest.mount_id;
|
||||
// control.trans_id = 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;
|
||||
while (1) {
|
||||
if (cur.mount_id == control.mount_id && cur.trans_id > control.trans_id) {
|
||||
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 (bh, cur);
|
||||
replayed ++;
|
||||
}
|
||||
if ((ret == TRANS_LAST) || ((ret = next_transaction (fs, &cur, newest)) == TRANS_NOT_FOUND) )
|
||||
ret = TRANS_FOUND;
|
||||
|
||||
while (cur.mount_id != control.mount_id || cur.trans_id != control.trans_id) {
|
||||
if (control.mount_id == cur.mount_id && control.trans_id == 0 &&
|
||||
control.desc_blocknr == 0)
|
||||
break;
|
||||
|
||||
ret = next_transaction (fs, &cur, newest);
|
||||
|
||||
if (ret != TRANS_FOUND)
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret == TRANS_FOUND) {
|
||||
if (control.mount_id != cur.mount_id || control.trans_id != 0 ||
|
||||
control.desc_blocknr != 0)
|
||||
{
|
||||
ret = next_transaction (fs, &cur, newest);
|
||||
|
||||
if (ret == TRANS_NOT_FOUND)
|
||||
break;
|
||||
|
||||
if (cur.mount_id != control.mount_id || cur.trans_id != control.trans_id + 1)
|
||||
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 (bh, cur);
|
||||
control = cur;
|
||||
replayed ++;
|
||||
}
|
||||
|
||||
reiserfs_warning (stderr, "%d transactions replayed\n", replayed);
|
||||
|
||||
mark_buffer_dirty (fs->fs_super_bh);
|
||||
|
||||
Reference in new issue
Block a user