📄 pack.c
字号:
return 1; return 0;}#endif/* we only pack leaves which do not have any corruptions */static int can_pack_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh){ int i; struct item_head * ih; ih = B_N_PITEM_HEAD (bh, 0); for (i = 0; i < get_blkh_nr_items (B_BLK_HEAD (bh)); i ++, ih ++) { if (is_it_bad_item (fs, ih, B_I_PITEM (bh, ih), 0/*check_unfm_ptr*/, 1/*bad dir*/)) return 0; } return 1;}/* pack leaf only if all its items are correct: keys are correct, direntries are hashed properly and hash function is defined, indirect items are correct, stat data ?, */static void pack_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh){ int i; struct item_head * ih; struct packed_item pi; __u16 v16; if (!can_pack_leaf (fs, bh)) { /* something looks suspicious in this leaf - pack whole block */ bad_leaves ++; pack_full_block (fs, bh); return; } /* start magic in low 8 bits, hash code in high 8 bits */ v16 = (LEAF_START_MAGIC | (func2code (fs->fs_hash_function) << 8)); fwrite_le16 (&v16); /* block number */ fwrite_le32 (&bh->b_blocknr); /* item number */ v16 = get_blkh_nr_items (B_BLK_HEAD (bh)); fwrite_le16 (&v16); ih = B_N_PITEM_HEAD (bh, 0); for (i = 0; i < v16; i ++, ih ++) {#if 0 v32 = ITEM_START_MAGIC; fwrite32 (&v32);#endif set_pi_mask (&pi, 0); set_pi_item_len (&pi, get_ih_item_len (ih)); set_pi_type (&pi, get_type (&ih->ih_key)); // format if (get_ih_key_format (ih) == KEY_FORMAT_2) set_pi_mask( &pi, get_pi_mask(&pi) | NEW_FORMAT ); // k_dir_id if (!i || (i && get_key_dirid (&ih->ih_key) != get_key_dirid (&(ih - 1)->ih_key))) { /* if item is first in the leaf or if previous item has different k_dir_id - store it */ set_pi_mask (&pi, get_pi_mask (&pi) | DIR_ID); } // k_object_id if (!i || (i && get_key_objectid (&ih->ih_key) != get_key_objectid (&(ih - 1)->ih_key))) { /* if item is first in the leaf or if previous item has different k_objectid - store it */ set_pi_mask (&pi, get_pi_mask (&pi) | OBJECT_ID); } /* store offset if it is != 0 in 32 or 64 bits */ if (get_offset (&ih->ih_key)) { int send_offset = 1; if ((get_pi_mask (&pi) & DIR_ID) == 0 && (get_pi_mask (&pi) & OBJECT_ID) == 0) { /* previous item is of the same object, so try to avoid sending k_offset */ if ((is_stat_data_ih (ih - 1) && get_offset (&ih->ih_key) == 1) || (is_indirect_ih (ih - 1) && is_direct_ih (ih) && get_offset (&(ih - 1)->ih_key) + get_bytes_number (ih - 1, fs->fs_blocksize) == get_offset (&ih->ih_key))) /* unpack can calculate offset itself */ send_offset = 0; } if (send_offset) { if (get_offset (&ih->ih_key) > 0xffffffffULL) set_pi_mask (&pi, get_pi_mask (&pi) | OFFSET_BITS_64); else set_pi_mask (&pi, get_pi_mask (&pi) | OFFSET_BITS_32); } } /* ih key format is correct, check fsck_need field */ if (get_ih_flags (ih)) set_pi_mask (&pi, get_pi_mask (&pi) | IH_FORMAT); if ((get_key_dirid (&ih->ih_key) == (__u32)-1) && (get_ih_item_len (ih) == 4)) set_pi_mask (&pi, get_pi_mask (&pi) | SAFE_LINK); if (is_direct_ih (ih)) { pack_direct (&pi, bh, ih); } else if (is_indirect_ih (ih)) pack_indirect (&pi, bh, ih); else if (is_direntry_ih (ih)) pack_direntry (fs, &pi, bh, ih); else if (is_stat_data_ih (ih)) pack_stat_data (&pi, bh, ih); else die ("pack_leaf: unknown item found");#if 0 v32 = ITEM_END_MAGIC; fwrite32 (&v32);#endif } v16 = LEAF_END_MAGIC; fwrite_le16 (&v16); had_to_be_sent += fs->fs_blocksize; packed_leaves ++; return;}static int can_pack_internal (reiserfs_filsys_t * fs, struct buffer_head * bh){ return 0;}/* pack internal node as a full block */static void pack_internal (reiserfs_filsys_t * fs, struct buffer_head * bh){ internals ++; if (!can_pack_internal (fs, bh)) { pack_full_block (fs, bh); return; } reiserfs_panic ("pack_internal: packing code is not ready");}/* packed blocks are marked free in the bitmap*/static void send_block (reiserfs_filsys_t * fs, struct buffer_head * bh, int send_unknown){ int type; packed ++; type = who_is_this (bh->b_data, bh->b_size); switch (type) { case THE_LEAF: pack_leaf (fs, bh); break; case HAS_IH_ARRAY: having_ih_array ++;// fprintf (stderr, "BROKEN BLOCK HEAD %lu\n", bh->b_blocknr); pack_full_block (fs, bh); break; case THE_INTERNAL: pack_internal (fs, bh); break; default: if (send_unknown) pack_full_block (fs, bh); else packed --; break; } /* do not send one block twice */ reiserfs_bitmap_clear_bit (what_to_pack, bh->b_blocknr);}/* super block, journal, bitmaps */static void pack_frozen_data (reiserfs_filsys_t * fs){ struct buffer_head * bh; unsigned long block; __u16 magic16; int sent_journal_start_magic = 0; unsigned int i; if (is_reiserfs_jr_magic_string(fs->fs_ondisk_sb) && get_jp_journal_dev(sb_jp(fs->fs_ondisk_sb)) && !journal_device_name(fs)) { if (!user_confirmed (stderr, "\n File system has non-standard journal " "that hasn't been specified.\n" "Continue packing without journal? [N/Yes] (note need to type Yes):", "Yes\n")) exit (0); } /* super block */ reiserfs_warning (stderr, "super block..");fflush (stderr); send_block (fs, fs->fs_super_bh, 1/*send block even if its format is not determined */); reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", get_sb_bmap_nr (fs->fs_ondisk_sb)); fflush (stderr); /* bitmaps */ block = fs->fs_super_bh->b_blocknr + 1; for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) { bh = bread (fs->fs_dev, block, fs->fs_blocksize); if (!bh) { fprintf (stderr, "pack_frozen_data: bread failed: %lu\n", block); continue; } send_block (fs, bh, 1); if (spread_bitmaps (fs)) block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); else block ++; brelse (bh); } /* journal */ if (get_jp_journal_dev (sb_jp (fs->fs_ondisk_sb))) { /* non-standard journal is on a separate device */ if (journal_device_name (fs) && !reiserfs_journal_opened (fs)) die ("Specified journal is not available. Specify it correctly or " "don't specify at all"); else if (!journal_device_name(fs)) /* non-standard journal was not specified (that confirmed by user) - skipped packing journal */ return; else { magic16 = SEPARATED_JOURNAL_START_MAGIC; fwrite_le16 (&magic16); sent_journal_start_magic = 1; } } block = get_jp_journal_1st_block (sb_jp (fs->fs_ondisk_sb)); reiserfs_warning (stderr, "ok\njournal (from %lu to %lu)..", block, block + get_jp_journal_size (sb_jp (fs->fs_ondisk_sb))); fflush (stderr); for (i = 0; i <= get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)); i ++) { bh = bread (fs->fs_journal_dev, block + i, fs->fs_blocksize); if (!bh) { reiserfs_warning (stderr, "could not read %lu, skipped\n", i); continue; } send_block (fs, bh, 1); brelse (bh); } if (sent_journal_start_magic) { magic16 = SEPARATED_JOURNAL_END_MAGIC; fwrite_le16 (&magic16); } reiserfs_warning (stderr, "ok\n");fflush (stderr); reiserfs_warning (stderr, "Super block, bitmaps, journal - %d blocks - done, %d blocks left\n", packed, reiserfs_bitmap_ones (what_to_pack));}/* pack all "not data blocks" and correct leaf */void pack_partition (reiserfs_filsys_t * fs){ struct buffer_head * bh; __u32 magic32; __u16 blocksize; __u16 magic16; unsigned long done = 0, total; unsigned int i; magic32 = REISERFS_SUPER_MAGIC; fwrite_le32 (&magic32); blocksize = fs->fs_blocksize; fwrite_le16 (&blocksize); /* will get information about what is to be packed. Bits corresponding to packed blocks will be cleared */ what_to_pack = input_bitmap(fs); /* super block, journal, bitmaps */ pack_frozen_data (fs); /* what's left */ total = reiserfs_bitmap_ones (what_to_pack); for (i = 0; i < get_sb_block_count (fs->fs_ondisk_sb); i ++) { if (!reiserfs_bitmap_test_bit (what_to_pack, i)) continue; print_how_far (stderr, &done, total, 1, be_quiet (fs)); bh = bread (fs->fs_dev, i, blocksize); if (!bh) { reiserfs_warning (stderr, "could not read block %lu\n", i); continue; } send_block (fs, bh, 0/*do not send block of not determined format */); brelse (bh); } magic16 = END_MAGIC; fwrite_le16 (&magic16); fprintf (stderr, "\nPacked %d blocks:\n" "\tcompessed %d\n" "\tfull blocks %d\n" "\t\tleaves with broken block head %d\n" "\t\tcorrupted leaves %d\n" "\t\tinternals %d\n" "\t\tdescriptors %d\n", packed, packed_leaves, full_blocks, having_ih_array, bad_leaves, internals, descs); fprintf (stderr, "data packed with ratio %.2f\n", (double)sent_bytes / had_to_be_sent);}void pack_one_block (reiserfs_filsys_t * fs, unsigned long block){ __u32 magic32; __u16 magic16; struct buffer_head * bh; // reiserfs magic magic32 = REISERFS_SUPER_MAGIC; fwrite_le32 (&magic32); // blocksize fwrite_le16 (&fs->fs_blocksize); bh = bread (fs->fs_dev, block, fs->fs_blocksize); if (!bh) return; if (who_is_this (bh->b_data, bh->b_size) == THE_LEAF) pack_leaf (fs, bh); else pack_full_block (fs, bh); brelse (bh); // end magic magic16 = END_MAGIC; fwrite_le16 (&magic16); fprintf (stderr, "Done\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -