Imported reiserfsprogs-3.6.2

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:27:42 -04:00
1 parent e7102bdb66
commit b69459eb80
86 files changed
+23136 -13423

No files matched your search

+350 -285
View File
@@ -1,66 +1,123 @@
/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
* Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
*/
#include "debugreiserfs.h"
/* counters for each kind of blocks */
int packed,
packed_leaves,
full_blocks,
having_ih_array, /* blocks with broken block head */
bad_leaves, /* failed to compress */
internals,
descs,
others;
reiserfs_bitmap_t what_to_pack;
reiserfs_bitmap_t what_packed;
int packed_leaves, bad_leaves, full_blocks, internals, descs, full_of_journal;
reiserfs_bitmap_t * what_to_pack;
/* these are to calculate compression */
unsigned long sent; /* how many bytes sent to stdout */
unsigned long sent_bytes; /* 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)
inline void set_pi_type( struct packed_item *pi, __u32 val )
{
if (pi->mask & DIR_ID) {
fwrite32 (&ih->ih_key.k_dir_id);
sent += sizeof (__u32);
set_bit_field_XX (32, pi, val, 0, 2);
}
inline __u32 get_pi_type( const struct packed_item *pi )
{
get_bit_field_XX (32, pi, 0, 2);
}
inline void set_pi_mask( struct packed_item *pi, __u32 val )
{
set_bit_field_XX (32, pi, val, 2, 18);
}
__u32 get_pi_mask( const struct packed_item *pi )
{
get_bit_field_XX (32, pi, 2, 18);
}
inline void set_pi_item_len( struct packed_item *pi, __u32 val )
{
set_bit_field_XX (32, pi, val, 20, 12);
}
inline __u32 get_pi_item_len( const struct packed_item *pi )
{
get_bit_field_XX (32, pi, 20, 12);
}
static void pack_ih (struct packed_item * pi, struct item_head * ih)
{
__u32 v32;
__u16 v16;
/* send packed item head first */
fwrite (pi, sizeof (*pi), 1, stdout);
sent_bytes += sizeof (*pi);
/* sen key components which are to be sent */
if (get_pi_mask(pi) & DIR_ID) {
v32 = get_key_dirid (&ih->ih_key);
fwrite_le32 (&v32);
}
if (pi->mask & OBJECT_ID) {
fwrite32 (&ih->ih_key.k_objectid);
sent += sizeof (__u32);
if (get_pi_mask(pi) & OBJECT_ID) {
v32 = get_key_objectid (&ih->ih_key);
fwrite_le32 (&v32);
}
if (pi->mask & OFFSET_BITS_64) {
if (get_pi_mask(pi) & OFFSET_BITS_64) {
__u64 offset;
offset = get_offset (&ih->ih_key);
fwrite64 (&offset);
sent += sizeof (__u64);
fwrite_le64 (&offset);
}
if (pi->mask & OFFSET_BITS_32) {
if (get_pi_mask(pi) & OFFSET_BITS_32) {
__u32 offset;
offset = get_offset (&ih->ih_key);
fwrite32 (&offset);
sent += sizeof (__u32);
fwrite_le32 (&offset);
}
if (get_pi_mask(pi) & IH_FREE_SPACE) {
v16 = get_ih_entry_count (ih);
fwrite_le16 (&v16);
}
if (get_pi_mask(pi) & IH_FORMAT) {
/* fixme */
fwrite16 (&ih->ih_format);
}
}
static void pack_direct (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
struct item_head * ih)
{
pi->mask |= DIRECT_ITEM;
if (get_ih_free_space (ih) != 0xffff)
/* ih_free_space has unexpected value */
set_pi_mask (pi, get_pi_mask (pi) | IH_FREE_SPACE);
if (get_pi_mask(pi) & SAFE_LINK)
set_key_dirid(&ih->ih_key, le32_to_cpu(*(__u32 *)B_I_PITEM (bh, ih)) );
/* 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);
pack_ih (pi, ih);
}
@@ -70,8 +127,8 @@ 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 */
if ((ind_item [i] == 0 && ind_item [i - 1] == 0) || /* hole continues */
le32_to_cpu (ind_item [i]) == le32_to_cpu (ind_item [i - 1]) + 1) { /* subsequent blocks */
len ++;
if (len > 2)
return 1;
@@ -94,50 +151,42 @@ static void pack_indirect (struct packed_item * pi, struct buffer_head * bh,
__u32 * ind_item;
__u16 len;
pi->mask |= INDIRECT_ITEM;
if (ih_entry_count (ih))
pi->mask |= ENTRY_COUNT;
if (get_ih_entry_count (ih))
set_pi_mask (pi, get_pi_mask (pi) | IH_FREE_SPACE);
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);
set_pi_mask (pi, get_pi_mask (pi) | WHOLE_INDIRECT);
/* send key components which are to be sent */
pack_key (pi, ih);
if (pi->mask & ENTRY_COUNT) {
__u16 ih_free_space;
if (get_pi_mask(pi) & SAFE_LINK)
set_key_dirid(&ih->ih_key, le32_to_cpu(*ind_item) );
ih_free_space = ih_entry_count (ih);
fwrite16 (&ih_free_space);
sent += sizeof (__u16);
}
pack_ih (pi, ih);
if (pi->mask & WHOLE_INDIRECT) {
fwrite (ind_item, ih_item_len (ih), 1, stdout);
sent += ih_item_len (ih);
if (get_pi_mask(pi) & SAFE_LINK)
return;
if (get_pi_mask(pi) & WHOLE_INDIRECT) {
fwrite (ind_item, get_ih_item_len (ih), 1, stdout);
sent_bytes += get_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 */
if ((ind_item [i] == 0 && ind_item [i - 1] == 0) || /* hole continues */
ind_item [i] == ind_item[ i - 1] + 1) { /* subsequent blocks */
len ++;
} else {
fwrite16 (&len);
fwrite_le16 (&len);
fwrite32 (&ind_item[i]);
sent += (sizeof (__u32) + sizeof (__u16));
len = 1;
}
}
fwrite16 (&len);
sent += sizeof (__u16);
fwrite_le16 (&len);
return;
}
@@ -154,7 +203,7 @@ static void pack_indirect (struct packed_item * pi, struct buffer_head * bh,
maybe gencounter (16)
maybe deh_state (16)
*/
static void pack_direntry (reiserfs_filsys_t fs, struct packed_item * pi,
static void pack_direntry (reiserfs_filsys_t * fs, struct packed_item * pi,
struct buffer_head * bh,
struct item_head * ih)
{
@@ -164,56 +213,45 @@ static void pack_direntry (reiserfs_filsys_t fs, struct packed_item * pi,
__u16 entry_count, gen_counter;
pi->mask |= (DIRENTRY_ITEM | ENTRY_COUNT);
set_pi_mask (pi, get_pi_mask (pi) | IH_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);
/* send item_head components which are to be sent */
pack_ih (pi, ih);
/* entry count is sent unconditionally */
entry_count = ih_entry_count (ih);
fwrite16 (&entry_count);
entry_count = get_ih_entry_count (ih);
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))
if (get_deh_dirid (deh) != get_key_objectid (&ih->ih_key))
/* entry points to name of another directory, store deh_dir_id */
pe.mask |= HAS_DIR_ID;
gen_counter = GET_GENERATION_NUMBER (deh_offset (deh));
gen_counter = GET_GENERATION_NUMBER (get_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)
if (get_deh_state (deh) != 4)
/* something unusual in deh_state. Store it */
pe.mask |= HAS_STATE;
fwrite8 (&pe.mask);
fwrite16 (&pe.entrylen);
fwrite_le16 (&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));
sent_bytes += pe.entrylen;
fwrite32 (&(deh->deh2_objectid));
if (pe.mask & HAS_DIR_ID) {
fwrite32 (&deh->deh_dir_id);
sent += sizeof (__u32);
}
if (pe.mask & HAS_DIR_ID)
fwrite32 (&deh->deh2_dir_id);
if (pe.mask & HAS_GEN_COUNTER) {
fwrite16 (&gen_counter);
sent += sizeof (__u16);
}
if (pe.mask & HAS_GEN_COUNTER)
fwrite_le16 (&gen_counter);
if (pe.mask & HAS_STATE) {
fwrite16 (&deh->deh_state);
sent += sizeof (__u16);
}
if (pe.mask & HAS_STATE)
fwrite16 (&deh->deh2_state);
}
}
@@ -221,7 +259,9 @@ static void pack_direntry (reiserfs_filsys_t fs, struct packed_item * pi,
static void pack_stat_data (struct packed_item * pi, struct buffer_head * bh,
struct item_head * ih)
{
pi->mask |= STAT_DATA_ITEM;
if (get_ih_free_space (ih) != 0xffff)
/* ih_free_space has unexpected value */
set_pi_mask (pi, get_pi_mask (pi) | IH_FREE_SPACE);
if (stat_data_v1 (ih)) {
/* for old stat data: we take
@@ -234,25 +274,19 @@ static void pack_stat_data (struct packed_item * pi, struct buffer_head * bh,
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;
if (sd_v1->sd_first_direct_byte != 0xffffffff) /* ok if -1 */
set_pi_mask (pi, get_pi_mask (pi) | 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);
pack_ih (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) {
if (get_pi_mask(pi) & WITH_SD_FIRST_DIRECT_BYTE)
fwrite32 (&sd_v1->sd_first_direct_byte);
sent += sizeof (__u32);
}
} else {
/* for new stat data
mode - 16 bits
@@ -261,85 +295,75 @@ static void pack_stat_data (struct packed_item * pi, struct buffer_head * bh,
blocks - 32 bits
*/
struct stat_data * sd;
/* these will maintain disk-order values */
__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;
if (sd_v2_nlink (sd) > 0xffff) {
set_pi_mask (pi, get_pi_mask (pi) | NLINK_BITS_32);
nlink32 = sd->sd_nlink;
} else {
nlink16 = sd->sd_nlink;
/* This is required to deal w/ big endian systems */
nlink16 = cpu_to_le16 ((__u16)sd_v2_nlink (sd));
}
if (sd->sd_size > 0xffffffff) {
pi->mask |= SIZE_BITS_64;
if (sd_v2_size (sd) > 0xffffffff) {
set_pi_mask (pi, get_pi_mask (pi) | SIZE_BITS_64);
size64 = sd->sd_size;
} else {
size32 = sd->sd_size;
/* This is required to deal w/ big endian systems */
size32 = cpu_to_le32 ((__u32)sd_v2_size (sd));
}
/* 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);
pack_ih (pi, ih);
fwrite16 (&sd->sd_mode);
sent += sizeof (__u16);
if (pi->mask & NLINK_BITS_32) {
if (get_pi_mask (pi) & NLINK_BITS_32) {
fwrite32 (&nlink32);
sent += sizeof (__u32);
} else {
fwrite16 (&nlink16);
sent += sizeof (__u16);
}
if (pi->mask & SIZE_BITS_64) {
if (get_pi_mask (pi) & 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)
static void pack_full_block (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
__u16 magic;
__u32 block;
magic = FULL_BLOCK_START_MAGIC;
fwrite16 (&magic);
fwrite_le16 (&magic);
block = bh->b_blocknr;
fwrite32 (&block);
fwrite_le32 (&block);
fwrite (bh->b_data, 4096, 1, stdout);
sent += 4096;
had_to_be_sent += 4096;
fwrite (bh->b_data, fs->fs_blocksize, 1, stdout);
sent_bytes += fs->fs_blocksize;
had_to_be_sent += fs->fs_blocksize;
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 ++;
}
#if 0
/* 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)
static int check_unfm_ptr (reiserfs_filsys_t * fs, __u32 block)
{
if (block >= SB_BLOCK_COUNT (fs))
return 1;
@@ -349,17 +373,17 @@ static int check_unfm_ptr (reiserfs_filsys_t fs, __u32 block)
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)
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*/))
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;
@@ -369,7 +393,7 @@ static int can_pack_leaf (reiserfs_filsys_t fs, struct buffer_head * bh)
/* 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)
static void pack_leaf (reiserfs_filsys_t * fs, struct buffer_head * bh)
{
int i;
struct item_head * ih;
@@ -377,60 +401,81 @@ static void pack_leaf (reiserfs_filsys_t fs, struct buffer_head * bh)
__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);
/* 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->s_hash_function) << 8));
fwrite16 (&v16);
v16 = (LEAF_START_MAGIC | (func2code (fs->fs_hash_function) << 8));
fwrite_le16 (&v16);
/* block number */
fwrite32 (&bh->b_blocknr);
fwrite_le32 (&bh->b_blocknr);
/* item number */
v16 = node_item_number (bh);
fwrite16 (&v16);
v16 = get_blkh_nr_items (B_BLK_HEAD (bh));
fwrite_le16 (&v16);
ih = B_N_PITEM_HEAD (bh, 0);
for (i = 0; i < node_item_number (bh); i ++, ih ++) {
for (i = 0; i < v16; i ++, ih ++) {
#if 0
v32 = ITEM_START_MAGIC;
fwrite32 (&v32);
#endif
pi.mask = 0;
pi.item_len = ih_item_len (ih);
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 (ih_key_format (ih) == KEY_FORMAT_2)
pi.mask |= NEW_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 && ih->ih_key.k_dir_id != (ih - 1)->ih_key.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 */
pi.mask |= DIR_ID;
set_pi_mask (&pi, get_pi_mask (&pi) | DIR_ID);
}
// k_object_id
if (!i || (i && ih->ih_key.k_objectid != (ih - 1)->ih_key.k_objectid)) {
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 */
pi.mask |= OBJECT_ID;
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)) {
if (get_offset (&ih->ih_key) > 0xffffffffULL)
pi.mask |= OFFSET_BITS_64;
else
pi.mask |= OFFSET_BITS_32;
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))
@@ -448,24 +493,26 @@ static void pack_leaf (reiserfs_filsys_t fs, struct buffer_head * bh)
}
v16 = LEAF_END_MAGIC;
fwrite16 (&v16);
fwrite_le16 (&v16);
had_to_be_sent += fs->fs_blocksize;
packed_leaves ++;
had_to_be_sent += 4096;
return;
}
static int can_pack_internal (reiserfs_filsys_t fs, struct buffer_head * bh)
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)
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;
@@ -475,83 +522,132 @@ static void pack_internal (reiserfs_filsys_t fs, struct buffer_head * bh)
}
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)
static void send_block (reiserfs_filsys_t * fs, struct buffer_head * bh, int send_unknown)
{
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
packed ++;
type = who_is_this (bh->b_data, bh->b_size);
switch (type) {
case THE_LEAF:
pack_leaf (fs, bh);
break;
reiserfs_bitmap_set_bit (what_packed, bh->b_blocknr);
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)
static void pack_frozen_data (reiserfs_filsys_t * fs)
{
int i;
struct buffer_head * bh;
unsigned long block;
__u16 magic16;
int sent_journal_start_magic = 0;
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->s_sbh);
reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", SB_BMAP_NR (fs));
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 */
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);
/* 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)
void pack_partition (reiserfs_filsys_t * fs)
{
int i, j;
struct buffer_head tmp, * bh;
int nr_to_read = BLOCKS_PER_READ;
int i;
struct buffer_head * bh;
__u32 magic32;
__u16 blocksize;
__u16 magic16;
@@ -559,94 +655,61 @@ void pack_partition (reiserfs_filsys_t fs)
magic32 = REISERFS_SUPER_MAGIC;
fwrite32 (&magic32);
blocksize = fs->s_blocksize;
fwrite16 (&blocksize);
fwrite_le32 (&magic32);
tmp.b_size = blocksize;
blocksize = fs->fs_blocksize;
fwrite_le16 (&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));
}
/* 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);
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));
/* what's left */
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);
}
}
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;
fwrite16 (&magic16);
fprintf (stderr, "Packed\n\tleaves %d\n"
fwrite_le16 (&magic16);
fprintf (stderr, "\nPacked %d blocks:\n"
"\tcompessed %d\n"
"\tfull blocks %d\n"
"\t\tof journal %d\n"
"\t\tleaves with broken block head %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);
packed,
packed_leaves, full_blocks, having_ih_array,
bad_leaves, internals, descs);
if (where_to_save)
reiserfs_bitmap_save (where_to_save, what_packed);
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)
void pack_one_block (reiserfs_filsys_t * fs, unsigned long block)
{
__u32 magic32;
__u16 magic16;
@@ -654,12 +717,12 @@ void pack_one_block (reiserfs_filsys_t fs, unsigned long block)
// reiserfs magic
magic32 = REISERFS_SUPER_MAGIC;
fwrite32 (&magic32);
fwrite_le32 (&magic32);
// blocksize
fwrite16 (&fs->s_blocksize);
fwrite_le16 (&fs->fs_blocksize);
bh = bread (fs->s_dev, block, fs->s_blocksize);
bh = bread (fs->fs_dev, block, fs->fs_blocksize);
if (who_is_this (bh->b_data, bh->b_size) == THE_LEAF)
pack_leaf (fs, bh);
@@ -670,10 +733,9 @@ void pack_one_block (reiserfs_filsys_t fs, unsigned long block)
// end magic
magic16 = END_MAGIC;
fwrite16 (&magic16);
fwrite_le16 (&magic16);
fprintf (stderr, "Packed\n\tleaves %d\n\tfull block %d\n\tcorrupted leaves %d\n",
packed_leaves, full_blocks, bad_leaves);
fprintf (stderr, "Done\n");
}
@@ -682,7 +744,7 @@ void pack_one_block (reiserfs_filsys_t fs, unsigned long block)
// 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'
// the the second mode standard input will be converted to the reiserfs leaf on 'file'
//
static int do_unpack (char * file)
{
@@ -714,7 +776,7 @@ static int do_unpack (char * file)
return 0;
}
static int do_pack (char * file, int block)
static int do_pack (char * file, unsigned long block)
{
int fd;
struct buffer_head * bh;
@@ -762,4 +824,7 @@ int main (int argc, char ** argv)
return 0;
}
#endif
#endif /* 0 */