Whamcloud - gitweb
e2fsck: check for an encrypted lost+found directory
authorTheodore Ts'o <tytso@mit.edu>
Thu, 16 Jul 2015 18:21:22 +0000 (14:21 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 16 Jul 2015 19:07:59 +0000 (15:07 -0400)
The /lost+found directory must not be encrypted, since e2fsck won't
have any keys.  If we find an encrypted lost+found directory, we
should delete the directory and recreate it.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass3.c
e2fsck/problem.c
e2fsck/problem.h
tests/f_encrypted_lpf/expect.1 [new file with mode: 0644]
tests/f_encrypted_lpf/expect.2 [new file with mode: 0644]
tests/f_encrypted_lpf/image.gz [new file with mode: 0644]
tests/f_encrypted_lpf/name [new file with mode: 0644]

index 1d5255f..d7b8802 100644 (file)
@@ -100,7 +100,8 @@ void e2fsck_pass3(e2fsck_t ctx)
 
        iter = e2fsck_dir_info_iter_begin(ctx);
        while ((dir = e2fsck_dir_info_iter(ctx, iter)) != 0) {
-               if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
+               if (ctx->flags & E2F_FLAG_SIGNAL_MASK ||
+                   ctx->flags & E2F_FLAG_RESTART)
                        goto abort_exit;
                if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
                        goto abort_exit;
@@ -415,6 +416,12 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
                        goto unlink;
                }
 
+               if (fix && (inode.i_flags & EXT4_ENCRYPT_FL)) {
+                       if (!fix_problem(ctx, PR_3_LPF_ENCRYPTED, &pctx))
+                               return 0;
+                       goto unlink;
+               }
+
                if (ext2fs_check_directory(fs, ino) == 0) {
                        ctx->lost_and_found = ino;
                        return ino;
@@ -437,6 +444,15 @@ unlink:
                }
                (void) e2fsck_dir_info_set_parent(ctx, ino, 0);
                e2fsck_adjust_inode_count(ctx, ino, -1);
+               /*
+                * If the old lost+found was a directory, we've just
+                * disconnected it from the directory tree, which
+                * means we need to restart the directory tree scan.
+                * The simplest way to do this is restart the whole
+                * e2fsck operation.
+                */
+               if (LINUX_S_ISDIR(inode.i_mode))
+                       ctx->flags |= E2F_FLAG_RESTART;
        } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
                pctx.errcode = retval;
                fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
index 23d2183..084131a 100644 (file)
@@ -1750,6 +1750,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("Insufficient space to recover lost files!\nMove data off the @f and re-run e2fsck.\n\n"),
          PROMPT_NONE, 0 },
 
+       /* Lost+found is encrypted */
+       { PR_3_LPF_ENCRYPTED,
+         N_("/@l is encrypted\n"),
+         PROMPT_CLEAR, 0 },
+
        /* Pass 3A Directory Optimization       */
 
        /* Pass 3A: Optimizing directories */
index e0b5d14..5af3edf 100644 (file)
@@ -1048,6 +1048,9 @@ struct problem_context {
 /* Insufficient space to recover lost files */
 #define PR_3_NO_SPACE_TO_RECOVER       0x03001A
 
+/* Lost+found is encrypted */
+#define PR_3_LPF_ENCRYPTED             0x03001B
+
 /*
  * Pass 3a --- rehashing diretories
  */
diff --git a/tests/f_encrypted_lpf/expect.1 b/tests/f_encrypted_lpf/expect.1
new file mode 100644 (file)
index 0000000..7e215b7
--- /dev/null
@@ -0,0 +1,27 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Unconnected directory inode 12 (/???)
+Connect to /lost+found? yes
+
+/lost+found is encrypted
+Clear? yes
+
+/lost+found not found.  Create? yes
+
+Restarting e2fsck from the beginning...
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Unconnected directory inode 11 (/???)
+Connect to /lost+found? yes
+
+Pass 3A: Optimizing directories
+Pass 4: Checking reference counts
+Inode 12 ref count is 3, should be 2.  Fix? yes
+
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 13/64 files (0.0% non-contiguous), 13/100 blocks
+Exit status is 1
diff --git a/tests/f_encrypted_lpf/expect.2 b/tests/f_encrypted_lpf/expect.2
new file mode 100644 (file)
index 0000000..6a59947
--- /dev/null
@@ -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: 13/64 files (0.0% non-contiguous), 13/100 blocks
+Exit status is 0
diff --git a/tests/f_encrypted_lpf/image.gz b/tests/f_encrypted_lpf/image.gz
new file mode 100644 (file)
index 0000000..7c89e07
Binary files /dev/null and b/tests/f_encrypted_lpf/image.gz differ
diff --git a/tests/f_encrypted_lpf/name b/tests/f_encrypted_lpf/name
new file mode 100644 (file)
index 0000000..b74259c
--- /dev/null
@@ -0,0 +1 @@
+encrypted lost+found directory