|
Re: e2fsck and large inodes: msg#00015file-systems.ext2.devel
Hi Theodore! If you have a minute, review this patch, please. all tests (I mean formal testing by make -C tests) passed. with best wishes, Alex %patch Index: e2fsprogs-1.34/debugfs/debugfs.c =================================================================== --- e2fsprogs-1.34.orig/debugfs/debugfs.c 2003-10-15 17:19:56.000000000 +0400 +++ e2fsprogs-1.34/debugfs/debugfs.c 2003-10-21 20:12:39.000000000 +0400 @@ -33,6 +33,8 @@ #include "uuid/uuid.h" #include "e2p/e2p.h" +#include <ext2fs/ext2_ext_attr.h> + #include "../version.h" extern ss_request_table debug_cmds; @@ -366,6 +368,68 @@ return 0; } +void dump_xattr_string(FILE *out, const unsigned char *str, int len) +{ + int printable = 1; + int i; + + /* check is string printable? */ + for (i = 0; i < len; i++) + if (!isprint(str[i])) { + printable = 0; + break; + } + + for (i = 0; i < len; i++) + if (printable) + fprintf(out, "%c", str[i]); + else + fprintf(out, "%02x ", str[i]); +} + +void internal_dump_inode_extra(FILE *out, const char *prefix, + ext2_ino_t inode_num, struct ext2_inode_large *inode) +{ + struct ext2_ext_attr_entry *entry; + __u32 *magic; + char *start, *end; + int storage_size; + int i; + + if (inode->i_extra_isize > EXT2_INODE_SIZE(current_fs->super) - + EXT2_GOOD_OLD_INODE_SIZE) { + fprintf(stderr, "invalid inode->i_extra_isize (%u)\n", + inode->i_extra_isize); + return; + } + storage_size = EXT2_INODE_SIZE(current_fs->super) - + EXT2_GOOD_OLD_INODE_SIZE - + inode->i_extra_isize; + magic = (__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE + + inode->i_extra_isize); + if (*magic == EXT2_EXT_ATTR_MAGIC) { + fprintf(out, "Extended attributes stored in inode body: \n"); + end = (char *) inode + EXT2_INODE_SIZE(current_fs->super); + start = (char *) magic + sizeof(__u32); + entry = (struct ext2_ext_attr_entry *) start; + while (!EXT2_EXT_IS_LAST_ENTRY(entry)) { + struct ext2_ext_attr_entry *next = + EXT2_EXT_ATTR_NEXT(entry); + if (entry->e_value_size > storage_size || + (char *) next >= end) { + fprintf(out, "invalid EA entry in inode\n"); + return; + } + fprintf(out, " "); + dump_xattr_string(out, entry->e_name, entry->e_name_len); + fprintf(out, " = \""); + dump_xattr_string(out, start + entry->e_value_offs, + entry->e_value_size); + fprintf(out, "\" (%d)\n", entry->e_value_size); + entry = next; + } + } +} static void dump_blocks(FILE *f, const char *prefix, ext2_ino_t inode) { @@ -453,6 +517,9 @@ if (inode->i_dtime) fprintf(out, "%sdtime: 0x%08x -- %s", prefix, inode->i_dtime, time_to_string(inode->i_dtime)); + if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE) + internal_dump_inode_extra(out, prefix, inode_num, + (struct ext2_inode_large *) inode); if (LINUX_S_ISLNK(inode->i_mode) && inode->i_blocks == 0) fprintf(out, "%sFast_link_dest: %.*s\n", prefix, (int) inode->i_size, (char *)inode->i_block); @@ -460,27 +527,40 @@ dump_blocks(out, prefix, inode_num); } -static void dump_inode(ext2_ino_t inode_num, struct ext2_inode inode) +static void dump_inode(ext2_ino_t inode_num, struct ext2_inode *inode) { FILE *out; out = open_pager(); - internal_dump_inode(out, "", inode_num, &inode, 1); + internal_dump_inode(out, "", inode_num, inode, 1); close_pager(out); } void do_stat(int argc, char *argv[]) { ext2_ino_t inode; - struct ext2_inode inode_buf; + struct ext2_inode * inode_buf; - if (common_inode_args_process(argc, argv, &inode, 0)) + inode_buf = (struct ext2_inode *) + malloc(EXT2_INODE_SIZE(current_fs->super)); + if (!inode_buf) { + fprintf(stderr, "do_stat: can't allocate buffer\n"); return; + } - if (debugfs_read_inode(inode, &inode_buf, argv[0])) + if (common_inode_args_process(argc, argv, &inode, 0)) { + free(inode_buf); return; + } + + if (debugfs_read_inode_full(inode, inode_buf, argv[0], + EXT2_INODE_SIZE(current_fs->super))) { + free(inode_buf); + return; + } - dump_inode(inode,inode_buf); + dump_inode(inode, inode_buf); + free(inode_buf); return; } Index: e2fsprogs-1.34/debugfs/util.c =================================================================== --- e2fsprogs-1.34.orig/debugfs/util.c 2003-10-15 16:57:17.000000000 +0400 +++ e2fsprogs-1.34/debugfs/util.c 2003-10-21 20:12:47.000000000 +0400 @@ -280,6 +280,19 @@ return 0; } +int debugfs_read_inode_full(ext2_ino_t ino, struct ext2_inode * inode, + const char *cmd, int bufsize) +{ + int retval; + + retval = ext2fs_read_inode_full(current_fs, ino, inode, bufsize); + if (retval) { + com_err(cmd, retval, "while reading inode %u", ino); + return 1; + } + return 0; +} + int debugfs_read_inode(ext2_ino_t ino, struct ext2_inode * inode, const char *cmd) { Index: e2fsprogs-1.34/lib/ext2fs/ext2_fs.h =================================================================== --- e2fsprogs-1.34.orig/lib/ext2fs/ext2_fs.h 2003-10-15 17:19:56.000000000 +0400 +++ e2fsprogs-1.34/lib/ext2fs/ext2_fs.h 2003-10-21 18:38:57.000000000 +0400 @@ -303,6 +303,65 @@ } osd2; /* OS dependent 2 */ }; +/* + * Permanent part of an large inode on a disk + */ +struct ext2_inode_large { + __u16 i_mode; /* File mode */ + __u16 i_uid; /* Low 16 bits of Owner Uid */ + __u32 i_size; /* Size in bytes */ + __u32 i_atime; /* Access time */ + __u32 i_ctime; /* Creation time */ + __u32 i_mtime; /* Modification time */ + __u32 i_dtime; /* Deletion Time */ + __u16 i_gid; /* Low 16 bits of Group Id */ + __u16 i_links_count; /* Links count */ + __u32 i_blocks; /* Blocks count */ + __u32 i_flags; /* File flags */ + union { + struct { + __u32 l_i_reserved1; + } linux1; + struct { + __u32 h_i_translator; + } hurd1; + struct { + __u32 m_i_reserved1; + } masix1; + } osd1; /* OS dependent 1 */ + __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ + __u32 i_generation; /* File version (for NFS) */ + __u32 i_file_acl; /* File ACL */ + __u32 i_dir_acl; /* Directory ACL */ + __u32 i_faddr; /* Fragment address */ + union { + struct { + __u8 l_i_frag; /* Fragment number */ + __u8 l_i_fsize; /* Fragment size */ + __u16 i_pad1; + __u16 l_i_uid_high; /* these 2 fields */ + __u16 l_i_gid_high; /* were reserved2[0] */ + __u32 l_i_reserved2; + } linux2; + struct { + __u8 h_i_frag; /* Fragment number */ + __u8 h_i_fsize; /* Fragment size */ + __u16 h_i_mode_high; + __u16 h_i_uid_high; + __u16 h_i_gid_high; + __u32 h_i_author; + } hurd2; + struct { + __u8 m_i_frag; /* Fragment number */ + __u8 m_i_fsize; /* Fragment size */ + __u16 m_pad1; + __u32 m_i_reserved2[2]; + } masix2; + } osd2; /* OS dependent 2 */ + __u16 i_extra_isize; + __u16 i_pad1; +}; + #define i_size_high i_dir_acl #if defined(__KERNEL__) || defined(__linux__) Index: e2fsprogs-1.34/lib/ext2fs/inode.c =================================================================== --- e2fsprogs-1.34.orig/lib/ext2fs/inode.c 2003-10-15 16:57:17.000000000 +0400 +++ e2fsprogs-1.34/lib/ext2fs/inode.c 2003-10-21 20:06:19.000000000 +0400 @@ -377,8 +377,8 @@ } #endif -errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino, - struct ext2_inode *inode) +errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino, + struct ext2_inode *inode, int bufsize) { errcode_t retval; int extra_bytes = 0; @@ -448,11 +448,12 @@ #ifdef EXT2FS_ENABLE_SWAPFS if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) || (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) - ext2fs_swap_inode(scan->fs, inode, - (struct ext2_inode *) scan->temp_buffer, 0); + ext2fs_swap_inode_full(scan->fs, inode, + (struct ext2_inode *) scan->temp_buffer, 0, + bufsize); else #endif - *inode = *((struct ext2_inode *) scan->temp_buffer); + memcpy(inode, scan->temp_buffer, bufsize); if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES) retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE; scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES; @@ -460,11 +461,12 @@ #ifdef EXT2FS_ENABLE_SWAPFS if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) || (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) - ext2fs_swap_inode(scan->fs, inode, - (struct ext2_inode *) scan->ptr, 0); + ext2fs_swap_inode_full(scan->fs, inode, + (struct ext2_inode *) scan->ptr, + 0, bufsize); else #endif - *inode = *((struct ext2_inode *) scan->ptr); + memcpy(inode, scan->ptr, bufsize); scan->ptr += scan->inode_size; scan->bytes_left -= scan->inode_size; if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) @@ -477,11 +479,15 @@ return retval; } -/* - * Functions to read and write a single inode. - */ -errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino, - struct ext2_inode * inode) +errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino, + struct ext2_inode *inode) +{ + return ext2fs_get_next_inode_full(scan, ino, inode, + sizeof(struct ext2_inode)); +} + +errcode_t ext2fs_read_inode_full (ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode * inode, int bufsize) { unsigned long group, block, block_nr, offset; char *ptr; @@ -503,10 +509,13 @@ return retval; } /* Check to see if it's in the inode cache */ - for (i=0; i < fs->icache->cache_size; i++) { - if (fs->icache->cache[i].ino == ino) { - *inode = fs->icache->cache[i].inode; - return 0; + if (bufsize == sizeof(struct ext2_inode)) { + /* only old good inode can be retrieve from the cache */ + for (i=0; i < fs->icache->cache_size; i++) { + if (fs->icache->cache[i].ino == ino) { + *inode = fs->icache->cache[i].inode; + return 0; + } } } if ((ino == 0) || (ino > fs->super->s_inodes_count)) @@ -537,16 +546,16 @@ offset &= (EXT2_BLOCK_SIZE(fs->super) - 1); ptr = ((char *) fs->icache->buffer) + (unsigned) offset; - memset(inode, 0, sizeof(struct ext2_inode)); length = EXT2_INODE_SIZE(fs->super); - if (length > sizeof(struct ext2_inode)) - length = sizeof(struct ext2_inode); + if (bufsize < length) + length = bufsize; + memset(inode, 0, length); if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) { clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset); memcpy((char *) inode, ptr, clen); length -= clen; - + retval = io_channel_read_blk(fs->io, block_nr+1, 1, fs->icache->buffer); if (retval) { @@ -559,11 +568,11 @@ fs->icache->buffer, length); } else memcpy((char *) inode, ptr, length); - + #ifdef EXT2FS_ENABLE_SWAPFS if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) - ext2fs_swap_inode(fs, inode, inode, 0); + ext2fs_swap_inode_full(fs, inode, inode, 0, length); #endif /* Update the inode cache */ @@ -574,15 +583,54 @@ return 0; } - -errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino, +/* + * Functions to read and write a single inode. + */ +errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino, struct ext2_inode * inode) { + return ext2fs_read_inode_full(fs, ino, inode, + sizeof(struct ext2_inode)); +} + +struct miovec { + char *iov_base; + int iov_len; +}; + +static void iovec_copy(char *buf, int bufsize, struct miovec *iov, + int iovnum, int *idx) +{ + int len; + + if (*idx >= iovnum) + return; + + while (*idx < iovnum && bufsize > 0) { + len = iov[*idx].iov_len; + if (bufsize < len) + len = bufsize; + + memcpy(buf, iov[*idx].iov_base, len); + iov[*idx].iov_len -= len; + iov[*idx].iov_base += len; + bufsize -= len; + buf += len; + + if (iov[*idx].iov_len == 0) + (*idx)++; + } +} + +errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode * inode, int bufsize) +{ unsigned long group, block, block_nr, offset; errcode_t retval; struct ext2_inode temp_inode; char *ptr; - int clen, length, i; + int clen, length, i, idx = 0, iovnum = 0; + struct miovec iov[2]; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -616,11 +664,22 @@ #ifdef EXT2FS_ENABLE_SWAPFS if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) - ext2fs_swap_inode(fs, &temp_inode, inode, 1); + ext2fs_swap_inode_full(fs, &temp_inode, inode, 1, bufsize); else #endif memcpy(&temp_inode, inode, sizeof(struct ext2_inode)); - + + iov[0].iov_base = (char *) &temp_inode; + iov[0].iov_len = sizeof(struct ext2_inode); + iovnum = 1; + + if (bufsize > sizeof(struct ext2_inode)) { + iov[1].iov_base = ((char *) inode) + + sizeof(struct ext2_inode); + iov[1].iov_len = bufsize - sizeof(struct ext2_inode); + iovnum = 2; + } + group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super); offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) * EXT2_INODE_SIZE(fs->super); @@ -631,10 +690,8 @@ offset &= (EXT2_BLOCK_SIZE(fs->super) - 1); ptr = (char *) fs->icache->buffer + (unsigned) offset; - length = EXT2_INODE_SIZE(fs->super); + length = bufsize; clen = length; - if (length > sizeof(struct ext2_inode)) - length = sizeof(struct ext2_inode); if (fs->icache->buffer_blk != block_nr) { retval = io_channel_read_blk(fs->io, block_nr, 1, @@ -650,7 +707,9 @@ } else { length = 0; } - memcpy(ptr, &temp_inode, clen); + + iovec_copy(ptr, clen, iov, iovnum, &idx); + retval = io_channel_write_blk(fs->io, block_nr, 1, fs->icache->buffer); if (retval) return retval; @@ -663,8 +722,7 @@ return retval; } fs->icache->buffer_blk = block_nr; - memcpy(fs->icache->buffer, ((char *) &temp_inode) + clen, - length); + iovec_copy(fs->icache->buffer, length, iov, iovnum, &idx); retval = io_channel_write_blk(fs->io, block_nr, 1, fs->icache->buffer); @@ -676,6 +734,13 @@ return 0; } +errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode * inode) +{ + return ext2fs_write_inode_full(fs, ino, inode, + sizeof(struct ext2_inode)); +} + errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks) { struct ext2_inode inode; Index: e2fsprogs-1.34/lib/ext2fs/swapfs.c =================================================================== --- e2fsprogs-1.34.orig/lib/ext2fs/swapfs.c 2002-10-20 10:24:09.000000000 +0400 +++ e2fsprogs-1.34/lib/ext2fs/swapfs.c 2003-10-21 18:38:57.000000000 +0400 @@ -17,6 +17,7 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include <ext2fs/ext2_ext_attr.h> #ifdef EXT2FS_ENABLE_SWAPFS void ext2fs_swap_super(struct ext2_super_block * sb) @@ -72,12 +73,13 @@ gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count); } -void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t, - struct ext2_inode *f, int hostorder) +void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, + struct ext2_inode_large *f, int hostorder, int bufsize) { unsigned i; int islnk = 0; - + __u32 *eaf, *eat; + if (hostorder && LINUX_S_ISLNK(f->i_mode)) islnk = 1; t->i_mode = ext2fs_swab16(f->i_mode); @@ -145,5 +147,44 @@ ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]); break; } + + if (bufsize < sizeof(struct ext2_inode) + sizeof(__u16)) + return; /* no i_extra_isize field */ + + t->i_extra_isize = ext2fs_swab16(f->i_extra_isize); + if (t->i_extra_isize > EXT2_INODE_SIZE(fs->super) - + sizeof(struct ext2_inode)) { + /* this is error case: i_extra_size is too large */ + return; + } + + i = sizeof(struct ext2_inode) + t->i_extra_isize + sizeof(__u32); + if (bufsize < i) + return; /* no space for EA magic */ + + eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) + + f->i_extra_isize); + + if (ext2fs_swab32(*eaf) != EXT2_EXT_ATTR_MAGIC) + return; /* it seems no magic here */ + + eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) + + f->i_extra_isize); + *eat = ext2fs_swab32(*eaf); + + /* convert EA(s) */ + ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1), + bufsize - sizeof(struct ext2_inode) - + t->i_extra_isize - sizeof(__u32), 0); + } + +void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t, + struct ext2_inode *f, int hostorder) +{ + ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t, + (struct ext2_inode_large *) f, hostorder, + sizeof(struct ext2_inode)); +} + #endif Index: e2fsprogs-1.34/e2fsck/util.c =================================================================== --- e2fsprogs-1.34.orig/e2fsck/util.c 2003-03-17 18:01:21.000000000 +0300 +++ e2fsprogs-1.34/e2fsck/util.c 2003-10-21 18:38:57.000000000 +0400 @@ -360,6 +360,20 @@ } } +extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino, + struct ext2_inode * inode, int bufsize, + const char *proc) +{ + int retval; + + retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize); + if (retval) { + com_err("ext2fs_write_inode", retval, + _("while writing inode %ld in %s"), ino, proc); + fatal_error(ctx, 0); + } +} + extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, struct ext2_inode * inode, const char *proc) { Index: e2fsprogs-1.34/e2fsck/problem.h =================================================================== --- e2fsprogs-1.34.orig/e2fsck/problem.h 2003-03-15 06:19:09.000000000 +0300 +++ e2fsprogs-1.34/e2fsck/problem.h 2003-10-22 03:09:59.000000000 +0400 @@ -404,6 +404,25 @@ /* HTREE too deep */ #define PR_1_HTREE_DEPTH 0x01004C +/* inode->i_size is too long */ +#define PR_1_EXTRA_ISIZE 0x01004D + +/* attribute name is too long */ +#define PR_1_ATTR_NAME_LEN 0x01004E + +/* wrong EA value offset */ +#define PR_1_ATTR_VALUE_OFFSET 0x01004F + +/* wrong EA blocknumber */ +#define PR_1_ATTR_VALUE_BLOCK 0x010050 + +/* wrong EA value size */ +#define PR_1_ATTR_VALUE_SIZE 0x010051 + +/* wrong EA hash value */ +#define PR_1_ATTR_HASH 0x010052 + + /* * Pass 1b errors */ Index: e2fsprogs-1.34/e2fsck/problem.c =================================================================== --- e2fsprogs-1.34.orig/e2fsck/problem.c 2003-06-25 02:06:03.000000000 +0400 +++ e2fsprogs-1.34/e2fsck/problem.c 2003-10-21 18:38:57.000000000 +0400 @@ -39,7 +39,8 @@ #define PROMPT_SUPPRESS 16 #define PROMPT_UNLINK 17 #define PROMPT_CLEAR_HTREE 18 -#define PROMPT_NULL 19 +#define PROMPT_CLEAR_EA 19 +#define PROMPT_NULL 20 /* * These are the prompts which are used to ask the user if they want @@ -65,7 +66,8 @@ N_("Suppress messages"),/* 16 */ N_("Unlink"), /* 17 */ N_("Clear HTree index"),/* 18 */ - "", /* 19 */ + N_("Clear EA(s)"), /* 19 */ + "", /* 20 */ }; /* @@ -698,6 +700,36 @@ N_("@h %i has a tree depth (%N) which is too big\n"), PROMPT_CLEAR_HTREE, PR_PREEN_OK }, + /* invalid inode->i_extra_isize */ + { PR_1_EXTRA_ISIZE, + N_("@i %i has a extra size (%IS) which is invalid\n"), + PROMPT_FIX, PR_PREEN_OK }, + + /* invalid ea entry->e_name_len */ + { PR_1_ATTR_NAME_LEN, + N_("@a in @i %i has a namelen (%N) which is invalid\n"), + PROMPT_CLEAR_EA, PR_PREEN_OK }, + + /* invalid ea entry->e_value_size */ + { PR_1_ATTR_VALUE_SIZE, + N_("@a in @i %i has a value size (%N) which is invalid\n"), + PROMPT_CLEAR_EA, PR_PREEN_OK }, + + /* invalid ea entry->e_value_offs */ + { PR_1_ATTR_VALUE_OFFSET, + N_("@a in @i %i has a value offset (%N) which is invalid\n"), + PROMPT_CLEAR_EA, PR_PREEN_OK }, + + /* invalid ea entry->e_value_block */ + { PR_1_ATTR_VALUE_BLOCK, + N_("@a in @i %i has a value block (%N) which is invalid (must be 0)\n"), + PROMPT_CLEAR_EA, PR_PREEN_OK }, + + /* invalid ea entry->e_hash */ + { PR_1_ATTR_HASH, + N_("@a in @i %i has a hash (%N) which is invalid (must be 0)\n"), + PROMPT_CLEAR_EA, PR_PREEN_OK }, + /* Pass 1b errors */ /* Pass 1B: Rescan for duplicate/bad blocks */ Index: e2fsprogs-1.34/e2fsck/message.c =================================================================== --- e2fsprogs-1.34.orig/e2fsck/message.c 2003-04-28 01:34:13.000000000 +0400 +++ e2fsprogs-1.34/e2fsck/message.c 2003-10-21 18:38:57.000000000 +0400 @@ -25,6 +25,7 @@ * %g <group> integer * %i <ino> inode number * %Is <inode> -> i_size + * %IS <inode> -> i_extra_isize * %Ib <inode> -> i_blocks * %Il <inode> -> i_links_count * %Im <inode> -> i_mode @@ -235,6 +236,7 @@ struct problem_context *ctx) { struct ext2_inode *inode; + struct ext2_inode_large *large_inode; char * time_str; time_t t; @@ -242,7 +244,8 @@ goto no_inode; inode = ctx->inode; - + large_inode = (struct ext2_inode_large *) inode; + switch (ch) { case 's': if (LINUX_S_ISDIR(inode->i_mode)) @@ -260,6 +263,9 @@ #endif } break; + case 'S': + printf("%u", large_inode->i_extra_isize); + break; case 'b': printf("%u", inode->i_blocks); break; Index: e2fsprogs-1.34/lib/ext2fs/ext2_ext_attr.h =================================================================== --- e2fsprogs-1.34.orig/lib/ext2fs/ext2_ext_attr.h 2003-03-06 19:10:16.000000000 +0300 +++ e2fsprogs-1.34/lib/ext2fs/ext2_ext_attr.h 2003-10-21 18:38:57.000000000 +0400 @@ -28,7 +28,7 @@ __u32 e_value_block; /* disk block attribute is stored on (n/i) */ __u32 e_value_size; /* size of attribute value */ __u32 e_hash; /* hash value of name and value */ -#if 0 +#if 1 char e_name[0]; /* attribute name */ #endif }; @@ -44,6 +44,7 @@ (char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->e_name_len)) ) #define EXT2_EXT_ATTR_SIZE(size) \ (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND) +#define EXT2_EXT_IS_LAST_ENTRY(entry) (*((__u32 *)(entry)) == 0UL) #ifdef __KERNEL__ # ifdef CONFIG_EXT2_FS_EXT_ATTR Index: e2fsprogs-1.34/lib/ext2fs/ext_attr.c =================================================================== --- e2fsprogs-1.34.orig/lib/ext2fs/ext_attr.c 2002-08-17 18:19:55.000000000 +0400 +++ e2fsprogs-1.34/lib/ext2fs/ext_attr.c 2003-10-21 18:38:57.000000000 +0400 @@ -24,28 +24,33 @@ #include "ext2fs.h" #ifdef EXT2FS_ENABLE_SWAPFS -void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from) +void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header) { struct ext2_ext_attr_header *from_header = (struct ext2_ext_attr_header *)from; struct ext2_ext_attr_header *to_header = (struct ext2_ext_attr_header *)to; struct ext2_ext_attr_entry *from_entry, *to_entry; - char *from_end = (char *)from_header + fs->blocksize; + char *from_end = (char *)from_header + bufsize; int n; if (to_header != from_header) - memcpy(to_header, from_header, fs->blocksize); + memcpy(to_header, from_header, bufsize); + + from_entry = (struct ext2_ext_attr_entry *)from_header; + to_entry = (struct ext2_ext_attr_entry *)to_header; + + if (has_header) { + to_header->h_magic = ext2fs_swab32(from_header->h_magic); + to_header->h_blocks = ext2fs_swab32(from_header->h_blocks); + to_header->h_refcount = ext2fs_swab32(from_header->h_refcount); + for (n=0; n<4; n++) + to_header->h_reserved[n] = + ext2fs_swab32(from_header->h_reserved[n]); + from_entry = (struct ext2_ext_attr_entry *)(from_header+1); + to_entry = (struct ext2_ext_attr_entry *)(to_header+1); + } - to_header->h_magic = ext2fs_swab32(from_header->h_magic); - to_header->h_blocks = ext2fs_swab32(from_header->h_blocks); - to_header->h_refcount = ext2fs_swab32(from_header->h_refcount); - for (n=0; n<4; n++) - to_header->h_reserved[n] = - ext2fs_swab32(from_header->h_reserved[n]); - - from_entry = (struct ext2_ext_attr_entry *)(from_header+1); - to_entry = (struct ext2_ext_attr_entry *)(to_header+1); while ((char *)from_entry < from_end && *(__u32 *)from_entry) { to_entry->e_value_offs = ext2fs_swab16(from_entry->e_value_offs); @@ -69,7 +74,7 @@ #ifdef EXT2FS_ENABLE_SWAPFS if ((fs->flags & (EXT2_FLAG_SWAP_BYTES| EXT2_FLAG_SWAP_BYTES_READ)) != 0) - ext2fs_swap_ext_attr(fs, buf, buf); + ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1); #endif return 0; } @@ -87,7 +92,7 @@ if (retval) return retval; write_buf = buf; - ext2fs_swap_ext_attr(fs, buf, inbuf); + ext2fs_swap_ext_attr(buf, inbuf, fs->blocksize, 1); } else #endif write_buf = (char *) inbuf; Index: e2fsprogs-1.34/lib/ext2fs/ext2fs.h =================================================================== --- e2fsprogs-1.34.orig/lib/ext2fs/ext2fs.h 2003-06-25 01:55:19.000000000 +0400 +++ e2fsprogs-1.34/lib/ext2fs/ext2fs.h 2003-10-21 18:38:57.000000000 +0400 @@ -677,7 +677,7 @@ extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir); /* ext_attr.c */ -void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from); +void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header); extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf); extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *buf); Index: e2fsprogs-1.34/e2fsck/pass1.c =================================================================== --- e2fsprogs-1.34.orig/e2fsck/pass1.c 2003-03-02 03:47:43.000000000 +0300 +++ e2fsprogs-1.34/e2fsck/pass1.c 2003-10-21 19:51:57.000000000 +0400 @@ -92,6 +92,7 @@ struct process_inode_block { ext2_ino_t ino; struct ext2_inode inode; + char extra[]; }; struct scan_callback_struct { @@ -239,6 +240,130 @@ e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1"); } +static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx) +{ + struct ext2_super_block *sb = ctx->fs->super; + struct ext2_inode_large *inode; + struct ext2_ext_attr_entry *entry; + char *start, *end, *name; + int storage_size, remain, offs; + int problem = 0; + + inode = (struct ext2_inode_large *) pctx->inode; + storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE - + inode->i_extra_isize; + start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE + + inode->i_extra_isize + sizeof(__u32); + end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super); + entry = (struct ext2_ext_attr_entry *) start; + + /* scan all entry's headers first */ + + /* take finish entry 0UL into account */ + remain = storage_size - sizeof(__u32); + offs = end - start; + + while (!EXT2_EXT_IS_LAST_ENTRY(entry)) { + + /* header eats this space */ + remain -= sizeof(struct ext2_ext_attr_entry); + + /* is attribute name valid? */ + if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) { + pctx->num = entry->e_name_len; + problem = PR_1_ATTR_NAME_LEN; + goto fix; + } + + /* attribute len eats this space */ + remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len); + + /* check value size */ + if (entry->e_value_size == 0 || entry->e_value_size > remain) { + pctx->num = entry->e_value_size; + problem = PR_1_ATTR_VALUE_SIZE; + goto fix; + } + + /* check value placement */ + if (entry->e_value_offs + entry->e_value_size != offs) { + pctx->num = entry->e_value_offs; + problem = PR_1_ATTR_VALUE_OFFSET; + goto fix; + } + + /* e_value_block must be 0 in inode's ea */ + if (entry->e_value_block != 0) { + pctx->num = entry->e_value_block; + problem = PR_1_ATTR_VALUE_BLOCK; + goto fix; + } + + /* e_hash must be 0 in inode's ea */ + if (entry->e_hash != 0) { + pctx->num = entry->e_hash; + problem = PR_1_ATTR_HASH; + goto fix; + } + + remain -= entry->e_value_size; + offs -= entry->e_value_size; + + entry = EXT2_EXT_ATTR_NEXT(entry); + } +fix: + /* + * it seems like a corruption. it's very unlikely we could repair + * EA(s) in automatic fashion -bzzz + */ +#if 0 + problem = PR_1_ATTR_HASH; +#endif + if (problem == 0 || !fix_problem(ctx, problem, pctx)) + return; + + /* simple remove all possible EA(s) */ + *((__u32 *)start) = 0UL; + e2fsck_write_inode_full(ctx, pctx->ino, inode, + EXT2_INODE_SIZE(sb), "pass1"); +} + +static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx) +{ + struct ext2_super_block *sb = ctx->fs->super; + struct ext2_inode_large *inode; + __u32 *eamagic; + int min, max; + + inode = (struct ext2_inode_large *) pctx->inode; + if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) { + /* this isn't large inode. so, nothing to check */ + return; + } + +#if 0 + printf("inode #%u, i_extra_size %d\n", pctx->ino, + inode->i_extra_isize); +#endif + /* i_extra_isize must cover i_extra_isize + i_pad1 at least */ + min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1); + max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE; + if (inode->i_extra_isize < min || inode->i_extra_isize > max) { + if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx)) + return; + inode->i_extra_isize = min; + e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode, + EXT2_INODE_SIZE(sb), "pass1"); + return; + } + + eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE + + inode->i_extra_isize); + if (*eamagic == EXT2_EXT_ATTR_MAGIC) { + /* it seems inode has an extended attribute(s) in body */ + check_ea_in_inode(ctx, pctx); + } +} void e2fsck_pass1(e2fsck_t ctx) { @@ -246,7 +371,7 @@ __u64 max_sizes; ext2_filsys fs = ctx->fs; ext2_ino_t ino; - struct ext2_inode inode; + struct ext2_inode *inode; ext2_inode_scan scan; char *block_buf; #ifdef RESOURCE_TRACK @@ -258,6 +383,7 @@ struct ext2_super_block *sb = ctx->fs->super; int imagic_fs; int busted_fs_time = 0; + int inode_extra_size; #ifdef RESOURCE_TRACK init_resource_track(&rtrack); @@ -332,10 +458,19 @@ ctx->flags |= E2F_FLAG_ABORT; return; } + + inode = (struct ext2_inode *) + e2fsck_allocate_memory(ctx, EXT2_INODE_SIZE(fs->super), + "inode (possible large)"); + + inode_extra_size = EXT2_INODE_SIZE(fs->super) - sizeof(struct ext2_inode); + if (inode_extra_size < 0) + inode_extra_size = 0; inodes_to_process = (struct process_inode_block *) e2fsck_allocate_memory(ctx, (ctx->process_inode_size * - sizeof(struct process_inode_block)), + (sizeof(struct process_inode_block) + + inode_extra_size)), "array of inodes to process"); process_inode_count = 0; @@ -373,7 +508,7 @@ return; } ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0); - ctx->stashed_inode = &inode; + ctx->stashed_inode = inode; scan_struct.ctx = ctx; scan_struct.block_buf = block_buf; ext2fs_set_inode_callback(scan, scan_callback, &scan_struct); @@ -384,7 +519,9 @@ busted_fs_time = 1; while (1) { - pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode); + pctx.errcode = + ext2fs_get_next_inode_full(scan, &ino, inode, + EXT2_INODE_SIZE(fs->super)); if (ctx->flags & E2F_FLAG_SIGNAL_MASK) return; if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { @@ -402,13 +539,13 @@ if (!ino) break; pctx.ino = ino; - pctx.inode = &inode; + pctx.inode = inode; ctx->stashed_ino = ino; - if (inode.i_links_count) { + if (inode->i_links_count) { pctx.errcode = ext2fs_icount_store(ctx->inode_link_info, - ino, inode.i_links_count); + ino, inode->i_links_count); if (pctx.errcode) { - pctx.num = inode.i_links_count; + pctx.num = inode->i_links_count; fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx); ctx->flags |= E2F_FLAG_ABORT; return; @@ -422,7 +559,7 @@ pb.num_illegal_blocks = 0; pb.suppress = 0; pb.clear = 0; pb.is_dir = 0; pb.is_reg = 0; pb.fragmented = 0; - pb.inode = &inode; + pb.inode = inode; pb.pctx = &pctx; pb.ctx = ctx; pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, @@ -441,13 +578,13 @@ * not, offer to clear it. It will be * regnerated in pass #3. */ - if (!LINUX_S_ISDIR(inode.i_mode)) { + if (!LINUX_S_ISDIR(inode->i_mode)) { if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) { - inode.i_dtime = time(0); - inode.i_links_count = 0; + inode->i_dtime = time(0); + inode->i_links_count = 0; ext2fs_icount_store(ctx->inode_link_info, ino, 0); - e2fsck_write_inode(ctx, ino, &inode, + e2fsck_write_inode(ctx, ino, inode, "pass1"); } @@ -461,54 +598,54 @@ * easily. But we will fix the root directory * as a special case. */ - if (inode.i_dtime && inode.i_links_count) { + if (inode->i_dtime && inode->i_links_count) { if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) { - inode.i_dtime = 0; - e2fsck_write_inode(ctx, ino, &inode, + inode->i_dtime = 0; + e2fsck_write_inode(ctx, ino, inode, "pass1"); } } } else if (ino == EXT2_JOURNAL_INO) { ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) { - if (!LINUX_S_ISREG(inode.i_mode) && + if (!LINUX_S_ISREG(inode->i_mode) && fix_problem(ctx, PR_1_JOURNAL_BAD_MODE, &pctx)) { - inode.i_mode = LINUX_S_IFREG; - e2fsck_write_inode(ctx, ino, &inode, + inode->i_mode = LINUX_S_IFREG; + e2fsck_write_inode(ctx, ino, inode, "pass1"); } check_blocks(ctx, &pctx, block_buf); continue; } - if ((inode.i_links_count || inode.i_blocks || - inode.i_blocks || inode.i_block[0]) && + if ((inode->i_links_count || inode->i_blocks || + inode->i_blocks || inode->i_block[0]) && fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, &pctx)) { - memset(&inode, 0, sizeof(inode)); + memset(inode, 0, sizeof(struct ext2_inode)); ext2fs_icount_store(ctx->inode_link_info, ino, 0); - e2fsck_write_inode(ctx, ino, &inode, "pass1"); + e2fsck_write_inode(ctx, ino, inode, "pass1"); } } else if (ino < EXT2_FIRST_INODE(fs->super)) { int problem = 0; ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); if (ino == EXT2_BOOT_LOADER_INO) { - if (LINUX_S_ISDIR(inode.i_mode)) + if (LINUX_S_ISDIR(inode->i_mode)) problem = PR_1_RESERVED_BAD_MODE; } else if (ino == EXT2_RESIZE_INO) { - if (inode.i_mode && - !LINUX_S_ISREG(inode.i_mode)) + if (inode->i_mode && + !LINUX_S_ISREG(inode->i_mode)) problem = PR_1_RESERVED_BAD_MODE; } else { - if (inode.i_mode != 0) + if (inode->i_mode != 0) problem = PR_1_RESERVED_BAD_MODE; } if (problem) { if (fix_problem(ctx, problem, &pctx)) { - inode.i_mode = 0; - e2fsck_write_inode(ctx, ino, &inode, + inode->i_mode = 0; + e2fsck_write_inode(ctx, ino, inode, "pass1"); } } @@ -532,12 +669,12 @@ * than nothing. The right answer is that there * shouldn't be any bugs in the orphan list handling. :-) */ - if (inode.i_dtime && !busted_fs_time && - inode.i_dtime < ctx->fs->super->s_inodes_count) { + if (inode->i_dtime && !busted_fs_time && + inode->i_dtime < ctx->fs->super->s_inodes_count) { if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) { - inode.i_dtime = inode.i_links_count ? + inode->i_dtime = inode->i_links_count ? 0 : time(0); - e2fsck_write_inode(ctx, ino, &inode, + e2fsck_write_inode(ctx, ino, inode, "pass1"); } } @@ -546,12 +683,12 @@ * This code assumes that deleted inodes have * i_links_count set to 0. */ - if (!inode.i_links_count) { - if (!inode.i_dtime && inode.i_mode) { + if (!inode->i_links_count) { + if (!inode->i_dtime && inode->i_mode) { if (fix_problem(ctx, PR_1_ZERO_DTIME, &pctx)) { - inode.i_dtime = time(0); - e2fsck_write_inode(ctx, ino, &inode, + inode->i_dtime = time(0); + e2fsck_write_inode(ctx, ino, inode, "pass1"); } } @@ -567,35 +704,35 @@ * should keep the file, not delete it. * */ - if (inode.i_dtime) { + if (inode->i_dtime) { if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) { - inode.i_dtime = 0; - e2fsck_write_inode(ctx, ino, &inode, "pass1"); + inode->i_dtime = 0; + e2fsck_write_inode(ctx, ino, inode, "pass1"); } } ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); switch (fs->super->s_creator_os) { case EXT2_OS_LINUX: - frag = inode.osd2.linux2.l_i_frag; - fsize = inode.osd2.linux2.l_i_fsize; + frag = inode->osd2.linux2.l_i_frag; + fsize = inode->osd2.linux2.l_i_fsize; break; case EXT2_OS_HURD: - frag = inode.osd2.hurd2.h_i_frag; - fsize = inode.osd2.hurd2.h_i_fsize; + frag = inode->osd2.hurd2.h_i_frag; + fsize = inode->osd2.hurd2.h_i_fsize; break; case EXT2_OS_MASIX: - frag = inode.osd2.masix2.m_i_frag; - fsize = inode.osd2.masix2.m_i_fsize; + frag = inode->osd2.masix2.m_i_frag; + fsize = inode->osd2.masix2.m_i_fsize; break; default: frag = fsize = 0; } - if (inode.i_faddr || frag || fsize || - (LINUX_S_ISDIR(inode.i_mode) && inode.i_dir_acl)) + if (inode->i_faddr || frag || fsize || + (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl)) mark_inode_bad(ctx, ino); - if (inode.i_flags & EXT2_IMAGIC_FL) { + if (inode->i_flags & EXT2_IMAGIC_FL) { if (imagic_fs) { if (!ctx->inode_imagic_map) alloc_imagic_map(ctx); @@ -603,64 +740,67 @@ ino); } else { if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) { - inode.i_flags &= ~EXT2_IMAGIC_FL; + inode->i_flags &= ~EXT2_IMAGIC_FL; e2fsck_write_inode(ctx, ino, - &inode, "pass1"); + inode, "pass1"); } } } - - if (LINUX_S_ISDIR(inode.i_mode)) { + + check_inode_extra_space(ctx, &pctx); + + if (LINUX_S_ISDIR(inode->i_mode)) { ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino); e2fsck_add_dir_info(ctx, ino, 0); ctx->fs_directory_count++; - } else if (LINUX_S_ISREG (inode.i_mode)) { + } else if (LINUX_S_ISREG (inode->i_mode)) { ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino); ctx->fs_regular_count++; - } else if (LINUX_S_ISCHR (inode.i_mode) && - e2fsck_pass1_check_device_inode(fs, &inode)) { + } else if (LINUX_S_ISCHR (inode->i_mode) && + e2fsck_pass1_check_device_inode(fs, inode)) { check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_chardev_count++; - } else if (LINUX_S_ISBLK (inode.i_mode) && - e2fsck_pass1_check_device_inode(fs, &inode)) { + } else if (LINUX_S_ISBLK (inode->i_mode) && + e2fsck_pass1_check_device_inode(fs, inode)) { check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_blockdev_count++; - } else if (LINUX_S_ISLNK (inode.i_mode) && - e2fsck_pass1_check_symlink(fs, &inode, block_buf)) { + } else if (LINUX_S_ISLNK (inode->i_mode) && + e2fsck_pass1_check_symlink(fs, inode, block_buf)) { check_immutable(ctx, &pctx); ctx->fs_symlinks_count++; - if (ext2fs_inode_data_blocks(fs, &inode) == 0) { + if (ext2fs_inode_data_blocks(fs, inode) == 0) { ctx->fs_fast_symlinks_count++; check_blocks(ctx, &pctx, block_buf); continue; } } - else if (LINUX_S_ISFIFO (inode.i_mode) && - e2fsck_pass1_check_device_inode(fs, &inode)) { + else if (LINUX_S_ISFIFO (inode->i_mode) && + e2fsck_pass1_check_device_inode(fs, inode)) { check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_fifo_count++; - } else if ((LINUX_S_ISSOCK (inode.i_mode)) && - e2fsck_pass1_check_device_inode(fs, &inode)) { + } else if ((LINUX_S_ISSOCK (inode->i_mode)) && + e2fsck_pass1_check_device_inode(fs, inode)) { check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_sockets_count++; } else mark_inode_bad(ctx, ino); - if (inode.i_block[EXT2_IND_BLOCK]) + if (inode->i_block[EXT2_IND_BLOCK]) ctx->fs_ind_count++; - if (inode.i_block[EXT2_DIND_BLOCK]) + if (inode->i_block[EXT2_DIND_BLOCK]) ctx->fs_dind_count++; - if (inode.i_block[EXT2_TIND_BLOCK]) + if (inode->i_block[EXT2_TIND_BLOCK]) ctx->fs_tind_count++; - if (inode.i_block[EXT2_IND_BLOCK] || - inode.i_block[EXT2_DIND_BLOCK] || - inode.i_block[EXT2_TIND_BLOCK] || - inode.i_file_acl) { + if (inode->i_block[EXT2_IND_BLOCK] || + inode->i_block[EXT2_DIND_BLOCK] || + inode->i_block[EXT2_TIND_BLOCK] || + inode->i_file_acl) { inodes_to_process[process_inode_count].ino = ino; - inodes_to_process[process_inode_count].inode = inode; + memcpy(&inodes_to_process[process_inode_count].inode, + inode, sizeof(struct ext2_inode)); process_inode_count++; } else check_blocks(ctx, &pctx, block_buf); @@ -729,6 +869,7 @@ e2fsck_use_inode_shortcuts(ctx, 0); ext2fs_free_mem((void **) &block_buf); + ext2fs_free_mem((void **) &inode); #ifdef RESOURCE_TRACK if (ctx->options & E2F_OPT_TIME2) { %diffstat debugfs/debugfs.c | 92 +++++++++++++- debugfs/util.c | 13 ++ e2fsck/message.c | 8 + e2fsck/pass1.c | 287 +++++++++++++++++++++++++++++++++------------ e2fsck/problem.c | 36 +++++ e2fsck/problem.h | 19 ++ e2fsck/util.c | 14 ++ lib/ext2fs/ext2_ext_attr.h | 3 lib/ext2fs/ext2_fs.h | 59 +++++++++ lib/ext2fs/ext2fs.h | 2 lib/ext2fs/ext_attr.c | 33 ++--- lib/ext2fs/inode.c | 133 +++++++++++++++----- lib/ext2fs/swapfs.c | 47 ++++++- 13 files changed, 611 insertions(+), 135 deletions(-) ------------------------------------------------------- This SF.net email is sponsored by: The SF.net Donation Program. Do you like what SourceForge.net is doing for the Open Source Community? Make a contribution, and help us add new features and functionality. Click here: http://sourceforge.net/donate/ |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | REALAtivan Ambien Valium Xanax wdxmkpelt ur m: 00015, Anibal Colbert |
|---|---|
| Next by Date: | RE:Buspar Xanax Vicodin Valium c: 00015, Johnie Sheldon |
| Previous by Thread: | Re: e2fsck and large inodesi: 00015, Andreas Dilger |
| Next by Thread: | paying at the pump? hvloec: 00015, Heather Hansen |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |