📄 ufile.c
字号:
"(%LLu) at the position %LLu\n", &comingih->ih_key, get_offset (&comingih->ih_key) + pos * fs->fs_blocksize, get_offset (&ih->ih_key) + bytes_number); /* take unformatted pointer from an indirect item */ count = I_UNFM_NUM(comingih) - pos; ni = getmem (count * UNFM_P_SIZE); memcpy (ni, (item + pos * UNFM_P_SIZE), count * UNFM_P_SIZE); if (!was_in_tree) { for (i = 0; i < count; i++ ) { if (still_bad_unfm_ptr_2 (d32_get (ni, i))) die ("reiserfsck_append_file: Trying to insert a pointer to illegal block (%u)", d32_get (ni, i)); mark_block_used (d32_get (ni, i), 0); } } retval = fs->fs_blocksize * count; } reiserfsck_paste_into_item (path, (const char *)ni, count * UNFM_P_SIZE); freemem (ni); return retval;}long long int must_there_be_a_hole (struct item_head * comingih, struct path * path){ struct item_head * ih = PATH_PITEM_HEAD (path); if (is_direct_ih (ih)) { direct2indirect2 (0, path); ih = PATH_PITEM_HEAD (path); } path->pos_in_item = I_UNFM_NUM (ih); return (get_offset (&comingih->ih_key) - get_offset (&ih->ih_key)) / fs->fs_blocksize - I_UNFM_NUM (ih);/* if (get_offset (&ih->ih_key) + (I_UNFM_NUM (ih) + 1) * fs->fs_blocksize <= get_offset (&comingih->ih_key)) return 1; return 0;*/}int reiserfs_append_zero_unfm_ptr (struct path * path, long long int p_count){ __u32 * ni; long long int count; if (is_direct_ih (PATH_PITEM_HEAD (path))) /* convert direct item to indirect */ direct2indirect2 (0, path); count = MAX_INDIRECT_ITEM_LEN (fs->fs_blocksize) / UNFM_P_SIZE; if (p_count <= count) count = p_count; ni = getmem (count * UNFM_P_SIZE); memset (ni, 0, count * UNFM_P_SIZE); reiserfsck_paste_into_item (path, (const char *)ni, count * UNFM_P_SIZE); freemem(ni); return 0;}/* write direct item to unformatted node *//* coming item is direct */static int overwrite_by_direct_item (struct item_head * comingih, char * item, struct path * path){ __u32 unfm_ptr; struct buffer_head * unbh, * bh; struct item_head * ih; int offset; __u64 coming_len = get_bytes_number (comingih, fs->fs_blocksize); bh = PATH_PLAST_BUFFER (path); ih = PATH_PITEM_HEAD (path); unfm_ptr = d32_get ((__u32 *)B_I_PITEM(bh, ih), path->pos_in_item); unbh = 0; if (unfm_ptr != 0 && unfm_ptr < get_sb_block_count (fs->fs_ondisk_sb)) { /**/ unbh = bread (fs->fs_dev, unfm_ptr, bh->b_size); if (!is_block_used (unfm_ptr)) die ("overwrite_by_direct_item: block %lu, item %d, pointer %d: The pointed block" "(%u) being overwritten is marked as unused.", bh->b_blocknr, PATH_LAST_POSITION(path), path->pos_in_item, unfm_ptr); if (unbh == 0) unfm_ptr = 0; } if (unfm_ptr == 0 || unfm_ptr >= get_sb_block_count (fs->fs_ondisk_sb)) { if ((unbh = reiserfsck_get_new_buffer (bh->b_blocknr)) != NULL) { memset (unbh->b_data, 0, unbh->b_size); d32_put ((__u32 *)B_I_PITEM(bh, ih), path->pos_in_item, unbh->b_blocknr); mark_buffer_dirty (bh); } else { die ("overwrite_by_direct_item: Could not allocate a new block for new data"); } } offset = (get_offset (&comingih->ih_key) % bh->b_size) - 1; if (offset + coming_len > bh->b_size) die ("overwrite_by_direct_item: The length of the file after insertion (offset=%lu, length=%u)" "will exceed the maximal possible length.", ( long unsigned ) get_offset (&comingih->ih_key), ( unsigned ) coming_len); memcpy (unbh->b_data + offset, item, coming_len);// save_unfm_overwriting (unbh->b_blocknr, comingih); if ((path->pos_in_item == (I_UNFM_NUM (ih) - 1)) && (bh->b_size - 0/*ih_free_space (ih)*/) < (offset + coming_len)) { set_ih_free_space (ih, bh->b_size - (offset + coming_len)) ; mark_buffer_dirty (bh); } mark_buffer_dirty (unbh);// mark_buffer_uptodate (unbh, 0); mark_buffer_uptodate (unbh, 1); brelse (unbh); return coming_len;}#if 0void overwrite_unfm_by_unfm (unsigned long unfm_in_tree, unsigned long coming_unfm, int bytes_in_unfm){ struct overwritten_unfm_segment * unfm_os_list;/* list of overwritten segments of the unformatted node */ struct overwritten_unfm_segment unoverwritten_segment; struct buffer_head * bh_in_tree, * coming_bh; if (!test_bit (coming_unfm % (fs->fs_blocksize * 8), SB_AP_BITMAP (fs)[coming_unfm / (fs->fs_blocksize * 8)]->b_data)) /* block (pointed by indirect item) is free, we do not have to keep its contents */ return; /* coming block is marked as used in disk bitmap. Put its contents to block in tree preserving everything, what has been overwritten there by direct items */ unfm_os_list = find_overwritten_unfm (unfm_in_tree, bytes_in_unfm, &unoverwritten_segment); if (unfm_os_list) { /* add_event (UNFM_OVERWRITING_UNFM);*/ bh_in_tree = bread (fs->fs_dev, unfm_in_tree, fs->fs_blocksize); coming_bh = bread (fs->fs_dev, coming_unfm, fs->fs_blocksize); if (bh_in_tree == 0 || coming_bh == 0) return; while (get_unoverwritten_segment (unfm_os_list, &unoverwritten_segment)) { if (unoverwritten_segment.ous_begin < 0 || unoverwritten_segment.ous_end > bytes_in_unfm - 1 || unoverwritten_segment.ous_begin > unoverwritten_segment.ous_end) die ("overwrite_unfm_by_unfm: invalid segment found (%d %d)", unoverwritten_segment.ous_begin, unoverwritten_segment.ous_end); memcpy (bh_in_tree->b_data + unoverwritten_segment.ous_begin, coming_bh->b_data + unoverwritten_segment.ous_begin, unoverwritten_segment.ous_end - unoverwritten_segment.ous_begin + 1); mark_buffer_dirty (bh_in_tree); } brelse (bh_in_tree); brelse (coming_bh); }}#endif/* put unformatted node pointers from incoming item over the in-tree ones */static int overwrite_by_indirect_item (struct item_head * comingih, __u32 * coming_item, struct path * path, int * pos_in_coming_item){ struct buffer_head * bh = PATH_PLAST_BUFFER (path); struct item_head * ih = PATH_PITEM_HEAD (path); int written; __u32 * item_in_tree; int src_unfm_ptrs, dest_unfm_ptrs, to_copy, i, dirty = 0; item_in_tree = (__u32 *)B_I_PITEM (bh, ih) + path->pos_in_item; coming_item += *pos_in_coming_item; dest_unfm_ptrs = I_UNFM_NUM (ih) - path->pos_in_item; src_unfm_ptrs = I_UNFM_NUM (comingih) - *pos_in_coming_item; if (dest_unfm_ptrs >= src_unfm_ptrs) { /* whole coming item (comingih) fits into item in tree (ih) starting with path->pos_in_item */ //free_sp = ih_get_free_space(0, comingih, (char *)coming_item); written = get_bytes_number (comingih, fs->fs_blocksize) - /* free_sp - */ *pos_in_coming_item * fs->fs_blocksize; *pos_in_coming_item = I_UNFM_NUM (comingih); to_copy = src_unfm_ptrs; if (dest_unfm_ptrs == src_unfm_ptrs) set_ih_free_space(ih, 0 /* free_sp */ ); } else { /* only part of coming item overlaps item in the tree */ *pos_in_coming_item += dest_unfm_ptrs; written = dest_unfm_ptrs * fs->fs_blocksize; to_copy = dest_unfm_ptrs; set_ih_free_space(ih, 0); } for (i = 0; i < to_copy; i ++) { if (d32_get (coming_item, i) != 0 && d32_get (item_in_tree, i) == 0) { /* overwrite holes only by correct a pointer in the coming item which must be correct */ d32_put (item_in_tree, i, d32_get (coming_item, i)); mark_block_used (d32_get (coming_item, i), 0); dirty ++; } } if (dirty) mark_buffer_dirty (bh); return written;}static int reiserfsck_overwrite_file (struct item_head * comingih, char * item, struct path * path, int * pos_in_coming_item, int was_in_tree){ __u32 unfm_ptr; int written = 0; struct item_head * ih = PATH_PITEM_HEAD (path); if (not_of_one_file (ih, &(comingih->ih_key))) reiserfs_panic ("reiserfsck_overwrite_file: The file to be overwritten %K must be of" " the same as the new data %K", &ih->ih_key, &comingih->ih_key); if (is_direct_ih (ih)) { unfm_ptr = 0; if (is_indirect_ih (comingih)) { if (get_offset (&ih->ih_key) % fs->fs_blocksize != 1) reiserfs_panic ("reiserfsck_overwrite_file: The second part of the tail %k can not" " be overwritten by indirect item %k", &ih->ih_key, &comingih->ih_key); /* use pointer from coming indirect item */ unfm_ptr = d32_get ((__u32 *)item, *pos_in_coming_item); if (!was_in_tree) { if (still_bad_unfm_ptr_2 (unfm_ptr)) die ("reiserfsck_overwrite_file: The pointer to the unformatted block (%u)" " points to the bad area.", unfm_ptr); } } /* */ direct2indirect2 (unfm_ptr, path); } if (is_direct_ih (comingih)) { written = overwrite_by_direct_item (comingih, item, path); } else { if (was_in_tree) reiserfs_panic ("reiserfsck_overwrite_file: Item %k we are going to overwrite with" " %k cannot not be in the tree yet", &ih->ih_key, &comingih->ih_key); written = overwrite_by_indirect_item (comingih, (__u32 *)item, path, pos_in_coming_item); } return written;}/* */int reiserfsck_file_write (struct item_head * ih, char * item, int was_in_tree) { struct path path; int count, pos_in_coming_item; long long int retval, written; struct key key; int file_format = KEY_FORMAT_UNDEFINED; int relocated = 0; if (!was_in_tree) { __u16 mode; /* We already inserted all SD items. If we cannot find SD of this item - skip it */ memset (&key, 0, sizeof (key));check_again: copy_short_key (&key, &(ih->ih_key)); if (reiserfs_search_by_key_4 (fs, &key, &path) != ITEM_FOUND) { fsck_log ("vpf-10260: The file we are inserting the new item (%H) into has no" " StatData, insertion was skipped\n", ih); pathrelse (&path); return 0; } /*SD found*/ file_format = get_ih_key_format (get_ih(&path)); get_sd_mode (get_ih(&path), get_item(&path), &mode); if (file_format != get_ih_key_format (ih)) { /* Not for symlinks and not for items which should be relocted. */ if (((S_ISDIR(mode) && is_direntry_ih(ih)) || (!S_ISDIR(mode) && !is_direntry_ih(ih))) && !S_ISLNK(mode)) { set_type_and_offset (file_format, &ih->ih_key, get_offset (&ih->ih_key), get_type (&ih->ih_key)); set_ih_key_format(ih, file_format); } } if (!relocated && should_relocate (ih)) { rewrite_file (ih, 1, 1/*change new_ih*/); pathrelse(&path); relocated = 1; /* object has been relocated but we should not mark it as used in semantic map, as it does not exist at pass2 and we do not get here for relocation as was_in_tree == 1 */ goto check_again; } if (make_file_writeable (get_bh(&path), get_item_pos (&path)) == -1) { /* write was not completed. Skip that item. Maybe it should be saved to lost_found */ fsck_log ("reiserfsck_file_write: WARNING: The file we are inserting the new item %k into was" " not recovered and is still in inconsistent state, insertion was skipped\n", &ih->ih_key); pathrelse(&path); return 0; } pathrelse (&path); } count = get_bytes_number (ih, fs->fs_blocksize); pos_in_coming_item = 0; copy_key (&key, &(ih->ih_key)); while (count) { retval = usearch_by_position (fs, &key, key_format (&key), &path); /* if there are items of bigger offset than we are looking for and there is no item between wamted offset and SD, insert first item */ if (retval == POSITION_NOT_FOUND && ( PATH_LAST_POSITION (&path) >= B_NR_ITEMS (get_bh(&path)) || get_offset (&get_ih(&path)->ih_key) > get_offset (&key))) retval = FILE_NOT_FOUND; if (retval == DIRECTORY_FOUND) reiserfs_panic ("The directory was found at the place of the file we are going to insert" " the item %k into", key); if (retval == POSITION_FOUND) { written = reiserfsck_overwrite_file (ih, item, &path, &pos_in_coming_item, was_in_tree); count -= written; set_offset (key_format (&key), &key, get_offset (&key) + written); } if (retval == FILE_NOT_FOUND) { written = create_first_item_of_file (ih, item, &path, was_in_tree); count -= written; set_offset (key_format (&key), &key, get_offset (&key) + written ); } if (retval == POSITION_NOT_FOUND) { if (is_direct_ih (ih)) { mark_ih_was_tail (get_ih(&path)); mark_buffer_dirty (get_bh(&path)); } if ((written = must_there_be_a_hole (ih, &path)) > 0) { reiserfs_append_zero_unfm_ptr (&path, written); }else { written = reiserfsck_append_file (ih, item, pos_in_coming_item, &path, was_in_tree); count -= written; set_offset (key_format (&key), &key, get_offset (&key) + written); pos_in_coming_item += written / fs->fs_blocksize; } } if (count < 0) reiserfs_panic ("reiserfsck_file_write: We wrote into the file %K more bytes than needed - count (%d) < 0.", &key, count); pathrelse (&path); } /* This is a test for writing into the file. If not sure that file data are consistent after reiserfsck_file_write - uncomment this clause: *//* if (!was_in_tree && are_file_items_correct (&ih->ih_key, (file_format == KEY_FORMAT_UNDEFINED) ? get_ih_key_format (ih) : file_format, &size, &blocks, 0, symlink, 0) == 0) reiserfs_panic ("reiserfsck_file_write: item was not inserted properly\n");*/ return get_bytes_number (ih, fs->fs_blocksize);}void one_more_corruption(reiserfs_filsys_t *fs, int kind) { if (kind == FATAL) fsck_check_stat (fs)->fatal_corruptions++; else if (kind == FIXABLE) fsck_check_stat (fs)->fixable_corruptions++;}void one_less_corruption(reiserfs_filsys_t *fs, int kind) { if (kind == FATAL) fsck_check_stat (fs)->fatal_corruptions--; else if (kind == FIXABLE) fsck_check_stat (fs)->fixable_corruptions--;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -