Handle items with old version key on new version reiserfs partition.

This commit is contained in:
jochen 2000-11-27 12:06:25 +00:00
parent 110ade1398
commit 8eff936f97
2 changed files with 43 additions and 21 deletions

View file

@ -1,3 +1,13 @@
2000-11-27 Jochen Hoenicke <jochen@gnu.org>
* stage2/fsys_reiserfs.c: Handle items with old version key on
new version reiserfs partition.
(K_OFFSET): Removed.
(IH_KEY_OFFSET): New Macro, which checks item head version.
(IH_KEY_ISOFFSET): Likewise.
(reiserfs_read): Use new macros.
(reiserfs_dir): Fixed version check for >4GB stat entries.
2000-11-27 OKUJI Yoshinori <okuji@gnu.org> 2000-11-27 OKUJI Yoshinori <okuji@gnu.org>
* stage2/common.c (init_bios_info) [!STAGE1_5]: Don't call * stage2/common.c (init_bios_info) [!STAGE1_5]: Don't call

View file

@ -173,8 +173,6 @@ struct key
}; };
#define KEY_SIZE (sizeof (struct key)) #define KEY_SIZE (sizeof (struct key))
#define K_OFFSET(key) (INFO->version < 2 ? \
key.u.v1.k_offset : key.u.v2.k_offset)
/* Header of a disk block. More precisely, header of a formatted leaf /* Header of a disk block. More precisely, header of a formatted leaf
or internal node, and not the header of an unformatted node. */ or internal node, and not the header of an unformatted node. */
@ -205,13 +203,26 @@ struct item_head
u; u;
__u16 ih_item_len; /* total size of the item body */ __u16 ih_item_len; /* total size of the item body */
__u16 ih_item_location; /* an offset to the item body within the block */ __u16 ih_item_location; /* an offset to the item body within the block */
__u16 ih_version; /* 0 for all old items, 2 for new __u16 ih_version; /* ITEM_VERSION_1 for all old items,
ones. Highest bit is set by fsck ITEM_VERSION_2 for new ones.
Highest bit is set by fsck
temporary, cleaned after all done */ temporary, cleaned after all done */
}; };
/* size of item header */ /* size of item header */
#define IH_SIZE (sizeof (struct item_head)) #define IH_SIZE (sizeof (struct item_head))
#define ITEM_VERSION_1 0
#define ITEM_VERSION_2 1
#define IH_KEY_OFFSET(ih) (INFO->version < 2 \
|| (ih)->ih_version == ITEM_VERSION_1 \
? (ih)->ih_key.u.v1.k_offset \
: (ih)->ih_key.u.v2.k_offset)
#define IH_KEY_ISTYPE(ih, type) (INFO->version < 2 \
|| (ih)->ih_version == ITEM_VERSION_1 \
? (ih)->ih_key.u.v1.k_uniqueness == V1_##type \
: (ih)->ih_key.u.v2.k_type == V2_##type)
struct disk_child struct disk_child
{ {
unsigned long dc_block_number; /* Disk child's block number. */ unsigned long dc_block_number; /* Disk child's block number. */
@ -710,11 +721,12 @@ next_key (void)
char *cache; char *cache;
#ifdef REISERDEBUG #ifdef REISERDEBUG
printf ("next_key:\n old key %d:%d:%d:%d\n", printf ("next_key:\n old ih: key %d:%d:%d:%d version:%d\n",
INFO->current_ih->ih_key.k_dir_id, INFO->current_ih->ih_key.k_dir_id,
INFO->current_ih->ih_key.k_objectid, INFO->current_ih->ih_key.k_objectid,
INFO->current_ih->ih_key.u.v1.k_offset, INFO->current_ih->ih_key.u.v1.k_offset,
INFO->current_ih->ih_key.u.v1.k_uniqueness); INFO->current_ih->ih_key.u.v1.k_uniqueness,
INFO->current_ih->ih_version);
#endif /* REISERDEBUG */ #endif /* REISERDEBUG */
if (ih == &ITEMHEAD[BLOCKHEAD (LEAF)->blk_nr_item]) if (ih == &ITEMHEAD[BLOCKHEAD (LEAF)->blk_nr_item])
@ -772,11 +784,12 @@ next_key (void)
INFO->current_ih = ih; INFO->current_ih = ih;
INFO->current_item = &LEAF[ih->ih_item_location]; INFO->current_item = &LEAF[ih->ih_item_location];
#ifdef REISERDEBUG #ifdef REISERDEBUG
printf (" new key %d:%d:%d:%d\n", printf (" new ih: key %d:%d:%d:%d version:%d\n",
INFO->current_ih->ih_key.k_dir_id, INFO->current_ih->ih_key.k_dir_id,
INFO->current_ih->ih_key.k_objectid, INFO->current_ih->ih_key.k_objectid,
INFO->current_ih->ih_key.u.v1.k_offset, INFO->current_ih->ih_key.u.v1.k_offset,
INFO->current_ih->ih_key.u.v1.k_uniqueness); INFO->current_ih->ih_key.u.v1.k_uniqueness,
INFO->current_ih->ih_version);
#endif /* REISERDEBUG */ #endif /* REISERDEBUG */
return 1; return 1;
} }
@ -866,12 +879,12 @@ reiserfs_read (char *buf, int len)
char *prev_buf = buf; char *prev_buf = buf;
#ifdef REISERDEBUG #ifdef REISERDEBUG
printf ("reiserfs_read: filepos=%d len=%d, offset=%d\n", printf ("reiserfs_read: filepos=%d len=%d, offset=%x:%x\n",
filepos, len, K_OFFSET (INFO->current_ih->ih_key) - 1); filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1);
#endif /* REISERDEBUG */ #endif /* REISERDEBUG */
if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
|| K_OFFSET (INFO->current_ih->ih_key) > filepos + 1) || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1)
{ {
search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid); search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid);
goto get_next_key; goto get_next_key;
@ -882,7 +895,7 @@ reiserfs_read (char *buf, int len)
if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid) if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid)
break; break;
offset = filepos - K_OFFSET (INFO->current_ih->ih_key) + 1; offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1;
blocksize = INFO->current_ih->ih_item_len; blocksize = INFO->current_ih->ih_item_len;
#ifdef REISERDEBUG #ifdef REISERDEBUG
@ -890,9 +903,7 @@ reiserfs_read (char *buf, int len)
filepos, len, offset, blocksize); filepos, len, offset, blocksize);
#endif /* REISERDEBUG */ #endif /* REISERDEBUG */
if ((INFO->version < 2 if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT)
? INFO->current_ih->ih_key.u.v1.k_uniqueness == V1_TYPE_DIRECT
: INFO->current_ih->ih_key.u.v2.k_type == V2_TYPE_DIRECT)
&& offset < blocksize) && offset < blocksize)
{ {
to_read = blocksize - offset; to_read = blocksize - offset;
@ -914,9 +925,7 @@ reiserfs_read (char *buf, int len)
memcpy (buf, INFO->current_item + offset, to_read); memcpy (buf, INFO->current_item + offset, to_read);
goto update_buf_len; goto update_buf_len;
} }
else if (INFO->version < 2 else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT))
? INFO->current_ih->ih_key.u.v1.k_uniqueness == V1_TYPE_INDIRECT
: INFO->current_ih->ih_key.u.v2.k_type == V2_TYPE_INDIRECT)
{ {
blocksize = (blocksize >> 2) << INFO->fullblocksize_shift; blocksize = (blocksize >> 2) << INFO->fullblocksize_shift;
@ -1075,7 +1084,8 @@ reiserfs_dir (char *dirname)
/* If this is a new stat data and size is > 4GB set filemax to /* If this is a new stat data and size is > 4GB set filemax to
* maximum * maximum
*/ */
if (INFO->current_ih->ih_version == 2 if (INFO->version >= 2
&& INFO->current_ih->ih_version == ITEM_VERSION_2
&& ((struct stat_data *) INFO->current_item)->sd_size_hi > 0) && ((struct stat_data *) INFO->current_item)->sd_size_hi > 0)
filemax = 0xffffffff; filemax = 0xffffffff;
@ -1108,10 +1118,12 @@ reiserfs_dir (char *dirname)
if (! next_key ()) if (! next_key ())
return 0; return 0;
#ifdef REISERDEBUG #ifdef REISERDEBUG
printf ("key %d:%d:%d:%d\n", INFO->current_ih->ih_key.k_dir_id, printf ("ih: key %d:%d:%d:%d version:%d\n",
INFO->current_ih->ih_key.k_dir_id,
INFO->current_ih->ih_key.k_objectid, INFO->current_ih->ih_key.k_objectid,
INFO->current_ih->ih_key.u.v1.k_offset, INFO->current_ih->ih_key.u.v1.k_offset,
INFO->current_ih->ih_key.u.v1.k_uniqueness); INFO->current_ih->ih_key.u.v1.k_uniqueness,
INFO->current_ih->ih_version);
#endif /* REISERDEBUG */ #endif /* REISERDEBUG */
if (INFO->current_ih->ih_key.k_objectid != objectid) if (INFO->current_ih->ih_key.k_objectid != objectid)