Extended Attributes patch to the e2fsprogs package 14 March 2002, 20:03:41 After extracting the e2fsprogs-1.27.tar.gz package, apply this patch as follows: cd e2fsprogs-1.27 patch -p1 < ../e2fsprogs-1.27-ea-0.8.21.patch diff -Nur e2fsprogs-1.27/debugfs/icheck.c e2fsprogs-1.27ea/debugfs/icheck.c --- e2fsprogs-1.27/debugfs/icheck.c Sun Feb 24 22:03:58 2002 +++ e2fsprogs-1.27ea/debugfs/icheck.c Thu Mar 14 07:26:40 2002 @@ -108,7 +108,7 @@ while (ino) { if (!inode.i_links_count) goto next; - if (!ext2fs_inode_has_valid_blocks(&inode)) + if (!ext2fs_inode_has_valid_blocks(current_fs, &inode)) goto next; /* * To handle filesystems touched by 0.3c extfs; can be diff -Nur e2fsprogs-1.27/e2fsck/e2fsck.c e2fsprogs-1.27ea/e2fsck/e2fsck.c --- e2fsprogs-1.27/e2fsck/e2fsck.c Sun Feb 24 22:03:58 2002 +++ e2fsprogs-1.27ea/e2fsck/e2fsck.c Thu Mar 14 07:26:44 2002 @@ -30,6 +30,7 @@ memset(context, 0, sizeof(struct e2fsck_struct)); context->process_inode_size = 256; + context->ext_attr_ver = 2; *ret = context; return 0; diff -Nur e2fsprogs-1.27/e2fsck/e2fsck.h e2fsprogs-1.27ea/e2fsck/e2fsck.h --- e2fsprogs-1.27/e2fsck/e2fsck.h Sun Feb 24 22:03:58 2002 +++ e2fsprogs-1.27ea/e2fsck/e2fsck.h Thu Mar 14 07:26:44 2002 @@ -254,6 +254,8 @@ int fs_ext_attr_inodes; int fs_ext_attr_blocks; + int ext_attr_ver; + /* * For the use of callers of the e2fsck functions; not used by * e2fsck functions themselves. @@ -322,7 +324,7 @@ /* pass1.c */ extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool); -extern int e2fsck_pass1_check_device_inode(struct ext2_inode *inode); +extern int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode); extern int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode); /* pass2.c */ diff -Nur e2fsprogs-1.27/e2fsck/pass1.c e2fsprogs-1.27ea/e2fsck/pass1.c --- e2fsprogs-1.27/e2fsck/pass1.c Sun Feb 24 22:03:58 2002 +++ e2fsprogs-1.27ea/e2fsck/pass1.c Thu Mar 14 08:42:27 2002 @@ -123,14 +123,14 @@ * since they have the same requirement; the i_block fields should be * zero. */ -int e2fsck_pass1_check_device_inode(struct ext2_inode *inode) +int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode) { int i; /* * If i_blocks is non-zero, then this is a bogus device/fifo/socket */ - if (inode->i_blocks) + if (ext2fs_inode_data_blocks(fs, inode) != 0) return 0; /* * We should be able to do the test below all the time, but @@ -179,9 +179,9 @@ EXT2_INDEX_FL))) return 0; - if (inode->i_blocks) { + if (inode->i_size > sizeof (inode->i_block) - 1) { if ((inode->i_size > fs->blocksize) || - (inode->i_blocks != fs->blocksize >> 9) || + (ext2fs_inode_data_blocks(fs, inode) != fs->blocksize>>9) || (inode->i_block[0] < fs->super->s_first_data_block) || (inode->i_block[0] >= fs->super->s_blocks_count)) return 0; @@ -190,7 +190,7 @@ if (inode->i_block[i]) return 0; } else { - if (inode->i_size > sizeof(inode->i_block) - 1) + if (ext2fs_inode_data_blocks(fs, inode) != 0) return 0; if (inode->i_size != @@ -603,12 +603,12 @@ 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(&inode)) { + 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(&inode)) { + e2fsck_pass1_check_device_inode(fs, &inode)) { check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_blockdev_count++; @@ -617,18 +617,19 @@ ctx->fs_symlinks_count++; if (!e2fsck_pass1_check_symlink(fs, &inode)) mark_inode_bad(ctx, ino); - if (!inode.i_blocks) { + if (ext2fs_inode_data_blocks(fs, &inode) == 0) { ctx->fs_fast_symlinks_count++; + check_blocks(ctx, &pctx, block_buf); goto next; } } else if (LINUX_S_ISFIFO (inode.i_mode) && - e2fsck_pass1_check_device_inode(&inode)) { + 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(&inode)) { + e2fsck_pass1_check_device_inode(fs, &inode)) { check_immutable(ctx, &pctx); check_size(ctx, &pctx); ctx->fs_sockets_count++; @@ -1057,7 +1058,10 @@ goto clear_extattr; header = (struct ext2_ext_attr_header *) block_buf; pctx->blk = inode->i_file_acl; - if (header->h_magic != EXT2_EXT_ATTR_MAGIC) { + if ((ctx->ext_attr_ver == 1 && + header->h_magic != EXT2_EXT_ATTR_MAGIC_v1) || + (ctx->ext_attr_ver == 2 && + header->h_magic != EXT2_EXT_ATTR_MAGIC)) { if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx)) goto clear_extattr; } @@ -1085,7 +1089,10 @@ if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) goto clear_extattr; } - if (entry->e_name_len == 0 || entry->e_name_index != 0) { + if ((ctx->ext_attr_ver == 1 && + (entry->e_name_len == 0 || entry->e_name_index != 0)) || + (ctx->ext_attr_ver == 2 && + entry->e_name_index == 0)) { if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx)) goto clear_extattr; } @@ -1136,9 +1143,9 @@ int bad_size = 0; __u64 size; - if (!ext2fs_inode_has_valid_blocks(pctx->inode)) + if (!ext2fs_inode_has_valid_blocks(fs, inode) && !inode->i_file_acl) return; - + pb.ino = ino; pb.num_blocks = pb.last_block = 0; pb.num_illegal_blocks = 0; @@ -1165,14 +1172,16 @@ } } - pctx->errcode = ext2fs_block_iterate2(fs, ino, - pb.is_dir ? BLOCK_FLAG_HOLE : 0, - block_buf, process_block, &pb); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - end_problem_latch(ctx, PR_LATCH_BLOCK); - if (pctx->errcode) - fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx); + if (ext2fs_inode_has_valid_blocks(fs, inode)) { + pctx->errcode = ext2fs_block_iterate2(fs, ino, + pb.is_dir ? BLOCK_FLAG_HOLE : 0, + block_buf, process_block, &pb); + if (ctx->flags & E2F_FLAG_SIGNAL_MASK) + return; + end_problem_latch(ctx, PR_LATCH_BLOCK); + if (pctx->errcode) + fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx); + } if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group) ctx->fs_fragmented++; diff -Nur e2fsprogs-1.27/e2fsck/pass1b.c e2fsprogs-1.27ea/e2fsck/pass1b.c --- e2fsprogs-1.27/e2fsck/pass1b.c Sun Feb 24 22:03:58 2002 +++ e2fsprogs-1.27ea/e2fsck/pass1b.c Thu Mar 14 07:26:40 2002 @@ -200,7 +200,7 @@ pctx.ino = ctx->stashed_ino = ino; if ((ino != EXT2_BAD_INO) && (!ext2fs_test_inode_bitmap(ctx->inode_used_map, ino) || - !ext2fs_inode_has_valid_blocks(&inode))) + !ext2fs_inode_has_valid_blocks(fs, &inode))) goto next; pb.ino = ino; diff -Nur e2fsprogs-1.27/e2fsck/pass2.c e2fsprogs-1.27ea/e2fsck/pass2.c --- e2fsprogs-1.27/e2fsck/pass2.c Sun Feb 24 22:03:59 2002 +++ e2fsprogs-1.27ea/e2fsck/pass2.c Thu Mar 14 07:26:40 2002 @@ -672,7 +672,7 @@ ext2fs_unmark_inode_bitmap(fs->inode_map, ino); ext2fs_mark_ib_dirty(fs); - if (!ext2fs_inode_has_valid_blocks(&inode)) + if (!ext2fs_inode_has_valid_blocks(fs, &inode)) return; if (!LINUX_S_ISDIR(inode.i_mode) && @@ -718,16 +718,16 @@ !(LINUX_S_ISSOCK(inode.i_mode))) problem = PR_2_BAD_MODE; else if (LINUX_S_ISCHR(inode.i_mode) - && !e2fsck_pass1_check_device_inode(&inode)) + && !e2fsck_pass1_check_device_inode(fs, &inode)) problem = PR_2_BAD_CHAR_DEV; else if (LINUX_S_ISBLK(inode.i_mode) - && !e2fsck_pass1_check_device_inode(&inode)) + && !e2fsck_pass1_check_device_inode(fs, &inode)) problem = PR_2_BAD_BLOCK_DEV; else if (LINUX_S_ISFIFO(inode.i_mode) - && !e2fsck_pass1_check_device_inode(&inode)) + && !e2fsck_pass1_check_device_inode(fs, &inode)) problem = PR_2_BAD_FIFO; else if (LINUX_S_ISSOCK(inode.i_mode) - && !e2fsck_pass1_check_device_inode(&inode)) + && !e2fsck_pass1_check_device_inode(fs, &inode)) problem = PR_2_BAD_SOCKET; else if (LINUX_S_ISLNK(inode.i_mode) && !e2fsck_pass1_check_symlink(fs, &inode)) { diff -Nur e2fsprogs-1.27/e2fsck/pass4.c e2fsprogs-1.27ea/e2fsck/pass4.c --- e2fsprogs-1.27/e2fsck/pass4.c Sun Feb 24 22:03:59 2002 +++ e2fsprogs-1.27ea/e2fsck/pass4.c Thu Mar 14 09:56:54 2002 @@ -34,8 +34,8 @@ pctx.ino = i; pctx.inode = &inode; - if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) || - LINUX_S_ISDIR(inode.i_mode))) { + if (ext2fs_inode_data_blocks(fs, &inode) == 0 && + (LINUX_S_ISREG(inode.i_mode) || LINUX_S_ISDIR(inode.i_mode))) { /* * This is a zero-length file; prompt to delete it... */ diff -Nur e2fsprogs-1.27/e2fsck/super.c e2fsprogs-1.27ea/e2fsck/super.c --- e2fsprogs-1.27/e2fsck/super.c Sun Feb 24 22:03:59 2002 +++ e2fsprogs-1.27ea/e2fsck/super.c Thu Mar 14 07:26:40 2002 @@ -172,7 +172,7 @@ errcode_t retval; struct process_block_struct pb; - if (!ext2fs_inode_has_valid_blocks(inode)) + if (!ext2fs_inode_has_valid_blocks(fs, inode)) return 0; pb.buf = block_buf + 3 * ctx->fs->blocksize; diff -Nur e2fsprogs-1.27/e2fsck/swapfs.c e2fsprogs-1.27ea/e2fsck/swapfs.c --- e2fsprogs-1.27/e2fsck/swapfs.c Sun Feb 24 22:03:59 2002 +++ e2fsprogs-1.27ea/e2fsck/swapfs.c Thu Mar 14 07:26:40 2002 @@ -158,7 +158,7 @@ ((inode->i_block[EXT2_IND_BLOCK] || inode->i_block[EXT2_DIND_BLOCK] || inode->i_block[EXT2_TIND_BLOCK]) && - ext2fs_inode_has_valid_blocks(inode))) + ext2fs_inode_has_valid_blocks(fs, inode))) swap_inode_blocks(ctx, ino, block_buf, inode); if (ctx->flags & E2F_FLAG_SIGNAL_MASK) diff -Nur e2fsprogs-1.27/e2fsck/unix.c e2fsprogs-1.27ea/e2fsck/unix.c --- e2fsprogs-1.27/e2fsck/unix.c Fri Mar 8 07:05:02 2002 +++ e2fsprogs-1.27ea/e2fsck/unix.c Thu Mar 14 07:26:44 2002 @@ -79,6 +79,7 @@ " -j external-journal Set location of the external journal\n" " -l bad_blocks_file Add to badblocks list\n" " -L bad_blocks_file Set badblocks list\n" + " -E version Extended attribute version (1-2)\n" )); exit(FSCK_USAGE); @@ -467,7 +468,7 @@ ctx->program_name = *argv; else ctx->program_name = "e2fsck"; - while ((c = getopt (argc, argv, "panyrcC:B:dfvtFVM:b:I:j:P:l:L:N:Ss")) != EOF) + while ((c = getopt (argc, argv, "panyrcC:B:dfvtFVM:b:I:j:P:l:L:N:SsE:")) != EOF) switch (c) { case 'C': ctx->progress = e2fsck_update_progress; @@ -580,6 +581,14 @@ "of e2fsck\n")); exit(1); #endif + case 'E': + if (atoi(optarg) != 1 && atoi(optarg) != 2) { + usage(ctx); + exit(1); + } + ctx->ext_attr_ver = atoi(optarg); + break; + default: usage(ctx); } diff -Nur e2fsprogs-1.27/lib/ext2fs/bmove.c e2fsprogs-1.27ea/lib/ext2fs/bmove.c --- e2fsprogs-1.27/lib/ext2fs/bmove.c Sun Feb 24 22:03:59 2002 +++ e2fsprogs-1.27ea/lib/ext2fs/bmove.c Thu Mar 14 07:26:40 2002 @@ -134,7 +134,7 @@ while (ino) { if ((inode.i_links_count == 0) || - !ext2fs_inode_has_valid_blocks(&inode)) + !ext2fs_inode_has_valid_blocks(fs, &inode)) goto next; pb.ino = ino; diff -Nur e2fsprogs-1.27/lib/ext2fs/ext2_ext_attr.h e2fsprogs-1.27ea/lib/ext2fs/ext2_ext_attr.h --- e2fsprogs-1.27/lib/ext2fs/ext2_ext_attr.h Sun Feb 24 22:03:59 2002 +++ e2fsprogs-1.27ea/lib/ext2fs/ext2_ext_attr.h Thu Mar 14 07:26:44 2002 @@ -7,7 +7,8 @@ */ /* Magic value in attribute blocks */ -#define EXT2_EXT_ATTR_MAGIC 0xEA010000 +#define EXT2_EXT_ATTR_MAGIC_v1 0xEA010000 +#define EXT2_EXT_ATTR_MAGIC 0xEA020000 /* Maximum number of references to one attribute block */ #define EXT2_EXT_ATTR_REFCOUNT_MAX 1024 @@ -22,7 +23,7 @@ struct ext2_ext_attr_entry { __u8 e_name_len; /* length of name */ - __u8 e_name_index; /* index into table of names (n/i) */ + __u8 e_name_index; /* attribute name index */ __u16 e_value_offs; /* offset in disk block of value */ __u32 e_value_block; /* disk block attribute is stored on (n/i) */ __u32 e_value_size; /* size of attribute value */ diff -Nur e2fsprogs-1.27/lib/ext2fs/ext2fs.h e2fsprogs-1.27ea/lib/ext2fs/ext2fs.h --- e2fsprogs-1.27/lib/ext2fs/ext2fs.h Fri Mar 8 07:05:02 2002 +++ e2fsprogs-1.27ea/lib/ext2fs/ext2fs.h Thu Mar 14 07:26:40 2002 @@ -811,7 +811,7 @@ struct ext2_inode *f, int hostorder); /* valid_blk.c */ -extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode); +extern int ext2fs_inode_has_valid_blocks(ext2_filsys fs, struct ext2_inode *inode); /* version.c */ extern int ext2fs_parse_version_string(const char *ver_string); @@ -992,6 +992,13 @@ _INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino) { return (ino - 1) / fs->super->s_inodes_per_group; +} + +_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs, + struct ext2_inode *inode) +{ + return inode->i_blocks - + (inode->i_file_acl ? fs->blocksize >> 9 : 0); } #undef _INLINE_ #endif diff -Nur e2fsprogs-1.27/lib/ext2fs/valid_blk.c e2fsprogs-1.27ea/lib/ext2fs/valid_blk.c --- e2fsprogs-1.27/lib/ext2fs/valid_blk.c Sun Feb 24 22:04:00 2002 +++ e2fsprogs-1.27ea/lib/ext2fs/valid_blk.c Thu Mar 14 07:26:40 2002 @@ -24,7 +24,7 @@ * This function returns 1 if the inode's block entries actually * contain block entries. */ -int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) +int ext2fs_inode_has_valid_blocks(ext2_filsys fs, struct ext2_inode *inode) { /* * Only directories, regular files, and some symbolic links @@ -38,7 +38,8 @@ * If the symbolic link is a "fast symlink", then the symlink * target is stored in the block entries. */ - if (LINUX_S_ISLNK (inode->i_mode) && inode->i_blocks == 0) + if (LINUX_S_ISLNK (inode->i_mode) && + ext2fs_inode_data_blocks(fs, inode) == 0) return 0; return 1; diff -Nur e2fsprogs-1.27/misc/e2image.c e2fsprogs-1.27ea/misc/e2image.c --- e2fsprogs-1.27/misc/e2image.c Tue Mar 5 09:31:15 2002 +++ e2fsprogs-1.27ea/misc/e2image.c Thu Mar 14 07:26:40 2002 @@ -396,7 +396,7 @@ if (ino == 0) break; if (!inode.i_links_count || - !ext2fs_inode_has_valid_blocks(&inode)) + !ext2fs_inode_has_valid_blocks(fs, &inode)) continue; stashed_ino = ino; diff -Nur e2fsprogs-1.27/resize/resize2fs.c e2fsprogs-1.27ea/resize/resize2fs.c --- e2fsprogs-1.27/resize/resize2fs.c Fri Mar 8 07:05:02 2002 +++ e2fsprogs-1.27ea/resize/resize2fs.c Thu Mar 14 07:26:40 2002 @@ -992,7 +992,7 @@ pb.is_dir = LINUX_S_ISDIR(inode.i_mode); pb.changed = 0; - if (ext2fs_inode_has_valid_blocks(&inode) && + if (ext2fs_inode_has_valid_blocks(rfs->old_fs, &inode) && (rfs->bmap || pb.is_dir)) { pb.ino = ino; retval = ext2fs_block_iterate2(rfs->old_fs, diff -Nur e2fsprogs-1.27/version.h e2fsprogs-1.27ea/version.h --- e2fsprogs-1.27/version.h Fri Mar 8 09:32:48 2002 +++ e2fsprogs-1.27ea/version.h Thu Mar 14 07:26:44 2002 @@ -6,5 +6,5 @@ * Ts'o. This file may be redistributed under the GNU Public License. */ -#define E2FSPROGS_VERSION "1.27" -#define E2FSPROGS_DATE "8-Mar-2002" +#define E2FSPROGS_VERSION "1.27ea" +#define E2FSPROGS_DATE "14-Mar-2002"