Whamcloud - gitweb
Merge branch 'maint' into next
authorTheodore Ts'o <tytso@mit.edu>
Thu, 1 Oct 2020 21:13:27 +0000 (17:13 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 1 Oct 2020 21:13:27 +0000 (17:13 -0400)
32 files changed:
configure.ac
debugfs/debugfs.c
debugfs/debugfs.h
debugfs/util.c
debugfs/zap.c
e2fsck/e2fsck.h
e2fsck/pass1.c
e2fsck/rehash.c
e2fsck/unix.c
e2fsck/util.c
lib/e2p/pf.c
lib/ext2fs/csum.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/fallocate.c
lib/ext2fs/imager.c
lib/ext2fs/openfs.c
lib/ext2fs/swapfs.c
misc/chattr.1.in
misc/chattr.c
misc/create_inode.c
misc/e2fuzz.c
misc/e4crypt.8.in
misc/e4crypt.c
misc/mke2fs.c
misc/tune2fs.c
tests/f_badjour_indblks/image [deleted file]
tests/r_inline_xattr/expect
tests/r_inline_xattr/script
tests/t_mmp_2off/script
tests/t_mmp_fail/is_slow_test [new file with mode: 0644]
tests/t_mmp_fail/name [new file with mode: 0644]
tests/t_mmp_fail/script [new file with mode: 0644]

index 18e434b..7d92107 100644 (file)
@@ -1142,6 +1142,9 @@ if test -n "$BLKID_CMT"; then
   AC_CHECK_LIB(blkid, blkid_probe_get_topology,
                      AC_DEFINE(HAVE_BLKID_PROBE_GET_TOPOLOGY, 1,
                                [Define to 1 if blkid has blkid_probe_get_topology]))
+  AC_CHECK_LIB(blkid, blkid_topology_get_dax,
+                     AC_DEFINE(HAVE_BLKID_TOPOLOGY_GET_DAX, 1,
+                               [Define to 1 if blkid has blkid_topology_get_dax]))
   AC_CHECK_LIB(blkid, blkid_probe_enable_partitions,
                      AC_DEFINE(HAVE_BLKID_PROBE_ENABLE_PARTITIONS, 1,
                                [Define to 1 if blkid has blkid_probe_enable_partitions]))
index 2022f3d..78e5577 100644 (file)
@@ -276,7 +276,11 @@ void do_open_filesys(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
                                return;
                        break;
                case 'z':
+#ifdef READ_ONLY
+                       goto print_usage;
+#else
                        undo_file = optarg;
+#endif
                        break;
                default:
                        goto print_usage;
@@ -294,9 +298,10 @@ void do_open_filesys(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
 
 print_usage:
        fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
+#ifdef READ_ONLY
                "[-d image_filename] [-z undo_file] [-c] [-i] [-f] [-e] [-D] "
-#ifndef READ_ONLY
-               "[-w] "
+#else
+               "[-d image_filename] [-c] [-i] [-f] [-e] [-D] [-w] "
 #endif
                "<device>\n", argv[0]);
 }
@@ -2379,7 +2384,6 @@ void do_fallocate(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
                return;
        }
 }
-#endif /* READ_ONLY */
 
 void do_symlink(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
                void *infop EXT2FS_ATTR((unused)))
@@ -2395,6 +2399,7 @@ void do_symlink(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
                com_err(argv[0], retval, 0);
 
 }
+#endif /* READ_ONLY */
 
 #if CONFIG_MMP
 void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[],
@@ -2539,8 +2544,8 @@ int main(int argc, char **argv)
        const char      *opt_string = "nicR:f:b:s:Vd:D";
 #else
        const char      *opt_string = "niwcR:f:b:s:Vd:Dz:";
-       char            *undo_file = NULL;
 #endif
+       char            *undo_file = NULL;
 #ifdef CONFIG_JBD_DEBUG
        char            *jbd_debug;
 #endif
@@ -2612,9 +2617,11 @@ int main(int argc, char **argv)
                        fprintf(stderr, "\tUsing %s\n",
                                error_message(EXT2_ET_BASE));
                        exit(0);
+#ifndef READ_ONLY
                case 'z':
                        undo_file = optarg;
                        break;
+#endif
                default:
                        com_err(argv[0], 0, usage, debug_prog_name);
                        return 1;
index 956517b..39bc024 100644 (file)
@@ -193,7 +193,8 @@ extern void do_get_quota(int argc, char *argv[], int sci_idx, void *infop);
 
 /* util.c */
 extern __s64 string_to_time(const char *arg);
-errcode_t read_list(char *str, blk64_t **list, size_t *len);
+extern errcode_t read_list(char *str, blk64_t **list, size_t *len);
+extern void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize);
 
 /* xattrs.c */
 void dump_inode_attributes(FILE *out, ext2_ino_t ino);
@@ -207,4 +208,3 @@ void block_xattr_dump(FILE *f, unsigned char *buf, unsigned int len);
 /* zap.c */
 extern void do_zap_block(int argc, char **argv, int sci_idx, void *infop);
 extern void do_block_dump(int argc, char **argv, int sci_idx, void *infop);
-extern void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize);
index 759bb39..da3a7ef 100644 (file)
@@ -562,3 +562,38 @@ err:
        free(lst);
        return retval;
 }
+
+void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize)
+{
+       size_t          i, j, max;
+       int             suppress = -1;
+
+       for (i = 0; i < bufsize; i += 16) {
+               max = (bufsize - i > 16) ? 16 : bufsize - i;
+               if (suppress < 0) {
+                       if (i && memcmp(buf + i, buf + i - max, max) == 0) {
+                               suppress = i;
+                               fprintf(fp, "*\n");
+                               continue;
+                       }
+               } else {
+                       if (memcmp(buf + i, buf + suppress, max) == 0)
+                               continue;
+                       suppress = -1;
+               }
+               fprintf(fp, "%04o  ", (unsigned int)i);
+               for (j = 0; j < 16; j++) {
+                       if (j < max)
+                               fprintf(fp, "%02x", buf[i+j]);
+                       else
+                               fprintf(fp, "  ");
+                       if ((j % 2) == 1)
+                               fprintf(fp, " ");
+               }
+               fprintf(fp, " ");
+               for (j = 0; j < max; j++)
+                       fprintf(fp, "%c", isprint(buf[i+j]) ? buf[i+j] : '.');
+               fprintf(fp, "\n");
+       }
+       fprintf(fp, "\n");
+}
index c7996b2..f120377 100644 (file)
@@ -239,38 +239,3 @@ void do_block_dump(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
 errout:
        free(buf);
 }
-
-void do_byte_hexdump(FILE *fp, unsigned char *buf, size_t bufsize)
-{
-       size_t          i, j, max;
-       int             suppress = -1;
-
-       for (i = 0; i < bufsize; i += 16) {
-               max = (bufsize - i > 16) ? 16 : bufsize - i;
-               if (suppress < 0) {
-                       if (i && memcmp(buf + i, buf + i - max, max) == 0) {
-                               suppress = i;
-                               fprintf(fp, "*\n");
-                               continue;
-                       }
-               } else {
-                       if (memcmp(buf + i, buf + suppress, max) == 0)
-                               continue;
-                       suppress = -1;
-               }
-               fprintf(fp, "%04o  ", (unsigned int)i);
-               for (j = 0; j < 16; j++) {
-                       if (j < max)
-                               fprintf(fp, "%02x", buf[i+j]);
-                       else
-                               fprintf(fp, "  ");
-                       if ((j % 2) == 1)
-                               fprintf(fp, " ");
-               }
-               fprintf(fp, " ");
-               for (j = 0; j < max; j++)
-                       fprintf(fp, "%c", isprint(buf[i+j]) ? buf[i+j] : '.');
-               fprintf(fp, "\n");
-       }
-       fprintf(fp, "\n");
-}
index 9b2b9ce..85f953b 100644 (file)
@@ -627,7 +627,7 @@ extern void log_err(e2fsck_t ctx, const char *fmt, ...)
 extern void e2fsck_read_bitmaps(e2fsck_t ctx);
 extern void e2fsck_write_bitmaps(e2fsck_t ctx);
 extern void preenhalt(e2fsck_t ctx);
-extern char *string_copy(e2fsck_t ctx, const char *str, int len);
+extern char *string_copy(e2fsck_t ctx, const char *str, size_t len);
 extern int fs_proc_check(const char *fs_name);
 extern int check_for_modules(const char *fs_name);
 #ifdef RESOURCE_TRACK
index 4de9ca6..8eecd95 100644 (file)
@@ -2654,7 +2654,7 @@ static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
                return 1;
 
        pctx->num = root->indirect_levels;
-       if ((root->indirect_levels > ext2_dir_htree_level(fs)) &&
+       if ((root->indirect_levels >= ext2_dir_htree_level(fs)) &&
            fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
                return 1;
 
index 1616d07..30e510a 100644 (file)
@@ -109,7 +109,7 @@ static int fill_dir_block(ext2_filsys fs,
                          void *priv_data)
 {
        struct fill_dir_struct  *fd = (struct fill_dir_struct *) priv_data;
-       struct hash_entry       *new_array, *ent;
+       struct hash_entry       *ent;
        struct ext2_dir_entry   *dirent;
        char                    *dir;
        unsigned int            offset, dir_offset, rec_len, name_len;
@@ -460,7 +460,7 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
        struct hash_entry       *ent;
        struct ext2_dir_entry   *dirent;
        unsigned int            rec_len, prev_rec_len, left, slack, offset;
-       int                     i;
+       blk_t                   i;
        ext2_dirhash_t          prev_hash;
        int                     csum_size = 0;
        struct                  ext2_dir_entry_tail *t;
index b144c38..1cb5167 100644 (file)
@@ -1444,7 +1444,7 @@ int main (int argc, char *argv[])
                fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
                      ctx->problem_logf);
                fprintf(ctx->problem_logf, "<problem_log time=\"%lu\">\n",
-                       ctx->now);
+                       (unsigned long) ctx->now);
                fprintf(ctx->problem_logf, "<invocation prog=\"%s\"",
                        argv[0]);
                for (i = 1; i < argc; i++)
index d98b8e4..e0623e4 100644 (file)
@@ -123,10 +123,10 @@ void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size,
        char buf[256];
 
 #ifdef DEBUG_ALLOCATE_MEMORY
-       printf("Allocating %u bytes for %s...\n", size, description);
+       printf("Allocating %lu bytes for %s...\n", size, description);
 #endif
        if (ext2fs_get_memzero(size, &ret)) {
-               sprintf(buf, "Can't allocate %u bytes for %s\n",
+               sprintf(buf, "Can't allocate %lu bytes for %s\n",
                        size, description);
                fatal_error(ctx, buf);
        }
@@ -135,7 +135,7 @@ void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size,
 }
 
 char *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)),
-                 const char *str, int len)
+                 const char *str, size_t len)
 {
        char    *ret;
 
@@ -436,7 +436,7 @@ void print_resource_track(e2fsck_t ctx, const char *desc,
 #define kbytes(x)      (((unsigned long long)(x) + 1023) / 1024)
 #ifdef HAVE_MALLINFO
        /* don't use mallinfo() if over 2GB used, since it returns "int" */
-       if ((char *)sbrk(0) - (char *)track->brk_start < 2ULL << 30) {
+       if ((char *)sbrk(0) - (char *)track->brk_start < 2LL << 30) {
                struct mallinfo malloc_info = mallinfo();
 
                log_out(ctx, _("Memory used: %lluk/%lluk (%lluk/%lluk), "),
index 0c6998c..61fd4ab 100644 (file)
@@ -44,6 +44,7 @@ static struct flags_name flags_array[] = {
        { EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
        { EXT4_EXTENTS_FL, "e", "Extents" },
        { FS_NOCOW_FL, "C", "No_COW" },
+       { FS_DAX_FL, "x", "DAX" },
        { EXT4_CASEFOLD_FL, "F", "Casefold" },
        { EXT4_INLINE_DATA_FL, "N", "Inline_Data" },
        { EXT4_PROJINHERIT_FL, "P", "Project_Hierarchy" },
index 8513d1a..86184b6 100644 (file)
@@ -266,15 +266,14 @@ static errcode_t __get_dirent_tail(ext2_filsys fs,
        d = dirent;
        top = EXT2_DIRENT_TAIL(dirent, fs->blocksize);
 
-       rec_len = translate(d->rec_len);
        while ((void *) d < top) {
+               rec_len = translate(d->rec_len);
                if ((rec_len < 8) || (rec_len & 0x03))
                        return EXT2_ET_DIR_CORRUPTED;
                d = (struct ext2_dir_entry *)(((char *)d) + rec_len);
-               rec_len = translate(d->rec_len);
        }
 
-       if ((void *)d > ((void *)dirent + fs->blocksize))
+       if ((char *)d > ((char *)dirent + fs->blocksize))
                        return EXT2_ET_DIR_CORRUPTED;
        if (d != top)
                return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
index 0376674..bfc30c2 100644 (file)
@@ -335,6 +335,7 @@ struct ext2_dx_tail {
 /* EXT4_EOFBLOCKS_FL 0x00400000 was here */
 #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
 #define EXT4_SNAPFILE_FL               0x01000000  /* Inode is a snapshot */
+#define FS_DAX_FL                      0x02000000 /* Inode is DAX */
 #define EXT4_SNAPFILE_DELETED_FL       0x04000000  /* Snapshot is being deleted */
 #define EXT4_SNAPFILE_SHRUNK_FL                0x08000000  /* Snapshot shrink has completed */
 #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data */
index 31e47f8..5cde7d5 100644 (file)
@@ -805,7 +805,8 @@ errcode_t ext2fs_fallocate(ext2_filsys fs, int flags, ext2_ino_t ino,
                           blk64_t start, blk64_t len)
 {
        struct ext2_inode       inode_buf;
-       blk64_t                 blk, x;
+       blk64_t                 blk, x, zero_blk, last = 0;
+       int                     zero_len = 0;
        errcode_t               err;
 
        if (((flags & EXT2_FALLOCATE_FORCE_INIT) &&
@@ -841,15 +842,32 @@ errcode_t ext2fs_fallocate(ext2_filsys fs, int flags, ext2_ino_t ino,
                if (x)
                        continue;
 
-               err = ext2fs_bmap2(fs, ino, inode, NULL,
-                                  BMAP_ALLOC | BMAP_UNINIT | BMAP_ZERO, blk,
-                                  0, &x);
+               err = ext2fs_bmap2(fs, ino, inode, NULL, BMAP_ALLOC,
+                                  blk, 0, &x);
                if (err)
-                       return err;
+                       goto errout;
+               if ((zero_len && (x != last+1)) ||
+                   (zero_len >= 65536)) {
+                       err = ext2fs_zero_blocks2(fs, zero_blk, zero_len,
+                                                 NULL, NULL);
+                       zero_len = 0;
+                       if (err)
+                               goto errout;
+               }
+               if (zero_len == 0) {
+                       zero_blk = x;
+                       zero_len = 1;
+               } else {
+                       zero_len++;
+               }
+               last = x;
        }
 
 out:
        if (inode == &inode_buf)
                ext2fs_write_inode(fs, ino, inode);
+errout:
+       if (zero_len)
+               ext2fs_zero_blocks2(fs, zero_blk, zero_len, NULL, NULL);
        return err;
 }
index f8d67d8..586227f 100644 (file)
@@ -67,7 +67,7 @@ errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags)
        blk64_t         blk;
        ssize_t         actual;
        errcode_t       retval;
-       loff_t          r;
+       ext2_loff_t     r;
 
        buf = malloc(fs->blocksize * BUF_BLOCKS);
        if (!buf)
index 3331452..3ed1e25 100644 (file)
@@ -134,6 +134,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
        int             j;
 #endif
        char            *time_env;
+       int             csum_retries = 0;
 
        EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
 
@@ -221,6 +222,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                if (retval)
                        goto cleanup;
        }
+retry:
        retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
                                     fs->super);
        if (retval)
@@ -232,8 +234,11 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
                retval = 0;
                if (!ext2fs_verify_csum_type(fs, fs->super))
                        retval = EXT2_ET_UNKNOWN_CSUM;
-               if (!ext2fs_superblock_csum_verify(fs, fs->super))
+               if (!ext2fs_superblock_csum_verify(fs, fs->super)) {
+                       if (csum_retries++ < 3)
+                               goto retry;
                        retval = EXT2_ET_SB_CSUM_INVALID;
+               }
        }
 
 #ifdef WORDS_BIGENDIAN
index 5b93b50..bc9f323 100644 (file)
@@ -456,12 +456,11 @@ errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf,
 {
        errcode_t       retval;
        char            *p, *end;
-       unsigned int    rec_len, left;
+       unsigned int    rec_len;
        struct ext2_dir_entry *dirent;
 
        p = buf;
        end = buf + size;
-       left = size;
        while (p < end) {
                dirent = (struct ext2_dir_entry *) p;
                retval = ext2fs_get_rec_len(fs, dirent, &rec_len);
index ff2fcf0..5a4928a 100644 (file)
@@ -23,13 +23,13 @@ chattr \- change file attributes on a Linux file system
 .B chattr
 changes the file attributes on a Linux file system.
 .PP
-The format of a symbolic mode is +-=[aAcCdDeFijPsStTu].
+The format of a symbolic mode is +-=[aAcCdDeFijPsStTux].
 .PP
 The operator '+' causes the selected attributes to be added to the
 existing attributes of the files; '-' causes them to be removed; and '='
 causes them to be the only attributes that the files have.
 .PP
-The letters 'aAcCdDeFijPsStTu' select the new attributes for the files:
+The letters 'aAcCdDeFijPsStTux' select the new attributes for the files:
 append only (a),
 no atime updates (A),
 compressed (c),
@@ -45,7 +45,8 @@ secure deletion (s),
 synchronous updates (S),
 no tail-merging (t),
 top of directory hierarchy (T),
-and undeletable (u).
+undeletable (u),
+and direct access for files (x).
 .PP
 The following attributes are read-only, and may be listed by
 .BR lsattr (1)
@@ -210,6 +211,14 @@ saved.  This allows the user to ask for its undeletion.  Note: please
 make sure to read the bugs and limitations section at the end of this
 document.
 .TP
+.B x
+The 'x' attribute can be set on a directory or file.  If the attribute
+is set on an existing directory, it will be inherited by all files and
+subdirectories that are subsequently created in the directory.  If an
+existing directory has contained some files and subdirectories, modifying
+the attribute on the parent directory doesn't change the attributes on
+these files and subdirectories.
+.TP
 .B V
 A file with the 'V' attribute set has fs-verity enabled.  It cannot be
 written to, and the filesystem will automatically verify all data read
index a5d6017..c0337f8 100644 (file)
@@ -86,7 +86,7 @@ static unsigned long sf;
 static void usage(void)
 {
        fprintf(stderr,
-               _("Usage: %s [-pRVf] [-+=aAcCdDeijPsStTuF] [-v version] files...\n"),
+               _("Usage: %s [-pRVf] [-+=aAcCdDeijPsStTuFx] [-v version] files...\n"),
                program_name);
        exit(1);
 }
@@ -112,6 +112,7 @@ static const struct flags_char flags_array[] = {
        { EXT2_NOTAIL_FL, 't' },
        { EXT2_TOPDIR_FL, 'T' },
        { FS_NOCOW_FL, 'C' },
+       { FS_DAX_FL, 'x' },
        { EXT4_CASEFOLD_FL, 'F' },
        { 0, 0 }
 };
index e8d1df6..837f387 100644 (file)
@@ -601,7 +601,7 @@ out:
        return err;
 }
 
-static int is_hardlink(struct hdlinks_s *hdlinks, dev_t dev, ext2_ino_t ino)
+static int is_hardlink(struct hdlinks_s *hdlinks, dev_t dev, ino_t ino)
 {
        int i;
 
index 7c0f776..685cdbe 100644 (file)
@@ -33,9 +33,10 @@ static unsigned long long user_corrupt_bytes = 0;
 static double user_corrupt_pct = 0.0;
 
 #if !defined HAVE_PWRITE64 && !defined HAVE_PWRITE
-static ssize_t my_pwrite(int fd, const void *buf, size_t count, off_t offset)
+static ssize_t my_pwrite(int fd, const void *buf, size_t count,
+                        ext2_loff_t offset)
 {
-       if (lseek(fd, offset, SEEK_SET) < 0)
+       if (ext2fs_llseek(fd, offset, SEEK_SET) < 0)
                return 0;
 
        return write(fd, buf, count);
@@ -82,7 +83,7 @@ static int find_block_helper(ext2_filsys fs EXT2FS_ATTR((unused)),
 }
 
 static errcode_t find_metadata_blocks(ext2_filsys fs, ext2fs_block_bitmap bmap,
-                                     off_t *corrupt_bytes)
+                                     ext2_loff_t *corrupt_bytes)
 {
        dgrp_t i;
        blk64_t b, c;
@@ -181,9 +182,8 @@ static int process_fs(const char *fsname)
        int flags, fd;
        ext2_filsys fs = NULL;
        ext2fs_block_bitmap corrupt_map;
-       loff_t hsize, count, off, offset, corrupt_bytes;
+       ext2_loff_t hsize, count, off, offset, corrupt_bytes, i;
        unsigned char c;
-       loff_t i;
 
        /* If mounted rw, force dryrun mode */
        ret = ext2fs_check_if_mounted(fsname, &flags);
index 75b968a..fe9372c 100644 (file)
@@ -48,7 +48,9 @@ values are 4, 8, 16, and 32.
 If one or more directory paths are specified, e4crypt will try to
 set the policy of those directories to use the key just added by the
 .B add_key
-command.
+command.  If a salt was explicitly specified, then it will be used
+to derive the encryption key of those directories.  Otherwise a
+directory-specific default salt will be used.
 .TP
 .B e4crypt get_policy \fIpath\fR ...
 Print the policy for the directories specified on the command line.
index 2ae6254..67d25d8 100644 (file)
@@ -26,6 +26,7 @@
 #include <getopt.h>
 #include <dirent.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -652,6 +653,7 @@ static void do_help(int argc, char **argv, const struct cmd_desc *cmd);
 static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd)
 {
        struct salt *salt;
+       bool explicit_salt = false;
        char *keyring = NULL;
        int i, opt, pad = 4;
        unsigned j;
@@ -666,8 +668,13 @@ static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd)
                        pad = atoi(optarg);
                        break;
                case 'S':
+                       if (explicit_salt) {
+                               fputs("May only provide -S once\n", stderr);
+                               exit(1);
+                       }
                        /* Salt value for passphrase. */
                        parse_salt(optarg, 0);
+                       explicit_salt = true;
                        break;
                case 'v':
                        options |= OPT_VERBOSE;
@@ -692,8 +699,9 @@ static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd)
                exit(1);
        }
        validate_paths(argc, argv, optind);
-       for (i = optind; i < argc; i++)
-               parse_salt(argv[i], PARSE_FLAGS_FORCE_FN);
+       if (!explicit_salt)
+               for (i = optind; i < argc; i++)
+                       parse_salt(argv[i], PARSE_FLAGS_FORCE_FN);
        printf("Enter passphrase (echo disabled): ");
        get_passphrase(in_passphrase, sizeof(in_passphrase));
        for (j = 0, salt = salt_list; j < num_salt; j++, salt++) {
@@ -702,8 +710,10 @@ static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd)
                generate_key_ref_str(salt);
                insert_key_into_keyring(keyring, salt);
        }
-       if (optind != argc)
-               set_policy(NULL, pad, argc, argv, optind);
+       if (optind != argc) {
+               salt = explicit_salt ? salt_list : NULL;
+               set_policy(salt, pad, argc, argv, optind);
+       }
        clear_secrets();
        exit(0);
 }
index c90dcf0..8c8f5ea 100644 (file)
@@ -1468,23 +1468,30 @@ int get_bool_from_profile(char **types, const char *opt, int def_val)
 extern const char *mke2fs_default_profile;
 static const char *default_files[] = { "<default>", 0 };
 
+struct device_param {
+       unsigned long min_io;           /* prefered minimum IO size */
+       unsigned long opt_io;           /* optimal IO size */
+       unsigned long alignment_offset; /* alignment offset wrt physical block size */
+       unsigned int dax:1;             /* supports dax? */
+};
+
 #ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
 /*
  * Sets the geometry of a device (stripe/stride), and returns the
  * device's alignment offset, if any, or a negative error.
  */
 static int get_device_geometry(const char *file,
-                              struct ext2_super_block *param,
-                              unsigned int psector_size)
+                              unsigned int blocksize,
+                              unsigned int psector_size,
+                              struct device_param *dev_param)
 {
        int rc = -1;
-       unsigned int blocksize;
        blkid_probe pr;
        blkid_topology tp;
-       unsigned long min_io;
-       unsigned long opt_io;
        struct stat statbuf;
 
+       memset(dev_param, 0, sizeof(*dev_param));
+
        /* Nothing to do for a regular file */
        if (!stat(file, &statbuf) && S_ISREG(statbuf.st_mode))
                return 0;
@@ -1497,23 +1504,20 @@ static int get_device_geometry(const char *file,
        if (!tp)
                goto out;
 
-       min_io = blkid_topology_get_minimum_io_size(tp);
-       opt_io = blkid_topology_get_optimal_io_size(tp);
-       blocksize = EXT2_BLOCK_SIZE(param);
-       if ((min_io == 0) && (psector_size > blocksize))
-               min_io = psector_size;
-       if ((opt_io == 0) && min_io)
-               opt_io = min_io;
-       if ((opt_io == 0) && (psector_size > blocksize))
-               opt_io = psector_size;
-
-       /* setting stripe/stride to blocksize is pointless */
-       if (min_io > blocksize)
-               param->s_raid_stride = min_io / blocksize;
-       if (opt_io > blocksize)
-               param->s_raid_stripe_width = opt_io / blocksize;
-
-       rc = blkid_topology_get_alignment_offset(tp);
+       dev_param->min_io = blkid_topology_get_minimum_io_size(tp);
+       dev_param->opt_io = blkid_topology_get_optimal_io_size(tp);
+       if ((dev_param->min_io == 0) && (psector_size > blocksize))
+               dev_param->min_io = psector_size;
+       if ((dev_param->opt_io == 0) && dev_param->min_io > 0)
+               dev_param->opt_io = dev_param->min_io;
+       if ((dev_param->opt_io == 0) && (psector_size > blocksize))
+               dev_param->opt_io = psector_size;
+
+       dev_param->alignment_offset = blkid_topology_get_alignment_offset(tp);
+#ifdef HAVE_BLKID_TOPOLOGY_GET_DAX
+       dev_param->dax = blkid_topology_get_dax(tp);
+#endif
+       rc = 0;
 out:
        blkid_free_probe(pr);
        return rc;
@@ -1562,6 +1566,7 @@ static void PRS(int argc, char *argv[])
        int             use_bsize;
        char            *newpath;
        int             pathlen = sizeof(PATH_SET) + 1;
+       struct device_param dev_param;
 
        if (oldpath)
                pathlen += strlen(oldpath);
@@ -2307,17 +2312,35 @@ profile_error:
        }
 
 #ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
-       retval = get_device_geometry(device_name, &fs_param,
-                                    (unsigned int) psector_size);
+       retval = get_device_geometry(device_name, blocksize,
+                                    psector_size, &dev_param);
        if (retval < 0) {
                fprintf(stderr,
                        _("warning: Unable to get device geometry for %s\n"),
                        device_name);
-       } else if (retval) {
-               printf(_("%s alignment is offset by %lu bytes.\n"),
-                      device_name, retval);
-               printf(_("This may result in very poor performance, "
-                         "(re)-partitioning suggested.\n"));
+       } else {
+               /* setting stripe/stride to blocksize is pointless */
+               if (dev_param.min_io > blocksize)
+                       fs_param.s_raid_stride = dev_param.min_io / blocksize;
+               if (dev_param.opt_io > blocksize) {
+                       fs_param.s_raid_stripe_width =
+                                               dev_param.opt_io / blocksize;
+               }
+
+               if (dev_param.alignment_offset) {
+                       printf(_("%s alignment is offset by %lu bytes.\n"),
+                              device_name, dev_param.alignment_offset);
+                       printf(_("This may result in very poor performance, "
+                                 "(re)-partitioning suggested.\n"));
+               }
+
+               if (dev_param.dax && blocksize != sys_page_size) {
+                       fprintf(stderr,
+                               _("%s is capable of DAX but current block size "
+                                 "%u is different from system page size %u so "
+                                 "filesystem will not support DAX.\n"),
+                               device_name, blocksize, sys_page_size);
+               }
        }
 #endif
 
index 81f90cb..f942c69 100644 (file)
@@ -426,7 +426,7 @@ static int update_mntopts(ext2_filsys fs, char *mntopts)
        return 0;
 }
 
-static void check_fsck_needed(ext2_filsys fs, const char *prompt)
+static int check_fsck_needed(ext2_filsys fs, const char *prompt)
 {
        /* Refuse to modify anything but a freshly checked valid filesystem. */
        if (!(fs->super->s_state & EXT2_VALID_FS) ||
@@ -436,15 +436,17 @@ static void check_fsck_needed(ext2_filsys fs, const char *prompt)
                puts(_(please_fsck));
                if (mount_flags & EXT2_MF_READONLY)
                        printf("%s", _("(and reboot afterwards!)\n"));
-               exit(1);
+               return 1;
        }
 
        /* Give the admin a few seconds to bail out of a dangerous op. */
        if (!getenv("TUNE2FS_FORCE_PROMPT") && (!isatty(0) || !isatty(1)))
-               return;
+               return 0;
 
        puts(prompt);
        proceed_question(5);
+
+       return 0;
 }
 
 static void request_dir_fsck_afterwards(ext2_filsys fs)
@@ -1274,12 +1276,13 @@ mmp_error:
 
        if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
                       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
-               check_fsck_needed(fs,
-                       _("Enabling checksums could take some time."));
+               if (check_fsck_needed(fs,
+                       _("Enabling checksums could take some time.")))
+                       return 1;
                if (mount_flags & EXT2_MF_MOUNTED) {
                        fputs(_("Cannot enable metadata_csum on a mounted "
                                "filesystem!\n"), stderr);
-                       exit(1);
+                       return 1;
                }
                if (!ext2fs_has_feature_extents(fs->super))
                        printf("%s",
@@ -1315,12 +1318,13 @@ mmp_error:
                        EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
                __u32   test_features[3];
 
-               check_fsck_needed(fs,
-                       _("Disabling checksums could take some time."));
+               if (check_fsck_needed(fs,
+                       _("Disabling checksums could take some time.")))
+                       return 1;
                if (mount_flags & EXT2_MF_MOUNTED) {
                        fputs(_("Cannot disable metadata_csum on a mounted "
                                "filesystem!\n"), stderr);
-                       exit(1);
+                       return 1;
                }
                rewrite_checksums = REWRITE_ALL;
 
@@ -1361,7 +1365,7 @@ mmp_error:
                if (mount_flags & EXT2_MF_MOUNTED) {
                        fputs(_("Cannot enable uninit_bg on a mounted "
                                "filesystem!\n"), stderr);
-                       exit(1);
+                       return 1;
                }
 
                /* Do not enable uninit_bg when metadata_csum enabled */
@@ -1376,7 +1380,7 @@ mmp_error:
                if (mount_flags & EXT2_MF_MOUNTED) {
                        fputs(_("Cannot disable uninit_bg on a mounted "
                                "filesystem!\n"), stderr);
-                       exit(1);
+                       return 1;
                }
 
                err = disable_uninit_bg(fs,
@@ -1395,7 +1399,7 @@ mmp_error:
                if (mount_flags & EXT2_MF_MOUNTED) {
                        fprintf(stderr, _("Cannot enable 64-bit mode "
                                          "while mounted!\n"));
-                       exit(1);
+                       return 1;
                }
                ext2fs_clear_feature_64bit(sb);
                feature_64bit = 1;
@@ -1405,7 +1409,7 @@ mmp_error:
                if (mount_flags & EXT2_MF_MOUNTED) {
                        fprintf(stderr, _("Cannot disable 64-bit mode "
                                          "while mounted!\n"));
-                       exit(1);
+                       return 1;
                }
                ext2fs_set_feature_64bit(sb);
                feature_64bit = -1;
@@ -1435,7 +1439,7 @@ mmp_error:
                if (fs->super->s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
                        fprintf(stderr, _("Cannot enable project feature; "
                                          "inode size too small.\n"));
-                       exit(1);
+                       return 1;
                }
                Q_flag = 1;
                quota_enable[PRJQUOTA] = QOPT_ENABLE;
@@ -1502,8 +1506,9 @@ mmp_error:
                                      stderr);
                                return 1;
                        }
-                       check_fsck_needed(fs, _("Recalculating checksums "
-                                               "could take some time."));
+                       if (check_fsck_needed(fs, _("Recalculating checksums "
+                                                   "could take some time.")))
+                               return 1;
                        rewrite_checksums = REWRITE_ALL;
                }
        }
@@ -1616,7 +1621,7 @@ err:
        return 1;
 }
 
-static void handle_quota_options(ext2_filsys fs)
+static int handle_quota_options(ext2_filsys fs)
 {
        errcode_t retval;
        quota_ctx_t qctx;
@@ -1630,13 +1635,13 @@ static void handle_quota_options(ext2_filsys fs)
                        break;
        if (qtype == MAXQUOTAS)
                /* Nothing to do. */
-               return;
+               return 0;
 
        if (quota_enable[PRJQUOTA] == QOPT_ENABLE &&
            fs->super->s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
                fprintf(stderr, _("Cannot enable project quota; "
                                  "inode size too small.\n"));
-               exit(1);
+               return 1;
        }
 
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
@@ -1648,7 +1653,7 @@ static void handle_quota_options(ext2_filsys fs)
        if (retval) {
                com_err(program_name, retval,
                        _("while initializing quota context in support library"));
-               exit(1);
+               return 1;
        }
 
        if (qtype_bits)
@@ -1664,7 +1669,7 @@ static void handle_quota_options(ext2_filsys fs)
                                        com_err(program_name, retval,
                                                _("while updating quota limits (%d)"),
                                                qtype);
-                                       exit(1);
+                                       return 1;
                                }
                        }
                        retval = quota_write_inode(qctx, 1 << qtype);
@@ -1672,7 +1677,7 @@ static void handle_quota_options(ext2_filsys fs)
                                com_err(program_name, retval,
                                        _("while writing quota file (%d)"),
                                        qtype);
-                               exit(1);
+                               return 1;
                        }
                        /* Enable Quota feature if one of quota enabled */
                        if (!ext2fs_has_feature_quota(fs->super)) {
@@ -1690,7 +1695,7 @@ static void handle_quota_options(ext2_filsys fs)
                                com_err(program_name, retval,
                                        _("while removing quota file (%d)"),
                                        qtype);
-                               exit(1);
+                               return 1;
                        }
                        if (qtype == PRJQUOTA) {
                                ext2fs_clear_feature_project(fs->super);
@@ -1713,7 +1718,7 @@ static void handle_quota_options(ext2_filsys fs)
        }
        if (need_dirty)
                ext2fs_mark_super_dirty(fs);
-       return;
+       return 0;
 }
 
 static int option_handle_function(char *token)
@@ -3008,8 +3013,10 @@ retry_open:
                        rc = 1;
                        goto closefs;
                }
-               check_fsck_needed(fs,
+               rc = check_fsck_needed(fs,
                        _("Resizing inodes could take some time."));
+               if (rc)
+                       goto closefs;
                /*
                 * If inode resize is requested use the
                 * Undo I/O manager
@@ -3065,16 +3072,16 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
        /* Recover the journal if possible. */
        if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
            ext2fs_has_feature_journal_needs_recovery(fs->super)) {
-               errcode_t err;
-
                printf(_("Recovering journal.\n"));
-               err = ext2fs_run_ext3_journal(&fs);
-               if (err) {
-                       com_err("tune2fs", err, "while recovering journal.\n");
+               retval = ext2fs_run_ext3_journal(&fs);
+               if (retval) {
+                       com_err("tune2fs", retval,
+                               "while recovering journal.\n");
                        printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
                        if (fs)
                                ext2fs_close_free(&fs);
-                       exit(1);
+                       rc = 1;
+                       goto closefs;
                }
                sb = fs->super;
        }
@@ -3178,13 +3185,13 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                        fputs(_("Warning: label too long, truncating.\n"),
                              stderr);
                memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
-               strncpy(sb->s_volume_name, new_label,
+               strncpy((char *)sb->s_volume_name, new_label,
                        sizeof(sb->s_volume_name));
                ext2fs_mark_super_dirty(fs);
        }
        if (M_flag) {
                memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
-               strncpy(sb->s_last_mounted, new_last_mounted,
+               strncpy((char *)sb->s_last_mounted, new_last_mounted,
                        sizeof(sb->s_last_mounted));
                ext2fs_mark_super_dirty(fs);
        }
@@ -3226,7 +3233,9 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                        rc = 1;
                        goto closefs;
                }
-               handle_quota_options(fs);
+               rc = handle_quota_options(fs);
+               if (rc)
+                       goto closefs;
        }
 
        if (U_flag) {
@@ -3245,9 +3254,11 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                if (!ext2fs_has_feature_csum_seed(fs->super) &&
                    (ext2fs_has_feature_metadata_csum(fs->super) ||
                     ext2fs_has_feature_ea_inode(fs->super))) {
-                       check_fsck_needed(fs,
+                       rc = check_fsck_needed(fs,
                                _("Setting the UUID on this "
                                  "filesystem could take some time."));
+                       if (rc)
+                               goto closefs;
                        rewrite_checksums = REWRITE_ALL;
                }
 
@@ -3269,7 +3280,8 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
                                        "metadata_csum_seed' and re-run this "
                                        "command.\n"), stderr);
                                try_confirm_csum_seed_support();
-                               exit(1);
+                               rc = 1;
+                               goto closefs;
                        }
 
                        /*
diff --git a/tests/f_badjour_indblks/image b/tests/f_badjour_indblks/image
deleted file mode 100644 (file)
index adbd1d7..0000000
Binary files a/tests/f_badjour_indblks/image and /dev/null differ
index 885de59..773db10 100644 (file)
@@ -1,5 +1,5 @@
 resize2fs test
-debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''
+debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \(''
 Inode: 1550   Type: regular    Mode:  0644   Flags: 0x0
   user.name (11) = "propervalue"
 Exit status is 0
@@ -8,7 +8,7 @@ Resizing the filesystem on test.img to 5120 (1k) blocks.
 The filesystem on test.img is now 5120 (1k) blocks long.
 
 Exit status is 0
-debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''
+debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \(''
 Inode: 12   Type: regular    Mode:  0644   Flags: 0x0
   user.name (11) = "propervalue"
 Exit status is 0
index 4e7dd94..2f754e6 100644 (file)
@@ -13,8 +13,8 @@ gunzip < $IMAGE > $TMPFILE
 echo "resize2fs test" > $OUT.new
 
 # Look at existing inline extended attribute
-echo "debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''" >> $OUT.new
-$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep "^Inode\|in inode body\|user.name (" >> $OUT.new
+echo "debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \\(''" >> $OUT.new
+$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep -E "^Inode|in inode body|user.name \(" >> $OUT.new
 status=$?
 echo Exit status is $status >> $OUT.new
 
@@ -25,8 +25,8 @@ status=$?
 echo Exit status is $status >> $OUT.new
 
 # Look at inline extended attribute in resized fs
-echo "debugfs -R ''stat file'' test.img 2>&1 | grep ''^Inode\|in inode body\|user.name (''" >> $OUT.new
-$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep "^Inode\|in inode body\|user.name (" >> $OUT.new
+echo "debugfs -R ''stat file'' test.img 2>&1 | grep -E ''^Inode\|in inode body\|user.name \\(''" >> $OUT.new
+$DEBUGFS -R "stat file" $TMPFILE 2>&1 | grep -E "^Inode|in inode body|user.name \(" >> $OUT.new
 status=$?
 echo Exit status is $status >> $OUT.new
 
index ccd859b..1cd0719 100644 (file)
@@ -8,7 +8,7 @@ if [ "$status" != 0 ] ; then
        return $status
 fi
 
-$TUNE2FS -O ^mmp $TMPFILE > $test_name.log 2>&1
+$TUNE2FS -O ^mmp $TMPFILE >> $test_name.log 2>&1
 status=$?
 if [ "$status" != 0 ] ; then
        echo "tune2fs -O ^mmp failed" > $test_name.failed
@@ -16,7 +16,7 @@ if [ "$status" != 0 ] ; then
        return $status
 fi
 
-$FSCK $FSCK_OPT $TMPFILE > $test_name.log 2>&1
+$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1
 status=$?
 if [ "$status" = 0 ] ; then
        echo "$test_name: $test_description: ok"
diff --git a/tests/t_mmp_fail/is_slow_test b/tests/t_mmp_fail/is_slow_test
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/t_mmp_fail/name b/tests/t_mmp_fail/name
new file mode 100644 (file)
index 0000000..e872dda
--- /dev/null
@@ -0,0 +1 @@
+error running tune2fs with MMP
diff --git a/tests/t_mmp_fail/script b/tests/t_mmp_fail/script
new file mode 100644 (file)
index 0000000..5fa6a84
--- /dev/null
@@ -0,0 +1,44 @@
+FSCK_OPT=-yf
+
+$MKE2FS -q -F -o Linux -I 128 -b 1024 -O mmp $TMPFILE 100 > $test_name.log 2>&1
+status=$?
+if [ "$status" != 0 ] ; then
+       echo "mke2fs -O mmp failed" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return $status
+fi
+
+$TUNE2FS -O project $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" == 0 ] ; then
+       echo "'tune2fs -O project' succeeded on small inode" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return 1
+fi
+$TUNE2FS -o bad_option $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" == 0 ] ; then
+       echo "'tune2fs -o bad_option' succeeded" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return 1
+fi
+$E2MMPSTATUS -i $TMPFILE >> $test_name.log 2>&1
+$E2MMPSTATUS $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" != 0 ] ; then
+       echo "$TUNE2FS left MMP block in bad state" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return $status
+fi
+
+$FSCK $FSCK_OPT $TMPFILE >> $test_name.log 2>&1
+status=$?
+if [ "$status" = 0 ] ; then
+       echo "$test_name: $test_description: ok"
+       touch $test_name.ok
+else
+       echo "e2fsck after MMP disable failed" > $test_name.failed
+       echo "$test_name: $test_description: failed"
+       return $status
+fi
+rm -f $TMPFILE