diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-06-21 21:07:38 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-06-21 21:07:38 -0400 |
commit | 8a480350952f6f0fdbce54326b6d847e66368897 (patch) | |
tree | 8f09d26e06335f00dec8166acaae425cc30c3523 /misc/e2image.c | |
parent | 8a6ede8b7a8d5be0d49d6bfa7616537b61dfdc1b (diff) | |
download | e2fsprogs-8a480350952f6f0fdbce54326b6d847e66368897.tar.gz |
Fix encoding for rec_len in directories for >= 64k blocksize file systems
Previously e2fsprogs interpreted 0 for a rec_len of 65536 (which could
occur if the directory block is completely empty in 64k blocksize
filesystems), while the kernel interpreted 65535 to mean 65536. The
kernel will accept both to mean 65536, and encodes 65535 to be 65536.
This commit changes e2fsprogs to match.
We add the encoding agreed upon for 128k and 256k filesystems, but we
don't enable support for these larger block sizes, since they haven't
been fully tested.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'misc/e2image.c')
-rw-r--r-- | misc/e2image.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/misc/e2image.c b/misc/e2image.c index dd2a1caa..83c1cca9 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -339,11 +339,14 @@ static void write_block(int fd, char *buf, int sparse_offset, int name_id[256]; +#define EXT4_MAX_REC_LEN ((1<<16)-1) + static void scramble_dir_block(ext2_filsys fs, blk_t blk, char *buf) { char *p, *end, *cp; struct ext2_dir_entry_2 *dirent; - int rec_len, id, len; + unsigned int rec_len; + int id, len; end = buf + fs->blocksize; for (p = buf; p < end-8; p += rec_len) { @@ -352,8 +355,10 @@ static void scramble_dir_block(ext2_filsys fs, blk_t blk, char *buf) #ifdef WORDS_BIGENDIAN rec_len = ext2fs_swab16(rec_len); #endif - rec_len = (rec_len || fs->blocksize < 65536) ? - rec_len : 65536; + if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0) + rec_len = fs->blocksize; + else + rec_len = (rec_len & 65532) | ((rec_len & 3) << 16); #if 0 printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len); #endif @@ -363,8 +368,10 @@ static void scramble_dir_block(ext2_filsys fs, blk_t blk, char *buf) "bad rec_len (%d)\n", (unsigned long) blk, rec_len); rec_len = end - p; + (void) ext2fs_set_rec_len(fs, rec_len, + (struct ext2_dir_entry *) dirent); #ifdef WORDS_BIGENDIAN - dirent->rec_len = ext2fs_swab16(rec_len); + dirent->rec_len = ext2fs_swab16(dirent->rec_len); #endif continue; } |