ext2fs_free_mem(&ctx->invalid_inode_table_flag);
ctx->invalid_inode_table_flag = 0;
}
+ if (ctx->encrypted_dirs) {
+ ext2fs_u32_list_free(ctx->encrypted_dirs);
+ ctx->encrypted_dirs = 0;
+ }
/* Clear statistic counters */
ctx->fs_directory_count = 0;
int ext_attr_ver;
profile_t profile;
int blocks_per_page;
+ ext2_u32_list encrypted_dirs;
/* Reserve blocks for root and l+f re-creation */
blk64_t root_repair_block, lnf_repair_block;
static void alloc_bb_map(e2fsck_t ctx);
static void alloc_imagic_map(e2fsck_t ctx);
static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
+static void add_encrypted_dir(e2fsck_t ctx, ino_t ino);
static void handle_fs_bad_blocks(e2fsck_t ctx);
static void process_inodes(e2fsck_t ctx, char *block_buf);
static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
e2fsck_add_dir_info(ctx, ino, 0);
ctx->fs_directory_count++;
+ if (inode->i_flags & EXT4_ENCRYPT_FL)
+ add_encrypted_dir(ctx, ino);
} else if (LINUX_S_ISREG (inode->i_mode)) {
ext2fs_mark_inode_bitmap2(ctx->inode_reg_map, ino);
ctx->fs_regular_count++;
ext2fs_mark_inode_bitmap2(ctx->inode_bad_map, ino);
}
+static void add_encrypted_dir(e2fsck_t ctx, ino_t ino)
+{
+ struct problem_context pctx;
+
+ if (!ctx->encrypted_dirs) {
+ pctx.errcode = ext2fs_u32_list_create(&ctx->encrypted_dirs, 0);
+ if (pctx.errcode)
+ goto error;
+ }
+ pctx.errcode = ext2fs_u32_list_add(ctx->encrypted_dirs, ino);
+ if (pctx.errcode == 0)
+ return;
+error:
+ fix_problem(ctx, PR_1_ALLOCATE_ENCRYPTED_DIRLIST, &pctx);
+ /* Should never get here */
+ ctx->flags |= E2F_FLAG_ABORT;
+}
/*
* This procedure will allocate the inode "bb" (badblock) map table
ext2fs_free_inode_bitmap(ctx->inode_reg_map);
ctx->inode_reg_map = 0;
}
+ if (ctx->encrypted_dirs) {
+ ext2fs_u32_list_free(ctx->encrypted_dirs);
+ ctx->encrypted_dirs = 0;
+ }
clear_problem_context(&pctx);
if (ctx->large_files) {
*/
static int check_name(e2fsck_t ctx,
struct ext2_dir_entry *dirent,
- ext2_ino_t dir_ino EXT2FS_ATTR((unused)),
+ ext2_ino_t dir_ino,
+ int *encrypted,
struct problem_context *pctx)
{
int i;
int fixup = -1;
int ret = 0;
+ if (*encrypted > 0)
+ return 0;
for ( i = 0; i < ext2fs_dirent_name_len(dirent); i++) {
- if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
- if (fixup < 0) {
- fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
- }
- if (fixup) {
- dirent->name[i] = '.';
- ret = 1;
- }
- }
+ if (dirent->name[i] != '/' && dirent->name[i] != '\0')
+ continue;
+ if (*encrypted < 0 && ctx->encrypted_dirs)
+ *encrypted = ext2fs_u32_list_test(ctx->encrypted_dirs,
+ dir_ino);
+ if (*encrypted > 0)
+ return 0;
+ if (fixup < 0)
+ fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
+ if (fixup == 0)
+ return 0;
+ dirent->name[i] = '.';
+ ret = 1;
}
return ret;
}
int is_leaf = 1;
size_t inline_data_size = 0;
int filetype = 0;
+ int encrypted = -1;
size_t max_block_size;
cd = (struct check_dir_struct *) priv_data;
}
}
- if (check_name(ctx, dirent, ino, &cd->pctx))
+ if (check_name(ctx, dirent, ino, &encrypted, &cd->pctx))
dir_modified++;
if (check_filetype(ctx, dirent, ino, &cd->pctx))
N_("@i %i has a duplicate @x mapping\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
PROMPT_CLEAR, 0 },
+ /* Error allocating memory for encrypted directory list */
+ { PR_1_ALLOCATE_ENCRYPTED_DIRLIST,
+ N_("@A memory for encrypted @d list\n"),
+ PROMPT_NONE, PR_FATAL },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
/* leaf extent collision */
#define PR_1_EXTENT_COLLISION 0x01007D
+/* Error allocating memory for encrypted directory list */
+#define PR_1_ALLOCATE_ENCRYPTED_DIRLIST 0x01007E
+
/*
* Pass 1b errors
*/