Imported reiserfsprogs-3.6.4

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:28:37 -04:00
1 parent b69459eb80
commit 99c89460c3
52 files changed
+2263 -2407

No files matched your search

+60 -130
View File
@@ -36,9 +36,7 @@ struct relocated {
struct relocated * relocated_list;
/* return objectid the object has to be remapped with */
__u32 objectid_for_relocation (struct key * key)
{
__u32 get_relocated_objectid_from_list (struct key * key) {
struct relocated * cur;
cur = relocated_list;
@@ -50,6 +48,17 @@ __u32 objectid_for_relocation (struct key * key)
return cur->new_objectid;
cur = cur->next;
}
return 0;
}
/* return objectid the object has to be remapped with */
__u32 objectid_for_relocation (struct key * key)
{
struct relocated * cur;
__u32 cur_id;
if ((cur_id = get_relocated_objectid_from_list (key)) != 0)
return cur_id;
cur = getmem (sizeof (struct relocated));
cur->old_dir_id = get_key_dirid (key);
@@ -57,16 +66,15 @@ __u32 objectid_for_relocation (struct key * key)
cur->new_objectid = get_unused_objectid (fs);
cur->next = relocated_list;
relocated_list = cur;
fsck_log ("relocation: (%K) is relocated to (%lu, %lu)\n",
key, get_key_dirid (key), cur->new_objectid);
/* fsck_log ("relocation: (%K) is relocated to (%lu, %lu)\n",
key, get_key_dirid (key), cur->new_objectid);*/
return cur->new_objectid;
}
/* this item is in tree. All unformatted pointer are correct. Do not
check them */
static void save_item_2 (struct si ** head, struct item_head * ih,
char * item, __u32 blocknr)
void save_item (struct si ** head, struct item_head * ih, char * item, __u32 blocknr)
{
struct si * si, * cur;
@@ -93,7 +101,7 @@ struct si * save_and_delete_file_item (struct si * si, struct path * path)
struct buffer_head * bh = PATH_PLAST_BUFFER (path);
struct item_head * ih = PATH_PITEM_HEAD (path);
save_item_2 (&si, ih, B_I_PITEM (bh, ih), bh->b_blocknr);
save_item (&si, ih, B_I_PITEM (bh, ih), bh->b_blocknr);
/* delete item temporary - do not free unformatted nodes */
reiserfsck_delete_item (path, 1/*temporary*/);
@@ -130,9 +138,6 @@ int should_relocate (struct item_head * ih)
break;
}
if (is_stat_data_ih (get_ih(&path)))
fix_obviously_wrong_sd_mode (&path);
path_ih = get_ih (&path);
if (not_of_one_file (&key, &(path_ih->ih_key))) {
/* there are no more item with this key */
@@ -140,6 +145,21 @@ int should_relocate (struct item_head * ih)
break;
}
if (is_stat_data_ih (path_ih)) {
fix_obviously_wrong_sd_mode (&path);
if (ih_checked (path_ih)) {
/* we have checked it already */
pathrelse (&path);
if (get_relocated_objectid_from_list (&path_ih->ih_key))
return 1; /* it was relocated */
break;
} else {
mark_ih_checked (path_ih);
mark_buffer_dirty (get_bh(&path));
}
}
/* ok, item found, but make sure that it is not a directory one */
if ((is_stat_data_ih (path_ih) && !not_a_directory (get_item (&path))) ||
(is_direntry_ih (path_ih))) {
@@ -155,95 +175,6 @@ int should_relocate (struct item_head * ih)
}
/* delete all items (but directory ones) with the same key 'ih' has
(including stat data of not a directory) and put them back at the
other place */
void relocate_file (struct item_head * ih, int change_ih)
{
struct key key;
struct key * rkey;
struct path path;
struct item_head * path_ih;
struct si * si;
__u32 new_objectid;
/* starting with the leftmost one - look for all items of file,
store them and delete */
key = ih->ih_key;
set_type_and_offset (KEY_FORMAT_1, &key, SD_OFFSET, TYPE_STAT_DATA);
si = 0;
while (1) {
reiserfs_search_by_key_4 (fs, &key, &path);
if (get_item_pos (&path) == B_NR_ITEMS (get_bh (&path))) {
rkey = uget_rkey (&path);
if (rkey && !not_of_one_file (&key, rkey)) {
/* file continues in the right neighbor */
key = *rkey;
pathrelse (&path);
continue;
}
/* there is no more items with this key */
pathrelse (&path);
break;
}
if (is_stat_data_ih (get_ih(&path)))
fix_obviously_wrong_sd_mode (&path);
path_ih = get_ih (&path);
if (not_of_one_file (&key, &(path_ih->ih_key))) {
/* there are no more item with this key */
pathrelse (&path);
break;
}
/* ok, item found, but make sure that it is not a directory one */
if ((is_stat_data_ih (path_ih) && !not_a_directory (get_item (&path))) ||
(is_direntry_ih (path_ih))) {
/* item of directory found. Leave it in the tree */
key = path_ih->ih_key;
set_offset (KEY_FORMAT_1, &key, get_offset (&key) + 1);
pathrelse (&path);
continue;
}
si = save_and_delete_file_item (si, &path);
}
if (si || change_ih) {
int moved_items;
struct key old, new;
/* get new objectid for relocation or get objectid with which file
was relocated already */
new_objectid = objectid_for_relocation (&ih->ih_key);
if (change_ih)
set_key_objectid (&ih->ih_key, new_objectid);
moved_items = 0;
/* put all items removed back into tree */
while (si) {
/*fsck_log ("relocate_file: move %H to ", &si->si_ih);*/
old = si->si_ih.ih_key;
set_key_objectid (&(si->si_ih.ih_key), new_objectid);
new = si->si_ih.ih_key;
/*fsck_log ("%H\n", &si->si_ih);*/
insert_item_separately (&(si->si_ih), si->si_dnm_data, 1/*was in tree*/);
si = remove_saved_item (si);
moved_items ++;
}
if (moved_items)
fsck_log ("relocate_file: %d items of file %K moved to %K\n",
moved_items, &old, &new);
}
}
/* this works for both new and old stat data */
#define st_mode(sd) le16_to_cpu(((struct stat_data *)(sd))->sd_mode)
@@ -300,12 +231,12 @@ static void put_sd_into_tree (struct item_head * new_ih, char * new_item)
/* new item is a stat data of a directory. So we have to
relocate all items which have the same short key and are of
not a directory */
relocate_file (new_ih, 0/*do not change new_ih*/);
rewrite_file (new_ih, 1, 0/*do not change new_ih*/);
} else {
/* new item is a stat data of something else but directory. If
there are items of directory - we have to relocate the file */
if (should_relocate (new_ih))
relocate_file (new_ih, 1/*change new_ih*/);
rewrite_file (new_ih, 1, 1/*change new_ih*/);
}
/* if we will have to insert item into tree - it is ready */
@@ -322,17 +253,17 @@ static void put_sd_into_tree (struct item_head * new_ih, char * new_item)
if (get_ih_key_format (get_ih(&path)) != get_ih_key_format (new_ih)) {
/* in tree stat data and a new one are of different
formats */
fsck_log ("put_sd_into_tree: inserting stat data %K (%M)..",
fsck_log ("put_sd_into_tree: Inserting the StatData %K, mode (%M)...",
&(new_ih->ih_key), st_mode (new_item));
if (stat_data_v1 (new_ih)) {
/* sd to be inserted is of V1, where as sd in the tree
is of V2 */
fsck_log ("found newer in the tree (%M), skip inserting\n",
fsck_log ("found newer in the tree, mode (%M), insersion was skipped.\n",
st_mode (get_item (&path)));
pathrelse (&path);
} else {
/* the stat data in the tree is sd_v1 */
fsck_log ("older sd (%M) is replaced with it\n",
fsck_log ("older sd, mode (%M), is replaced with it.\n",
st_mode (get_item (&path)));
reiserfsck_delete_item (&path, 0/*not temporary*/);
@@ -364,7 +295,7 @@ static void put_directory_item_into_tree (struct item_head * comingih, char * it
/* if there are anything with this key but a directory - move it
somewhere else */
relocate_file (comingih, 0/* do not change ih */);
rewrite_file (comingih, 1, 0/* do not change ih */);
deh = (struct reiserfs_de_head *)item;
@@ -373,7 +304,8 @@ static void put_directory_item_into_tree (struct item_head * comingih, char * it
namelen = name_in_entry_length (comingih, deh, i);
if (!is_properly_hashed (fs, name, namelen, get_deh_offset (deh)))
reiserfs_panic ("put_directory_item_into_tree: should be hashed properly (%k)", &comingih->ih_key);
reiserfs_panic ("put_directory_item_into_tree: The entry (%d) \"%.*s\" of the directory %k has"
" badly hashed entry", i, namelen, name, &comingih->ih_key);
asprintf (&buf, "%.*s", namelen, name);
/* 1 for fsck is important: if there is no any items of this
@@ -427,16 +359,13 @@ void insert_item_separately (struct item_head * ih,
char * item, int was_in_tree)
{
if (get_key_dirid (&ih->ih_key) == get_key_objectid (&ih->ih_key))
reiserfs_panic ("insert_item_separately: can not insert bad item %H", ih);
reiserfs_panic ("insert_item_separately: The item being inserted has the bad key %H", ih);
if (is_stat_data_ih (ih)) {
put_sd_into_tree (ih, item);
} else if (is_direntry_ih (ih)) {
put_directory_item_into_tree (ih, item);
} else {
if (!was_in_tree && should_relocate (ih))
relocate_file (ih, 1/*change new_ih*/);
reiserfsck_file_write (ih, item, was_in_tree);
}
}
@@ -498,8 +427,8 @@ static void save_pass_2_result (reiserfs_filsys_t * fs)
retval = unlink (state_dump_file (fs));
retval = rename ("temp_fsck_file.deleteme", state_dump_file (fs));
if (retval != 0)
fsck_progress ("pass 2: could not rename temp file temp_fsck_file.deleteme to %s",
state_dump_file (fs));
fsck_progress ("%s: Could not rename the temporary file temp_fsck_file.deleteme to %s",
__FUNCTION__, state_dump_file (fs));
}
@@ -537,36 +466,36 @@ static void do_pass_2 (reiserfs_filsys_t * fs) {
if (!total)
return;
fsck_progress ("\nPass2:\n");
fsck_progress ("\nPass 2:\n");
for (i = 0; i < 2; i++) {
j = 0;
while (reiserfs_bitmap_find_zero_bit (fsck_uninsertables (fs), &j) == 0) {
bh = bread (fs->fs_dev, j, fs->fs_blocksize);
if (bh == 0) {
fsck_log ("pass_2_take_bad_blocks_put_into_tree: "
"unable to read %lu block on device 0x%x\n",
fsck_log ("pass_2: Reading of the block (%lu) failed on the device 0x%x\n",
j, fs->fs_dev);
goto next;
}
if (is_block_used (bh->b_blocknr) && !(block_of_journal (fs, bh->b_blocknr) &&
fsck_data(fs)->rebuild.use_journal_area)) {
fsck_log ("pass_2_take_bad_blocks_put_into_tree: "
"block %d can not be in tree\n", bh->b_blocknr);
fsck_log ("%s: The block (%lu) is in the tree already. Should not happen.\n",
__FUNCTION__, bh->b_blocknr);
goto next;
}
/* this must be leaf */
what_node = who_is_this (bh->b_data, bh->b_size);
if (what_node != THE_LEAF) { // || B_IS_KEYS_LEVEL(bh)) {
fsck_log ("take_bad_blocks_put_into_tree: buffer (%b %z) must contain leaf\n", bh, bh);
fsck_log ("%s: The block (%b), marked as a leaf on the first two passes, is not a leaf! Will be skipped.\n",
__FUNCTION__, bh);
goto next;
}
// fsck_log ("block %lu is being inserted\n", bh->b_blocknr);
// fflush(fsck_log_file (fs));
/*
fsck_log ("block %lu is being inserted\n", bh->b_blocknr);
check_buffers_mem(fsck_log_file (fs));
fflush(fsck_log_file (fs));
*/
if (i) {
/* insert all not SD items */
put_not_stat_data_items (bh);
@@ -606,10 +535,11 @@ static void after_pass_2 (reiserfs_filsys_t * fs)
/* DEBUG only */
if (reiserfs_bitmap_compare (fsck_allocable_bitmap (fs), fsck_new_bitmap(fs))) {
reiserfs_warning (fsck_log_file (fs), "allocable bitmap differs from new bitmap after pass2\n");
/* if (reiserfs_bitmap_compare (fsck_allocable_bitmap (fs), fsck_new_bitmap(fs))) {
fsck_log ("Allocable bitmap differs from the new bitmap after pass2\n");
reiserfs_bitmap_copy (fsck_allocable_bitmap(fs), fsck_new_bitmap (fs));
}
*/
/* update super block: objectid map, fsck state */
set_sb_fs_state (fs->fs_ondisk_sb, TREE_IS_BUILT);
@@ -621,12 +551,12 @@ static void after_pass_2 (reiserfs_filsys_t * fs)
fs->fs_dirt = 1;
reiserfs_flush_to_ondisk_bitmap (fs->fs_bitmap2, fs);
reiserfs_flush (fs);
fsck_progress ("done\n");
fsck_progress ("finished\n");
/* fixme: should be optional */
/* fsck_progress ("Tree is built. Checking it - ");
reiserfsck_check_pass1 ();
fsck_progress ("done\n");*/
fsck_progress ("finished\n");*/
stage_report (2, fs);
@@ -653,7 +583,7 @@ static void after_pass_2 (reiserfs_filsys_t * fs)
"###########\n", ctime (&t));
fs->fs_dirt = 1;
reiserfs_close (fs);
exit (4);
exit(0);
}
@@ -670,7 +600,7 @@ void pass_2 (reiserfs_filsys_t * fs)
do_pass_2 (fs);
after_pass_2 (fs);
if (get_sb_root_block (fs->fs_ondisk_sb) == -1)
die ("\n\nNo reiserfs metadata found");
}