From aae09cdc6274aa4492c103bea3dddfba7301b7e8 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 05:06:58 +0000 Subject: import gfs2-utils-3.1.10-9.el7 --- diff --git a/SOURCES/bz1498068-mkfs_gfs2_Scale_down_journal_size_for_smaller_devices.patch b/SOURCES/bz1498068-mkfs_gfs2_Scale_down_journal_size_for_smaller_devices.patch new file mode 100644 index 0000000..e123ed9 --- /dev/null +++ b/SOURCES/bz1498068-mkfs_gfs2_Scale_down_journal_size_for_smaller_devices.patch @@ -0,0 +1,187 @@ +commit cc079a4d907eedd24c69ab2a88e9e0fcdef58a5d +Author: Andrew Price +Date: Mon Feb 12 19:27:48 2018 +0000 + + mkfs.gfs2: Scale down journal size for smaller devices + + Currently the default behaviour when the journal size is not specified + is to use a default size of 128M, which means that mkfs.gfs2 can run out + of space while writing to a small device. The hard default also means + that some xfstests fail with gfs2 as they try to create small file + systems. + + This patch addresses these problems by setting sensible default journal + sizes depending on the size of the file system. Journal sizes specified + by the user are limited to half of the fs. As the minimum journal size + is 8MB that means we effectively get a hard minimum file system size of + 16MB (per journal). + + Resolves: rhbz#1498068 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index ebf6bca7..570c89b9 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -319,6 +319,8 @@ struct metapath { + + #define GFS2_DEFAULT_BSIZE (4096) + #define GFS2_DEFAULT_JSIZE (128) ++#define GFS2_MAX_JSIZE (1024) ++#define GFS2_MIN_JSIZE (8) + #define GFS2_DEFAULT_RGSIZE (256) + #define GFS2_DEFAULT_UTSIZE (1) + #define GFS2_DEFAULT_QCSIZE (1) +diff --git a/gfs2/man/mkfs.gfs2.8 b/gfs2/man/mkfs.gfs2.8 +index 342a636d..35e355a5 100644 +--- a/gfs2/man/mkfs.gfs2.8 ++++ b/gfs2/man/mkfs.gfs2.8 +@@ -32,8 +32,9 @@ Enable debugging output. + Print out a help message describing the available options, then exit. + .TP + \fB-J\fP \fImegabytes\fR +-The size of each journal. The default journal size is 128 megabytes and the +-minimum size is 8 megabytes. ++The size of each journal. The minimum size is 8 megabytes and the maximum is ++1024. If this is not specified, a value based on a sensible proportion of the ++file system will be chosen. + .TP + \fB-j\fP \fIjournals\fR + The number of journals for mkfs.gfs2 to create. At least one journal is +diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c +index 2e08bc62..24e5a850 100644 +--- a/gfs2/mkfs/main_mkfs.c ++++ b/gfs2/mkfs/main_mkfs.c +@@ -552,7 +552,7 @@ static void opts_check(struct mkfs_opts *opts) + if (!opts->journals) + die( _("no journals specified\n")); + +- if (opts->jsize < 8 || opts->jsize > 1024) ++ if (opts->jsize < GFS2_MIN_JSIZE || opts->jsize > GFS2_MAX_JSIZE) + die( _("bad journal size\n")); + + if (!opts->qcsize || opts->qcsize > 64) +@@ -575,6 +575,7 @@ static void print_results(struct gfs2_sb *sb, struct mkfs_opts *opts, uint64_t r + printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Filesystem size:"), + (fssize / ((float)(1 << 30)) * sb->sb_bsize), _("GB"), fssize, _("blocks")); + printf("%-27s%u\n", _("Journals:"), opts->journals); ++ printf("%-27s%uMB\n", _("Journal size:"), opts->jsize); + printf("%-27s%"PRIu64"\n", _("Resource groups:"), rgrps); + printf("%-27s\"%s\"\n", _("Locking protocol:"), opts->lockproto); + printf("%-27s\"%s\"\n", _("Lock table:"), opts->locktable); +@@ -823,6 +824,36 @@ static int place_rgrps(struct gfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts + return 0; + } + ++/* ++ * Find a reasonable journal file size (in blocks) given the number of blocks ++ * in the filesystem. For very small filesystems, it is not reasonable to ++ * have a journal that fills more than half of the filesystem. ++ * ++ * n.b. comments assume 4k blocks ++ * ++ * This was copied and adapted from e2fsprogs. ++ */ ++static int default_journal_size(unsigned bsize, uint64_t num_blocks) ++{ ++ int min_blocks = (GFS2_MIN_JSIZE << 20) / bsize; ++ ++ if (num_blocks < 2 * min_blocks) ++ return -1; ++ if (num_blocks < 131072) /* 512 MB */ ++ return min_blocks; /* 8 MB */ ++ if (num_blocks < 512*1024) /* 2 GB */ ++ return (4096); /* 16 MB */ ++ if (num_blocks < 2048*1024) /* 8 GB */ ++ return (8192); /* 32 MB */ ++ if (num_blocks < 4096*1024) /* 16 GB */ ++ return (16384); /* 64 MB */ ++ if (num_blocks < 262144*1024) /* 1 TB */ ++ return (32768); /* 128 MB */ ++ if (num_blocks < 2621440*1024) /* 10 TB */ ++ return (131072); /* 512 MB */ ++ return 262144; /* 1 GB */ ++} ++ + static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsize) + { + memset(sdp, 0, sizeof(struct gfs2_sbd)); +@@ -847,9 +878,28 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsiz + opts->dev.size / ((float)(1 << 30)), _("GB"), + opts->dev.size / sdp->bsize, _("blocks")); + } +- /* TODO: Check if the fssize is too small, somehow */ + sdp->device.length = opts->fssize; + } ++ /* opts->jsize has already been max/min checked but we need to check it ++ makes sense for the device size, or set a sensible default, if one ++ will fit. For user-provided journal sizes, limit it to half of the fs. */ ++ if (!opts->got_jsize) { ++ int default_jsize = default_journal_size(sdp->bsize, sdp->device.length / opts->journals); ++ if (default_jsize < 0) { ++ fprintf(stderr, _("gfs2 will not fit on this device.\n")); ++ exit(1); ++ } ++ opts->jsize = (default_jsize * sdp->bsize) >> 20; ++ } else if ((((opts->jsize * opts->journals) << 20) / sdp->bsize) > (sdp->device.length / 2)) { ++ unsigned max_jsize = (sdp->device.length / 2 * sdp->bsize / opts->journals) >> 20; ++ ++ fprintf(stderr, _("gfs2 will not fit on this device.\n")); ++ if (max_jsize >= GFS2_MIN_JSIZE) ++ fprintf(stderr, _("Maximum size for %u journals on this device is %uMB.\n"), ++ opts->journals, max_jsize); ++ exit(1); ++ } ++ sdp->jsize = opts->jsize; + } + + static int probe_contents(struct mkfs_dev *dev) +diff --git a/tests/edit.at b/tests/edit.at +index 3bd41636..e1a0fca7 100644 +--- a/tests/edit.at ++++ b/tests/edit.at +@@ -6,7 +6,7 @@ AT_KEYWORDS(gfs2_edit edit) + GFS_TGT_REGEN + AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT $(($(gfs_max_blocks 4096)/2))], 0, [ignore], [ignore]) + AT_CHECK([gfs2_edit savemeta $GFS_TGT test.meta > savemeta.log], 0, [ignore], [ignore]) +-AT_CHECK([head -2 savemeta.log], 0, [There are 1310718 blocks of 4096 bytes in the filesystem. ++AT_CHECK([head -2 savemeta.log], 0, [There are 1310716 blocks of 4096 bytes in the filesystem. + Filesystem size: 4.1023GB + ], [ignore]) + GFS_TGT_REGEN +diff --git a/tests/mkfs.at b/tests/mkfs.at +index 274a81db..68195e93 100644 +--- a/tests/mkfs.at ++++ b/tests/mkfs.at +@@ -123,3 +123,13 @@ AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:65536:393216:512 $GFS_ + # Check rgrp alignment to minimum_io_size: 65536 / 4096 == 16 + AT_CHECK([gfs2_edit -p rindex $GFS_TGT | grep ri_addr | awk '{print $2, $2 % 16; if ($2 % 16 != 0) { exit 1 }}'], 0, [ignore], [ignore]) + AT_CLEANUP ++ ++AT_SETUP([Small filesystems]) ++AT_KEYWORDS(mkfs.gfs2 mkfs) ++GFS_TGT_SIZE(32M) ++AT_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT], 0, [ignore], [ignore]) ++AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) ++GFS_TGT_SIZE(64M) ++AT_CHECK([$GFS_MKFS -p lock_nolock -j2 $GFS_TGT], 0, [ignore], [ignore]) ++AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) ++AT_CLEANUP +diff --git a/tests/testsuite.at b/tests/testsuite.at +index cc1bd54d..522ac1c2 100644 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -4,6 +4,12 @@ m4_define([GFS_TGT_REGEN], + [AT_CHECK([rm -f $GFS_TGT && truncate -s ${GFS_TGT_SZ}G ${GFS_TGT}], [ignore], [ignore], [ignore]) + AT_SKIP_IF([test ! -f ${GFS_TGT}])]) + ++# Regenerate the sparse file used for testing, with a given size, and skip the test if it fails ++# Usage: GFS_TGT_REGEN() ++m4_define([GFS_TGT_SIZE], ++[AT_CHECK([rm -f $GFS_TGT && truncate -s $1 ${GFS_TGT}], [ignore], [ignore], [ignore]) ++AT_SKIP_IF([test ! -f ${GFS_TGT}])]) ++ + # Regenerate, check, fsck is used a lot so combine it into one macro + # Usage: GFS_FSCK_CHECK ([mkfs.gfs2 ... $GFS_TGT]) + m4_define([GFS_FSCK_CHECK], diff --git a/SOURCES/bz1544944-glocktop_Remove_a_non_existent_flag_from_the_usage_string.patch b/SOURCES/bz1544944-glocktop_Remove_a_non_existent_flag_from_the_usage_string.patch new file mode 100644 index 0000000..afaa35a --- /dev/null +++ b/SOURCES/bz1544944-glocktop_Remove_a_non_existent_flag_from_the_usage_string.patch @@ -0,0 +1,24 @@ +commit 26b4d21c9ced2b8a8d03e2b0e4413373bd0de69b +Author: Andrew Price +Date: Thu Feb 15 11:06:18 2018 +0000 + + glocktop: Remove a non-existent flag from the usage string + + There is no -f option. + + Signed-off-by: Andrew Price + +diff --git a/gfs2/glocktop/glocktop.c b/gfs2/glocktop/glocktop.c +index bcee3d8b..cef368a0 100644 +--- a/gfs2/glocktop/glocktop.c ++++ b/gfs2/glocktop/glocktop.c +@@ -1630,8 +1630,7 @@ static void parse_glocks_file(int fd, const char *fsname, int dlmwaiters, + static void usage(void) + { + printf("Usage:\n"); +- printf("glocktop [-i] [-d ] [-f] [-n ] [-sX] " +- "[-c] [-D] [-H] [-r] [-t]\n"); ++ printf("glocktop [-i] [-d ] [-n ] [-sX] [-c] [-D] [-H] [-r] [-t]\n"); + printf("\n"); + printf("-i : Runs glocktop in interactive mode.\n"); + printf("-d : delay between refreshes, in seconds (default: %d).\n", REFRESH_TIME); diff --git a/SOURCES/bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch b/SOURCES/bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch new file mode 100644 index 0000000..17e2320 --- /dev/null +++ b/SOURCES/bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch @@ -0,0 +1,130 @@ +commit 1a4581c3f54b5c794da6537789eeab298b78e031 +Author: Andrew Price +Date: Fri Aug 17 12:49:24 2018 +0100 + + fsck.gfs2: Don't check fs formats we don't recognise + + Currently fsck.gfs2 will ignore sb_fs_format but in order to support + future formats we need to make sure it doesn't try to check filesystems + with formats we don't recognise yet. Better late than never. + + Tests included. + + rhbz#1616389 + rhbz#1622050 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h +index 8af4eb41..db173c67 100644 +--- a/gfs2/fsck/fsck.h ++++ b/gfs2/fsck/fsck.h +@@ -4,6 +4,8 @@ + #include "libgfs2.h" + #include "osi_tree.h" + ++#define FSCK_MAX_FORMAT (1801) ++ + #define FSCK_HASH_SHIFT (13) + #define FSCK_HASH_SIZE (1 << FSCK_HASH_SHIFT) + #define FSCK_HASH_MASK (FSCK_HASH_SIZE - 1) +diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c +index 75f050b5..4e323ffa 100644 +--- a/gfs2/fsck/initialize.c ++++ b/gfs2/fsck/initialize.c +@@ -1332,12 +1332,12 @@ static int fill_super_block(struct gfs2_sbd *sdp) + if (sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){ + log_crit( _("GFS superblock is larger than the blocksize!\n")); + log_debug("sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize\n"); +- return -1; ++ return FSCK_ERROR; + } + + if (compute_constants(sdp)) { + log_crit("%s\n", _("Failed to compute file system constants")); +- exit(FSCK_ERROR); ++ return FSCK_ERROR; + } + ret = read_sb(sdp); + if (ret < 0) { +@@ -1346,10 +1346,15 @@ static int fill_super_block(struct gfs2_sbd *sdp) + /* Now that we've tried to repair it, re-read it. */ + ret = read_sb(sdp); + if (ret < 0) +- return -1; ++ return FSCK_ERROR; + } + if (sdp->gfs1) + sbd1 = (struct gfs_sb *)&sdp->sd_sb; ++ else if (sdp->sd_sb.sb_fs_format > FSCK_MAX_FORMAT) { ++ log_crit(_("Unsupported gfs2 format found: %"PRIu32"\n"), sdp->sd_sb.sb_fs_format); ++ log_crit(_("A newer fsck.gfs2 is required to check this file system.\n")); ++ return FSCK_USAGE; ++ } + return 0; + } + +@@ -1554,6 +1559,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + int *all_clean) + { + int clean_journals = 0, open_flag; ++ int err; + + *all_clean = 0; + +@@ -1599,8 +1605,9 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + } + + /* read in sb from disk */ +- if (fill_super_block(sdp)) +- return FSCK_ERROR; ++ err = fill_super_block(sdp); ++ if (err != FSCK_OK) ++ return err; + + /* Change lock protocol to be fsck_* instead of lock_* */ + if (!opts.no && preen_is_safe(sdp, preen, force_check)) { +diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c +index 61752031..cc9679f5 100644 +--- a/gfs2/libgfs2/super.c ++++ b/gfs2/libgfs2/super.c +@@ -29,11 +29,18 @@ int check_sb(struct gfs2_sb *sb) + errno = EIO; + return -1; + } ++ /* Check for gfs1 */ + if (sb->sb_fs_format == GFS_FORMAT_FS && + sb->sb_header.mh_format == GFS_FORMAT_SB && + sb->sb_multihost_format == GFS_FORMAT_MULTI) { + return 1; + } ++ /* It's gfs2. Check format number is in a sensible range. */ ++ if (sb->sb_fs_format < GFS2_FORMAT_FS || ++ sb->sb_fs_format > 1899) { ++ errno = EINVAL; ++ return -1; ++ } + return 2; + } + +diff --git a/tests/fsck.at b/tests/fsck.at +index 0dfeac33..d3cf3dbb 100644 +--- a/tests/fsck.at ++++ b/tests/fsck.at +@@ -45,3 +45,16 @@ AT_SETUP([Fix bad rindex entry #1]) + AT_KEYWORDS(fsck.gfs2 fsck) + GFS_NUKERG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [-i 1]) + AT_CLEANUP ++ ++AT_SETUP([gfs2 format versions]) ++AT_KEYWORDS(fsck.gfs2 fsck) ++GFS_TGT_REGEN ++AT_CHECK([mkfs.gfs2 -O -p lock_nolock ${GFS_TGT}], 0, [ignore], [ignore]) ++AT_CHECK([echo "set sb { sb_fs_format: 1802 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore]) ++# Unsupported format, FSCK_USAGE == 16 ++AT_CHECK([fsck.gfs2 -y $GFS_TGT], 16, [ignore], [ignore]) ++# Format out of range ++AT_CHECK([echo "set sb { sb_fs_format: 4242 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore]) ++AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore]) ++AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore]) ++AT_CLEANUP diff --git a/SOURCES/bz1616389-2-libgfs2_Fix_pointer_cast_byte_order_issue.patch b/SOURCES/bz1616389-2-libgfs2_Fix_pointer_cast_byte_order_issue.patch new file mode 100644 index 0000000..79e2a5b --- /dev/null +++ b/SOURCES/bz1616389-2-libgfs2_Fix_pointer_cast_byte_order_issue.patch @@ -0,0 +1,47 @@ +commit 9349bf264b3a8e60f071ab0f9c11859ca6342395 +Author: Andrew Price +Date: Thu Sep 6 14:28:19 2018 +0100 + + libgfs2: Fix pointer cast byte order issue + + lgfs2_field_assign() currently uses pointer casting to achieve generic + integer assignment based on the width of the field, but this is broken + as a uin32_t field can be assigned the value from the high bytes of the + uint64_t value, for instance. To fix this, store the value into a + uint64_t before casting to the narrower types. + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c +index 500757d9..55133b1d 100644 +--- a/gfs2/libgfs2/meta.c ++++ b/gfs2/libgfs2/meta.c +@@ -919,6 +919,7 @@ int lgfs2_field_str(char *str, const size_t size, const char *blk, const struct + int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const void *val) + { + char *fieldp = blk + field->offset; ++ uint64_t num = *(uint64_t *)val; + + if (field->flags & LGFS2_MFF_UUID) { + memcpy(fieldp, val, 16); +@@ -938,16 +939,16 @@ int lgfs2_field_assign(char *blk, const struct lgfs2_metafield *field, const voi + + switch(field->length) { + case sizeof(uint8_t): +- *fieldp = *(uint8_t *)val; ++ *fieldp = (uint8_t)num; + return 0; + case sizeof(uint16_t): +- *(uint16_t *)fieldp = cpu_to_be16(*(uint16_t *)val); ++ *(uint16_t *)fieldp = cpu_to_be16((uint16_t)num); + return 0; + case sizeof(uint32_t): +- *(uint32_t *)fieldp = cpu_to_be32(*(uint32_t *)val); ++ *(uint32_t *)fieldp = cpu_to_be32((uint32_t)num); + return 0; + case sizeof(uint64_t): +- *(uint64_t *)fieldp = cpu_to_be64(*(uint64_t *)val); ++ *(uint64_t *)fieldp = cpu_to_be64((uint64_t)num); + return 0; + default: + /* Will never happen */ diff --git a/SPECS/gfs2-utils.spec b/SPECS/gfs2-utils.spec index af5c842..24a5d8d 100644 --- a/SPECS/gfs2-utils.spec +++ b/SPECS/gfs2-utils.spec @@ -12,7 +12,7 @@ Name: gfs2-utils Version: 3.1.10 -Release: 6%{?dist} +Release: 9%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Kernel Summary: Utilities for managing the global file system (GFS2) @@ -50,6 +50,10 @@ Patch4: bz1440269-3-libgfs2_Issue_one_write_per_rgrp_when_creating_them.patch Patch5: bz1482542-gfs2_edit_savemeta_Fix_up_saving_of_dinodes_symlinks.patch Patch6: bz1507091-fsck_gfs2_Make_p_n_and_y_conflicting_options.patch Patch7: bz1518938-gfs2_edit_Print_offsets_of_indirect_pointers.patch +Patch8: bz1498068-mkfs_gfs2_Scale_down_journal_size_for_smaller_devices.patch +Patch9: bz1544944-glocktop_Remove_a_non_existent_flag_from_the_usage_string.patch +Patch10: bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch +Patch11: bz1616389-2-libgfs2_Fix_pointer_cast_byte_order_issue.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -63,6 +67,10 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %patch5 -p1 -b .bz1482542-gfs2_edit_savemeta_Fix_up_saving_of_dinodes_symlinks %patch6 -p1 -b .bz1507091-fsck_gfs2_Make_p_n_and_y_conflicting_options %patch7 -p1 -b .bz1518938-gfs2_edit_Print_offsets_of_indirect_pointers +%patch8 -p1 -b .bz1498068-mkfs_gfs2_Scale_down_journal_size_for_smaller_devices +%patch9 -p1 -b .bz1544944-glocktop_Remove_a_non_existent_flag_from_the_usage_string +%patch10 -p1 -b .bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise +%patch11 -p1 -b .bz1616389-2-libgfs2_Fix_pointer_cast_byte_order_issue %build ./autogen.sh @@ -108,6 +116,19 @@ file systems. %{_prefix}/lib/udev/rules.d/82-gfs2-withdraw.rules %changelog +* Thu Sep 06 2018 Andrew Price - 3.1.10-9 +- fsck.gfs2: Don't check fs formats we don't recognise +- libgfs2: Fix pointer cast byte order issue + Resolves: rhbz#1616389 + +* Fri Jun 22 2018 Andrew Price - 3.1.10-8 +- glocktop: Remove a non-existent flag from the usage string + Resolves: rhbz#1544944 + +* Sun Apr 15 2018 Andrew Price - 3.1.10-7 +- mkfs.gfs2: Scale down journal size for smaller devices + Resolves: rhbz#1498068 + * Tue Dec 05 2017 Andrew Price - 3.1.10-6 - gfs2_edit: Print offsets of indirect pointers Resolves: rhbz#1518938