From d030908bfc424d492c10e6da94ae938e252093ef Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 Jan 2016 20:12:22 -0500 Subject: [PATCH 1/7] ext2fs: work around FreeBSD header breakage FreeBSD 10.2 will blow up compiling its own header files in sys/file.h if _XOPEN_SOURCE is defined. In file included from tdb.c:59: /usr/include/sys/file.h:209:2: error: unknown type name 'u_int' u_int xf_flag; /* flags (see fcntl.h) */ ^ 1 error generated. This is despite the fact that POSIX.1 requires comforming applications to define _XOPEN_SOURCE (to different numbers depending on the version of POSIX.1 the program is expecting to work against). See section 2.2.1 in POSIX.1 for chapter and verse. Work around this by removing the _XOPEN_SOURCE declaration. This will cause compiler warnings (and will cause builds against some versions of Solaris to break), so only do this for FreeBSD. Signed-off-by: Theodore Ts'o --- lib/ext2fs/tdb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ext2fs/tdb.c b/lib/ext2fs/tdb.c index 61e30ed2..b313f3ad 100644 --- a/lib/ext2fs/tdb.c +++ b/lib/ext2fs/tdb.c @@ -36,7 +36,9 @@ Last Changed Date: 2007-06-22 13:36:10 -0400 (Fri, 22 Jun 2007) #define HAVE_UTIME_H #define HAVE_UTIME #endif +#ifndef __FreeBSD__ #define _XOPEN_SOURCE 600 +#endif #include "config.h" #include From 0355d6d047884f5ba41ef526fc7d13fba1f6b258 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 Jan 2016 21:44:12 -0500 Subject: [PATCH 2/7] Fix build system to be compatible with BSD pmake This fixes a number of incompatibilities which caused maint branch to fail to build on on FreeBSD. Also fix the Makefile in the tests directory so that "make -jN check" works correctly on FreeBSD. Previously the Makefile in the tests directory used a construct which was specific to GNU Make, which which silently expanded to an empty list, which caused "make check" to be a no-op when running using BSD's pmake. This Makefile has been changed to use the != macro assignment syntax which is common to GNU make and BSD pmake. It's technically not completely portable (it will not be recognized by Solaris's ccs make, for example), but most other operating systems ship GNU make (Solaris, AIX), or BSD pmake (*BSD, Mac OS) as either the primary or alternative make utility that this should an acceptable compromise, since it makes running all of tests using something like "make -j8 check" or "make -j16 check" run *much* faster. There are still some caveats if using BSD pmake; in particular, if the configure script is run on a system which has GNU make (installed as gmake on FreeBSD for example), the configure script will find it, and enable some GNU make features in the Makefile, and the generated makefiles *must* be built using gmake. However, if isolated build jail / chroot is used which only has pmake, the Makefiles should now work with pmake. Signed-off-by: Theodore Ts'o --- MCONFIG.in | 4 ++-- Makefile.in | 3 ++- misc/Makefile.in | 4 ++-- tests/Makefile.in | 8 +++++++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/MCONFIG.in b/MCONFIG.in index f1003cfa..10c3025b 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -59,11 +59,11 @@ pkgconfigdir = $(libdir)/pkgconfig @ifGNUmake@ ifeq ("$(C)", "1") @ifGNUmake@ CHECK_CMD=$(CHECK) $(CHECK_OPTS) @ifGNUmake@ else -@ifGNUmake@ CHECK_CMD=@true +@ifGNUmake@ CHECK_CMD=true @ifGNUmake@ endif @ifGNUmake@ endif -@ifNotGNUmake@ CHECK_CMD=@true +@ifNotGNUmake@ CHECK_CMD=true CC = @CC@ BUILD_CC = @BUILD_CC@ diff --git a/Makefile.in b/Makefile.in index f5727a80..f443fba5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -19,7 +19,7 @@ LIB_SUBDIRS=lib/et lib/ss lib/e2p $(UUID_LIB_SUBDIR) $(BLKID_LIB_SUBDIR) $(QUOTA PROG_SUBDIRS=e2fsck $(DEBUGFS_DIR) misc $(RESIZE_DIR) tests/progs po SUBDIRS=util $(LIB_SUBDIRS) $(PROG_SUBDIRS) tests -SUBS= util/subst.conf lib/config.h lib/dirpaths.h \ +SUBS= util/subst.conf lib/config.h $(top_builddir)/lib/dirpaths.h \ lib/ext2fs/ext2_types.h lib/blkid/blkid_types.h lib/uuid/uuid_types.h TAR=tar @@ -34,6 +34,7 @@ subs: $(DEP_SUBSTITUTE) then $(MAKE) $$i || exit $$? ; fi ; done @(if test -d lib/et ; then cd lib/et && $(MAKE) compile_et; fi) @(if test -d lib/ext2fs ; then cd lib/ext2fs && $(MAKE) ext2_err.h; fi) + @(if test -d e2fsck ; then cd e2fsck && $(MAKE) prof_err.h; fi) progs: all-progs-recursive libs: all-libs-recursive diff --git a/misc/Makefile.in b/misc/Makefile.in index c203fb43..e7642c69 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -123,8 +123,8 @@ prof_err.c prof_err.h: $(srcdir)/../e2fsck/prof_err.et $(Q) $(COMPILE_ET) $(srcdir)/../e2fsck/prof_err.et profile.h: $(top_srcdir)/e2fsck/profile.h - $(E) " CP $<" - $(Q) cp $< $@ + $(E) " CP $@" + $(Q) cp $(top_srcdir)/e2fsck/profile.h $@ mke2fs.conf: $(srcdir)/mke2fs.conf.in if test -f $(srcdir)/mke2fs.conf.custom.in ; then \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 37a043ea..d9845510 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -35,10 +35,16 @@ mke2fs.conf: $(srcdir)/mke2fs.conf.in .PHONY : test_pre test_post check always_run -TESTS=$(wildcard $(srcdir)/[a-z]_*) +always_run: + +TESTS != echo $(srcdir)/[a-z]_* + $(TESTS):: test_one always_run @./test_one $@ +foo: + echo $(TESTS) + test_pre: @$(RM) -f *.failed @echo "Running e2fsprogs test suite..." From 865dc0d7534ca881dbe1e9fc9fd95792e7f3f0ab Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 5 Mar 2016 17:38:31 -0700 Subject: [PATCH 3/7] blkid: fix ZFS device detection While the main blkid functionality is in util-linux, there is still use for blkid on non-Linux platforms. Fix the ZFS device detection by looking at multiple uberblocks to see if any are present, rather than looking for the ZFS boot block which is not always present. There are slots for up to 128 uberblocks, but the first 4 are not written to disk on a newly-formatted filesystem, so check several of them at different offsets within the uberblock array. Signed-off-by: Andreas Dilger Signed-off-by: Theodore Ts'o --- lib/blkid/probe.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c index 4b797ab1..161f4f1a 100644 --- a/lib/blkid/probe.c +++ b/lib/blkid/probe.c @@ -1440,10 +1440,19 @@ static struct blkid_magic type_array[] = { { "iso9660", 32, 1, 5, "CD001", probe_iso9660 }, { "iso9660", 32, 9, 5, "CDROM", probe_iso9660 }, { "jfs", 32, 0, 4, "JFS1", probe_jfs }, - { "zfs", 8, 0, 8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", probe_zfs }, - { "zfs", 8, 0, 8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", probe_zfs }, - { "zfs", 264, 0, 8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", probe_zfs }, - { "zfs", 264, 0, 8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", probe_zfs }, + /* ZFS has 128 root blocks (#4 is the first used), check only 6 of them */ + { "zfs", 128, 0, 8, "\0\0\0\0\0\xba\xb1\x0c", probe_zfs }, + { "zfs", 128, 0, 8, "\x0c\xb1\xba\0\0\0\0\0", probe_zfs }, + { "zfs", 132, 0, 8, "\0\0\0\0\0\xba\xb1\x0c", probe_zfs }, + { "zfs", 132, 0, 8, "\x0c\xb1\xba\0\0\0\0\0", probe_zfs }, + { "zfs", 136, 0, 8, "\0\0\0\0\0\xba\xb1\x0c", probe_zfs }, + { "zfs", 136, 0, 8, "\x0c\xb1\xba\0\0\0\0\0", probe_zfs }, + { "zfs", 384, 0, 8, "\0\0\0\0\0\xba\xb1\x0c", probe_zfs }, + { "zfs", 384, 0, 8, "\x0c\xb1\xba\0\0\0\0\0", probe_zfs }, + { "zfs", 388, 0, 8, "\0\0\0\0\0\xba\xb1\x0c", probe_zfs }, + { "zfs", 388, 0, 8, "\x0c\xb1\xba\0\0\0\0\0", probe_zfs }, + { "zfs", 392, 0, 8, "\0\0\0\0\0\xba\xb1\x0c", probe_zfs }, + { "zfs", 392, 0, 8, "\x0c\xb1\xba\0\0\0\0\0", probe_zfs }, { "hfsplus", 1, 0, 2, "BD", probe_hfsplus }, { "hfsplus", 1, 0, 2, "H+", probe_hfsplus }, { "hfsplus", 1, 0, 2, "HX", probe_hfsplus }, From 2fe6136c48610791de8bb4c8fcad536292ffe36e Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 5 Mar 2016 17:38:32 -0700 Subject: [PATCH 4/7] debugfs: improve dump_mmp handling If MMP is not enabled on a filesystem (s_mmp_block == 0), print this clearly rather than "MMP: block number beyond filesystem range". Add an option to "debugfs dump_mmp" to specify the MMP block number instead of getting it from the superblock s_mmp_block field. Signed-off-by: Andreas Dilger Signed-off-by: Theodore Ts'o --- debugfs/debugfs.8.in | 9 +++++++-- debugfs/debugfs.c | 25 ++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in index bae14db0..49287910 100644 --- a/debugfs/debugfs.8.in +++ b/debugfs/debugfs.8.in @@ -221,8 +221,13 @@ option is given set the owner, group and permissions information on to match .IR filespec . .TP -.B dump_mmp -Display the multiple-mount protection (mmp) field values. +.BI dump_mmp " [mmp_block]" +Display the multiple-mount protection (mmp) field values. If +.I mmp_block +is specified then verify and dump the MMP values from the given block +number, otherwise use the +.B s_mmp_block +field in the superblock to locate and use the existing MMP block. .TP .BI dx_hash " [-h hash_alg] [-s hash_seed] filename" Calculate the directory hash of diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c index 5423634b..260698c1 100644 --- a/debugfs/debugfs.c +++ b/debugfs/debugfs.c @@ -2351,12 +2351,31 @@ try_again: void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[]) { struct mmp_struct *mmp_s; + unsigned long long mmp_block; time_t t; errcode_t retval = 0; if (check_fs_open(argv[0])) return; + if (argc > 1) { + char *end = NULL; + mmp_block = strtoull(argv[1], &end, 0); + if (end == argv[0] || mmp_block == 0) { + fprintf(stderr, "%s: invalid MMP block '%s' given\n", + argv[0], argv[1]); + return; + } + } else { + mmp_block = current_fs->super->s_mmp_block; + } + + if (mmp_block == 0) { + fprintf(stderr, "%s: MMP: not active on this filesystem.\n", + argv[0]); + return; + } + if (current_fs->mmp_buf == NULL) { retval = ext2fs_get_mem(current_fs->blocksize, ¤t_fs->mmp_buf); @@ -2368,10 +2387,10 @@ void do_dump_mmp(int argc EXT2FS_ATTR((unused)), char *argv[]) mmp_s = current_fs->mmp_buf; - retval = ext2fs_mmp_read(current_fs, current_fs->super->s_mmp_block, - current_fs->mmp_buf); + retval = ext2fs_mmp_read(current_fs, mmp_block, current_fs->mmp_buf); if (retval) { - com_err(argv[0], retval, "reading MMP block.\n"); + com_err(argv[0], retval, "reading MMP block %llu.\n", + mmp_block); return; } From 7fd5374012709bc7dba8a1e80d62048ea48b4dbd Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 5 Mar 2016 17:38:33 -0700 Subject: [PATCH 5/7] misc: add missing declarations on maint Fix compile warnings for missing declarations on the maint branch. Signed-off-by: Andreas Dilger Signed-off-by: Theodore Ts'o --- misc/util.c | 3 +++ util/subst.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/misc/util.c b/misc/util.c index 28988306..5a24e7e5 100644 --- a/misc/util.c +++ b/misc/util.c @@ -21,6 +21,9 @@ #ifdef HAVE_ERRNO_H #include #endif +#if HAVE_UNISTD_H +#include +#endif #ifdef HAVE_LINUX_MAJOR_H #include #endif diff --git a/util/subst.c b/util/subst.c index 91f6d449..db729234 100644 --- a/util/subst.c +++ b/util/subst.c @@ -19,8 +19,12 @@ #ifdef HAVE_SYS_TIME_H #include #endif +#ifdef HAVE_SYS_TYPES_H #include +#endif +#ifdef HAVE_SYS_STAT_H #include +#endif #include #include #include From 1e3f5c889d3f86f88dca94cd93dcfbe9aa37d641 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sat, 5 Mar 2016 17:38:34 -0700 Subject: [PATCH 6/7] lsattr: treat inode generation as an unsigned int The EXT2_GETVERSION ioctl is defined to take a "long" parameter, but fgetversion() calls ioctl() with an "int" parameter instead. This is handled in the kernel correctly, but the generation is sign-extended in fgetversion() before return on 64-bit systems and lsattr prints it as a huge positive number for inode generation above 0x80000000: 1635574212 -------------e-- /mnt/ost0/O/0/d0/12928 18446744073045131735 -------------e-- /mnt/ost0/O/0/d0/166240 782808861 -------------e-- /mnt/ost0/O/0/d0/31744 18446744072181134840 -------------e-- /mnt/ost0/O/0/d0/135008 Correctly assign the returned generation number as an unsigned value, and print it with a 10-character field width. The version is printed left-aligned for consistency with the old code and to ensure it is always printed in the first column for use with tools like "cut": 1635574212 -------------e-- /mnt/ost0/O/0/d0/12928 3630547415 -------------e-- /mnt/ost0/O/0/d0/166240 782808861 -------------e-- /mnt/ost0/O/0/d0/31744 2766550520 -------------e-- /mnt/ost0/O/0/d0/135008 Do not return a random value from the stack as the version on error. Clean up some style issues and consolidate some duplicate code. Signed-off-by: Andreas Dilger Signed-off-by: Theodore Ts'o --- lib/e2p/fgetversion.c | 36 +++++++++++++++++++----------------- misc/lsattr.c | 2 +- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/e2p/fgetversion.c b/lib/e2p/fgetversion.c index e6cee8bf..2ad813bb 100644 --- a/lib/e2p/fgetversion.c +++ b/lib/e2p/fgetversion.c @@ -37,32 +37,34 @@ #define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) #endif -int fgetversion (const char * name, unsigned long * version) +int fgetversion(const char *name, unsigned long *version) { + unsigned int ver = -1; + int rc = -1; #if HAVE_EXT2_IOCTLS -#if !APPLE_DARWIN - int fd, r, ver, save_errno = 0; +# if !APPLE_DARWIN + int fd, save_errno = 0; - fd = open (name, OPEN_FLAGS); + fd = open(name, OPEN_FLAGS); if (fd == -1) return -1; - r = ioctl (fd, EXT2_IOC_GETVERSION, &ver); - if (r == -1) + + rc = ioctl(fd, EXT2_IOC_GETVERSION, &ver); + if (rc == -1) save_errno = errno; - *version = ver; - close (fd); - if (save_errno) + close(fd); + if (rc == -1) errno = save_errno; - return r; -#else - int ver=-1, err; - err = syscall(SYS_fsctl, name, EXT2_IOC_GETVERSION, &ver, 0); - *version = ver; - return(err); -#endif +# else /* APPLE_DARWIN */ + rc = syscall(SYS_fsctl, name, EXT2_IOC_GETVERSION, &ver, 0); +# endif /* !APPLE_DARWIN */ #else /* ! HAVE_EXT2_IOCTLS */ extern int errno; + errno = EOPNOTSUPP; - return -1; #endif /* ! HAVE_EXT2_IOCTLS */ + if (rc == 0) + *version = ver; + + return rc; } diff --git a/misc/lsattr.c b/misc/lsattr.c index e5e59690..4c34e2f1 100644 --- a/misc/lsattr.c +++ b/misc/lsattr.c @@ -92,7 +92,7 @@ static int list_attributes (const char * name) name); return -1; } - printf ("%5lu ", generation); + printf ("%-10lu ", generation); } if (pf_options & PFOPT_LONG) { printf("%-28s ", name); From ba60bb903f1e7e5fc29922bd851737fa26e0a5ae Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Sun, 6 Mar 2016 18:16:04 -0500 Subject: [PATCH 7/7] findsuper: improve output if s_mkfs_time unset If s_mkfs_time is not set in the superblock, print the s_mtime field instead to identify the different superblocks. This can happen if the superblock is corrupted, since s_mkfs_time is not reset by e2fsck. Signed-off-by: Andreas Dilger Signed-off-by: Theodore Ts'o --- misc/findsuper.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/misc/findsuper.c b/misc/findsuper.c index eb9130ba..b3b76cda 100644 --- a/misc/findsuper.c +++ b/misc/findsuper.c @@ -187,7 +187,7 @@ int main(int argc, char *argv[]) if (print_jnl_copies) printf(_("[*] probably superblock written in the ext3 " "journal superblock,\n\tso start/end/grp wrong\n")); - printf(_("byte_offset byte_start byte_end fs_blocks blksz grp last_mount_time sb_uuid label\n")); + printf(_("byte_offset byte_start byte_end fs_blocks blksz grp mkfs/mount_time sb_uuid label\n")); for (; lseek64(fd, sk, SEEK_SET) != -1 && read(fd, &ext2, 512) == 512; sk += skiprate) { static unsigned char last_uuid[16] = "blah"; @@ -230,7 +230,10 @@ int main(int argc, char *argv[]) WHY("free_inodes_count > inodes_count (%u > %u)\n", ext2.s_free_inodes_count, ext2.s_inodes_count); - tm = ext2.s_mtime; + if (ext2.s_mkfs_time != 0) + tm = ext2.s_mkfs_time; + else + tm = ext2.s_mtime; s = ctime(&tm); s[24] = 0; bsize = 1 << (ext2.s_log_block_size + 10);