logo       

Re: e2fsck and large inodes: msg#00015

file-systems.ext2.devel

Subject: Re: e2fsck and large inodes

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>
Google Custom Search

News | FAQ | advertise