Whamcloud - gitweb
e2fsck: suppress bad name checks for encrypted directories
authorTheodore Ts'o <tytso@mit.edu>
Mon, 23 Feb 2015 22:44:23 +0000 (17:44 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 23 Feb 2015 22:44:23 +0000 (17:44 -0500)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/e2fsck.c
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/problem.c
e2fsck/problem.h

index fcda7d7..cf43a8c 100644 (file)
@@ -144,6 +144,10 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)
                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;
index 615ad75..b895f1e 100644 (file)
@@ -368,6 +368,7 @@ struct e2fsck_struct {
        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;
index 2b4aae7..78a4c71 100644 (file)
@@ -68,6 +68,7 @@ static void mark_table_blocks(e2fsck_t ctx);
 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);
@@ -1609,6 +1610,8 @@ void e2fsck_pass1(e2fsck_t ctx)
                        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++;
@@ -1898,6 +1901,23 @@ static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
        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
index 6f9e717..33e4854 100644 (file)
@@ -263,6 +263,10 @@ void e2fsck_pass2(e2fsck_t ctx)
                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) {
@@ -459,23 +463,30 @@ static int check_dotdot(e2fsck_t ctx,
  */
 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;
 }
@@ -872,6 +883,7 @@ static int check_dir_block(ext2_filsys fs,
        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;
@@ -1345,7 +1357,7 @@ skip_checksum:
                        }
                }
 
-               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))
index a63e61c..960fb07 100644 (file)
@@ -1101,6 +1101,11 @@ static struct e2fsck_problem problem_table[] = {
          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 */
index 3c28166..19b2301 100644 (file)
@@ -641,6 +641,9 @@ struct problem_context {
 /* 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
  */