diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 04aeb26f..3b05cf25 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -935,6 +935,10 @@ void e2fsck_pass1(e2fsck_t ctx) if (inode->i_faddr || frag || fsize || (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl)) mark_inode_bad(ctx, ino); + if (!(fs->super->s_feature_incompat & + EXT4_FEATURE_INCOMPAT_64BIT) && + inode->osd2.linux2.l_i_file_acl_high != 0) + mark_inode_bad(ctx, ino); if ((fs->super->s_creator_os == EXT2_OS_LINUX) && !(fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 28badc9a..b33f596e 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -1353,6 +1353,17 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, } } + if (!(fs->super->s_feature_incompat & + EXT4_FEATURE_INCOMPAT_64BIT) && + inode.osd2.linux2.l_i_file_acl_high != 0) { + pctx.num = inode.osd2.linux2.l_i_file_acl_high; + if (fix_problem(ctx, PR_2_I_FILE_ACL_HI_ZERO, &pctx)) { + inode.osd2.linux2.l_i_file_acl_high = 0; + inode_modified++; + } else + not_fixed++; + } + if (inode.i_file_acl && ((inode.i_file_acl < fs->super->s_first_data_block) || (inode.i_file_acl >= fs->super->s_blocks_count))) { diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 82934750..3ff17f0a 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -1286,6 +1286,11 @@ static struct e2fsck_problem problem_table[] = { N_("@E references @i %Di found in @g %g's unused inodes area.\n"), PROMPT_FIX, PR_PREEN_OK }, + /* i_blocks_hi should be zero */ + { PR_2_I_FILE_ACL_HI_ZERO, + N_("i_file_acl_hi @F %N, @s zero.\n"), + PROMPT_CLEAR, 0 }, + /* Pass 3 errors */ /* Pass 3: Checking directory connectivity */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 1cb054c4..ce8de767 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -768,6 +768,9 @@ struct problem_context { /* Inode found in group unused inodes area */ #define PR_2_INOREF_IN_UNUSED 0x020047 +/* i_file_acl_hi should be zero */ +#define PR_2_I_FILE_ACL_HI_ZERO 0x020048 + /* * Pass 3 errors */ diff --git a/tests/f_file_acl_high/expect.1 b/tests/f_file_acl_high/expect.1 new file mode 100644 index 00000000..24d6e06d --- /dev/null +++ b/tests/f_file_acl_high/expect.1 @@ -0,0 +1,12 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +i_file_acl_hi for inode 12 (/motd) is 2, should be zero. +Clear? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 12/16 files (0.0% non-contiguous), 22/100 blocks +Exit status is 1 diff --git a/tests/f_file_acl_high/expect.2 b/tests/f_file_acl_high/expect.2 new file mode 100644 index 00000000..4c5476c4 --- /dev/null +++ b/tests/f_file_acl_high/expect.2 @@ -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: 12/16 files (0.0% non-contiguous), 22/100 blocks +Exit status is 0 diff --git a/tests/f_file_acl_high/image.gz b/tests/f_file_acl_high/image.gz new file mode 100644 index 00000000..6342d583 Binary files /dev/null and b/tests/f_file_acl_high/image.gz differ diff --git a/tests/f_file_acl_high/name b/tests/f_file_acl_high/name new file mode 100644 index 00000000..fd54b064 --- /dev/null +++ b/tests/f_file_acl_high/name @@ -0,0 +1 @@ +i_file_acl_high should be zero