Initial commit -- seeded with reiserfsprogs 3.x.0j
This commit is contained in:
commit
e7102bdb66
77 files changed
+33513
No files matched your search
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
|
||||
*/
|
||||
|
||||
#include "debugreiserfs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
reiserfs_bitmap_t what_to_pack;
|
||||
reiserfs_bitmap_t what_packed;
|
||||
|
||||
int packed_leaves, bad_leaves, full_blocks, internals, descs, full_of_journal;
|
||||
|
||||
|
||||
/* these are to calculate compression */
|
||||
unsigned long sent; /* how many bytes sent to stdout */
|
||||
unsigned long had_to_be_sent; /* how many bytes were to be sent */
|
||||
|
||||
|
||||
|
||||
static void pack_key (struct packed_item * pi, struct item_head * ih)
|
||||
{
|
||||
if (pi->mask & DIR_ID) {
|
||||
fwrite32 (&ih->ih_key.k_dir_id);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
if (pi->mask & OBJECT_ID) {
|
||||
fwrite32 (&ih->ih_key.k_objectid);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
if (pi->mask & OFFSET_BITS_64) {
|
||||
__u64 offset;
|
||||
|
||||
offset = get_offset (&ih->ih_key);
|
||||
fwrite64 (&offset);
|
||||
sent += sizeof (__u64);
|
||||
}
|
||||
|
||||
if (pi->mask & OFFSET_BITS_32) {
|
||||
__u32 offset;
|
||||
|
||||
offset = get_offset (&ih->ih_key);
|
||||
fwrite32 (&offset);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pack_direct (struct packed_item * pi, struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
pi->mask |= DIRECT_ITEM;
|
||||
|
||||
/* send packed item header to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
}
|
||||
|
||||
|
||||
/* if there is at least one extent longer than 2 - it is worth packing */
|
||||
static int should_pack_indirect (__u32 * ind_item, int unfm_num)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
for (i = 1, len = 1; i < unfm_num; i ++) {
|
||||
if ((!ind_item [i] && !ind_item [i - 1]) || /* hole continues */
|
||||
ind_item [i] == ind_item [i - 1] + 1) { /* subsequent blocks */
|
||||
len ++;
|
||||
if (len > 2)
|
||||
return 1;
|
||||
} else {
|
||||
/* sequence of blocks or hole broke */
|
||||
len = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* indirect item can be either packed using "extents" (when it is
|
||||
worth doing) or be stored as is. Size of item in packed form is not
|
||||
stored. Unpacking will stop when full item length is reached */
|
||||
static void pack_indirect (struct packed_item * pi, struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
int i;
|
||||
__u32 * ind_item;
|
||||
__u16 len;
|
||||
|
||||
pi->mask |= INDIRECT_ITEM;
|
||||
if (ih_entry_count (ih))
|
||||
pi->mask |= ENTRY_COUNT;
|
||||
|
||||
ind_item = (__u32 *)B_I_PITEM (bh, ih);
|
||||
if (!should_pack_indirect (ind_item, I_UNFM_NUM (ih)))
|
||||
pi->mask |= WHOLE_INDIRECT;
|
||||
|
||||
/* send packed item header to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
if (pi->mask & ENTRY_COUNT) {
|
||||
__u16 ih_free_space;
|
||||
|
||||
ih_free_space = ih_entry_count (ih);
|
||||
fwrite16 (&ih_free_space);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
|
||||
if (pi->mask & WHOLE_INDIRECT) {
|
||||
fwrite (ind_item, ih_item_len (ih), 1, stdout);
|
||||
sent += ih_item_len (ih);
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite32 (&ind_item [0]);
|
||||
sent += sizeof (__u32);
|
||||
for (i = 1, len = 1; i < I_UNFM_NUM (ih); i ++) {
|
||||
if ((!ind_item [i] && !ind_item [i - 1]) || /* hole continues */
|
||||
ind_item [i] == ind_item[ i - 1] + 1) { /* subsequent blocks */
|
||||
len ++;
|
||||
} else {
|
||||
fwrite16 (&len);
|
||||
fwrite32 (&ind_item[i]);
|
||||
sent += (sizeof (__u32) + sizeof (__u16));
|
||||
len = 1;
|
||||
}
|
||||
}
|
||||
fwrite16 (&len);
|
||||
sent += sizeof (__u16);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* directory item is packed:
|
||||
entry count - 16 bits
|
||||
for each entry
|
||||
mask (8 bits) - it shows whether there are any of (deh_dir_id, gen counter, deh_state)
|
||||
entry length 16 bits
|
||||
entry itself
|
||||
deh_objectid - 32 bits
|
||||
maybe deh_dir_id (32 bits)
|
||||
maybe gencounter (16)
|
||||
maybe deh_state (16)
|
||||
*/
|
||||
static void pack_direntry (reiserfs_filsys_t fs, struct packed_item * pi,
|
||||
struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
int i;
|
||||
struct reiserfs_de_head * deh;
|
||||
struct packed_dir_entry pe;
|
||||
__u16 entry_count, gen_counter;
|
||||
|
||||
|
||||
pi->mask |= (DIRENTRY_ITEM | ENTRY_COUNT);
|
||||
|
||||
/* send packed item header to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
/* entry count is sent unconditionally */
|
||||
entry_count = ih_entry_count (ih);
|
||||
fwrite16 (&entry_count);
|
||||
|
||||
deh = B_I_DEH (bh, ih);
|
||||
for (i = 0; i < entry_count; i ++, deh ++) {
|
||||
pe.entrylen = entry_length (ih, deh, i);
|
||||
pe.mask = 0;
|
||||
if (deh_dir_id (deh) != le32_to_cpu (ih->ih_key.k_objectid))
|
||||
/* entry points to name of another directory, store deh_dir_id */
|
||||
pe.mask |= HAS_DIR_ID;
|
||||
|
||||
gen_counter = GET_GENERATION_NUMBER (deh_offset (deh));
|
||||
if (gen_counter != 0)
|
||||
/* store generation counter if it is != 0 */
|
||||
pe.mask |= HAS_GEN_COUNTER;
|
||||
|
||||
if (le16_to_cpu (deh->deh_state) != 4)
|
||||
/* something unusual in deh_state. Store it */
|
||||
pe.mask |= HAS_STATE;
|
||||
|
||||
fwrite8 (&pe.mask);
|
||||
fwrite16 (&pe.entrylen);
|
||||
fwrite (name_in_entry (deh, i), pe.entrylen, 1, stdout);
|
||||
fwrite32 (&(deh->deh_objectid));
|
||||
sent += (sizeof (__u8) + sizeof (__u16) + pe.entrylen + sizeof (__u32));
|
||||
|
||||
if (pe.mask & HAS_DIR_ID) {
|
||||
fwrite32 (&deh->deh_dir_id);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
if (pe.mask & HAS_GEN_COUNTER) {
|
||||
fwrite16 (&gen_counter);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
|
||||
if (pe.mask & HAS_STATE) {
|
||||
fwrite16 (&deh->deh_state);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pack_stat_data (struct packed_item * pi, struct buffer_head * bh,
|
||||
struct item_head * ih)
|
||||
{
|
||||
pi->mask |= STAT_DATA_ITEM;
|
||||
|
||||
if (stat_data_v1 (ih)) {
|
||||
/* for old stat data: we take
|
||||
mode - 16 bits
|
||||
nlink - 16 bits
|
||||
size - 32 bits
|
||||
blocks/rdev - 32 bits
|
||||
maybe first_direct byte 32 bits
|
||||
*/
|
||||
struct stat_data_v1 * sd_v1;
|
||||
|
||||
sd_v1 = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
|
||||
if (sd_v1->sd_first_direct_byte != 0xffffffff)
|
||||
pi->mask |= WITH_SD_FIRST_DIRECT_BYTE;
|
||||
|
||||
/* we are done with packed_item send packed it to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
fwrite16 (&sd_v1->sd_mode);
|
||||
fwrite16 (&sd_v1->sd_nlink);
|
||||
fwrite32 (&sd_v1->sd_size);
|
||||
fwrite32 (&sd_v1->u.sd_blocks);
|
||||
sent += (sizeof (__u16) * 2 + sizeof (__u32) * 2);
|
||||
if (pi->mask & WITH_SD_FIRST_DIRECT_BYTE) {
|
||||
fwrite32 (&sd_v1->sd_first_direct_byte);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
} else {
|
||||
/* for new stat data
|
||||
mode - 16 bits
|
||||
nlink in either 16 or 32 bits
|
||||
size in either 32 or 64 bits
|
||||
blocks - 32 bits
|
||||
*/
|
||||
struct stat_data * sd;
|
||||
__u16 nlink16;
|
||||
__u32 nlink32, size32;
|
||||
__u64 size64;
|
||||
|
||||
sd = (struct stat_data *)B_I_PITEM (bh, ih);
|
||||
if (sd->sd_nlink > 0xffff) {
|
||||
pi->mask |= NLINK_BITS_32;
|
||||
nlink32 = sd->sd_nlink;
|
||||
} else {
|
||||
nlink16 = sd->sd_nlink;
|
||||
}
|
||||
if (sd->sd_size > 0xffffffff) {
|
||||
pi->mask |= SIZE_BITS_64;
|
||||
size64 = sd->sd_size;
|
||||
} else {
|
||||
size32 = sd->sd_size;
|
||||
}
|
||||
|
||||
/* we are done with packed_item send packed it to stdout */
|
||||
fwrite (pi, sizeof (*pi), 1, stdout);
|
||||
sent += sizeof (*pi);
|
||||
|
||||
/* send key components which are to be sent */
|
||||
pack_key (pi, ih);
|
||||
|
||||
fwrite16 (&sd->sd_mode);
|
||||
sent += sizeof (__u16);
|
||||
if (pi->mask & NLINK_BITS_32) {
|
||||
fwrite32 (&nlink32);
|
||||
sent += sizeof (__u32);
|
||||
} else {
|
||||
fwrite16 (&nlink16);
|
||||
sent += sizeof (__u16);
|
||||
}
|
||||
|
||||
if (pi->mask & SIZE_BITS_64) {
|
||||
fwrite64 (&size64);
|
||||
sent += sizeof (__u64);
|
||||
} else {
|
||||
fwrite32 (&size32);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
|
||||
fwrite32 (&sd->sd_blocks);
|
||||
sent += sizeof (__u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pack_full_block (reiserfs_filsys_t fs, struct buffer_head * bh)
|
||||
{
|
||||
__u16 magic;
|
||||
__u32 block;
|
||||
|
||||
magic = FULL_BLOCK_START_MAGIC;
|
||||
fwrite16 (&magic);
|
||||
|
||||
block = bh->b_blocknr;
|
||||
fwrite32 (&block);
|
||||
|
||||
fwrite (bh->b_data, 4096, 1, stdout);
|
||||
sent += 4096;
|
||||
had_to_be_sent += 4096;
|
||||
|
||||
full_blocks ++;
|
||||
|
||||
if (who_is_this (bh->b_data, bh->b_size) == THE_JDESC)
|
||||
descs ++;
|
||||
if (who_is_this (bh->b_data, bh->b_size) == THE_INTERNAL)
|
||||
internals ++;
|
||||
if (block_of_journal (fs, bh->b_blocknr))
|
||||
full_of_journal ++;
|
||||
}
|
||||
|
||||
|
||||
/* unformatted node pointer is considered bad when it points either to blocks
|
||||
of journal, bitmap blocks, super block or is transparently out of range of
|
||||
disk block numbers */
|
||||
static int check_unfm_ptr (reiserfs_filsys_t fs, __u32 block)
|
||||
{
|
||||
if (block >= SB_BLOCK_COUNT (fs))
|
||||
return 1;
|
||||
|
||||
if (not_data_block (fs, block))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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 < node_item_number (bh); i ++, ih ++) {
|
||||
if (is_it_bad_item (fs, ih, B_I_PITEM (bh, ih), 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)) {
|
||||
/* if something looks suspicious in this leaf - pack whole block */
|
||||
pack_full_block (fs, bh);
|
||||
fprintf (stderr, "leaf %lu is bad\n", bh->b_blocknr);
|
||||
bad_leaves ++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* start magic in low 8 bits, hash code in high 8 bits */
|
||||
v16 = (LEAF_START_MAGIC | (func2code (fs->s_hash_function) << 8));
|
||||
fwrite16 (&v16);
|
||||
|
||||
/* block number */
|
||||
fwrite32 (&bh->b_blocknr);
|
||||
|
||||
/* item number */
|
||||
v16 = node_item_number (bh);
|
||||
fwrite16 (&v16);
|
||||
|
||||
ih = B_N_PITEM_HEAD (bh, 0);
|
||||
|
||||
for (i = 0; i < node_item_number (bh); i ++, ih ++) {
|
||||
#if 0
|
||||
v32 = ITEM_START_MAGIC;
|
||||
fwrite32 (&v32);
|
||||
#endif
|
||||
|
||||
pi.mask = 0;
|
||||
pi.item_len = ih_item_len (ih);
|
||||
|
||||
// format
|
||||
if (ih_key_format (ih) == KEY_FORMAT_2)
|
||||
pi.mask |= NEW_FORMAT;
|
||||
|
||||
// k_dir_id
|
||||
if (!i || (i && ih->ih_key.k_dir_id != (ih - 1)->ih_key.k_dir_id)) {
|
||||
/* if item is first in the leaf or if previous item has different
|
||||
k_dir_id - store it */
|
||||
pi.mask |= DIR_ID;
|
||||
}
|
||||
// k_object_id
|
||||
if (!i || (i && ih->ih_key.k_objectid != (ih - 1)->ih_key.k_objectid)) {
|
||||
/* if item is first in the leaf or if previous item has different
|
||||
k_objectid - store it */
|
||||
pi.mask |= OBJECT_ID;
|
||||
}
|
||||
|
||||
/* store offset if it is != 0 in 32 or 64 bits */
|
||||
if (get_offset (&ih->ih_key)) {
|
||||
if (get_offset (&ih->ih_key) > 0xffffffffULL)
|
||||
pi.mask |= OFFSET_BITS_64;
|
||||
else
|
||||
pi.mask |= OFFSET_BITS_32;
|
||||
}
|
||||
|
||||
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;
|
||||
fwrite16 (&v16);
|
||||
|
||||
packed_leaves ++;
|
||||
had_to_be_sent += 4096;
|
||||
|
||||
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)
|
||||
{
|
||||
if (!can_pack_internal (fs, bh)) {
|
||||
pack_full_block (fs, bh);
|
||||
return;
|
||||
}
|
||||
|
||||
reiserfs_panic ("pack_internal: packing code is not ready");
|
||||
}
|
||||
|
||||
|
||||
static int how_many_to_pack (reiserfs_filsys_t fs, unsigned long first, int count)
|
||||
{
|
||||
int i;
|
||||
int used;
|
||||
|
||||
used = 0;
|
||||
for (i = 0; i < count; i ++) {
|
||||
if ((SB_BLOCK_COUNT (fs) > (first + i)) &&
|
||||
reiserfs_bitmap_test_bit (what_to_pack, first + i))
|
||||
used ++;
|
||||
}
|
||||
return used;
|
||||
}
|
||||
|
||||
|
||||
/* packed blocks are marked free in the bitmap*/
|
||||
static void send_block (reiserfs_filsys_t fs, struct buffer_head * bh)
|
||||
{
|
||||
int type;
|
||||
|
||||
|
||||
if ((type = who_is_this (bh->b_data, bh->b_size)) != THE_LEAF) {
|
||||
if (type == THE_INTERNAL) {
|
||||
pack_internal (fs, bh);
|
||||
} else if (!not_data_block (fs, bh->b_blocknr)) {
|
||||
/* unformatted */
|
||||
return;
|
||||
} else
|
||||
/* bitmaps, super block, blocks of journal - not leaves */
|
||||
pack_full_block (fs, bh);
|
||||
} else
|
||||
pack_leaf (fs, bh);
|
||||
|
||||
reiserfs_bitmap_set_bit (what_packed, bh->b_blocknr);
|
||||
reiserfs_bitmap_clear_bit (what_to_pack, bh->b_blocknr);
|
||||
}
|
||||
|
||||
|
||||
/* super block, journal, bitmaps */
|
||||
static void pack_frozen_data (reiserfs_filsys_t fs)
|
||||
{
|
||||
int i;
|
||||
struct buffer_head * bh;
|
||||
|
||||
/* super block */
|
||||
reiserfs_warning (stderr, "super block..");fflush (stderr);
|
||||
send_block (fs, fs->s_sbh);
|
||||
reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", SB_BMAP_NR (fs));
|
||||
fflush (stderr);
|
||||
|
||||
/* bitmaps */
|
||||
for (i = 0; i < SB_BMAP_NR (fs); i ++) {
|
||||
send_block (fs, SB_AP_BITMAP (fs)[i]);
|
||||
}
|
||||
|
||||
reiserfs_warning (stderr, "ok\njournal (from %lu to %lu)..",
|
||||
rs_journal_start (fs->s_rs),
|
||||
rs_journal_start (fs->s_rs) + rs_journal_size (fs->s_rs));
|
||||
fflush (stderr);
|
||||
/* journal */
|
||||
for (i = rs_journal_start (fs->s_rs);
|
||||
i <= rs_journal_start (fs->s_rs) + rs_journal_size (fs->s_rs);
|
||||
i ++) {
|
||||
bh = bread (fs->s_dev, i, fs->s_blocksize);
|
||||
send_block (fs, bh);
|
||||
brelse (bh);
|
||||
}
|
||||
reiserfs_warning (stderr, "ok\n");fflush (stderr);
|
||||
}
|
||||
|
||||
|
||||
/* pack all "not data blocks" and correct leaf */
|
||||
void pack_partition (reiserfs_filsys_t fs)
|
||||
{
|
||||
int i, j;
|
||||
struct buffer_head tmp, * bh;
|
||||
int nr_to_read = BLOCKS_PER_READ;
|
||||
__u32 magic32;
|
||||
__u16 blocksize;
|
||||
__u16 magic16;
|
||||
unsigned long done = 0, total;
|
||||
|
||||
|
||||
magic32 = REISERFS_SUPER_MAGIC;
|
||||
fwrite32 (&magic32);
|
||||
|
||||
blocksize = fs->s_blocksize;
|
||||
fwrite16 (&blocksize);
|
||||
|
||||
tmp.b_size = blocksize;
|
||||
|
||||
/* will save information about what packed here */
|
||||
what_packed = reiserfs_create_bitmap (SB_BLOCK_COUNT (fs));
|
||||
|
||||
/* will get information about what is to be packed */
|
||||
what_to_pack = reiserfs_create_bitmap (SB_BLOCK_COUNT (fs));
|
||||
if (!what_to_pack)
|
||||
die ("pack_partition: could not create bitmap");
|
||||
if (mode == DO_PACK) {
|
||||
/* read blocks marked used and pack them */
|
||||
reiserfs_fetch_disk_bitmap (what_to_pack, fs);
|
||||
reiserfs_warning (stderr, "Packing blocks marked used on the device %d\n",
|
||||
reiserfs_bitmap_ones (what_to_pack));
|
||||
} else {
|
||||
reiserfs_bitmap_fill (what_to_pack);
|
||||
reiserfs_warning (stderr, "Packing all blocks of the device %d\n",
|
||||
reiserfs_bitmap_ones (what_to_pack));
|
||||
}
|
||||
|
||||
|
||||
/* super block, journal, bitmaps */
|
||||
pack_frozen_data (fs);
|
||||
|
||||
reiserfs_warning (stderr,
|
||||
"Super block, bitmaps, journal - %d blocks - done, %d blocks left\n",
|
||||
reiserfs_bitmap_ones (what_packed), reiserfs_bitmap_ones (what_to_pack));
|
||||
total = reiserfs_bitmap_ones (what_to_pack);
|
||||
|
||||
for (i = 0; i < SB_BLOCK_COUNT (fs); i += nr_to_read) {
|
||||
int to_pack;
|
||||
|
||||
to_pack = how_many_to_pack (fs, i, nr_to_read);
|
||||
if (to_pack) {
|
||||
print_how_far (&done, total, to_pack, opt_quiet);
|
||||
|
||||
bh = bread (fs->s_dev, i / nr_to_read, blocksize * nr_to_read);
|
||||
if (bh) {
|
||||
for (j = 0; j < nr_to_read; j ++) {
|
||||
if (reiserfs_bitmap_test_bit (what_to_pack, i + j)) {
|
||||
tmp.b_data = bh->b_data + j * tmp.b_size;
|
||||
tmp.b_blocknr = i + j;
|
||||
send_block (fs, &tmp);
|
||||
}
|
||||
}
|
||||
brelse (bh);
|
||||
} else {
|
||||
/* bread failed */
|
||||
if (nr_to_read != 1) {
|
||||
/* we tryied to read bunch of blocks. Try to read them by one */
|
||||
nr_to_read = 1;
|
||||
i --;
|
||||
continue;
|
||||
} else {
|
||||
/* we were reading one block at time, and failed, so mark
|
||||
block bad */
|
||||
reiserfs_warning (stderr, "could not read block %lu\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
magic16 = END_MAGIC;
|
||||
fwrite16 (&magic16);
|
||||
|
||||
fprintf (stderr, "Packed\n\tleaves %d\n"
|
||||
"\tfull blocks %d\n"
|
||||
"\t\tof journal %d\n"
|
||||
"\t\tcorrupted leaves %d\n"
|
||||
"\t\tinternals %d\n"
|
||||
"\t\tdescriptors %d\n",
|
||||
packed_leaves, full_blocks, full_of_journal, bad_leaves, internals, descs);
|
||||
fprintf (stderr, "data packed with ratio %.2f\n", (double)sent / had_to_be_sent);
|
||||
|
||||
if (where_to_save)
|
||||
reiserfs_bitmap_save (where_to_save, what_packed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
fwrite32 (&magic32);
|
||||
|
||||
// blocksize
|
||||
fwrite16 (&fs->s_blocksize);
|
||||
|
||||
bh = bread (fs->s_dev, block, fs->s_blocksize);
|
||||
|
||||
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;
|
||||
fwrite16 (&magic16);
|
||||
|
||||
fprintf (stderr, "Packed\n\tleaves %d\n\tfull block %d\n\tcorrupted leaves %d\n",
|
||||
packed_leaves, full_blocks, bad_leaves);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
//
|
||||
// this test program has two modes: 'pack file blocknr'
|
||||
// and 'unpack file'
|
||||
// in the first mode blocknr-th 4k block of the 'file' will be packed out to stdout
|
||||
// the the second mode standart input will be converted to the reiserfs leaf on 'file'
|
||||
//
|
||||
static int do_unpack (char * file)
|
||||
{
|
||||
char * buf;
|
||||
int fd;
|
||||
|
||||
fd = open (file, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror ("open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = malloc (4096);
|
||||
if (!buf) {
|
||||
perror ("malloc failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread (buf, 4096, 1, stdin);
|
||||
if (!feof (stdin)) {
|
||||
printf ("fread returned not eof\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unpack_leaf (buf, fd);
|
||||
|
||||
free (buf);
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_pack (char * file, int block)
|
||||
{
|
||||
int fd;
|
||||
struct buffer_head * bh;
|
||||
char * buf;
|
||||
int len;
|
||||
|
||||
fprintf (stderr, "dumping block %d of the \"%s\"\n", block, file);
|
||||
|
||||
fd = open (file, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror ("open failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bh = bread (fd, block, 4096);
|
||||
if (!bh) {
|
||||
fprintf (stderr, "bread failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (who_is_this (bh->b_data, bh->b_size) != THE_LEAF) {
|
||||
fprintf (stderr, "block %d is not a leaf\n", block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = pack_leaf (bh, buf);
|
||||
fwrite (buf, len, 1, stdout);
|
||||
|
||||
free (buf);
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
if (argc == 3 && !strcmp (argv[1], "unpack"))
|
||||
return do_unpack (argv[2]);
|
||||
|
||||
if (argc == 4 && !strcmp (argv[1], "pack"))
|
||||
return do_pack (argv[2], atoi (argv[3]));
|
||||
|
||||
fprintf (stderr, "Usage: \n\t%s pack filename block\nor\n"
|
||||
"\t%s unpack filename\n", argv[0], argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user