From 0684a4f33b5c268fe12f57fcbc77a880c79ab282 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 17 Aug 2002 10:19:44 -0400 Subject: [PATCH] Overhaul extended attribute handling. Should now be correct with respect to the latest V2 bestbits ACL code. --- e2fsck/ChangeLog | 68 ++++++++++++++++++++++++++++ e2fsck/e2fsck.8.in | 16 +++++++ e2fsck/e2fsck.c | 1 + e2fsck/e2fsck.h | 5 ++- e2fsck/pass1.c | 85 ++++++++++++++++++----------------- e2fsck/pass1b.c | 62 ++++++++++++++++++------- e2fsck/pass2.c | 44 +++++++++++------- e2fsck/pass3.c | 10 +---- e2fsck/pass4.c | 13 +++--- e2fsck/problem.c | 13 +++++- e2fsck/problem.h | 8 +++- e2fsck/super.c | 37 ++++++++------- e2fsck/unix.c | 66 ++++++++++++++++++++++++++- lib/ext2fs/ChangeLog | 15 +++++++ lib/ext2fs/ext2_err.et.in | 3 ++ lib/ext2fs/ext2fs.h | 16 ++++++- lib/ext2fs/ext_attr.c | 45 ++++++++++++++++++- lib/ext2fs/valid_blk.c | 17 +++++-- tests/ChangeLog | 14 ++++++ tests/f_badinode/expect.1 | 8 +--- tests/f_badroot/expect.1 | 15 ------- tests/f_badsymlinks/expect.1 | 12 +---- tests/f_badtable/expect.1 | 11 +++-- tests/f_dupdot/expect.1 | 6 --- tests/f_filetype/expect.1 | 6 +++ tests/f_illitable/expect.1 | 13 +++++- tests/f_imagic/expect.1 | 13 +++++- tests/f_imagic_fs/expect.1 | 13 +++++- tests/f_lpf/expect.1 | 11 ++--- tests/f_lpffile/expect.1 | 15 ------- tests/f_mke2fs2b/expect.1 | 6 +++ tests/f_noroot/expect.1 | 9 ---- tests/f_recnect_bad/expect.1 | 6 +++ tests/f_special_ea/expect.1 | 7 +++ tests/f_special_ea/image.gz | Bin 0 -> 30344 bytes tests/f_special_ea/name | 1 + tests/f_special_ea/script | 2 + 37 files changed, 505 insertions(+), 187 deletions(-) create mode 100644 tests/f_special_ea/expect.1 create mode 100644 tests/f_special_ea/image.gz create mode 100644 tests/f_special_ea/name create mode 100644 tests/f_special_ea/script diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 5da29d9d..8e58a035 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,71 @@ +2002-08-17 Theodore Ts'o + + * e2fsck.h, e2fsck.c (e2fsck_allocate_context): Add new field to + the e2fsck context, ext_attr_ver, which specifies the EA + format version. + + * unix.c (usage, parse_extended_opts, PRS), e2fsck.8.in: Add new + option -E, which allows the users to specify extended + options. Added ea_ver extended option. + + * pass1.c (e2fsck_pass1_check_device_inode): Add ext2_filsys + argument to this function, so we can account for the + presence of extended attribute blocks attached to device + inodes. + (e2fsck_pass1_check_symlink, e2fsck_pass1): Take into + account the fact that symlinks can also have extended + attribute blocks. + (check_ext_attr): Don't be flexible about the EA format + version. Check against the version number in + ctx->ext_attr_ver. + (check_blocks): Check all inodes, so that we account for + extended attribute blocks belonging to special files. + Clean up i_size checks. + + * pass1b.c (pass1b): Check all inodes, so that we account for + extended attribute blocks belonging to special files. + (delete_file_block): Use ext2fs_alloc_block_stats() to + update the filesystem statistics. + (delete_file): Attempt to decrement the extended + attribute refcount, and free the EA block if the count + hits zero. + (clone_file): Fixed bugs in EA handling. Don't call + block_iterate on inodes that don't have a valid i_block[] + array. Reread the base inode since it may have been + changed by ext2fs_block_iterate. When updating inodes as + part of cloning an EA block, write out the correct inode + structure. + + * pass2.c (deallocate_inode_block, deallocate_inode): Use standard + ext2fs_alloc_*_stats functions to update the filesystem + statistics. + (deallocate_inode): Attempt to decrement the extended + attribute refcount, and free the EA block if the count + hits zero. + (e2fsck_process_bad_inode): Add extra argument to calls + to e2fsck_pass1_check_device_inode (). + + * pass3.c (e2fsck_get_lost_and_found): Use standard + ext2fs_alloc_*_stats functions to update the filesystem. + statistics when creating /lost+found. + (adjust_inode_count): Remove debugging code that can never + be triggered. + + * pass4.c (disconnect_inode): Add explanation about why we only + clear inodes that have no data blocks and no EA blocks. + Use ext2fs_inode_alloc_stats2 function to update the + filesystem statistics when clearing a zero-length inode. + + * problem.c, problem.h (PR_1B_ADJ_EA_REFCOUNT, + PR_2_ADJ_EA_REFCOUNT): Add new problem codes. + + * super.c (release_inode_block), (release_orphan_inodes): Use the + standard ext2fs_alloc_*_stats functions to update the + filesystem statistics. + (release_inode_blocks): Attempt to decrement the extended + attribute refcount, and free the EA block if the count + hits zero. + 2002-08-01 Theodore Ts'o * dict.c, dict.h: New file from kazlib 1.20 which implements a diff --git a/e2fsck/e2fsck.8.in b/e2fsck/e2fsck.8.in index 8438a306..70596266 100644 --- a/e2fsck/e2fsck.8.in +++ b/e2fsck/e2fsck.8.in @@ -30,6 +30,10 @@ e2fsck \- check a Linux second extended file system @JDEV@.B \-j @JDEV@.I external-journal @JDEV@] +[ +.B \-E +.I extended_options +] .I device .SH DESCRIPTION .B e2fsck @@ -122,6 +126,18 @@ filesystem supports directory indexing, or by sorting and compressing directories for smaller directories, or for filesystems using traditional linear directories. .TP +.BI \-E " extended_options" +Set e2fsck extended options. Extended options are comma +separated, and may take an argument using the equals ('=') sign. The +following options are supported: +.RS 1.2i +.TP +.BI ea_ver= extended_attribute_version +Assume the format of the extended attribute blocks in the filesystem is +the specified version number. The version number may be 1 or 2. The +default extended attribute version format is 2. +.RE +.TP .B \-f Force checking even if the file system seems clean. .TP diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c index e9ccbb4c..4f49ec82 100644 --- a/e2fsck/e2fsck.c +++ b/e2fsck/e2fsck.c @@ -30,6 +30,7 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret) memset(context, 0, sizeof(struct e2fsck_struct)); context->process_inode_size = 256; + context->ext_attr_ver = 2; *ret = context; return 0; diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index c2dbc26c..6fcb1e79 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -308,6 +308,8 @@ struct e2fsck_struct { 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. @@ -382,7 +384,8 @@ extern void e2fsck_move_ext3_journal(e2fsck_t ctx); /* 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, char *buf); diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index ce63792f..a0e39b71 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -125,7 +125,7 @@ static void unwind_pass1(ext2_filsys fs) * 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; @@ -133,7 +133,8 @@ int e2fsck_pass1_check_device_inode(struct ext2_inode *inode) * If i_blocks is non-zero, or the index flag is set, then * this is a bogus device/fifo/socket */ - if (inode->i_blocks || (inode->i_flags & EXT2_INDEX_FL)) + if ((ext2fs_inode_data_blocks(fs, inode) != 0) || + (inode->i_flags & EXT2_INDEX_FL)) return 0; /* @@ -179,14 +180,16 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, { int len; int i; + blk_t blocks; if ((inode->i_size_high || inode->i_size == 0) || (inode->i_flags & EXT2_INDEX_FL)) return 0; - if (inode->i_blocks) { + blocks = ext2fs_inode_data_blocks(fs, inode); + if (blocks) { if ((inode->i_size >= fs->blocksize) || - (inode->i_blocks != fs->blocksize >> 9) || + (blocks != fs->blocksize >> 9) || (inode->i_block[0] < fs->super->s_first_data_block) || (inode->i_block[0] >= fs->super->s_blocks_count)) return 0; @@ -614,12 +617,12 @@ void e2fsck_pass1(e2fsck_t ctx) 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++; @@ -627,18 +630,19 @@ void e2fsck_pass1(e2fsck_t ctx) e2fsck_pass1_check_symlink(fs, &inode, block_buf)) { check_immutable(ctx, &pctx); ctx->fs_symlinks_count++; - 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++; @@ -990,7 +994,6 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx, struct ext2_ext_attr_entry *entry; int count; region_t region; - int ext_attr_ver; blk = inode->i_file_acl; if (blk == 0) @@ -1068,12 +1071,13 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx, 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_v1) - ext_attr_ver = 1; - if (header->h_magic != EXT2_EXT_ATTR_MAGIC) - ext_attr_ver = 2; - else if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx)) - goto clear_extattr; + 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; + } if (header->h_blocks != 1) { if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx)) @@ -1099,9 +1103,9 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx, if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) goto clear_extattr; } - if ((ext_attr_ver == 1 && + if ((ctx->ext_attr_ver == 1 && (entry->e_name_len == 0 || entry->e_name_index != 0)) || - (ext_attr_ver == 2 && + (ctx->ext_attr_ver == 2 && entry->e_name_index == 0)) { if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx)) goto clear_extattr; @@ -1205,11 +1209,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, int dirty_inode = 0; __u64 size; - if (!ext2fs_inode_has_valid_blocks(inode)) - return; - pb.ino = ino; - pb.num_blocks = pb.last_block = 0; + pb.num_blocks = 0; + pb.last_block = -1; pb.num_illegal_blocks = 0; pb.suppress = 0; pb.clear = 0; pb.fragmented = 0; @@ -1222,6 +1224,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, pb.pctx = pctx; pb.ctx = ctx; pctx->ino = ino; + pctx->errcode = 0; if (inode->i_flags & EXT2_COMPRBLK_FL) { if (fs->super->s_feature_incompat & @@ -1235,13 +1238,14 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, } } - pctx->errcode = ext2fs_block_iterate2(fs, ino, + if (ext2fs_inode_has_valid_blocks(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) - goto out; end_problem_latch(ctx, PR_LATCH_BLOCK); end_problem_latch(ctx, PR_LATCH_TOOBIG); + if (ctx->flags & E2F_FLAG_SIGNAL_MASK) + goto out; if (pctx->errcode) fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx); @@ -1280,15 +1284,6 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, ((inode->i_size / fs->blocksize) >= 3)) ext2fs_u32_list_add(ctx->dirs_to_hash, ino); - if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) - pb.num_blocks++; - - pb.num_blocks *= (fs->blocksize / 512); -#if 0 - printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n", - ino, inode->i_size, pb.last_block, inode->i_blocks, - pb.num_blocks); -#endif if (!pb.num_blocks && pb.is_dir) { if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) { inode->i_links_count = 0; @@ -1299,9 +1294,19 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino); ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); ctx->fs_directory_count--; - pb.is_dir = 0; + goto out; } } + + if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) + pb.num_blocks++; + + pb.num_blocks *= (fs->blocksize / 512); +#if 0 + printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n", + ino, inode->i_size, pb.last_block, inode->i_blocks, + pb.num_blocks); +#endif if (pb.is_dir) { int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super); if (nblock > (pb.last_block + 1)) @@ -1312,19 +1317,19 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, bad_size = 2; } } else { - if (!LINUX_S_ISREG(inode->i_mode) && inode->i_size_high) - bad_size = 5; size = inode->i_size | ((__u64) inode->i_size_high << 32); - if ((size < pb.last_block * fs->blocksize)) + if ((pb.last_block >= 0) && + (size < pb.last_block * fs->blocksize)) bad_size = 3; else if (size > ext2_max_sizes[fs->super->s_log_block_size]) bad_size = 4; } - if (bad_size) { + /* i_size for symlinks is checked elsewhere */ + if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) { pctx->num = (pb.last_block+1) * fs->blocksize; if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) { inode->i_size = pctx->num; - if (LINUX_S_ISREG(inode->i_mode)) + if (!LINUX_S_ISDIR(inode->i_mode)) inode->i_size_high = pctx->num >> 32; dirty_inode++; } diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index 8549a655..c370601e 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -259,15 +259,17 @@ static void pass1b(e2fsck_t ctx, char *block_buf) while (ino) { 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_test_inode_bitmap(ctx->inode_used_map, ino)) goto next; pb.ino = ino; pb.dup_blocks = 0; pb.inode = &inode; - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, - process_pass1b_block, &pb); + + if (ext2fs_inode_has_valid_blocks(&inode) || + (ino == EXT2_BAD_INO)) + pctx.errcode = ext2fs_block_iterate2(fs, ino, + 0, block_buf, process_pass1b_block, &pb); if (inode.i_file_acl) process_pass1b_block(fs, &inode.i_file_acl, BLOCK_COUNT_EXTATTR, 0, 0, &pb); @@ -543,7 +545,7 @@ static int delete_file_block(ext2_filsys fs, *block_nr); } else { ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); - ext2fs_unmark_block_bitmap(fs->block_map, *block_nr); + ext2fs_block_alloc_stats(fs, *block_nr, -1); } return 0; @@ -556,6 +558,7 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino, struct process_block_struct pb; struct ext2_inode inode; struct problem_context pctx; + unsigned int count; clear_problem_context(&pctx); pctx.ino = pb.ino = ino; @@ -563,23 +566,47 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino, pb.ctx = ctx; pctx.str = "delete_file"; - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, - delete_file_block, &pb); + e2fsck_read_inode(ctx, ino, &inode, "delete_file"); + if (ext2fs_inode_has_valid_blocks(&inode)) + pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, + delete_file_block, &pb); if (pctx.errcode) fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); if (ctx->inode_bad_map) ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); - ext2fs_unmark_inode_bitmap(fs->inode_map, ino); - ext2fs_mark_ib_dirty(fs); - ext2fs_mark_bb_dirty(fs); + ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); + + /* Inode may have changed by block_iterate, so reread it */ e2fsck_read_inode(ctx, ino, &inode, "delete_file"); inode.i_links_count = 0; inode.i_dtime = time(0); - if (inode.i_file_acl) - delete_file_block(fs, &inode.i_file_acl, - BLOCK_COUNT_EXTATTR, 0, 0, &pb); + if (inode.i_file_acl && + (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { + count = 1; + pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, + block_buf, -1, &count); + if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { + pctx.errcode = 0; + count = 1; + } + if (pctx.errcode) { + pctx.blk = inode.i_file_acl; + fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx); + } + /* + * If the count is zero, then arrange to have the + * block deleted. If the block is in the block_dup_map, + * also call delete_file_block since it will take care + * of keeping the accounting straight. + */ + if ((count == 0) || + ext2fs_test_block_bitmap(ctx->block_dup_map, + inode.i_file_acl)) + delete_file_block(fs, &inode.i_file_acl, + BLOCK_COUNT_EXTATTR, 0, 0, &pb); + } e2fsck_write_inode(ctx, ino, &inode, "delete_file"); } @@ -683,8 +710,9 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino, pctx.ino = ino; pctx.str = "clone_file"; - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, - clone_file_block, &cs); + if (ext2fs_inode_has_valid_blocks(&dp->inode)) + pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, + clone_file_block, &cs); ext2fs_mark_bb_dirty(fs); if (pctx.errcode) { fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); @@ -697,6 +725,8 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino, retval = cs.errcode; goto errout; } + /* The inode may have changed on disk, so we have to re-read it */ + e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA"); blk = dp->inode.i_file_acl; if (blk && (clone_file_block(fs, &dp->inode.i_file_acl, BLOCK_COUNT_EXTATTR, 0, 0, &cs) == @@ -717,7 +747,7 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino, if (di->inode.i_file_acl == blk) { di->inode.i_file_acl = dp->inode.i_file_acl; e2fsck_write_inode(ctx, ino_el->inode, - &dp->inode, "clone file EA"); + &di->inode, "clone file EA"); decrement_badcount(ctx, blk, db); } } diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 1f484f45..e61a6a27 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -886,7 +886,7 @@ static int deallocate_inode_block(ext2_filsys fs, if (HOLE_BLKADDR(*block_nr)) return 0; ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); - ext2fs_unmark_block_bitmap(fs->block_map, *block_nr); + ext2fs_block_alloc_stats(fs, *block_nr, -1); return 0; } @@ -898,6 +898,7 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) ext2_filsys fs = ctx->fs; struct ext2_inode inode; struct problem_context pctx; + __u32 count; ext2fs_icount_store(ctx->inode_link_info, ino, 0); e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); @@ -915,8 +916,29 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); if (ctx->inode_bad_map) ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); - ext2fs_unmark_inode_bitmap(fs->inode_map, ino); - ext2fs_mark_ib_dirty(fs); + ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); + + if (inode.i_file_acl && + (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { + pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, + block_buf, -1, &count); + if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { + pctx.errcode = 0; + count = 1; + } + if (pctx.errcode) { + pctx.blk = inode.i_file_acl; + fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx); + ctx->flags |= E2F_FLAG_ABORT; + return; + } + if (count == 0) { + ext2fs_unmark_block_bitmap(ctx->block_found_map, + inode.i_file_acl); + ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1); + } + inode.i_file_acl = 0; + } if (!ext2fs_inode_has_valid_blocks(&inode)) return; @@ -925,13 +947,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) (inode.i_size_high || inode.i_size & 0x80000000UL)) ctx->large_files--; - if (inode.i_file_acl) { - ext2fs_unmark_block_bitmap(ctx->block_found_map, - inode.i_file_acl); - ext2fs_unmark_block_bitmap(fs->block_map, inode.i_file_acl); - } - - ext2fs_mark_bb_dirty(fs); pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, deallocate_inode_block, ctx); if (pctx.errcode) { @@ -947,7 +962,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) static void clear_htree(e2fsck_t ctx, ext2_ino_t ino) { struct ext2_inode inode; - struct problem_context pctx; e2fsck_read_inode(ctx, ino, &inode, "clear_htree"); inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL; @@ -980,16 +994,16 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, !(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, buf)) { diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 167add85..d4fea082 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -430,8 +430,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) return 0; } ext2fs_mark_block_bitmap(ctx->block_found_map, blk); - ext2fs_mark_block_bitmap(fs->block_map, blk); - ext2fs_mark_bb_dirty(fs); + ext2fs_block_alloc_stats(fs, blk, +1); /* * Next find a free inode. @@ -445,8 +444,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) } ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino); - ext2fs_mark_inode_bitmap(fs->inode_map, ino); - ext2fs_mark_ib_dirty(fs); + ext2fs_inode_alloc_stats2(fs, ino, +1, 1); /* * Now let's create the actual data block for the inode @@ -594,10 +592,6 @@ static errcode_t adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj) return 0; ext2fs_icount_decrement(ctx->inode_link_info, ino, 0); inode.i_links_count--; - } else { - /* Should never happen */ - fatal_error(ctx, _("Debug error in e2fsck adjust_inode_count, " - "should never happen.\n")); } retval = ext2fs_write_inode(fs, ino, &inode); diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index 28c0996c..d1ffd82e 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -34,11 +34,14 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i) pctx.ino = i; pctx.inode = &inode; + /* + * Offer to delete any zero-length files that does not have + * blocks. If there is an EA block, it might have useful + * information, so we won't prompt to delete it, but let it be + * reconnected to lost+found. + */ if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) || LINUX_S_ISDIR(inode.i_mode))) { - /* - * This is a zero-length file; prompt to delete it... - */ if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) { ext2fs_icount_store(ctx->inode_link_info, i, 0); inode.i_links_count = 0; @@ -51,8 +54,8 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i) e2fsck_read_bitmaps(ctx); ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i); ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i); - ext2fs_unmark_inode_bitmap(fs->inode_map, i); - ext2fs_mark_ib_dirty(fs); + ext2fs_inode_alloc_stats2(fs, i, -1, + LINUX_S_ISDIR(inode.i_mode)); return 0; } } diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 07687cd6..0b3b557b 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -735,7 +735,13 @@ static const struct e2fsck_problem problem_table[] = { { PR_1B_BLOCK_ITERATE, N_("Error while iterating over @bs in @i %i (%s): %m\n"), PROMPT_NONE, 0 }, - + + /* Error adjusting EA refcount */ + { PR_1B_ADJ_EA_REFCOUNT, + N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"), + PROMPT_NONE, 0 }, + + /* Pass 1C: Scan directories for inodes with dup blocks. */ { PR_1C_PASS_HEADER, N_("Pass 1C: Scan directories for @is with dup @bs.\n"), @@ -1051,6 +1057,11 @@ static const struct e2fsck_problem problem_table[] = { N_("@p @h %d (%q): bad @b number %b.\n"), PROMPT_CLEAR_HTREE, 0 }, + /* Error adjusting EA refcount */ + { PR_2_ADJ_EA_REFCOUNT, + N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"), + PROMPT_NONE, PR_FATAL }, + /* Pass 3 errors */ /* Pass 3: Checking directory connectivity */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 05eba230..2196a33b 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -429,7 +429,10 @@ struct problem_context { /* Error while iterating over blocks */ #define PR_1B_BLOCK_ITERATE 0x0110006 - +/* Error adjusting EA refcount */ +#define PR_1B_ADJ_EA_REFCOUNT 0x0110007 + + /* Pass 1C: Scan directories for inodes with dup blocks. */ #define PR_1C_PASS_HEADER 0x012000 @@ -624,6 +627,9 @@ struct problem_context { /* Bad block in htree interior node */ #define PR_2_HTREE_BADBLK 0x02003A +/* Error adjusting EA refcount */ +#define PR_2_ADJ_EA_REFCOUNT 0x02003B + /* * Pass 3 errors */ diff --git a/e2fsck/super.c b/e2fsck/super.c index 227a0254..a8ea779d 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -152,10 +152,7 @@ static int release_inode_block(ext2_filsys fs, retval |= BLOCK_CHANGED; } - ext2fs_unmark_block_bitmap(fs->block_map, blk); - fs->group_desc[ext2fs_group_of_blk(fs, blk)].bg_free_blocks_count++; - fs->super->s_free_blocks_count++; - + ext2fs_block_alloc_stats(fs, blk, -1); return retval; } @@ -168,9 +165,10 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, struct ext2_inode *inode, char *block_buf, struct problem_context *pctx) { + struct process_block_struct pb; ext2_filsys fs = ctx->fs; errcode_t retval; - struct process_block_struct pb; + __u32 count; if (!ext2fs_inode_has_valid_blocks(inode)) return 0; @@ -211,7 +209,23 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, inode->i_blocks -= pb.truncated_blocks * (fs->blocksize / 512); - ext2fs_mark_bb_dirty(fs); + if (inode->i_file_acl) { + retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl, + block_buf, -1, &count); + if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) { + retval = 0; + count = 1; + } + if (retval) { + com_err("release_inode_blocks", retval, + _("while calling ext2fs_adjust_ea_refocunt for inode %d"), + ino); + return 1; + } + if (count == 0) + ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1); + inode->i_file_acl = 0; + } return 0; } @@ -222,7 +236,6 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, static int release_orphan_inodes(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; - int group; ext2_ino_t ino, next_ino; struct ext2_inode inode; struct problem_context pctx; @@ -281,14 +294,8 @@ static int release_orphan_inodes(e2fsck_t ctx) goto return_abort; if (!inode.i_links_count) { - ext2fs_unmark_inode_bitmap(fs->inode_map, ino); - ext2fs_mark_ib_dirty(fs); - group = ext2fs_group_of_ino(fs, ino); - fs->group_desc[group].bg_free_inodes_count++; - fs->super->s_free_inodes_count++; - if (LINUX_S_ISDIR(inode.i_mode)) - fs->group_desc[group].bg_used_dirs_count--; - + ext2fs_inode_alloc_stats2(fs, ino, -1, + LINUX_S_ISDIR(inode.i_mode)); inode.i_dtime = time(0); } else { inode.i_dtime = 0; diff --git a/e2fsck/unix.c b/e2fsck/unix.c index fab82a25..156d25b1 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -61,7 +61,8 @@ static void usage(e2fsck_t ctx) fprintf(stderr, _("Usage: %s [-panyrcdfvstFSV] [-b superblock] [-B blocksize]\n" "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n" - "\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal] device\n"), + "\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal]\n" + "\t\t[-E extended-options] device\n"), ctx->program_name); fprintf(stderr, _("\nEmergency help:\n" @@ -448,6 +449,60 @@ static void signal_cancel(int sig) } #endif +static void parse_extended_opts(e2fsck_t ctx, const char *opts) +{ + char *buf, *token, *next, *p, *arg; + int len, ea_ver; + int extended_usage = 0; + + len = strlen(opts); + buf = malloc(len+1); + if (!buf) { + fprintf(stderr, _("Couldn't allocate memory to parse " + "extended options!\n")); + exit(1); + } + strcpy(buf, opts); + for (token = buf; token && *token; token = next) { + p = strchr(token, ','); + next = 0; + if (p) { + *p = 0; + next = p+1; + } + arg = strchr(token, '='); + if (arg) { + *arg = 0; + arg++; + } + if (strcmp(token, "ea_ver") == 0) { + if (!arg) { + extended_usage++; + continue; + } + ea_ver = strtoul(arg, &p, 0); + if (*p || + ((ea_ver != 1) && (ea_ver != 2))) { + fprintf(stderr, + _("Invalid EA version.\n")); + extended_usage++; + continue; + } + ctx->ext_attr_ver = ea_ver; + } else + extended_usage++; + } + if (extended_usage) { + fprintf(stderr, _("Extended options are separated by commas, " + "and may take an argument which\n" + "is set off by an equals ('=') sign. " + "Valid raid options are:\n" + "\tea_ver=program_name = *argv; else ctx->program_name = "e2fsck"; - while ((c = getopt (argc, argv, "panyrcC:B:dfvtFVM:b:I:j:P:l:L:N:SsD")) != EOF) + while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsD")) != EOF) switch (c) { case 'C': ctx->progress = e2fsck_update_progress; @@ -497,6 +553,9 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) case 'D': ctx->options |= E2F_OPT_COMPRESS_DIRS; break; + case 'E': + extended_opts = optarg; + break; case 'p': case 'a': ctx->options |= E2F_OPT_PREEN; @@ -602,6 +661,9 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) ctx->options |= E2F_OPT_READONLY; ctx->filesystem_name = argv[optind]; + if (extended_opts) + parse_extended_opts(ctx, extended_opts); + if (flush) { fd = open(ctx->filesystem_name, O_RDONLY, 0); if (fd < 0) { diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog index 68d55249..bf0ae7b5 100644 --- a/lib/ext2fs/ChangeLog +++ b/lib/ext2fs/ChangeLog @@ -1,3 +1,18 @@ +2002-08-16 Theodore Ts'o + + * ext2_err.et.in (EXT2_ET_BAD_EA_BLOCK_NUM): New error code + + * ext2fs.h (ext2fs_inode_data_blocks): New function which returns + the number of data blocks used by an inode exclusive of + the EA block. + + * ext_attr.c (ext2fs_adjust_ea_refcount): New function which + adjusts the reference count in an extended attribute block. + + * valid_blk.c (ext2fs_inode_has_valid_blocks): Add code to + correctly deal with extended attribute blocks in symbolic + links. + 2002-08-13 * Makefile.in: Move dupfs.o and test_io.o from the diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in index c22e5d86..b08f8635 100644 --- a/lib/ext2fs/ext2_err.et.in +++ b/lib/ext2fs/ext2_err.et.in @@ -278,5 +278,8 @@ ec EXT2_ET_NO_JOURNAL, ec EXT2_ET_DIRHASH_UNSUPP, "Directory hash unsupported" +ec EXT2_ET_BAD_EA_BLOCK_NUM, + "Illegal extended attribute block number" + end diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 60021930..507b1a3b 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -663,7 +663,12 @@ 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); 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); +extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, + void *buf); +extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk, + char *block_buf, + int adjust, __u32 *newcount); + /* fileio.c */ extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino, int flags, ext2_file_t *ret); @@ -873,6 +878,8 @@ extern int ext2fs_test_ib_dirty(ext2_filsys fs); extern int ext2fs_test_bb_dirty(ext2_filsys fs); extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk); extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino); +extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs, + struct ext2_inode *inode); /* * The actual inlined functions definitions themselves... @@ -1025,6 +1032,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 --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index b5404390..5ebb22bb 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -1,7 +1,9 @@ /* * ext_attr.c --- extended attribute blocks * - * Copyright (C) Andreas Gruenbacher, + * Copyright (C) 2001 Andreas Gruenbacher, + * + * Copyright (C) 2002 Theodore Ts'o. * * %Begin-Header% * This file may be redistributed under the terms of the GNU Public @@ -96,3 +98,44 @@ errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf) ext2fs_mark_changed(fs); return retval; } + +/* + * This function adjusts the reference count of the EA block. + */ +errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk, + char *block_buf, int adjust, + __u32 *newcount) +{ + errcode_t retval; + struct ext2_ext_attr_header *header; + char *buf = 0; + + if ((blk >= fs->super->s_blocks_count) || + (blk < fs->super->s_first_data_block)) + return EXT2_ET_BAD_EA_BLOCK_NUM; + + if (!block_buf) { + retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); + if (retval) + return retval; + block_buf = buf; + } + + retval = ext2fs_read_ext_attr(fs, blk, block_buf); + if (retval) + goto errout; + + header = (struct ext2_ext_attr_header *) block_buf; + header->h_refcount += adjust; + if (newcount) + *newcount = header->h_refcount; + + retval = ext2fs_write_ext_attr(fs, blk, block_buf); + if (retval) + goto errout; + +errout: + if (buf) + ext2fs_free_mem((void **) &buf); + return retval; +} diff --git a/lib/ext2fs/valid_blk.c b/lib/ext2fs/valid_blk.c index 9e50ed5a..5236f1e3 100644 --- a/lib/ext2fs/valid_blk.c +++ b/lib/ext2fs/valid_blk.c @@ -38,8 +38,19 @@ int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode) * 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) - return 0; - + if (LINUX_S_ISLNK (inode->i_mode)) { + if (inode->i_file_acl == 0) { + /* With no EA block, we can rely on i_blocks */ + if (inode->i_blocks == 0) + return 0; + } else { + /* With an EA block, life gets more tricky */ + if (inode->i_size >= EXT2_N_BLOCKS*4) + return 1; /* definitely using i_block[] */ + if (inode->i_size > 3 && inode->i_block[1] != 0) + return 1; /* probably using i_block[] */ + return 0; /* Probably a fast symlink */ + } + } return 1; } diff --git a/tests/ChangeLog b/tests/ChangeLog index 98511519..3bf008bf 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,17 @@ +2002-08-17 Theodore Ts'o + + * f_badinode, f_badroot, f_badsymlinks, f_badtable, f_dupdot, + f_filetype, f_illitable, f_imagic, f_imagic_fs, f_lpf, + f_lpffile, f_mke2fs2b, f_noroot, f_recnect_bad: Update + expect files to deal with changes in the extended + attribute block processing, and in how e2fsck updates + filesystem statistics when deleting files and creating + /lost+found. + + * f_special_ea: New test which checks to make sure e2fsck + correctly handles special device files with extended + attribute blocks. + 2002-08-01 Theodore Ts'o * f_dup, f_dup2, f_dup3, f_bbfile, f_dupfsblks: Update expect diff --git a/tests/f_badinode/expect.1 b/tests/f_badinode/expect.1 index 6207042c..4601f1e3 100644 --- a/tests/f_badinode/expect.1 +++ b/tests/f_badinode/expect.1 @@ -1,6 +1,8 @@ Filesystem did not have a UUID; generating one. Pass 1: Checking inodes, blocks, and sizes +Inode 12, i_blocks is 2, should be 0. Fix? yes + Pass 2: Checking directory structure Inode 12 (/motd) has a bad mode (0110444). Clear? yes @@ -32,12 +34,6 @@ Fix? yes Free blocks count wrong (76, counted=77). Fix? yes -Free inodes count wrong for group #0 (16, counted=20). -Fix? yes - -Free inodes count wrong (16, counted=20). -Fix? yes - test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 12/32 files (0.0% non-contiguous), 23/100 blocks diff --git a/tests/f_badroot/expect.1 b/tests/f_badroot/expect.1 index 187c49a4..66ff32ee 100644 --- a/tests/f_badroot/expect.1 +++ b/tests/f_badroot/expect.1 @@ -23,21 +23,6 @@ Connect to /lost+found? yes Inode 12 ref count is 2, should be 1. Fix? yes Pass 5: Checking group summary information -Free blocks count wrong for group #0 (77, counted=76). -Fix? yes - -Free blocks count wrong (77, counted=76). -Fix? yes - -Free inodes count wrong for group #0 (20, counted=19). -Fix? yes - -Directories count wrong for group #0 (2, counted=3). -Fix? yes - -Free inodes count wrong (20, counted=19). -Fix? yes - test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 13/32 files (0.0% non-contiguous), 24/100 blocks diff --git a/tests/f_badsymlinks/expect.1 b/tests/f_badsymlinks/expect.1 index d8314b46..b28b57d6 100644 --- a/tests/f_badsymlinks/expect.1 +++ b/tests/f_badsymlinks/expect.1 @@ -1,6 +1,4 @@ Pass 1: Checking inodes, blocks, and sizes -Inode 16, i_size is 4294967358, should be 1024. Fix? yes - Special (device/socket/fifo/symlink) file (inode 18) has immutable or append-only flag set. Clear? yes @@ -51,16 +49,10 @@ Clear? yes Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -Free blocks count wrong for group #0 (995, counted=1001). +Free blocks count wrong for group #0 (1000, counted=1001). Fix? yes -Free blocks count wrong (995, counted=1001). -Fix? yes - -Free inodes count wrong for group #0 (9, counted=19). -Fix? yes - -Free inodes count wrong (9, counted=19). +Free blocks count wrong (1000, counted=1001). Fix? yes diff --git a/tests/f_badtable/expect.1 b/tests/f_badtable/expect.1 index 14a3a148..56881f1b 100644 --- a/tests/f_badtable/expect.1 +++ b/tests/f_badtable/expect.1 @@ -21,19 +21,22 @@ Pass 5: Checking group summary information Block bitmap differences: -(12--20) Fix? yes -Free blocks count wrong for group #0 (78, counted=87). +Free blocks count wrong for group #0 (77, counted=87). Fix? yes -Free blocks count wrong (78, counted=87). +Free blocks count wrong (77, counted=87). Fix? yes Inode bitmap differences: +(12--16) +(25--32) Fix? yes -Free inodes count wrong for group #0 (21, counted=7). +Free inodes count wrong for group #0 (20, counted=7). Fix? yes -Free inodes count wrong (21, counted=7). +Directories count wrong for group #0 (3, counted=2). +Fix? yes + +Free inodes count wrong (20, counted=7). Fix? yes diff --git a/tests/f_dupdot/expect.1 b/tests/f_dupdot/expect.1 index d630e032..611f8701 100644 --- a/tests/f_dupdot/expect.1 +++ b/tests/f_dupdot/expect.1 @@ -16,12 +16,6 @@ Inode 13 ref count is 2, should be 1. Fix? yes Unattached zero-length inode 14. Clear? yes Pass 5: Checking group summary information -Free inodes count wrong for group #0 (2, counted=3). -Fix? yes - -Free inodes count wrong (2, counted=3). -Fix? yes - test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 13/16 files (0.0% non-contiguous), 22/100 blocks diff --git a/tests/f_filetype/expect.1 b/tests/f_filetype/expect.1 index a94560e9..1624bfca 100644 --- a/tests/f_filetype/expect.1 +++ b/tests/f_filetype/expect.1 @@ -37,6 +37,12 @@ Setting filetype for entry '..' in /dir (13) to 2. Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information +Free inodes count wrong for group #0 (50, counted=47). +Fix? yes + +Free inodes count wrong (50, counted=47). +Fix? yes + test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 17/64 files (0.0% non-contiguous), 27/100 blocks diff --git a/tests/f_illitable/expect.1 b/tests/f_illitable/expect.1 index cc0ca345..3d7161a7 100644 --- a/tests/f_illitable/expect.1 +++ b/tests/f_illitable/expect.1 @@ -28,10 +28,19 @@ Pass 5: Checking group summary information Block bitmap differences: -(11--21) Fix? yes -Free blocks count wrong for group #0 (78, counted=89). +Free blocks count wrong for group #0 (77, counted=89). Fix? yes -Free blocks count wrong (78, counted=89). +Free blocks count wrong (77, counted=89). +Fix? yes + +Free inodes count wrong for group #0 (20, counted=21). +Fix? yes + +Directories count wrong for group #0 (3, counted=2). +Fix? yes + +Free inodes count wrong (20, counted=21). Fix? yes diff --git a/tests/f_imagic/expect.1 b/tests/f_imagic/expect.1 index 88e1f70e..ebee1926 100644 --- a/tests/f_imagic/expect.1 +++ b/tests/f_imagic/expect.1 @@ -26,10 +26,19 @@ Pass 5: Checking group summary information Block bitmap differences: -(9--19) Fix? yes -Free blocks count wrong for group #0 (76, counted=87). +Free blocks count wrong for group #0 (75, counted=87). Fix? yes -Free blocks count wrong (76, counted=87). +Free blocks count wrong (75, counted=87). +Fix? yes + +Free inodes count wrong for group #0 (1, counted=2). +Fix? yes + +Directories count wrong for group #0 (3, counted=2). +Fix? yes + +Free inodes count wrong (1, counted=2). Fix? yes diff --git a/tests/f_imagic_fs/expect.1 b/tests/f_imagic_fs/expect.1 index 13aa850e..b21fd358 100644 --- a/tests/f_imagic_fs/expect.1 +++ b/tests/f_imagic_fs/expect.1 @@ -10,10 +10,19 @@ Pass 5: Checking group summary information Block bitmap differences: -(9--19) Fix? yes -Free blocks count wrong for group #0 (76, counted=87). +Free blocks count wrong for group #0 (75, counted=87). Fix? yes -Free blocks count wrong (76, counted=87). +Free blocks count wrong (75, counted=87). +Fix? yes + +Free inodes count wrong for group #0 (1, counted=2). +Fix? yes + +Directories count wrong for group #0 (3, counted=2). +Fix? yes + +Free inodes count wrong (1, counted=2). Fix? yes diff --git a/tests/f_lpf/expect.1 b/tests/f_lpf/expect.1 index 767c3b54..4f2853c5 100644 --- a/tests/f_lpf/expect.1 +++ b/tests/f_lpf/expect.1 @@ -27,22 +27,19 @@ Pass 5: Checking group summary information Block bitmap differences: +(22--23) +49 +(57--58) Fix? yes -Free blocks count wrong for group #0 (25, counted=33). +Free blocks count wrong for group #0 (24, counted=33). Fix? yes -Free blocks count wrong (39, counted=33). +Free blocks count wrong (38, counted=33). Fix? yes Inode bitmap differences: +13 Fix? yes -Free inodes count wrong for group #0 (2, counted=0). +Free inodes count wrong for group #0 (1, counted=0). Fix? yes -Directories count wrong for group #0 (1, counted=2). -Fix? yes - -Free inodes count wrong (2, counted=0). +Free inodes count wrong (1, counted=0). Fix? yes diff --git a/tests/f_lpffile/expect.1 b/tests/f_lpffile/expect.1 index 909952e8..04cce4ce 100644 --- a/tests/f_lpffile/expect.1 +++ b/tests/f_lpffile/expect.1 @@ -26,21 +26,6 @@ Connect to /lost+found? yes Inode 14 ref count is 2, should be 1. Fix? yes Pass 5: Checking group summary information -Free blocks count wrong for group #0 (86, counted=85). -Fix? yes - -Free blocks count wrong (86, counted=85). -Fix? yes - -Free inodes count wrong for group #0 (18, counted=17). -Fix? yes - -Directories count wrong for group #0 (1, counted=2). -Fix? yes - -Free inodes count wrong (18, counted=17). -Fix? yes - test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 15/32 files (0.0% non-contiguous), 15/100 blocks diff --git a/tests/f_mke2fs2b/expect.1 b/tests/f_mke2fs2b/expect.1 index 87222470..5ffedcb9 100644 --- a/tests/f_mke2fs2b/expect.1 +++ b/tests/f_mke2fs2b/expect.1 @@ -13,6 +13,12 @@ Pass 4: Checking reference counts Unattached zero-length inode 15. Clear? yes Pass 5: Checking group summary information +Free inodes count wrong for group #0 (18, counted=17). +Fix? yes + +Free inodes count wrong (18, counted=17). +Fix? yes + test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 15/32 files (0.0% non-contiguous), 25/100 blocks diff --git a/tests/f_noroot/expect.1 b/tests/f_noroot/expect.1 index cc90d93a..7bdd7cba 100644 --- a/tests/f_noroot/expect.1 +++ b/tests/f_noroot/expect.1 @@ -27,18 +27,9 @@ Inode 12 ref count is 4, should be 3. Fix? yes Unattached zero-length inode 15. Clear? yes Pass 5: Checking group summary information -Free blocks count wrong for group #0 (75, counted=74). -Fix? yes - -Free blocks count wrong (75, counted=74). -Fix? yes - Free inodes count wrong for group #0 (17, counted=16). Fix? yes -Directories count wrong for group #0 (4, counted=5). -Fix? yes - Free inodes count wrong (17, counted=16). Fix? yes diff --git a/tests/f_recnect_bad/expect.1 b/tests/f_recnect_bad/expect.1 index 96fe9dbe..609a8fde 100644 --- a/tests/f_recnect_bad/expect.1 +++ b/tests/f_recnect_bad/expect.1 @@ -23,6 +23,12 @@ Inode 28 (...) has a bad mode (0177777). Clear? yes Pass 5: Checking group summary information +Free inodes count wrong for group #0 (18, counted=17). +Fix? yes + +Free inodes count wrong (18, counted=17). +Fix? yes + test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 15/32 files (0.0% non-contiguous), 26/100 blocks diff --git a/tests/f_special_ea/expect.1 b/tests/f_special_ea/expect.1 new file mode 100644 index 00000000..3c775d43 --- /dev/null +++ b/tests/f_special_ea/expect.1 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 17/1024 files (0.0% non-contiguous), 1180/4096 blocks +Exit status is 1 diff --git a/tests/f_special_ea/image.gz b/tests/f_special_ea/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..c447cb73e788d11926014d1595156f910bee1af6 GIT binary patch literal 30344 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

^r1~PAg<;co z;;Qea83y!B3-($=%5{UXp6|l}oPVoQrE~7||8|%TRh&6 zYb^ukVd}_YVblU)zEJeD$eY@)d00&nzHnb?W@2Si+ddK~kDmI9(P+Q|akBsy1`ggt za?Lhi$ytH!j-CBD=FK!hhoE#bt`?FNzFFZ@JrCwXk?eS=(d8GRPIVUd;WZ;w>!oXr z+l-ql9n{Rsa<514Mqa}~Ir_gy)Va@&T}ES-HI~8o*0gsHI?Bkg6ynE_N3q!Ej|C1T zG0^~~U;Y#05%l)VJ>vzC-Fp`8iRF5@hFc8~MU4abv?+t$(UU*}5|AKeFDzT>0|)ZV+gaTwX0~1+R_f_%P_TZJ^;_ zF{Dru$aesLi);YBR(d*nDsftW3SF~1b@Oys1v=pUZUVC0Fp1N5S4k}rA&y<(cK6lh zQ@JboTPQdDhx|RNL8Q>F=7`Ld>a|Ia&s-c1Eo}rMgIu*;XSG-}n8Tcug@9j(E-FON zCeUJ4V%5Oop)6|_Zg0nPNj7!=z0vOKyY%GrIS<(9+u)yAaaa=`4_X-F9z|>r*q`K zP6Q?-m$*zU#47L|{AW84RwdSur-U9H zOT-c#>K?Q$Oe=Vf!Sx*i4NMN->%0D*QhIPL5!QFHI&m!#xOX+LE|Vx_0q>j{Pda%L zdk}+3d~Qk7J}#u&n|<}0UvJymOT>TY))f4U)hXUe;2qgN?|JjOlocD3WxT~_dU)#H zwPx1GoI>L;^Yoy+b(){M%=KQt`E=Xsow%lJ-NeM6@HZ?YX|k%mKM9x0D)cAekEVQZ z`Hj;HddoXQ->4MW>L5SHEnJI5y}dSa|1f^8d+v5}!E2RPxuyT@VyOgMLNPD@2H?gXoss)Z-PWmxE3DEiYYc8jWJ< zZ7&IP#Xf&GqsY@S!!NK%H*FxMdn<>@st5QJ*Gta_vbWO2UXE%=hefyM#{*`Z$Jely=00rx4z$uy&<_Do)BF9i(TB&w`Q};=Dt9AGIhhBJ1m6l}$sB4>cRAYK4++NGQgXTfQnkl`W`L0=P2$P^ zXb7~;x+Vr?U)T+|mP;#gjktaQJQ}ADZ}aVLfInm#XyO!vi|Sp##r68I{Z1!`_bTbm ztgeVO;#T}pS18cZk=SoXdfmr87Qy_ZyO8IAZqP@Us)x(HFk!M?#kNmSay#8A+tqy^x;CPCIP0z)1APa<>Bk0=#+?Y@+xfiJgxcueFY!? z-&~)Lq|M|Uv<8UJ9$XTQu`NMG!>CzE9Xzg5cTki20{ zEcDy;_O(zf?B~x6@cDXUk!$hU$aVHyGyN`iIG<_evAUn4=yJ-v$Lw=uyFuS$sHsI# z%-Bf?Nz|y;VojaZ9)16%Rw!{#dB$+Tn%ecy%`B3#*OmoTbjXNW4O^d^r*S`X8=_ zHjhJGIPXSy>28*!-gI1+sGI3;8LwQ*ymPFarZ7zPI6r&%;)AwGZ*Z^$+l-Yvl7Dco z4&7|uZ1CoZjy2u3Mrotw3c#v$0=(Be0jAI}KQF+Y^B){w{c(nZ zs!n0D$t?k1G-MtSwgaN28PE^{x{)V`Ug^#o%i(r2)L0ev4b||_uo?pYaMwjsmVfu+ zJ-1|j^~T428)NEiC~{Z+WqT8U&x+h=-6eHy{3GpV`dprbkhAqv>S)!gC?(M5VsuJ_ z<4?7gbX$P4`!hA@+Ll|BhBe@3M#Zo4DlF3rk|E)|ROM8=xd(_sa-n%va4ZdG&f zu}{WTP;c9z@ON?9r)^hESJ!LDw-!TjV6;le=)t>?#=kypVa@YI;mDyVEb1RXN*C^z$kfvSryq=3Q@J zGdqbtZ9Oe4dg9SJB#QmVcbQld&3^;`REgqkmmiN7FTuHb$Oy`c?G&WiT+pCYU!%;Q zek=0BMH8#vs9NyNXL+Y?TU`k8MK1fYkl(aFAlbu9&wo>ksRkIDLCnfNb~A5k(aUF+ z3>NO^S@Ug_v{+nfwpRn*w)(b&HrGev{~;%$PUQ`|M5}1#;}g2H*PI|PFno3-NB712FNjBA18mC zY~PbKPZ^sJ%T`-rOMD(bb{Nui8n_tu1mkw5ohdX>qC6R!w8w6gYkzHaxX}PtQzpC= z964)6gNAn(A9MDqo`cMD<@4=E5#G^bQqS&fG+e%~TIFh0_C1sNaO(eONBwhjB%g^j z9J(0PRxA`j*kW_^l-KLEEM*&2ItPk^`=rgIbmq)NL}HuCYvLNiB5hZQK&y}yHU^xk zyciVB8#w_!T+(ha?*YNqmxSR~r{vJ~Tu**IXFtfFY`9KVHSdE4awh__2dl4fGWRrQ zMq>+Cr9hfwbNA*5t{ym%Q$wFW=)1Rx{}ad3-_1YLe+Q==w+SZ@`;b%;SJ^)sw*&|2 zU+bURtMr{2#}QASAO%KD5P~a$v*q98zldXp3&VHCiNc9%BPUS7`-fA8?}5vVtAXoB zB}qw)o0LsVfF*IFT21!f!Ii?OJ zX$F<;mMx0#E=t+LE=)7YQMh;D_jI z?9I7;Ys>gi7~3`3Zy4#8^`}y_fX=GSNzgb|On}Q8j~+)M_{n!V20p$tuzd+xi=`-{ zT7Ub~V7t{YcdGDTS3SS&kJhc}!+iWay!-+t210+Q5;dS!`hxup#Vf5XZFSP3)+Qs} z&K9m;9)!QQmeNb_H(aO6d0ZtMF)%O@@O)TIpJittzQxWe!4={9S(2SDzh|;e&pqf>gSc z4Cc+wmE81b+0q;?d8YiaSMv4c;N^XmrMfaCJY|!wtUk}6&YvPt`^m_>Lvi--?wGK3 z{U@IuHL;8&lcPZLIwo>d6!>{^ct-KN4J)`LZ&~X}i@wRw@}{%iX0aCUI?4Uz+9v!h zFH~g;3%y7k0j4N$-0)v4<6LFIaoPi{Wd-vQuo!7TMroBildXEgZDJYc~Ks``vI{W_DgqYC1*iK3#d$?w5eUYMn$ zT#L8a(7dI*48{v$zOa&m96bETE3Jro&a15a`Fy8`aU#&rHX|#@kucIbConm?#+Ki& zS)9#QY_`AQm+w#+oqd(vWu0s&nYL0T#8!0w#vSS6c2Lv>d8MvLK+3% zPiKAHTJfC#rp5G1zfnu>SzKj*erMJ~cg>|g=yQ%L*}IY4ld!gEQMOnzx9VizyKd@d z`$%_d%$4eKfYoeohTKGZNq3a+dtDt}1@P1Jd&4e3$`@Je6V~@BvQeQj`OtzH8lT6t z`1?AcTxa*Gre{G6*Kh=9^uR9w_FU@(J~c{oTF1#NII+jIUnABI1Y^O{X9wqzXX`OX zI@9FxaKCvr_hq>NaMo0-Tp!3_(Qg@Kpz|1d|M^r>f+4O!a7`31t>-_O8f)%i-l}~1 z%r_i+=NEOo+^2Cs*}rBLC%+eUL`b`9%-5E*3+!J7s1DSMB`gB8{)BD7eQzW7{1sbb z$IN`qOk$$_p(2dJsg-lN|!^q5|w2+1qZOB((#xR&=Ixo z8`hG&BkPFN#2D{hgLxnyJe@gUE5(fo)bf3$Z}HGh#j8&E!^NYEOUl)S{O5ZhaxWd< z;s}D|S4~lY6X2B9K(;nZwcMj1Xoa1u^no__nTH*NRn(8wKmjte# z+m_K85`5B_w8(G#DE)68E-VdhIsq!SL9ixiEm_;!i7V$@-6)z;d5H3;V2}hT4na3w z{-w%J9D}NCREsK)4o&L@T0VVYEDWbFSGq3MrmZ2p@!dTqAN`UpvDj%bL3{xgwZ)!a z>^9V~#)&f{f8C@ZFW#T?OA0FFBM%RwLWO79F%#E?BZX!);m)>y2wh8GXtV^COY!YY zZZAG*W4b!7dgUjR#hiY$;OhJ0!KDElOYW5`c5#H`SH#&lsx@=Q6IerOignn8oV{)d zlTbQ#K2MkY64S0k90WH``(>F?@dJP*EijS(fqqy|$i~gsWV#4~o<;C&+>ayiK_SoZ z3bB9o5|E-Z436`1lqU+uI}KZmlqATd!f%Q z^aAzc^91d@Pvc2JtI`%n*VQQQog>G+G7ddc^$Ttt?aK+UqFWyU4SLY7caSqdB0bPW zIUhmZ^=w@8r~_y1zlPD12|KD81A?c6a<{bYwxHd4nFJSqhE@D4Tz+(DC#8xMQONl> zf5ez(7G_KHSn9_)j=De9>XWcHTYqQXALCx(@Shd8P-yJ@dVj2;z9ryKG!}=~UhQW4 z5Ji{&RZzkFnYF*Tzl-#0*841q(=uFmYjH+7f#ah@A^>OJU+)FlZWZ?)82{+Q7~TSI z3%)Z>?Yka@1UE)m(^W9(!f4K5a`BS$<3vYO;fUE~JhX)SFPl7@E2#;LXX_+Lu_+p* z4o#aN^D1;yZ7O^o=P(i3S|79WK|F@JAr`=$Xx+kBhIK3d20fA@d;B%xmiCn+@4i5G zd)@u7R+s7;s$R;AF%W9|@{g z{nBlg8(7aJM9E z7(L6K6=@kq0-@+k{f46@l1BLN+ob2+p)wxS8YisZvgBHzTg@M;TxK0{1ar$Y78~(B zP7P~1=y4`q`JF;y!IaXs^yiO4@mZz>Udia7V|)NI0D4~RyMXuYcwS(u9{fYxV{&9s z<(Kb=>d?jBGoo&NS4R+4*7y;viA+rP!9%?>>nScOdpYGxs+|}amCNXj&+}mQk`1CU z!9nK{B;s~-z7|65fMqOPBPfHyh(ACW6uuK z=whegm(ckC>veIw^O7*0e@DR6JI7l(|AK(-eOM0?R*!M2k?=}1i)kJ#sqCJt*k^Xtx4GonR(^N_XbRT&xP-tN016mM?g#fG7TJ%?Zi`p5 z`r%xQ9As7%EQTm#lP$h%>#6xynn=%Ed$%Ib2)fuB*9* z2L-L~y`_~J1i%M4G4!G5= zu7&Sk#vwg{m`CnqB9XO}RwMd25ccDTe47)h-!9p_-lo{BN3XO?{yrHIwyf0<|KZsF z>Q>*~xJG<6zmUjFbH&?R@jH`pgigjM0UY(3wdmi}^3qoHCrRi9ycnz&4Ep%Zl1)g`v+e+Vl7=+H;1Pm^i^<)7VlHQLcjL;m zip~6w3hMcnIlQ|}+B`kzlXfeQU!huEw3*WNx7NqHXvObq2*yI${jL^R5Z+YC1*;uo zE8Tmw+oC($*YuKT5*@f1BU@#x$3U+kk@{Ba>yRQ*uiR5{+|k2nhJJY~^`v%@xkN_8 zGrZ^*&6Ik!q$H-YP#H;bwf1-ely}v52cx%MD~20Rwq(rP0U1bva|t?Yw>9Xa4?2d< zGlG_%AK$UH^%oG2xt>G}xL|%)?hEW%wrde{hPCM*jv-s>J~?<~GZoGX2a#^)%&G*g zia#(4j}UlReb$QpO>cX0P_GSpW%h;Oly3}1_^TYb-tP|1st?>&+q8di15!wix-#zb z4)M6p35d2s?y>q3cquF9M;yc^g|^s_4F*XbH5V$>oBry@q4veBZ%WyL`Lf4y;Dt90m}GvEW>f(S-Q7BVnd*oK580uX1&w>^<3h}7;GxxT zT|VVuf0lKTjoFt701lfPcyR4ip0MUKAEuT}?t>eT`C|NE2eTe*L`#JSQZ%*)_XSwc zuy^yov%567Wf9Oq10S#$Tho)&Z_=?06CKN0N^|w*elBbi7(p}misE;)+;y+*mMwwfx>GJOe&U8&ch>x0W zfW0x4*URS#~U%(&N+j!0;=CEpE(~sou ze-oRpj^55cRarIm*YV@^%X9qhcd(+lTGA+zJ)v$n8ZXBRSy{}2SB6Ms3?qeoSQrtHPhGuTahkK9(gTbb>=3|DO3RhH~c%)yb)x? zmf296iU`@%75#pF2culOf_89v81ztMNbd51mLOE$0(fEek;BliP;Kl7itb5h(>(C$ zm51B-nU~jfPblOPKnyw8m;3tMhD*qM>|K{+6?hrkVgBv`rtk)<>I+!J);af{?VdP} zj-tTPcZ9{(+hZh92L~<_XAxMKGZ4L!?3%)Fh5Bja7Og=*=eL>z8wF6M2q@i0A(Iz7 z06tJ=8+2N)fxQr=48b$jVOeMS=%M!zPI8Oh1mH-DTL5YZIs-Ivj&Pf|G0N@$kf7qB z0RUUpdjK4W7U%cQG|fZ!bq2cc11I-tLa2PCU$v$okAQ3#^cV{O(XDphf9^}q5?TA_ zMNpD5PCk|9eagRWZsQR5(2=e8d24tfaoelYb@Xm8w0Jgw%48SI( zS^!}3$=Xr3)Pj)r!dT`CCgbT407LxxuZ`0WOKIja-2*@f3wy^hZlZQ&a0AFw$?E5|%_8{j3Xjk4v58g0b7!BECOf8Na0-@ixx@}v0 zfRi0KAmyC)>cJTXmJJ1Vx@|kh1UP)b-=rr1=Wc+2!MV3hJ_-Z+y54QOet#CAX~0rp zu(I@6ptl+ut@7vwEcx=JDPIi3 z_ei9>C5GNdU^sd=Ng<&QhiaG{?}q-kYfb3$3j%yBZHIrF z!&B|YGoT3fi&!L=Te#j~F!CU~VhAmE?zm}NH2X79rgmMn$`_* z%e4sqsallztnbO>jhW|=Jndwqd{KJFLoHB*prqoFZjO(MXkj%nWx&E$n^i}dg=Kyv zIVp6O*T&BPWGYt-?TP(WEWu;+m5m)+coG>!AFaf4(B;$dt%p>5mS!FHaMBW(u93fr zaI(E;8_oUd?3uzPLAXjXk7%CdwJ$g#uE}iJo$U!WFFPud-h~+w-so6w^j7NitttnU z=d>Dl3U7OsH3#WJ5N31DvB?B+hl?nULSCnUlD_-p&Lga63ga!k58e+zWw!W(uHw&f zcIJ;L{X(!5)nw=+y}gW%)O%5j7+1X z87>E5YgJ#It%se?8 z!4ohWIb)O#uo_-K4XpO-&%T>g3|XE#b#{E*~;V{shBh0GveAIK%YAu1219#mu+ zie3Ry=t}UObWVp1c3`0$1am;?8@fy25v0kKcfT%p@eUm#MA1-MQ>r-@Es~u&-~_8E z`UyCJNVQ;K8e&x#pq=o@a}gL_5cfhuFPxnO(0AY@QH9Q407L=eAuP=NxA+h?`?tH2 zLG9MzCD6xg3yf}#V?jsgH}IJZb0E5nWNZauJ34v@j6?k=u%L~h708~T|NMWzgaQ8x ztp-jE7#sk2wSxy5s@sjT#xjlJxyUb%ssPG;xt6eye%_Zurb%Trz<(s`^R79-ZnSDR z>J%+l&T!ZeqDERoP{!51XRHVhK>%50O*K0}=E*gz`sx~X2N&}B6#)M#7AEDq{``B` z0T4rt^z-wO4sxuDZp4mWO#|l7+1h~MQ8_UH+q+j)Sc%0-U}fX}t{V*k?R&j)tIhy) z2!JRo`M>TtAyLnGN=|@o1R!^vXFL}`jgMG{hpX@n5Z|`eWbzpUjF621)+c$7yGDpH z&{jnNrkVqQ|6*^EfcN7IzrRUIIfMg8jzv zBdnZR_d9xv(*7Ar9#A~qkqwa!*pjZ3kouLPVa>sUf0!|gWh>dq`7Baa-swT!={EDd z@E1QT4ol%8oy#{k{72MR>w_=Fvs&M1U)r1C z+x!lHlb1)(GBU#Tk(OxC_1XRrJfE&KN1Gcq&L-&gqUD4vvMB0t9vxfy6CsW*y z^D;E5{Fw8t4K|((m0k&rD|FqMLmhMzdNwQl=K2l5LoaeqT7*pQ)5$}GR}k{4RIp3q{%hd^$&)X-%H@H(bqH84gl;_I-G<_DSqrlmi0 z^Ao=S|IKLUsn!SLpL+_~8@68x{lb6$qG?-V{IRiJ3A?%x!8|DY8VBh3waEY#*u63ufNdwzWl%89st?p7}(PxEJUpT6VF|ZDMQlN7!D1- z0M=XUIn}cNsf3^SQBRm(^ZsI_9jBVBG+WKo(4A27?PxcPe8iK?u-)}e9ekg>27NCT zRPGya@{2ngw0VE+hOZr|#cr5jQI#444Hn#V+#;nr(+{}D9OrTGjry)NQ7COualWoy z;pD+~X<`_BGPu`D?>@K7`Rg7hU3KoR8v02XBIU>pnD%8~t7>gWZvmA?{2y6`9b^=5 zy6(*$*b%5HEk>Vh7;j;DN<&0Si>O{C{0)>$8olAAIGvzb=Md0Pit!9eD5o8{zzx$? z4;B{&`3tgA5SA2CwJW#FNEGsoP~FyRgZ$?%%QWsknSpTh=kX2vF>qFXYa8)szNn3E zJ5<&{d|(5`G6Y)xx=22i4H{wn!aPu2_bzZJIr|17LxTC5%cI7YhYQK&WFsT3&Ji*F z>3Xk}xz6|6`dM-LyC+W|d2vpM32ypu)+c-&ic!IX;gpF9c(W?(g6O`3Tr3{si@sX4 z{f+LIbCj+&50W8Fq9-dpr!5_o#O<~W*0~WLQk6R;|90P3ErI{H3+tlZI14|xQ5f7v zp5cBP2A_!KG{-WY5Mm|1anYhP=BsMK2d(h&S67SvmYYuouGy)u{|>McT)ar2fQ;h`C<_$BMGSu9RHGtz z1w9P*CO{~5=ah@Qf<86mSSH$oz^X^sm0M}+|i ze8=h;({7zXHnV*GUG>`^QniKo;Z%apK4jmsT&-P)zKOdjnR=Y`eIv9bB}8^EyAPh2 z$h}N@J#-V(2MY3-#TOEwR`q0oKn-()Zm*cHk6dLFoaIhO-GVmB*gv4k**zmHuJ7nF z?AXioerBGX7EPFxHM%~zxg0Fll_-Co*rItWuADrkcw0XL!Z641j zoBRywr_BFN@F%@+mMo6lK4|KrHPMAs?X^3WY+OS$gLoLVg1Z0vWy2iVtdn5Vs$Sw| z{@yb$ut{PDCsUE1p^rjt_XR^a8Q&P?s#`;^g31Swre32wF(&6s6`F0zRRq&$&4G(b<##5b(xUoYd)sOv_xD%hyZ4yPIqCg*bM*^E3Ns5dkbL>8WUujMX8uuPwR z95sL6h-ipvu>JDIbrp1U0-JOF42^QV3@r!$Y0EQ&W(YlMP%Rix=g8$F9w0 zD=l($opA2;r9UfX@c6JBkwp3=kuO|CGW!kDt``S2kfr{RfvE5H->vY-HsUT|1BU{@ z=nnt@Ct+cQ&~&u0O8ZO>LqUo*D( z{UvStyjrSGe4VTprAqWSe~EH+G5N*HJC$wJ3C#&{jG*L@Pn7nMSU!Y{w9_$kZKHed z>+i}H!1x-QO?#KsZDFB=pvWJpwEbA%FIfdpKe40r=}IpM11;>tf*a*O0olH|mjHKp z4bXcve+XD&!|MSJMq41d4pn>-e3**Atu- zK;_QCbq0{!qQ@)^oJifJM!>SD?Ir?fg1y@T#t}OLJ=f4_5*_7BS?1$gSXO2lLK>h# zSlk}of?En?0jiCzOdwgC)(@MVV|9f9%GkDVVN=MQRv!7n#2p|9&bD<8ef@#`<8hVi zUGK1Q^xW*c>ux~F2`tPVwXUD>RSaKA94f_iyJ8!A3AcdR*akq)JBL#WWmEw)_T8E^qer7?acNw_PoMH|I6> zZ}%T4c}i8s#}T@c#&8Kqfx8<)<)*GoDZ zr1+OBTU&=`m-avC=Sw`;DlAMq*|kB{AD@4z*sl&BvbCj}ty5@X8RdJv2epMy%xoj; zy-JU44e4DLw7uWirS~qbFTRhocmc72EXMMWu~` zG>G)76}z38Sm5fSl_hVjj1kE0J?U*A*%&-n#IQl%1d4)(KZ)&C^M0!n^S=EXSxWY3 zIUx!8iuIrIX2Wy>AzcXJRT}dweZh`l4(`^XyOgOLqUvu5b zvZrCQ@=3`A6mLakOq*o|qG89*E_&bPz#R2eZPSapXGbQ6F}5K*ahO-8rSR#^zYzQW zp=#r*D%M(l&0qD-nR24DA3pW*c;_}YR#x`wn#S2z7)GYnMPlje2PbP9Wx0B-#6B66 zw(<)kQ+Z9L*jF=6^6S2fIYv&)e;%q^_&P~8(_pkj!RC1M)upb7vbC-xXL@q=az>Z_ zMKGy|i~ix4Gx6uw`4kDeAj3DHFKi8DgfAZB^PK*-& z`6GsjR(^;2QGB|QN+XKBBsU>wn$OCDD#9QBYZP*D-e~e6Z0Dif3w$}UJxtQm(l@e)_^T^MS5$(=d-yD|G$ zI07ttF2oF(y>r5ua=+hcPor{!I*G(`tJPvYTy?SRQM9wSleEwJ+X{}vTH)WV0U;mZ zC;Xqdytu|VAKFFz8E_nNC~?(s+6dozlWgK5aNY6g@vCrq{1g58aRgVH+R6OSs(_OX zG*sQ^E(9+mK()%9=X%ZGGcz~zr?F|MGdMMRe|ta7m+FS*59^~#x!qA} zU%F?$`;QU_R=j9TX-vG5I%K=!^?_z+x3EX46d^|tOIdU63SuzhAr~5+4c(WHouLxv`g>YZvq~m~D z$qB1)i0&jxCOg{Qar$xO9#Nf2n$fP-`^&eh`Ui~$ez(Jwz&j?A#C_*qh%<^$h^z48 znxUipb-PzPW&4NrH~uKxN(dpoD6RxPJ)R$VAKn8zKR{Q=iIf`YCM3ixL{&j7B+5w6 zLZJ=KZGgzPia!fcaT;~V^+p?Kex7%DqssM}kDx8Y93Pw-rN0DJyNiu!(HS;L?{P*` zzjGlbKSz^GGLMa^z4-LqikI{IOT`H;5^AanwfN_*kM>45BfFK8gdRT@X&z!@J+san z>hq#D4Lw^;$;=d+kIht=ip}$0%GlW5lvD^%jALb*)wT9I(bp}9zj<{gd5Tg+-6>1$KkdmUedwN;ELE({A=Hrc zVR$2G!SujnkQDLyP4f2gnlrjf_t*$(v7rK(iq6j5OO=qZwslbW(c3CDRWWX=dsK$f zt+bq1UOBAtiT2j92sCcV`#O6afVj87cq(@Fu0~e0`V*z5o@PyhLH;L^waBEz!S0^s zvfNw|N81nmKU?l=jKLaX`G2QL`cqnb`RUV8_LEy=buM=72B`&P=9Cmct54LotXF=&c{U_fUYSG6 zoGZ@Qd*86dUz3e@Q`>`0?izNC6uEky;sUp zG6UD#q1r#NS@?TKfJ9Q{oQ7z&7fO5?JD9oe>*n@O)A4ln9)8ZkXT8H=UL!-z1jyU! zv=nkBBzDy*EqpMX^v$rR{>UGXbPaj;m~D5ZfyDVI%5=&-+W+1PD<>_l4I`$8a(7)!Rxz{liUx*}HfdQC>T7Ih=cRa`z3)9h9*H z8D9j?k_3>So?BYJG8-iQN&59?vgbtUg=P#tzrZtofuYjAVV+B`Q=N54a-HylFXYoV zlhq>C+n-i)EB1!?)H&qrw;Ow?G}mk+a;qvl9&LFfdw1g>T^`cS(}k1%9I__W?IDC` z%HRD>kl?ZQGWk9FGXc<55JKiUNv&3eq7*QR&16NLLXs(xgjC zVn;=KuR$S1M2J8DDIp39LWD>L5-A}_4*>$HkTx&R`u>Jzt@mBunYDko*P1nZ_FQw# z-uLWvU)P6|ttUuRI=VVq0pr=t+$WrYvTvPaOtE)M9bgZLHboE-=A!~^P*d=d^>}Fk(gw+a)fw$oa{haaNa|? z-S2~cft5Sra6J>9P(^*d@_oJG40G$R2!#({3TE8i*4MR#Uw(Im)D|mAa-P*|vh=O8 za?Uxqr!`Vl!+!M7Kc2e55WilYBb~VDwada$S@*?-3m2l7UoO5WY8(3_)V8Fl+&Ho0 zB_me#*5^wX;8t%Ly2D$yzV14yeWF^6pL01XH;xRCi%So2tD0x{#ceMOOZR9a&$m)) zZn}Z=lY>GvKL;Z}PPrZc?96K_FMTTuZ}Wa~Ywd+J<)%^nsZ#pjw>w9iPxO0ludS3N zw)qX#=A{4KtcvsWd*gIzCXmZ?ym?^3GEWsxBA-61>#W?yXtgBkE?qsBQzE&D}g;|Jv;rYlk-j2D*ll7k1?`Xd4<&WWblwZ0em5S zd%Og>jS3oldS94>1OxN}|oHQO&ffasy^g>j7FQ*x!O>T^N{WzvSV&!$+^AVup z&9=W3x5{@JKSFTRtbXFcOwe$`U83aJDEkiuGiABelz<7zF{Ehi_Ygc}n_$TRl_tRK zX9>2X4|LF1FPATUB{)qi<+Oh90FSEl!>#oJImsaX3tKjc)-KA*mTD$w*MwqL_CRbV zsz1_SknO56>h3eMij8yMx0P*6dCUCLd?s`CSs%N8`XK1$-1KHKtABM5TT*!lvan0A zH%gtZ>Npk}Ih{XXPGL*A-!e1g7-v_nDBEoWqTo8vFlEWf6s@HRZZqE%P9`vI*fBQ|ER-r5Jf&xIF8cj11)o{E#^ zNvx@ZN%Mx+J1FjAid?+BNf|-*iBaBr`K;BrNrr7&Bm35G1ehB8mR=S8r#jQOwC~yx zfy~gw?Q$Mh-_jvh)_%8#Pe@J1%D5=aK9S%HJO>DmNnQJ|B78xU$GycBMVArGdSNZHv~JDsGF>`#^YN}unZcP< z?2A>>_0Yu!*@-pE1HoktJBl7V`l9i2XEiCr3jxCF>!tBS-^-Vs+y2layq=rWq5Bjx z!v#_|y^ys;B|_!ou$unxjn4IhvsQ@*$`mIlLk|bMCiiMCpOWlMIQ(Zk4ifTsm!W4^ zny>N0uW6Yv+T8=b77tZvVROm#MPM@FH{LO&ppS76Fe{<7eq(7=s`>kl^%r3w+s(7{ z=kAyxLQ4o-xaKoG=&c0$mM+32M1uN+N9UTEneS8jneIcRBmQRR#p#*pjU-p%{fYWx z(j9NQjkXzl7<+GdF`@8PEv0?5vOzaXteB-Ysk-(poOosggxig+Y9}X0LwCxls*?hwox3G+DzHa#j29Nk zWTP7ck++`8))dPbDh0j?X1fm#8+d4ZFo@PB{uN&^ypLMxSv2Cb!)r?8Q2<;C!iDh{lO>)$q<>GJ8_)ku`p|7!v__m4C}mFciB4aJ+cCX_AFfvKQK3tr`K{qxM^VZPEogddn*`g?#-?~ z@WaW~9n`zQ1cy(`{yI(u3m-57Lmqp^kDVh?A+9MCIvDlf(BRt%-LMy_W-}A5THo)d zz|`y|$IyQsY43Kh+VoV=eAQU`aH^ef- znbB@N>DfOJ6OSO4PTFcW*=o;o#UDX=@prcJHt^6($hokO0xZ1kiwLjn5;^k`#nQJn zQ04IVJW)D*5M-c;_vh8$1h-gb^1A4ecRylTLX>Gk=LF^lb<$ZR_{Q&ck0G7As^Dy% zRQV6w;tD;W7hapNd*H}1e4Cwl%(3?(%JmX{o2RCSsPnvC71oFx{nm9s%XNPkM~1HrxQ4cZ(pA3PY>xGMCw+L%JVLaEQrd*HH+7m6FNz=6<@>gq%3-1I(>b+&c6Gy z5a-=Quk)NM2xWQY)ZJ|p&GFM-Jvlt^ydf^X<^GwrMDo@zxXe4GS*ohoufrxxFyAgv z4-Oj@G7ES82LJqZ90B9V3F-Nm?WO;nlL zE0J@xN5(3t`@`&Ih1YJ=r}2eDs?ie=@|Fo{R2X5Qvu9*@fNeQCYn{=cks)6veI>?b zIEa3ylKsrPOjp>abgv?u4Qn+HmX!SsiO9$wS9UIW$UC|mAtOmlZ$z@1oqni)f3CLB z&cW$&+BsD>H#V;E(x%VeAaaTc{*v3EyWqnGP=U0sN*emz_1eXG(9-hBt=wvm7$l)r z*@H&ICE4xG-Ko`^1DW6fAz`Rdirr->tM_3ZbQu*A41b>d{%H_YxrT}<{m+S?_Z%N8 z(^vONd^9cCQ;gbWTnPxht*a2KI5o)|>S=4%&2P%|{e0Wo)(JH?=^dWU5u(oS|B*XC zSzP8N{-LEn`uO$h=v>Q3%Z*GUW)<&yEJR~VmYKKjr;y7cjZG95o_6S7gV+#eo?`Xj zgQV5Q+uk7dw4@*NRxafzXDYK2;q8<{NoD3v(+3HN1qR(60&lfu+b?xyZz$1Dl(u+l zjV4Ce3HA+J)(|q5%F14`(h@?bM{}`KT2d9kGGmH3=%YU^fwQ;GD8S%5*1eLn5_U9y z^#_A}Gyv+(+d^LRG`mmAMBgW_gGZtV_~4Ss&@=nTO|tQJI4W0HiRjbgD-QZ~eRpGl zGVcA?bM<>N9sdyE`=3-F{7ogyMx}JV9d~u)j{YLM|qx_rH&`;TxAUy;Hj{d*7viM2!@BG8az}ozE-R6V!389;m;Iz5*@lTCl zz$jS1wDDig2Tw4;o{dsQQk?V1xT9+M-i-EQu=ZkEsPFv*u8|3{CplU0?n#5VxL|deq(ux;;SY9WSe}-FPd4A z`!h02MrZP$$HL#>qJqCuLit_A>EiAkp?c-f4=pWM%itadt{Bh%l7ScBmDf&TZK-(X zDBbky10ir_tF?6HaeMYkQ_{s1{N0dqA8!)&BFa+T!v0CscZyG2V7#5wzc&x2!fBO5 zmAIB2VE<*zn*R-5lL?Mb*j?-TDT4_Z+yEmbS2n1Yn!4uxG}OzX@4v>+li=&MpH3Bi zcKV~U{?78^_3<&^gl~L!5=;kMh`< zmGwD`u-x(eh=t_q!e%B|~U)wjRw`lPF zW<}r2&hw9Ft}`<;W3}fYX~s7Wtm9jUUaZJe=*a#=t?^QB>!3Q=n3Tz>f2j>b?uzV&1BS7`mun z?M@gu#N5I^ehGyP?IBL2zE?h)lYL-See=!O0#mgh%h=CBwrcmgWys!7t+E5g)Vd?e zQD9LPdP;JnnteVay48yI+L|k`1{jpfcN*MdsYdUD$@?zb0;*Zy43H_YSBzG3B$sF)??THRHK~zgWxWSp9|nvLTiR_^o|^H0sKrFk+9)j$ z@b(o7RU=9~FI!j>_gj0_siDRk;XXdL#ShLZ3-bW))EVxSEJrgGc#`XNE>PdQEqAeH zw7NFH*<^vL5^XeJsdMpgCTg|M&@SjVB%FzH~)r~77Kk+qIp zQ?I*nv1N}Z@)@TDxpm+wz(BcAjN-Ts^QZOYhwY$?$1m`GH{ClCCS9ni*WI$ zaoJgwESb5)iEYq9Y08%JMDrVZLmwde%bB~yYxBk>*!elFkxjoK_wxBcvcmlpI1fuz zAAIT>|2X`iioj`BWG%qT7s;rCKR&Rszo8Bv7(5#A430fN4i7vGjrZ=oQJp$wVLK95 zG*iV9GrlBoT31qfimEsXxWIKm#+#{aY_-x@wWa)ueir1Y^2Wz29xtx5*qz8tlZk&Y zd+LIkv98~agd4>vy&z`{oY`7VSi zNQl=w8-dR)O|Hq{pHG&Ixi*7Xj0D;0x3R=5qF_F>)uVi{IJX%LRl5bs$GUgUErW&I z7r|j)>JKR-hy{+yYw+mco)8+SW}L?b~;Q4a%HS7ef z`hFrSM3&0>rxK*7%ppsr?!f5&BKh0`Ph?MBtsbRzYxRik(Guc$MrN+a{Cge;PP9`gIu|3@XURjZ=lMmuMIl13-m?GpY&~50qD0;{QZxL^yKw&zX zq&%Y4;H?+3?33H>$D7EC8bbB&4K@wG=Nlf2xJIR}pX^+~@UfW-TFg=pEM_a>9@T58 zUCL-yn~_G#SzqOYkl5VM)tv3p4~1@x!Qs-kMtX5^ffj+hk3m4JbS~U_hV3^_5iYMU zQ330ayAZnWH-?)T52_~szqj#2ooRDAGOt2IduE7!X2gwxt+`-21gYN?wdz7V<3e}~ zm(1MX66j_4mM3}T$x=752oua4C?-s00h+9|^@#QGtLh5ov0w9jf>FAFb*}H$pdsXX zxNu z{#31mDK_d)nBfOx2j4YR9?ZL5yev+BE2?YQ3`Uy)9s<@wP3+IGA8B1(L*bD%W%|f` z?;MQ&26097%c;ZC+@q-yB*cgU=2B5dVTmwemB@pB4si4x)a<7H$>(_;#ymTWQy%w6GV@*?nlC^ zL5@Cthz)JVf);@$(wkKNTEpoS-MQSUwCHwl{lO@ccqXb*07|%VzULY&5TwJZC<-@T zB#^nZY(>75da-sil@lgEE%v7-=@xbYgB^5(gbs4 z(FilqbhKlzN@UR*iuQ*_wKP$XMIZZTdaqZHq57Aif|Y$*!$v0jn^V~PmpQNbtDU_J zVzlx=+d&^F$XoGWZ$ANT?l?`~-Vo<|uc57qX4nRo#j}N%R52Dg!8-N=^WqH)7E-P+ zHoN=w^%DDH(O5GQUFaID7FuIi8}N%!vkJbwTLf;@+3FGkqrm>9KK3*hVIukR;m}TK zj5Jv1s+aUzO*cU~wI<^GrykBia`TMKyQxYQ6U?}&s+WoC4U-ag0WVvmuLDq<8#m+^ zQvT|EFN2+DG~19G<62Xepu^nOyE<;3|+k)Ny~pAzT${qxe)=A7;jO0{I;z9j4^g5-X*8Wt;FIDsVS z5M5JvW2T&*HW#^2i}q@2$%q)!&L6BZFQ%5%wZ5AbOQ|J&&|rElbGAuHc+ zH%KIk%~E^+UGHe&w{nmOP+0j`j)7b{M)go7QG}07mb%eFSnt_B^CWYrPsAtbmhGw_ zmUACRm6y^tq7(FKlO+^rxKjv9qEkTEiqz_g7>fKxnA;6PCfAVTU_8i@Agdem1z=eT z4Ed14|py`^nDB#?nN4POz$oVWC7pcebRp=t`&q=vl@?#NC;TI>rihrJ*S& zfL>9y$8rMur9DUJDeWI@mei$YECVwQ)uPCJOhloA7Y$ex_v=yJbX{w(4Skb2qrpP} zfW!*fKFqvUP5xjn;z5^c{W+#MOi?OZlU##;(|D8V_~T=ZziZUELSxR1PNzcSEhp@C zM`jyjF?u?r(?iGE0^ujb6_rHaXpM;Z#(JSRl!#4iKPVNpb%{N54n+2-2z1PjAl69~}XyH1@8*ZVGj z5OF(+=0mKNoe@HhX3ur)K6fuxgvLx;-{~cCUGUv@J?7WOZ*{aZVo)C6(abfMZbF3^ z<_>G+DrR$>`UOVQjnP#(@a(&8bFR=Dvj}O=x^&f3;IfYBbO0|0jOCAtVNN~;SnV06 zW>suzFQb!LO`ub}DOAE?uOnmyfc^ z;k`(JA1QXx35absFFEC?Nbrsl=r4w19Z;j=^zo@7!_$81Qrn>opALR6U&AjU(%%Pc z^J~At6YB|rlKCj@1=In7tVp2EB6iULWc*AFeXrZ>YBP(f%Nrau`#25>&ByAq{Jo}@ z*m0*KLcq1SiKT`LSJ5c*Rkg^$JQLEU6Wawvis@K$}T~*V2&5Pp%@!-Dw8oHt|4Y0tV;aBPiqMO_4u{JT>|wMK8tG6 z?lUI#8{h3E5{%Xaf(U&DJd!Xwy%0x4<){`=5cF|Hx*9&RnkQK3|M1paN@IHVF6A;t zXKGFLsmReC4HR~k-;#O%Omx?6VcuQj^N7TTnzC45H`Kjb@rwR)ZQ;$Q={V1d%NG7K zs|5*hT~1ycfeQp=bMhm@qtu+Rdg6GnPEkF_bi=F_Gh9F$Lx~bP1RDMkIWj@}^{svjXJr+9GWTf>DJI+#Bm3)LftuzrUEmb>bP9~v*DA&fqPwb7z-=JBgt6vB z8wHcW4Y^EA$`UwXGH3D;q`yWS2SXP@suZb!$br3-fE^j=K#*{C5md;r0hc$__dlhn zN5eMp$4sPi2WX=*ky7c{x_SGCuoB{L39>k#B`Ck?zjb`LZQ6u!5jlibM|-2Xx8xY0 zdN^Pkci2E5u3L<rFg1TvTmB}N9fk6RrH6GjW2gdr^_ z;CfyqH8yl8#0KKvT2VzFVpub}83o)-F2Jqlaw3C;7leK-x{~8ws1O^Yib8T9g9>vI zItqh@UM)vy1tIoLm|=#1k-|-k3~15rvyH(tGfE;uTl8qCS@b&WY}`S~DakR5JXJfS zlRSn{ZcQ#@U>UXC`$CVn!xs5>V`)pa_)5JY;0o;0fuaL28+TKk%p6A|dItDmaAFr! zyL>P3oZE)G;%<`cK!R44E0j9}JAowfT^P^ccy+pW5ye5zHW1wa%yY>&CwHS{TRnRw zng{&EogF!eH&3?5+F%`&(8+)X!x;wP+(yjtrg)7rz#4Z1ccCDy(ZK^<4Hz<_V53|i z&MVGp#BwQ3qe2Bx0-P9*usNK4T*Sy3{89WFN4r*Z6PgC7!oo-N@fJ(j73Fxq5=O`Q zj6m?}Drs^KEQhN=EBP#ABGSgxKqW^GYF!?KQ3vA5ml=2loH5UpMmiMaq&TYCbfc$$ z9gHuLR|-m;oG|5A0T|;kgUfwwpkADAS!9{f?+}1atw=?uVxZ;Fih96=ag~82V}NG7 zH~8P;)c=WoA7IR|O)jFKf_%%|ekcm6P_9?L6S%-gV%Rf?3~k0FcZl1-<#CfEZH4|q zmlgxK8C(-?7p$C*oXEYeFH8rt2fHF*{7*P!<3v#@)2%MZaAI0tt_ zo!lI#74X5pygJRrL7mJY+refGPFp~#GrZGW9Q7RZ?5fa1z+2qKxG;Bp{E_Nxic=Y2 z517Je1{(Mi)wvX?FR&ff$z>bp;t%6b2WJ^N6_&fA9RYtBhr7Tn7<8Bd0)c(7b0epN zvm2d8%cZK)^t5O5{JLC-M4@jx0MF^kd)<<45FmQ*)K{@!}K*maR2fP$58<0V3cO z%-z%weo!Sh1*%!T2e5_3nVJ-5I5}d_@)ZD(NPZQ0QFu>iW2#@AZCPNMV_9OEZkgZj zG*=EqgSIHAxe5|DR)N%2Vu`P$;5XnKwNw54GJ6DVvS`8COhLWKGiA(|- z7z&JBMhmwp65eu%mKS1Ygz>?+F^m{Zj2K2vWMGR9t;8Qg$C#1T$i<8r15H}-Y(+d7 z&uEWC7Ua%iwlN-ZySW(djW{idiA9k#L)A95f>6;-o??VDUT|-}8wzYF87vfDvCzrh zj{aPk{;V7goQ4hKJl!pKId+m)aOd1lCEJkfwb9wYH?A0G7kAeE4E`iut2)O8T1Gy= z_zLUeX5d`h&61t;9GT@&KpwXa=j{$jc2p|g1rULc+?U*5+~pDD;0*6IVzHF2fw2Ha0dJVyh}lvm-%*5?0A}RPj8EKtgEM$-l`J`@#BwX(CSxV?d|Zs_ zX}qRN_ITlVZi*8N+FcG~{Nz52^fa|BPIGe5L^BxEk#?qMigPUUoS&ZM|hnUc;LUqm;b%}u8eKG{YDDV>fO$-NEF7!Q$0viTkIdb-dX|@DI+BCW;Kfm zzbX$|`SfdDn$zAcL|os3`W1Zq?7!l~vwgOyM! zLQcM)weor6`UW&x6>%?^mjJJT&8+)iXMLtQu@fA%HTi_#{ewI)c5WS_MFQiP>-46T zbppBG9CT&h=s+%VkUtKW{QteI{_myEza#q>fqxPB7lD5f_!ohH5%?E@e-ZfKkAPTn P&F6^w&#_IL{@L_DGD)vN literal 0 HcmV?d00001 diff --git a/tests/f_special_ea/name b/tests/f_special_ea/name new file mode 100644 index 00000000..8dfb2f4d --- /dev/null +++ b/tests/f_special_ea/name @@ -0,0 +1 @@ +Special files with extended attributes diff --git a/tests/f_special_ea/script b/tests/f_special_ea/script new file mode 100644 index 00000000..8ab2b9c6 --- /dev/null +++ b/tests/f_special_ea/script @@ -0,0 +1,2 @@ +ONE_PASS_ONLY="true" +. $cmd_dir/run_e2fsck