diff --git a/SOURCES/bz1028388-1-libgfs2_Add_sd_heightsize_bounds_checking_in_read_sb.patch b/SOURCES/bz1028388-1-libgfs2_Add_sd_heightsize_bounds_checking_in_read_sb.patch new file mode 100644 index 0000000..176f76a --- /dev/null +++ b/SOURCES/bz1028388-1-libgfs2_Add_sd_heightsize_bounds_checking_in_read_sb.patch @@ -0,0 +1,78 @@ +commit 7d57e6d4aff2a0b356c92db1706b346329fabc45 +Author: Andrew Price +Date: Mon Oct 28 16:56:56 2013 +0000 + + libgfs2: Add sd_heightsize bounds checking in read_sb + + read_sb wasn't checking that x was less than the size of sd_heightsize + when looping over it. This patch adds a check for that. This resolves a + segfault in all tools which use read_sb, when the sb_bsize has been + zeroed in the superblock. + + A test case has been added for this scenario in tests/fsck.at + + Resolves: bz#1028388 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c +index f87734a..8ffd144 100644 +--- a/gfs2/libgfs2/super.c ++++ b/gfs2/libgfs2/super.c +@@ -88,7 +88,7 @@ int read_sb(struct gfs2_sbd *sdp) + sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); + sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); + sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; +- for (x = 2; ; x++){ ++ for (x = 2; x <= GFS2_MAX_META_HEIGHT; x++){ + space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; + /* FIXME: Do we really need this first check?? */ + if (space / sdp->sd_inptrs != sdp->sd_heightsize[x - 1] || +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 3336304..616a44e 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -40,6 +40,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac + TESTSUITE_AT = \ + testsuite.at \ + mkfs.at \ ++ fsck.at \ + libgfs2.at + + TESTSUITE = $(srcdir)/testsuite +diff --git a/tests/fsck.at b/tests/fsck.at +new file mode 100644 +index 0000000..34c5bd5 +--- /dev/null ++++ b/tests/fsck.at +@@ -0,0 +1,8 @@ ++AT_TESTED([fsck.gfs2]) ++AT_BANNER([fsck.gfs2 tests]) ++ ++AT_SETUP([Zeroed block size]) ++GFS_LANG_CHECK( ++ [mkfs.gfs2 -O -p lock_nolock $GFS_TGT], ++ [set sb { sb_bsize: 0 }]) ++AT_CLEANUP +diff --git a/tests/testsuite.at b/tests/testsuite.at +index 2c74985..fc90879 100644 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -9,8 +9,17 @@ m4_define([GFS_FSCK_CHECK], + AT_CHECK($1, 0, [ignore], [ignore]) + AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore])]) + ++# Regenerate, mkfs, modify fs with gfs2l, fsck ++m4_define([GFS_LANG_CHECK], ++[GFS_TGT_REGEN ++AT_CHECK($1, 0, [ignore], [ignore]) ++AT_CHECK([echo "$2" | 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_INIT([]) + AT_COLOR_TESTS + + m4_include([mkfs.at]) ++m4_include([fsck.at]) + m4_include([libgfs2.at]) diff --git a/SOURCES/bz1028388-2-fsck_gfs2_Fix_block_size_validation.patch b/SOURCES/bz1028388-2-fsck_gfs2_Fix_block_size_validation.patch new file mode 100644 index 0000000..5954048 --- /dev/null +++ b/SOURCES/bz1028388-2-fsck_gfs2_Fix_block_size_validation.patch @@ -0,0 +1,75 @@ +commit 32d72eb22fdf00c759df50e5fce49292d15be5ed +Author: Andrew Price +Date: Fri Nov 8 16:59:44 2013 +0000 + + fsck.gfs2: Fix block size validation + + The previous patch had an off-by-one error when looping over + sdp->sd_heightsize. This fixes that and adds an explicit sanity check + for sb_bsize. Some new tests are added to cover both valid and invalid + block size cases. + + Resolves: bz#1028388 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c +index 8ffd144..d074236 100644 +--- a/gfs2/libgfs2/super.c ++++ b/gfs2/libgfs2/super.c +@@ -67,6 +67,9 @@ int read_sb(struct gfs2_sbd *sdp) + sdp->gfs1 = 1; + sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT; + sdp->bsize = sdp->sd_sb.sb_bsize; ++ if (sdp->bsize < 512 || sdp->bsize != (sdp->bsize & -sdp->bsize)) { ++ return -1; ++ } + if (sdp->gfs1) { + sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - + sizeof(struct gfs_dinode)) / +@@ -88,7 +91,7 @@ int read_sb(struct gfs2_sbd *sdp) + sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); + sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); + sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; +- for (x = 2; x <= GFS2_MAX_META_HEIGHT; x++){ ++ for (x = 2; x < GFS2_MAX_META_HEIGHT; x++){ + space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; + /* FIXME: Do we really need this first check?? */ + if (space / sdp->sd_inptrs != sdp->sd_heightsize[x - 1] || +diff --git a/tests/fsck.at b/tests/fsck.at +index 34c5bd5..d7a8357 100644 +--- a/tests/fsck.at ++++ b/tests/fsck.at +@@ -1,8 +1,10 @@ + AT_TESTED([fsck.gfs2]) + AT_BANNER([fsck.gfs2 tests]) + +-AT_SETUP([Zeroed block size]) +-GFS_LANG_CHECK( +- [mkfs.gfs2 -O -p lock_nolock $GFS_TGT], +- [set sb { sb_bsize: 0 }]) ++AT_SETUP([Fix invalid block sizes]) ++GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 0 }]) ++GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 1 }]) ++GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 513 }]) ++GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4095 }]) ++GFS_LANG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [set sb { sb_bsize: 4097 }]) + AT_CLEANUP +diff --git a/tests/mkfs.at b/tests/mkfs.at +index aff6a0d..a3973af 100644 +--- a/tests/mkfs.at ++++ b/tests/mkfs.at +@@ -31,6 +31,13 @@ GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT]) + GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_dlm -t foo:bar $GFS_TGT]) + AT_CLEANUP + ++AT_SETUP([Valid block sizes 512-4096]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 1024 $GFS_TGT]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 2048 $GFS_TGT]) ++GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 4096 $GFS_TGT]) ++AT_CLEANUP ++ + AT_SETUP([Max. blocks, min. block size]) + GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT $(gfs_max_blocks 512)]) + AT_CLEANUP diff --git a/SOURCES/bz1028388-3-gfs2l_Build_with_D_FILE_OFFSET_BITS_64.patch b/SOURCES/bz1028388-3-gfs2l_Build_with_D_FILE_OFFSET_BITS_64.patch new file mode 100644 index 0000000..8758ee8 --- /dev/null +++ b/SOURCES/bz1028388-3-gfs2l_Build_with_D_FILE_OFFSET_BITS_64.patch @@ -0,0 +1,27 @@ +commit 5e4fe097ac39ceb8e6768da98cd1e84ff99b8176 +Author: Andrew Price +Date: Tue Nov 12 16:38:34 2013 +0000 + + gfs2l: Build with -D_FILE_OFFSET_BITS=64 + + The latest test cases were failing on 32-bit architectures as gfs2l + wasn't being built with large file support. This adds + -D_FILE_OFFSET_BITS=64 to fix the tests. + + Resolves: bz#1028388 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/Makefile.am b/gfs2/libgfs2/Makefile.am +index b57f6d9..c5cb288 100644 +--- a/gfs2/libgfs2/Makefile.am ++++ b/gfs2/libgfs2/Makefile.am +@@ -22,7 +22,7 @@ libgfs2_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 \ + -I$(top_srcdir)/gfs2/include + + gfs2l_SOURCES = gfs2l.c +-gfs2l_CPPFLAGS = -I$(top_srcdir)/gfs2/include ++gfs2l_CPPFLAGS = -I$(top_srcdir)/gfs2/include -D_FILE_OFFSET_BITS=64 + gfs2l_LDADD = libgfs2.la + + # Autotools can't handle header files output by flex so we have to generate it manually diff --git a/SOURCES/bz1059443-1-gfs2_edit_Convert_fssize_to_bytes_before_reporting_fs_size.patch b/SOURCES/bz1059443-1-gfs2_edit_Convert_fssize_to_bytes_before_reporting_fs_size.patch new file mode 100644 index 0000000..97b4b00 --- /dev/null +++ b/SOURCES/bz1059443-1-gfs2_edit_Convert_fssize_to_bytes_before_reporting_fs_size.patch @@ -0,0 +1,70 @@ +commit 979c86c6e76aa6a879c2a163f8d20653a4a759da +Author: Andrew Price +Date: Fri Jan 31 06:30:00 2014 -0600 + + gfs2_edit: Convert fssize to bytes before reporting fs size + + gfs2_edit savemeta wasn't converting sbd.fssize to bytes before converting it + to a human-friendly number. This patch adds that multiplier along with a sanity + test for savemeta/restoremeta. + + Resolves: rhbz#1059443 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c +index 986fdbe..b4c85d6 100644 +--- a/gfs2/edit/savemeta.c ++++ b/gfs2/edit/savemeta.c +@@ -736,7 +736,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel) + gfs1_ri_update(&sbd, 0, &rgcount, 0); + else + ri_update(&sbd, 0, &rgcount, &sane); +- printf("Done. File system size: %s\n\n", anthropomorphize(sbd.fssize)); ++ printf("Done. File system size: %s\n\n", anthropomorphize(sbd.fssize * sbd.bsize)); + fflush(stdout); + + get_journal_inode_blocks(); +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 616a44e..5f02d3a 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -41,6 +41,7 @@ TESTSUITE_AT = \ + testsuite.at \ + mkfs.at \ + fsck.at \ ++ edit.at \ + libgfs2.at + + TESTSUITE = $(srcdir)/testsuite +diff --git a/tests/edit.at b/tests/edit.at +new file mode 100644 +index 0000000..014d118 +--- /dev/null ++++ b/tests/edit.at +@@ -0,0 +1,15 @@ ++AT_TESTED([gfs2_edit]) ++AT_BANNER([gfs2_edit tests]) ++ ++AT_SETUP([Savemeta/restoremeta, defaults]) ++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 2621440 blocks of 4096 bytes in the destination device. ++Reading resource groups...Done. File system size: 4.1023G ++], [ignore]) ++GFS_TGT_REGEN ++AT_CHECK([gfs2_edit restoremeta test.meta $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 fc90879..fe781a7 100644 +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -22,4 +22,5 @@ AT_COLOR_TESTS + + m4_include([mkfs.at]) + m4_include([fsck.at]) ++m4_include([edit.at]) + m4_include([libgfs2.at]) diff --git a/SOURCES/bz1059443-2-mkfs_gfs2_tests_Enable_debug_output.patch b/SOURCES/bz1059443-2-mkfs_gfs2_tests_Enable_debug_output.patch new file mode 100644 index 0000000..a0e7f5b --- /dev/null +++ b/SOURCES/bz1059443-2-mkfs_gfs2_tests_Enable_debug_output.patch @@ -0,0 +1,122 @@ +commit 9a070d60d70937da51f1430c6626327c971dec33 +Author: Andrew Price +Date: Wed Jan 22 18:46:53 2014 +0000 + + mkfs.gfs2 tests: Enable debug output + + Enable debug output of mkfs.gfs2 tests and define the base options as a + shell variable to make them easier to maintain. + + Resolves: rhbz#1059443 + + Signed-off-by: Andrew Price + +diff --git a/tests/atlocal.in b/tests/atlocal.in +index 660c87a..b021b13 100644 +--- a/tests/atlocal.in ++++ b/tests/atlocal.in +@@ -1,5 +1,6 @@ + GFS_TGT="$abs_builddir/testvol" + GFS_TGT_SZ=10 ++GFS_MKFS="mkfs.gfs2 -O -D" + + gfs_max_blocks() + { +diff --git a/tests/mkfs.at b/tests/mkfs.at +index a3973af..2616109 100644 +--- a/tests/mkfs.at ++++ b/tests/mkfs.at +@@ -2,70 +2,70 @@ AT_TESTED([mkfs.gfs2]) + AT_BANNER([mkfs.gfs2 tests]) + + AT_SETUP([Locking protocol validation]) +-AT_CHECK([mkfs.gfs2 -O -p badprotocol $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p badprotocol $GFS_TGT], 255, [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Resource group size validation]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -r 31 $GFS_TGT], 255, [ignore], [ignore]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -r 2049 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -r 31 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -r 2049 $GFS_TGT], 255, [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Journal size validation]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -J 7 $GFS_TGT], 255, [ignore], [ignore]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -J 1025 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -J 7 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -J 1025 $GFS_TGT], 255, [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Block count validation]) + GFS_TGT_REGEN +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT $(($(gfs_max_blocks 512)+1))], 255, [ignore], [ignore]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -b 4096 $GFS_TGT $(($(gfs_max_blocks 4096)+1))], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT $(($(gfs_max_blocks 512)+1))], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT $(($(gfs_max_blocks 4096)+1))], 255, [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Quota change file size validation]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -c 0 $GFS_TGT], 255, [ignore], [ignore]) +-AT_CHECK([mkfs.gfs2 -O -p lock_nolock -c 65 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -c 0 $GFS_TGT], 255, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -c 65 $GFS_TGT], 255, [ignore], [ignore]) + AT_CLEANUP + + AT_SETUP([Locking protocols]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_dlm -t foo:bar $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_dlm -t foo:bar $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Valid block sizes 512-4096]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 1024 $GFS_TGT]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 2048 $GFS_TGT]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 4096 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 1024 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 2048 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Max. blocks, min. block size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 512 $GFS_TGT $(gfs_max_blocks 512)]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 512 $GFS_TGT $(gfs_max_blocks 512)]) + AT_CLEANUP + + AT_SETUP([Max. blocks, max. block size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -b 4096 $GFS_TGT $(util_max_blocks 4096)]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -b 4096 $GFS_TGT $(util_max_blocks 4096)]) + AT_CLEANUP + + AT_SETUP([Max. resource group size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -r 2048 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 2048 $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Min. resource group size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -r 32 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -r 32 $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Max. journal size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -J 1024 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 1024 $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Min. journal size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -J 8 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -J 8 $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Max. quota change file size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -c 64 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -c 64 $GFS_TGT]) + AT_CLEANUP + + AT_SETUP([Min. quota change file size]) +-GFS_FSCK_CHECK([mkfs.gfs2 -O -p lock_nolock -c 1 $GFS_TGT]) ++GFS_FSCK_CHECK([$GFS_MKFS -p lock_nolock -c 1 $GFS_TGT]) + AT_CLEANUP diff --git a/SOURCES/bz1063842-1-libgfs2_Superblock_building_and_writing_improvements.patch b/SOURCES/bz1063842-1-libgfs2_Superblock_building_and_writing_improvements.patch new file mode 100644 index 0000000..a3691df --- /dev/null +++ b/SOURCES/bz1063842-1-libgfs2_Superblock_building_and_writing_improvements.patch @@ -0,0 +1,500 @@ +commit 37cf0257bf6298df38ca74ee8577bac5a40e6598 +Author: Andrew Price +Date: Thu Feb 6 04:25:27 2014 +0000 + + libgfs2: Superblock building and writing improvements + + build_sb was creating the sb, setting its fields from an sdp and then + writing it, and also zeroing the gap before the sb on the device in a + block-by-block way using buffer_heads. + + This patch splits the build_sb function into lgfs2_sb_init and + lgfs2_sb_write which operate on gfs2_sb structures instead of gfs2_sbds. + lgfs2_sb_write now uses pwritev to zero the initial blocks and write the + sb to an fd. + + get_random_bytes has been moved into structures.c and made static as + only lgfs2_sb_init now uses it. + + Resolves: rhbz#1063842 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c +index 719ba9c..ce056a7 100644 +--- a/gfs2/convert/gfs2_convert.c ++++ b/gfs2/convert/gfs2_convert.c +@@ -2374,7 +2374,8 @@ int main(int argc, char **argv) + bh = bread(&sb2, sb2.sb_addr); + sb2.sd_sb.sb_fs_format = GFS2_FORMAT_FS; + sb2.sd_sb.sb_multihost_format = GFS2_FORMAT_MULTI; +- gfs2_sb_out(&sb2.sd_sb, bh); ++ gfs2_sb_out(&sb2.sd_sb, bh->b_data); ++ bmodified(bh); + brelse(bh); + + error = fsync(sb2.device_fd); +diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c +index f0d9789..36f6600 100644 +--- a/gfs2/edit/hexedit.c ++++ b/gfs2/edit/hexedit.c +@@ -2132,7 +2132,8 @@ static void process_field(const char *field, const char *nstr) + gfs2_sb_assigns(&lsb, field, nstr); + else + gfs2_sb_assignval(&lsb, field, newval); +- gfs2_sb_out(&lsb, rbh); ++ gfs2_sb_out(&lsb, rbh->b_data); ++ bmodified(rbh); + if (!termlines) + gfs2_sb_printval(&lsb, field); + } else { +diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c +index 5758607..0f33aa6 100644 +--- a/gfs2/fsck/initialize.c ++++ b/gfs2/fsck/initialize.c +@@ -60,7 +60,7 @@ static int block_mounters(struct gfs2_sbd *sdp, int block_em) + } + } + +- if (write_sb(sdp)) { ++ if (lgfs2_sb_write(&sdp->sd_sb, sdp->device_fd, sdp->bsize)) { + stack; + return -1; + } +@@ -1130,7 +1130,6 @@ static int sb_repair(struct gfs2_sbd *sdp) + { + uint64_t half; + uint32_t known_bsize = 0; +- unsigned char uuid[16]; + int error = 0; + + memset(&fix_md, 0, sizeof(fix_md)); +@@ -1205,9 +1204,8 @@ static int sb_repair(struct gfs2_sbd *sdp) + } + } + /* Step 3 - Rebuild the lock protocol and file system table name */ +- strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO); +- strcpy(sdp->locktable, "unknown"); + if (query(_("Okay to fix the GFS2 superblock? (y/n)"))) { ++ struct gfs2_sb sb; + log_info(_("Found system master directory at: 0x%llx\n"), + sdp->sd_sb.sb_master_dir.no_addr); + sdp->master_dir = lgfs2_inode_read(sdp, +@@ -1226,8 +1224,12 @@ static int sb_repair(struct gfs2_sbd *sdp) + log_crit(_("Error reading root inode: %s\n"), strerror(errno)); + return -1; + } +- get_random_bytes(uuid, sizeof(uuid)); +- build_sb(sdp, uuid); ++ lgfs2_sb_init(&sb, sdp->bsize); ++ strcpy(sb.sb_lockproto, GFS2_DEFAULT_LOCKPROTO); ++ strcpy(sb.sb_locktable, "unknown"); ++ sb.sb_master_dir = sdp->master_dir->i_di.di_num; ++ sb.sb_root_dir = sdp->md.rooti->i_di.di_num; ++ lgfs2_sb_write(&sb, sdp->device_fd, sdp->bsize); + inode_put(&sdp->md.rooti); + inode_put(&sdp->master_dir); + sb_fixed = 1; +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index e785017..6710e72 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -724,7 +724,6 @@ extern int mount_gfs2_meta(struct gfs2_sbd *sdp); + extern void cleanup_metafs(struct gfs2_sbd *sdp); + extern int set_sysfs(const char *fsname, const char *filename, const char *val); + extern int is_fsname(char *name); +-extern void get_random_bytes(void *buf, int nbytes); + + /* recovery.c */ + extern void gfs2_replay_incr_blk(struct gfs2_inode *ip, unsigned int *blk); +@@ -758,7 +757,8 @@ static inline unsigned int rgrp_size(struct rgrp_tree *rgrp) + + /* structures.c */ + extern int build_master(struct gfs2_sbd *sdp); +-extern void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid); ++extern void lgfs2_sb_init(struct gfs2_sb *sb, unsigned bsize); ++extern int lgfs2_sb_write(const struct gfs2_sb *sb, int fd, const unsigned bsize); + extern int build_journal(struct gfs2_sbd *sdp, int j, + struct gfs2_inode *jindex); + extern int build_jindex(struct gfs2_sbd *sdp); +@@ -794,14 +794,14 @@ extern void print_it(const char *label, const char *fmt, const char *fmt2, ...) + /* Translation functions */ + + extern void gfs2_inum_in(struct gfs2_inum *no, char *buf); +-extern void gfs2_inum_out(struct gfs2_inum *no, char *buf); ++extern void gfs2_inum_out(const struct gfs2_inum *no, char *buf); + extern void gfs2_meta_header_in(struct gfs2_meta_header *mh, + struct gfs2_buffer_head *bh); + extern void gfs2_meta_header_out(const struct gfs2_meta_header *mh, char *buf); + extern void gfs2_meta_header_out_bh(const struct gfs2_meta_header *mh, + struct gfs2_buffer_head *bh); + extern void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh); +-extern void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh); ++extern void gfs2_sb_out(const struct gfs2_sb *sb, char *buf); + extern void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf); + extern void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf); + extern void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh); +diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c +index c4ed722..d707687 100644 +--- a/gfs2/libgfs2/misc.c ++++ b/gfs2/libgfs2/misc.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + #include + + #include "libgfs2.h" +@@ -304,47 +303,3 @@ int set_sysfs(const char *fsname, const char *filename, const char *val) + close(fd); + return 0; + } +- +-/* +- * get_random_bytes - Generate a series of random bytes using /dev/urandom. +- * +- * Modified from original code in gen_uuid.c in e2fsprogs/lib +- */ +-void get_random_bytes(void *buf, int nbytes) +-{ +- int i, n = nbytes, fd; +- int lose_counter = 0; +- unsigned char *cp = (unsigned char *) buf; +- struct timeval tv; +- +- gettimeofday(&tv, 0); +- fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); +- srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); +- /* Crank the random number generator a few times */ +- gettimeofday(&tv, 0); +- for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) +- rand(); +- if (fd >= 0) { +- while (n > 0) { +- i = read(fd, cp, n); +- if (i <= 0) { +- if (lose_counter++ > 16) +- break; +- continue; +- } +- n -= i; +- cp += i; +- lose_counter = 0; +- } +- close(fd); +- } +- +- /* +- * We do this all the time, but this is the only source of +- * randomness if /dev/random/urandom is out to lunch. +- */ +- for (cp = buf, i = 0; i < nbytes; i++) +- *cp++ ^= (rand() >> 7) & 0xFF; +- +- return; +-} +diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c +index 4baacc7..43618bc 100644 +--- a/gfs2/libgfs2/ondisk.c ++++ b/gfs2/libgfs2/ondisk.c +@@ -48,7 +48,7 @@ void gfs2_inum_in(struct gfs2_inum *no, char *buf) + CPIN_64(no, str, no_addr); + } + +-void gfs2_inum_out(struct gfs2_inum *no, char *buf) ++void gfs2_inum_out(const struct gfs2_inum *no, char *buf) + { + struct gfs2_inum *str = (struct gfs2_inum *)buf; + +@@ -124,11 +124,11 @@ void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh) + #endif + } + +-void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh) ++void gfs2_sb_out(const struct gfs2_sb *sb, char *buf) + { +- struct gfs2_sb *str = (struct gfs2_sb *)bh->b_data; ++ struct gfs2_sb *str = (struct gfs2_sb *)buf; + +- gfs2_meta_header_out_bh(&sb->sb_header, bh); ++ gfs2_meta_header_out(&sb->sb_header, buf); + + CPOUT_32(sb, str, sb_fs_format); + CPOUT_32(sb, str, sb_multihost_format); +@@ -144,7 +144,6 @@ void gfs2_sb_out(struct gfs2_sb *sb, struct gfs2_buffer_head *bh) + #ifdef GFS2_HAS_UUID + memcpy(str->sb_uuid, sb->sb_uuid, 16); + #endif +- bmodified(bh); + } + + const char *str_uuid(const unsigned char *uuid) +diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c +index e888f1e..2c1939a 100644 +--- a/gfs2/libgfs2/structures.c ++++ b/gfs2/libgfs2/structures.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include "libgfs2.h" + +@@ -41,43 +42,102 @@ int build_master(struct gfs2_sbd *sdp) + return 0; + } + +-void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid) ++#ifdef GFS2_HAS_UUID ++/** ++ * Generate a series of random bytes using /dev/urandom. ++ * Modified from original code in gen_uuid.c in e2fsprogs/lib ++ */ ++static void get_random_bytes(void *buf, int nbytes) + { +- unsigned int x; +- struct gfs2_buffer_head *bh; +- struct gfs2_sb sb; +- +- /* Zero out the beginning of the device up to the superblock */ +- for (x = 0; x < sdp->sb_addr; x++) { +- bh = bget(sdp, x); +- memset(bh->b_data, 0, sdp->bsize); +- bmodified(bh); +- brelse(bh); ++ int i, n = nbytes, fd; ++ int lose_counter = 0; ++ unsigned char *cp = (unsigned char *) buf; ++ struct timeval tv; ++ ++ gettimeofday(&tv, 0); ++ fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); ++ srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec); ++ /* Crank the random number generator a few times */ ++ gettimeofday(&tv, 0); ++ for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--) ++ rand(); ++ if (fd >= 0) { ++ while (n > 0) { ++ i = read(fd, cp, n); ++ if (i <= 0) { ++ if (lose_counter++ > 16) ++ break; ++ continue; ++ } ++ n -= i; ++ cp += i; ++ lose_counter = 0; ++ } ++ close(fd); + } + +- memset(&sb, 0, sizeof(struct gfs2_sb)); +- sb.sb_header.mh_magic = GFS2_MAGIC; +- sb.sb_header.mh_type = GFS2_METATYPE_SB; +- sb.sb_header.mh_format = GFS2_FORMAT_SB; +- sb.sb_fs_format = GFS2_FORMAT_FS; +- sb.sb_multihost_format = GFS2_FORMAT_MULTI; +- sb.sb_bsize = sdp->bsize; +- sb.sb_bsize_shift = ffs(sdp->bsize) - 1; +- sb.sb_master_dir = sdp->master_dir->i_di.di_num; +- sb.sb_root_dir = sdp->md.rooti->i_di.di_num; +- strcpy(sb.sb_lockproto, sdp->lockproto); +- strcpy(sb.sb_locktable, sdp->locktable); ++ /* ++ * We do this all the time, but this is the only source of ++ * randomness if /dev/random/urandom is out to lunch. ++ */ ++ for (cp = buf, i = 0; i < nbytes; i++) ++ *cp++ ^= (rand() >> 7) & 0xFF; ++ ++ return; ++} ++#endif ++ ++/** ++ * Initialise a gfs2_sb structure with sensible defaults. ++ */ ++void lgfs2_sb_init(struct gfs2_sb *sb, unsigned bsize) ++{ ++ memset(sb, 0, sizeof(struct gfs2_sb)); ++ sb->sb_header.mh_magic = GFS2_MAGIC; ++ sb->sb_header.mh_type = GFS2_METATYPE_SB; ++ sb->sb_header.mh_format = GFS2_FORMAT_SB; ++ sb->sb_fs_format = GFS2_FORMAT_FS; ++ sb->sb_multihost_format = GFS2_FORMAT_MULTI; ++ sb->sb_bsize = bsize; ++ sb->sb_bsize_shift = ffs(bsize) - 1; + #ifdef GFS2_HAS_UUID +- memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid)); ++ get_random_bytes(&sb->sb_uuid, sizeof(sb->sb_uuid)); + #endif +- bh = bget(sdp, sdp->sb_addr); +- gfs2_sb_out(&sb, bh); +- brelse(bh); ++} + +- if (sdp->debug) { +- printf("\nSuper Block:\n"); +- gfs2_sb_print(&sb); ++int lgfs2_sb_write(const struct gfs2_sb *sb, int fd, const unsigned bsize) ++{ ++ int i, err = -1; ++ struct iovec *iov; ++ const size_t sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / bsize; ++ const size_t len = sb_addr + 1; ++ ++ /* We only need 2 blocks: one for zeroing and a second for the superblock */ ++ char *buf = calloc(2, bsize); ++ if (buf == NULL) ++ return -1; ++ ++ iov = malloc(len * sizeof(*iov)); ++ if (iov == NULL) ++ goto out_buf; ++ ++ for (i = 0; i < len; i++) { ++ iov[i].iov_base = buf; ++ iov[i].iov_len = bsize; + } ++ ++ gfs2_sb_out(sb, buf + bsize); ++ iov[sb_addr].iov_base = buf + bsize; ++ ++ if (pwritev(fd, iov, len, 0) < (len * bsize)) ++ goto out_iov; ++ ++ err = 0; ++out_iov: ++ free(iov); ++out_buf: ++ free(buf); ++ return err; + } + + int write_journal(struct gfs2_sbd *sdp, unsigned int j, unsigned int blocks) +diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c +index d074236..b956366 100644 +--- a/gfs2/libgfs2/super.c ++++ b/gfs2/libgfs2/super.c +@@ -309,15 +309,3 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet) + + return __ri_update(sdp, fd, rgcount, &sane, quiet); + } +- +-int write_sb(struct gfs2_sbd *sbp) +-{ +- struct gfs2_buffer_head *bh; +- +- bh = bread(sbp, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift); +- gfs2_sb_out(&sbp->sd_sb, bh); +- brelse(bh); +- fsync(sbp->device_fd); /* make sure the change gets to disk ASAP */ +- return 0; +-} +- +diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c +index 0d84064..8bd396a 100644 +--- a/gfs2/mkfs/main_mkfs.c ++++ b/gfs2/mkfs/main_mkfs.c +@@ -569,8 +569,8 @@ static void print_results(struct gfs2_sbd *sdp, uint64_t real_device_size, + (unsigned long long)sdp->fssize, _("blocks")); + printf("%-27s%u\n", _("Journals:"), sdp->md.journals); + printf("%-27s%llu\n", _("Resource groups:"), (unsigned long long)sdp->rgrps); +- printf("%-27s\"%s\"\n", _("Locking protocol:"), sdp->lockproto); +- printf("%-27s\"%s\"\n", _("Lock table:"), sdp->locktable); ++ printf("%-27s\"%s\"\n", _("Locking protocol:"), opts->lockproto); ++ printf("%-27s\"%s\"\n", _("Lock table:"), opts->locktable); + /* Translators: "UUID" = universally unique identifier. */ + printf("%-27s%s\n", _("UUID:"), str_uuid(uuid)); + } +@@ -701,8 +701,6 @@ static void sbd_init(struct gfs2_sbd *sdp, struct mkfs_opts *opts, struct mkfs_d + /* TODO: Check if the fssize is too small, somehow */ + sdp->device.length = opts->fssize; + } +- strcpy(sdp->lockproto, opts->lockproto); +- strcpy(sdp->locktable, opts->locktable); + } + + static int probe_contents(struct mkfs_dev *dev) +@@ -791,11 +789,11 @@ static void open_dev(const char *path, struct mkfs_dev *dev) + void main_mkfs(int argc, char *argv[]) + { + struct gfs2_sbd sbd; ++ struct gfs2_sb sb; + struct mkfs_opts opts; + struct mkfs_dev dev; + lgfs2_rgrps_t rgs; + int error; +- unsigned char uuid[16]; + unsigned bsize; + + opts_init(&opts); +@@ -810,15 +808,16 @@ void main_mkfs(int argc, char *argv[]) + } + + sbd_init(&sbd, &opts, &dev, bsize); ++ lgfs2_sb_init(&sb, bsize); + if (opts.debug) { + printf(_("File system options:\n")); + printf(" bsize = %u\n", sbd.bsize); + printf(" qcsize = %u\n", sbd.qcsize); + printf(" jsize = %u\n", sbd.jsize); + printf(" journals = %u\n", sbd.md.journals); +- printf(" proto = %s\n", sbd.lockproto); ++ printf(" proto = %s\n", opts.lockproto); ++ printf(" table = %s\n", opts.locktable); + printf(" rgsize = %u\n", sbd.rgsize); +- printf(" table = %s\n", sbd.locktable); + printf(" fssize = %"PRIu64"\n", opts.fssize); + printf(" sunit = %lu\n", opts.sunit); + printf(" swidth = %lu\n", opts.swidth); +@@ -838,8 +837,13 @@ void main_mkfs(int argc, char *argv[]) + exit(1); + } + sbd.rgtree.osi_node = lgfs2_rgrps_root(rgs); // Temporary ++ + build_root(&sbd); ++ sb.sb_root_dir = sbd.md.rooti->i_di.di_num; ++ + build_master(&sbd); ++ sb.sb_master_dir = sbd.master_dir->i_di.di_num; ++ + error = build_jindex(&sbd); + if (error) { + fprintf(stderr, _("Error building '%s': %s\n"), "jindex", strerror(errno)); +@@ -872,8 +876,9 @@ void main_mkfs(int argc, char *argv[]) + fprintf(stderr, _("Error building '%s': %s\n"), "quota", strerror(errno)); + exit(EXIT_FAILURE); + } +- get_random_bytes(uuid, sizeof(uuid)); +- build_sb(&sbd, uuid); ++ ++ strcpy(sb.sb_lockproto, opts.lockproto); ++ strcpy(sb.sb_locktable, opts.locktable); + + do_init_inum(&sbd); + do_init_statfs(&sbd); +@@ -884,6 +889,13 @@ void main_mkfs(int argc, char *argv[]) + inode_put(&sbd.md.statfs); + + gfs2_rgrp_free(&sbd.rgtree); ++ ++ error = lgfs2_sb_write(&sb, dev.fd, sbd.bsize); ++ if (error) { ++ perror(_("Failed to write superblock\n")); ++ exit(EXIT_FAILURE); ++ } ++ + error = fsync(dev.fd); + if (error){ + perror(opts.device); +@@ -897,5 +909,5 @@ void main_mkfs(int argc, char *argv[]) + } + + if (!opts.quiet) +- print_results(&sbd, dev.size, &opts, uuid); ++ print_results(&sbd, dev.size, &opts, sb.sb_uuid); + } diff --git a/SOURCES/bz1063842-2-gfs2_utils_Ensure_sb_uuid_uses_are_guarded.patch b/SOURCES/bz1063842-2-gfs2_utils_Ensure_sb_uuid_uses_are_guarded.patch new file mode 100644 index 0000000..6afb997 --- /dev/null +++ b/SOURCES/bz1063842-2-gfs2_utils_Ensure_sb_uuid_uses_are_guarded.patch @@ -0,0 +1,108 @@ +commit 75a68102d55a1c361725ed01864c98fee6f77199 +Author: Andrew Price +Date: Thu Feb 6 13:16:18 2014 +0000 + + gfs2-utils: Ensure sb_uuid uses are guarded + + Guard uses of sb_uuid with #ifdef GFS2_HAS_UUID + + Tweak print_results() in mkfs.gfs2 to accept the gfs2_sb which we + conditionally print the uuid from, instead of the gfs2_sbd. + + Resolves: rhbz#1063842 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c +index 36f6600..0708445 100644 +--- a/gfs2/edit/hexedit.c ++++ b/gfs2/edit/hexedit.c +@@ -104,10 +104,12 @@ static int gfs2_sb_printval(struct gfs2_sb *lsb, const char *strfield) + checkprints(strfield, lsb, sb_locktable); + checkprint(strfield, lsb, __pad3.no_addr); + checkprint(strfield, lsb, __pad4.no_addr); ++#ifdef GFS2_HAS_UUID + if (strcmp(strfield, "sb_uuid") == 0) { + printf("%s\n", str_uuid(lsb->sb_uuid)); + return 0; + } ++#endif + + return -1; + } +@@ -135,8 +137,9 @@ static int gfs2_sb_assigns(struct gfs2_sb *lsb, const char *strfield, + { + checkassigns(strfield, lsb, sb_lockproto, val); + checkassigns(strfield, lsb, sb_locktable, val); ++#ifdef GFS2_HAS_UUID + checkassigns(strfield, lsb, sb_uuid, val); +- ++#endif + return -1; + } + +diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c +index 8bd396a..32da585 100644 +--- a/gfs2/mkfs/main_mkfs.c ++++ b/gfs2/mkfs/main_mkfs.c +@@ -555,24 +555,25 @@ static void opts_check(struct mkfs_opts *opts) + } + } + +-static void print_results(struct gfs2_sbd *sdp, uint64_t real_device_size, +- struct mkfs_opts *opts, unsigned char uuid[16]) ++static void print_results(struct gfs2_sb *sb, struct mkfs_dev *dev, struct mkfs_opts *opts, ++ uint64_t rgrps, uint64_t fssize) + { + printf("%-27s%s\n", _("Device:"), opts->device); +- printf("%-27s%u\n", _("Block size:"), sdp->bsize); +- printf("%-27s%.2f %s (%llu %s)\n", _("Device size:"), ++ printf("%-27s%u\n", _("Block size:"), sb->sb_bsize); ++ printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Device size:"), + /* Translators: "GB" here means "gigabytes" */ +- real_device_size / ((float)(1 << 30)), _("GB"), +- (unsigned long long)real_device_size / sdp->bsize, _("blocks")); +- printf("%-27s%.2f %s (%llu %s)\n", _("Filesystem size:"), +- sdp->fssize / ((float)(1 << 30)) * sdp->bsize, _("GB"), +- (unsigned long long)sdp->fssize, _("blocks")); +- printf("%-27s%u\n", _("Journals:"), sdp->md.journals); +- printf("%-27s%llu\n", _("Resource groups:"), (unsigned long long)sdp->rgrps); ++ (dev->size / ((float)(1 << 30))), _("GB"), ++ (dev->size / sb->sb_bsize), _("blocks")); ++ 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%"PRIu64"\n", _("Resource groups:"), rgrps); + printf("%-27s\"%s\"\n", _("Locking protocol:"), opts->lockproto); + printf("%-27s\"%s\"\n", _("Lock table:"), opts->locktable); ++#ifdef GFS2_HAS_UUID + /* Translators: "UUID" = universally unique identifier. */ +- printf("%-27s%s\n", _("UUID:"), str_uuid(uuid)); ++ printf("%-27s%s\n", _("UUID:"), str_uuid(sb->sb_uuid)); ++#endif + } + + static void warn_of_destruction(const char *path) +@@ -909,5 +910,5 @@ void main_mkfs(int argc, char *argv[]) + } + + if (!opts.quiet) +- print_results(&sbd, dev.size, &opts, sb.sb_uuid); ++ print_results(&sb, &dev, &opts, sbd.rgrps, sbd.fssize); + } +diff --git a/gfs2/tune/super.c b/gfs2/tune/super.c +index cc34990..cbd0026 100644 +--- a/gfs2/tune/super.c ++++ b/gfs2/tune/super.c +@@ -124,8 +124,9 @@ static int is_gfs2(const struct tunegfs2 *tfs) + int print_super(const struct tunegfs2 *tfs) + { + printf(_("File system volume name: %s\n"), tfs->sb->sb_locktable); +- if (is_gfs2(tfs)) +- printf(_("File system UUID: %s\n"), uuid2str(tfs->sb->sb_uuid)); ++#ifdef GFS2_HAS_UUID ++ printf(_("File system UUID: %s\n"), uuid2str(tfs->sb->sb_uuid)); ++#endif + printf( _("File system magic number: 0x%X\n"), be32_to_cpu(tfs->sb->sb_header.mh_magic)); + printf(_("Block size: %d\n"), be32_to_cpu(tfs->sb->sb_bsize)); + printf(_("Block shift: %d\n"), be32_to_cpu(tfs->sb->sb_bsize_shift)); diff --git a/SOURCES/bz1063842-3-libgfs2_Add_support_for_new_leaf_hint_fields.patch b/SOURCES/bz1063842-3-libgfs2_Add_support_for_new_leaf_hint_fields.patch new file mode 100644 index 0000000..dd1d1e3 --- /dev/null +++ b/SOURCES/bz1063842-3-libgfs2_Add_support_for_new_leaf_hint_fields.patch @@ -0,0 +1,286 @@ +commit e7b57dae8cfd096514b970d200e1e97648b495a6 +Author: Andrew Price +Date: Thu Feb 6 16:19:02 2014 +0000 + + libgfs2: Add support for new leaf hint fields + + Kernel commit 01bcb0de introduces new gfs2_leaf fields. This patch adds + support for those fields to libgfs2, conditional upon them being + discovered in the configure stage. Includes meta.c changes by Steve + Whitehouse. + + Resolves: rhbz#1063842 + + Signed-off-by: Andrew Price + +diff --git a/configure.ac b/configure.ac +index 628d85e..80310be 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -116,12 +116,10 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h limits.h locale.h mnt + AC_CHECK_HEADERS([linux/dlmconstants.h linux/limits.h linux/types.h linux/netlink.h linux/fs.h],, + [AC_MSG_ERROR([Unable to find all required kernel headers.])]) + +-AC_CHECK_HEADERS([linux/gfs2_ondisk.h], +- [AC_CHECK_MEMBERS([struct gfs2_sb.sb_uuid],, +- [AC_MSG_ERROR([Unable to find gfs2 uuid support in your headers. +-Please update your kernel headers to a more recent version])], +- [#include ])], +- [AC_MSG_ERROR([Unable to find required kernel headers.])]) ++AC_CHECK_HEADER([linux/gfs2_ondisk.h], [], [AC_MSG_ERROR([Unable to find linux/gfs2_ondisk.h])]) ++AC_CHECK_MEMBER([struct gfs2_sb.sb_uuid], [], [], [[#include ]]) ++AC_CHECK_MEMBER([struct gfs2_leaf.lf_inode],[AC_DEFINE([GFS2_HAS_LEAF_HINTS],[],[Leaf block hints])], ++ [], [[#include ]]) + + # Checks for typedefs, structures, and compiler characteristics. + AC_C_INLINE +diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c +index 27c32a9..328e35c 100644 +--- a/gfs2/edit/extended.c ++++ b/gfs2/edit/extended.c +@@ -296,8 +296,18 @@ static void print_inode_type(__be16 de_type) + } + } + ++#ifdef GFS2_HAS_LEAF_HINTS ++#define LEAF_HINT_FMTS "lf_inode: 0x%"PRIx64", lf_dist: %"PRIu32", " \ ++ "lf_nsec: %"PRIu32", lf_sec: %"PRIu64", " ++#define LEAF_HINT_FIELDS(lp) lp->lf_inode, lp->lf_dist, lp->lf_nsec, lp->lf_sec, ++#else ++#define LEAF_HINT_FMTS ++#define LEAF_HINT_FIELDS(lp) ++#endif ++ + static int display_leaf(struct iinfo *ind) + { ++ struct gfs2_leaf *leaf = &ind->ii[0].lf; + int start_line, total_dirents = start_row[dmode]; + int d; + +@@ -305,11 +315,13 @@ static int display_leaf(struct iinfo *ind) + if (gfs2_struct_type == GFS2_METATYPE_SB) + print_gfs2("The superblock has 2 directories"); + else +- print_gfs2("Directory block: lf_depth:%d, lf_entries:%d," ++ print_gfs2("Directory block: lf_depth:%d, lf_entries:%d, " ++ LEAF_HINT_FMTS + "fmt:%d next=0x%llx (%d dirents).", +- ind->ii[0].lf_depth, ind->ii[0].lf_entries, +- ind->ii[0].lf_dirent_format, +- ind->ii[0].lf_next, ++ leaf->lf_depth, leaf->lf_entries, ++ LEAF_HINT_FIELDS(leaf) ++ leaf->lf_dirent_format, ++ leaf->lf_next, + ind->ii[0].dirents); + + start_line = line; +diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c +index cc0ceb6..cda4dbe 100644 +--- a/gfs2/edit/gfs2hex.c ++++ b/gfs2/edit/gfs2hex.c +@@ -341,17 +341,12 @@ uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir) + { + int x, i; + struct gfs2_dirent de; +- struct gfs2_leaf leaf; + struct gfs2_buffer_head tbh; /* kludge */ + + x = 0; + memset(indir, 0, sizeof(*indir)); + tbh.b_data = dlebuf; +- gfs2_leaf_in(&leaf, &tbh); +- indir->ii[0].lf_depth = leaf.lf_depth; +- indir->ii[0].lf_entries = leaf.lf_entries; +- indir->ii[0].lf_dirent_format = leaf.lf_dirent_format; +- indir->ii[0].lf_next = leaf.lf_next; ++ gfs2_leaf_in(&indir->ii[0].lf, &tbh); + /* Directory Entries: */ + for (i = sizeof(struct gfs2_leaf); i < sbd.bsize; + i += de.de_rec_len) { +@@ -372,7 +367,7 @@ uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir) + if (de.de_rec_len <= sizeof(struct gfs2_dirent)) + break; + } +- return leaf.lf_next; ++ return indir->ii[0].lf.lf_next; + } + + static void do_eattr_extended(struct gfs2_buffer_head *ebh) +diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c +index 0708445..1738652 100644 +--- a/gfs2/edit/hexedit.c ++++ b/gfs2/edit/hexedit.c +@@ -219,7 +219,15 @@ static int gfs2_leaf_printval(struct gfs2_leaf *lf, const char *strfield) + checkprint(strfield, lf, lf_entries); + checkprint(strfield, lf, lf_dirent_format); + checkprint(strfield, lf, lf_next); ++#ifdef GFS2_HAS_LEAF_HINTS ++ checkprint(strfield, lf, lf_inode); ++ checkprint(strfield, lf, lf_dist); ++ checkprint(strfield, lf, lf_nsec); ++ checkprint(strfield, lf, lf_sec); ++ checkprints(strfield, lf, lf_reserved2); ++#else + checkprints(strfield, lf, lf_reserved); ++#endif + + return -1; + } +@@ -231,6 +239,12 @@ static int gfs2_leaf_assignval(struct gfs2_leaf *lf, const char *strfield, + checkassign(strfield, lf, lf_entries, value); + checkassign(strfield, lf, lf_dirent_format, value); + checkassign(strfield, lf, lf_next, value); ++#ifdef GFS2_HAS_LEAF_HINTS ++ checkassign(strfield, lf, lf_inode, value); ++ checkassign(strfield, lf, lf_dist, value); ++ checkassign(strfield, lf, lf_nsec, value); ++ checkassign(strfield, lf, lf_sec, value); ++#endif + + return -1; + } +diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h +index 706909c..ebe3855 100644 +--- a/gfs2/edit/hexedit.h ++++ b/gfs2/edit/hexedit.h +@@ -78,10 +78,7 @@ struct indirect_info { + int height; + uint64_t block; + uint32_t dirents; +- uint16_t lf_depth; +- uint16_t lf_entries; +- uint32_t lf_dirent_format; +- uint64_t lf_next; ++ struct gfs2_leaf lf; + struct metapath mp; + struct gfs2_dirents dirent[64]; + }; +diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c +index b8cef87..59fbde8 100644 +--- a/gfs2/fsck/metawalk.c ++++ b/gfs2/fsck/metawalk.c +@@ -657,7 +657,6 @@ static void dir_leaf_reada(struct gfs2_inode *ip, uint64_t *tbl, unsigned hsize) + static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) + { + int error = 0; +- struct gfs2_leaf leaf; + unsigned hsize = (1 << ip->i_di.di_depth); + uint64_t leaf_no, leaf_next; + uint64_t first_ok_leaf, orig_di_blocks; +@@ -767,6 +766,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass) + + chained_leaf = 0; + do { ++ struct gfs2_leaf leaf; + if (fsck_abort) { + free(tbl); + posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL); +diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c +index 4a84687..1790421 100644 +--- a/gfs2/libgfs2/fs_ops.c ++++ b/gfs2/libgfs2/fs_ops.c +@@ -1024,6 +1024,9 @@ void dir_split_leaf(struct gfs2_inode *dip, uint32_t start, uint64_t leaf_no, + oleaf->lf_depth = cpu_to_be16(oleaf->lf_depth); + nleaf->lf_depth = oleaf->lf_depth; + ++#ifdef GFS2_HAS_LEAF_HINTS ++ nleaf->lf_inode = cpu_to_be64(dip->i_di.di_num.no_addr); ++#endif + dip->i_di.di_blocks++; + bmodified(dip->i_bh); + +@@ -1206,7 +1209,9 @@ restart: + nleaf = (struct gfs2_leaf *)nbh->b_data; + nleaf->lf_depth = leaf->lf_depth; + nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE); +- ++#ifdef GFS2_HAS_LEAF_HINTS ++ nleaf->lf_inode = cpu_to_be64(dip->i_di.di_num.no_addr); ++#endif + err = dirent_alloc(dip, nbh, len, &dent); + if (err) + return err; +@@ -1256,7 +1261,9 @@ static void dir_make_exhash(struct gfs2_inode *dip) + leaf = (struct gfs2_leaf *)bh->b_data; + leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE); + leaf->lf_entries = cpu_to_be16(dip->i_di.di_entries); +- ++#ifdef GFS2_HAS_LEAF_HINTS ++ leaf->lf_inode = cpu_to_be64(dip->i_di.di_num.no_addr); ++#endif + buffer_copy_tail(sdp, bh, sizeof(struct gfs2_leaf), + dip->i_bh, sizeof(struct gfs2_dinode)); + +diff --git a/gfs2/libgfs2/meta.c b/gfs2/libgfs2/meta.c +index 94be823..4305393 100644 +--- a/gfs2/libgfs2/meta.c ++++ b/gfs2/libgfs2/meta.c +@@ -317,7 +317,15 @@ F(lf_depth) + F(lf_entries) + F(lf_dirent_format) + F(lf_next) ++#ifdef GFS2_HAS_LEAF_HINTS ++FP(lf_inode, .points_to = (1 << LGFS2_MT_GFS2_DINODE)) ++F(lf_dist) ++F(lf_nsec, .flags = LGFS2_MFF_NSECS) ++F(lf_sec, .flags = LGFS2_MFF_SECS) ++RF(lf_reserved2) ++#else + RF(lf_reserved) ++#endif + }; + + #undef STRUCT +diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c +index 43618bc..dcc537e 100644 +--- a/gfs2/libgfs2/ondisk.c ++++ b/gfs2/libgfs2/ondisk.c +@@ -433,8 +433,15 @@ void gfs2_leaf_in(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh) + CPIN_16(lf, str, lf_entries); + CPIN_32(lf, str, lf_dirent_format); + CPIN_64(lf, str, lf_next); +- ++#ifdef GFS2_HAS_LEAF_HINTS ++ CPIN_64(lf, str, lf_inode); ++ CPIN_32(lf, str, lf_dist); ++ CPIN_32(lf, str, lf_nsec); ++ CPIN_64(lf, str, lf_sec); ++ CPIN_08(lf, str, lf_reserved2, 40); ++#else + CPIN_08(lf, str, lf_reserved, 32); ++#endif + } + + void gfs2_leaf_out(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh) +@@ -446,8 +453,15 @@ void gfs2_leaf_out(struct gfs2_leaf *lf, struct gfs2_buffer_head *bh) + CPOUT_16(lf, str, lf_entries); + CPOUT_32(lf, str, lf_dirent_format); + CPOUT_64(lf, str, lf_next); +- +- CPOUT_08(lf, str, lf_reserved, 32); ++#ifdef GFS2_HAS_LEAF_HINTS ++ CPOUT_64(lf, str, lf_inode); ++ CPOUT_32(lf, str, lf_dist); ++ CPOUT_32(lf, str, lf_nsec); ++ CPOUT_64(lf, str, lf_sec); ++ CPOUT_08(lf, str, lf_reserved2, 40); ++#else ++ CPOUT_08(lf, str, lf_reserved, 64); ++#endif + bmodified(bh); + } + +@@ -458,6 +472,12 @@ void gfs2_leaf_print(struct gfs2_leaf *lf) + pv(lf, lf_entries, "%u", "0x%x"); + pv(lf, lf_dirent_format, "%u", "0x%x"); + pv(lf, lf_next, "%llu", "0x%llx"); ++#ifdef GFS2_HAS_LEAF_HINTS ++ pv(lf, lf_inode, "%llu", "0x%llx"); ++ pv(lf, lf_dist, "%u", "0x%x"); ++ pv(lf, lf_nsec, "%u", "0x%x"); ++ pv(lf, lf_sec, "%llu", "0x%llx"); ++#endif + } + + void gfs2_ea_header_in(struct gfs2_ea_header *ea, char *buf) diff --git a/SOURCES/bz991204-1-gfs2_grow_Don_t_try_to_open_an_empty_string.patch b/SOURCES/bz991204-1-gfs2_grow_Don_t_try_to_open_an_empty_string.patch new file mode 100644 index 0000000..dc5e4de --- /dev/null +++ b/SOURCES/bz991204-1-gfs2_grow_Don_t_try_to_open_an_empty_string.patch @@ -0,0 +1,185 @@ +commit 43da4b0b6a55cfad8f78a703fb3359cac0c4968a +Author: Andrew Price +Date: Thu Aug 8 17:50:47 2013 +0100 + + gfs2_grow: Don't try to open an empty string + + sdp->device_name wasn't getting set in gfs2_grow so is_gfs2() (called + via check_for_gfs2()) fails to open "" and so we get an ENOENT. + + This fixes the open("") by setting sdp->device_name before passing it to + is_pathname_mounted(), which has been updated to make it more clear + which args will be modified by it. + + is_gfs2() and check_for_gfs2() have also been removed from libgfs2 as + these were the only places they were being called and they aren't + needed: superblock checking is done further along via other functions + calling check_sb(). + + Resolves: rhbz#991204 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c +index b45ae08..6612fe7 100644 +--- a/gfs2/fsck/initialize.c ++++ b/gfs2/fsck/initialize.c +@@ -1491,7 +1491,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + strncpy(sdp->device_name, opts.device, + sizeof(sdp->device_name)); + sdp->path_name = sdp->device_name; /* This gets overwritten */ +- is_mounted = is_pathname_mounted(sdp, &ro); ++ is_mounted = is_pathname_mounted(sdp->path_name, sdp->device_name, &ro); + /* If the device is busy, but not because it's mounted, fail. + This protects against cases where the file system is LVM + and perhaps mounted on a different node. */ +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index fe7129a..e994d3b 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -716,11 +716,9 @@ extern void decrease_verbosity(void); + extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, + uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs); + extern int compute_constants(struct gfs2_sbd *sdp); +-extern int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount); +-extern int is_gfs2(struct gfs2_sbd *sdp); ++extern int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount); + extern int find_gfs2_meta(struct gfs2_sbd *sdp); + extern int dir_exists(const char *dir); +-extern int check_for_gfs2(struct gfs2_sbd *sdp); + extern int mount_gfs2_meta(struct gfs2_sbd *sdp); + extern void cleanup_metafs(struct gfs2_sbd *sdp); + extern int set_sysfs(const char *fsname, const char *filename, const char *val); +diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c +index c05a770..6f2dbdb 100644 +--- a/gfs2/libgfs2/misc.c ++++ b/gfs2/libgfs2/misc.c +@@ -99,7 +99,7 @@ int compute_constants(struct gfs2_sbd *sdp) + return 0; + } + +-int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) ++int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount) + { + FILE *fp; + struct mntent *mnt; +@@ -112,7 +112,7 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) + perror("open: /proc/mounts"); + return 0; + } +- if (stat(sdp->path_name, &st_buf) == 0) { ++ if (stat(path_name, &st_buf) == 0) { + if (S_ISBLK(st_buf.st_mode)) { + #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ + file_rdev = st_buf.st_rdev; +@@ -124,12 +124,12 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) + } + while ((mnt = getmntent (fp)) != NULL) { + /* Check if they specified the device instead of mnt point */ +- if (strcmp(sdp->device_name, mnt->mnt_fsname) == 0) { +- strcpy(sdp->path_name, mnt->mnt_dir); /* fix it */ ++ if (strcmp(device_name, mnt->mnt_fsname) == 0) { ++ strcpy(path_name, mnt->mnt_dir); /* fix it */ + break; + } +- if (strcmp(sdp->path_name, mnt->mnt_dir) == 0) { +- strcpy(sdp->device_name, mnt->mnt_fsname); /* fix it */ ++ if (strcmp(path_name, mnt->mnt_dir) == 0) { ++ strcpy(device_name, mnt->mnt_fsname); /* fix it */ + break; + } + if (stat(mnt->mnt_fsname, &st_buf) == 0) { +@@ -160,36 +160,6 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) + return 1; /* mounted */ + } + +-int is_gfs2(struct gfs2_sbd *sdp) +-{ +- int fd, rc; +- struct gfs2_sb sb; +- +- fd = open(sdp->device_name, O_RDWR); +- if (fd < 0) +- return 0; +- +- rc = 0; +- if (lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK, SEEK_SET) >= 0 && +- read(fd, &sb, sizeof(sb)) == sizeof(sb) && +- be32_to_cpu(sb.sb_header.mh_magic) == GFS2_MAGIC && +- be32_to_cpu(sb.sb_header.mh_type) == GFS2_METATYPE_SB) +- rc = 1; +- close(fd); +- return rc; +-} +- +-int check_for_gfs2(struct gfs2_sbd *sdp) +-{ +- int ro; +- +- if (!is_pathname_mounted(sdp, &ro)) +- return -1; +- if (!is_gfs2(sdp)) +- return -1; +- return 0; +-} +- + static int lock_for_admin(struct gfs2_sbd *sdp) + { + int error; +diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c +index 73c7f84..d324af9 100644 +--- a/gfs2/mkfs/main_grow.c ++++ b/gfs2/mkfs/main_grow.c +@@ -323,6 +323,7 @@ main_grow(int argc, char *argv[]) + int rgcount, rindex_fd; + char rindex_name[PATH_MAX]; + int error = EXIT_SUCCESS; ++ int ro_mnt = 0; + + memset(sdp, 0, sizeof(struct gfs2_sbd)); + sdp->bsize = GFS2_DEFAULT_BSIZE; +@@ -336,17 +337,20 @@ main_grow(int argc, char *argv[]) + int sane; + struct rgrp_tree *last_rgrp; + ++ strncpy(sdp->device_name, argv[optind], PATH_MAX - 1); + sdp->path_name = argv[optind++]; +- sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); +- if (sdp->path_fd < 0){ ++ ++ if ((!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt))) { + perror(sdp->path_name); + exit(EXIT_FAILURE); + } + +- if (check_for_gfs2(sdp)) { ++ sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); ++ if (sdp->path_fd < 0){ + perror(sdp->path_name); + exit(EXIT_FAILURE); + } ++ + sdp->device_fd = open(sdp->device_name, + (test ? O_RDONLY : O_RDWR) | O_CLOEXEC); + if (sdp->device_fd < 0){ +diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c +index 58fb046..2646829 100644 +--- a/gfs2/mkfs/main_jadd.c ++++ b/gfs2/mkfs/main_jadd.c +@@ -491,6 +491,7 @@ void main_jadd(int argc, char *argv[]) + { + struct gfs2_sbd sbd, *sdp = &sbd; + unsigned int total; ++ int ro_mnt = 0; + + memset(sdp, 0, sizeof(struct gfs2_sbd)); + sdp->jsize = GFS2_DEFAULT_JSIZE; +@@ -506,7 +507,7 @@ void main_jadd(int argc, char *argv[]) + exit(EXIT_FAILURE); + } + +- if (check_for_gfs2(sdp)) { ++ if (!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt)) { + perror(sdp->path_name); + exit(EXIT_FAILURE); + } diff --git a/SOURCES/bz991204-2-libgfs2_Add_lgfs2_open_mnt_functions.patch b/SOURCES/bz991204-2-libgfs2_Add_lgfs2_open_mnt_functions.patch new file mode 100644 index 0000000..eff8974 --- /dev/null +++ b/SOURCES/bz991204-2-libgfs2_Add_lgfs2_open_mnt_functions.patch @@ -0,0 +1,143 @@ +commit 3c8db52fe77267109a6f01c178370747a23e64fd +Author: Andrew Price +Date: Sat Nov 16 02:10:52 2013 -0600 + + libgfs2: Add lgfs2_open_mnt* functions + + lgfs2_open_mnt is a replacement for is_pathname_mounted which tries to reduce + races by opening paths speculatively and passing back the open fds once they're + known to be correct. lgfs2_open_mnt_{dev,dir} build on this to provide a + convenient way to open just the device or mount directory relating to a path + which could be either. + + Resolves: bz#991204 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index f864a08..3e5d09c 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include + #include "osi_list.h" +@@ -715,6 +716,9 @@ extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, + uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs); + extern int compute_constants(struct gfs2_sbd *sdp); + extern int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount); ++extern int lgfs2_open_mnt(const char *path, int dirflags, int *dirfd, int devflags, int *devfd, struct mntent **mnt); ++extern int lgfs2_open_mnt_dev(const char *path, int flags, struct mntent **mnt); ++extern int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt); + extern int find_gfs2_meta(struct gfs2_sbd *sdp); + extern int dir_exists(const char *dir); + extern int mount_gfs2_meta(struct gfs2_sbd *sdp); +diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c +index 7f500e6..195b983 100644 +--- a/gfs2/libgfs2/misc.c ++++ b/gfs2/libgfs2/misc.c +@@ -163,6 +163,100 @@ int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount) + return 1; /* mounted */ + } + ++/* Returns 0 if fd1 and fd2 refer to the same device/file, 1 otherwise, or -1 on error */ ++static int fdcmp(int fd1, int fd2) ++{ ++ struct stat st1, st2; ++ if ((fstat(fd1, &st1) != 0) || (fstat(fd2, &st2) != 0)) ++ return -1; ++ if (S_ISBLK(st1.st_mode) && S_ISBLK(st2.st_mode)) { ++ if (st1.st_rdev == st2.st_rdev) { ++ return 0; ++ } ++ } else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino)) { ++ return 0; ++ } ++ return 1; ++} ++ ++int lgfs2_open_mnt(const char *path, int dirflags, int *dirfd, int devflags, int *devfd, struct mntent **mnt) ++{ ++ FILE *fp = setmntent("/proc/mounts", "r"); ++ if (fp == NULL) { ++ perror("open: /proc/mounts"); ++ return 1; ++ } ++ /* Assume path is mount point until we know better. */ ++ *dirfd = open(path, dirflags); ++ if (*dirfd < 0) ++ return 1; ++ ++ while ((*mnt = getmntent(fp)) != NULL) { ++ int fd; ++ if (strcmp((*mnt)->mnt_type, "gfs2") != 0) ++ continue; ++ *devfd = open((*mnt)->mnt_fsname, devflags); ++ /* Defer checking *devfd until later: whether it's ok to ignore ++ * the error depends on whether we find the mount point. */ ++ ++ if (strcmp(path, (*mnt)->mnt_dir) == 0) ++ break; ++ if (strcmp(path, (*mnt)->mnt_fsname) == 0 || fdcmp(*dirfd, *devfd) == 0) { ++ /* We have a match but our above assumption was ++ incorrect and *dirfd is actually the device. */ ++ close(*dirfd); ++ *dirfd = open((*mnt)->mnt_dir, dirflags); ++ break; ++ } ++ ++ fd = open((*mnt)->mnt_dir, dirflags); ++ if (fd >= 0) { ++ int diff = fdcmp(*dirfd, fd); ++ close(fd); ++ if (diff == 0) ++ break; ++ } ++ if (*devfd >= 0) ++ close(*devfd); ++ } ++ endmntent(fp); ++ if (*mnt == NULL) { ++ close(*dirfd); ++ return 0; /* Success. Answer is no. Both fds closed. */ ++ } ++ if (*dirfd < 0) { ++ close(*devfd); ++ return 1; ++ } ++ if (*devfd < 0) { ++ close(*dirfd); ++ return 1; ++ } ++ return 0; /* Success. Answer is yes. Both fds open. */ ++} ++ ++int lgfs2_open_mnt_dev(const char *path, int flags, struct mntent **mnt) ++{ ++ int dirfd = -1; ++ int devfd = -1; ++ if (lgfs2_open_mnt(path, O_RDONLY, &dirfd, flags, &devfd, mnt) != 0) ++ return -1; ++ if (*mnt != NULL) ++ close(dirfd); ++ return devfd; ++} ++ ++int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt) ++{ ++ int dirfd = -1; ++ int devfd = -1; ++ if (lgfs2_open_mnt(path, flags, &dirfd, O_RDONLY, &devfd, mnt) != 0) ++ return -1; ++ if (*mnt != NULL) ++ close(devfd); ++ return dirfd; ++} ++ + static int lock_for_admin(struct gfs2_sbd *sdp) + { + int error; diff --git a/SOURCES/bz991204-3-Switch_is_pathname_mounted_callers_to_lgfs2_open_mnt.patch b/SOURCES/bz991204-3-Switch_is_pathname_mounted_callers_to_lgfs2_open_mnt.patch new file mode 100644 index 0000000..27209d1 --- /dev/null +++ b/SOURCES/bz991204-3-Switch_is_pathname_mounted_callers_to_lgfs2_open_mnt.patch @@ -0,0 +1,170 @@ +commit 63bd2eff2043c2d14399d5511e116ae0cdd8bba3 +Author: Andrew Price +Date: Sat Nov 16 02:19:07 2013 -0600 + + Switch is_pathname_mounted callers to lgfs2_open_mnt* + + Use the new lgfs2_open_mnt* functions in fsck.gfs2, gfs2_grow, and gfs2_jadd. + + Resolves: bz#991204 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c +index 6612fe7..5758607 100644 +--- a/gfs2/fsck/initialize.c ++++ b/gfs2/fsck/initialize.c +@@ -1475,8 +1475,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + + sdp->device_fd = open(opts.device, open_flag); + if (sdp->device_fd < 0) { +- int is_mounted, ro; +- ++ struct mntent *mnt; + if (open_flag == O_RDONLY || errno != EBUSY) { + log_crit( _("Unable to open device: %s\n"), + opts.device); +@@ -1485,30 +1484,23 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + /* We can't open it EXCL. It may be already open rw (in which + case we want to deny them access) or it may be mounted as + the root file system at boot time (in which case we need to +- allow it.) We use is_pathname_mounted here even though +- we're specifying a device name, not a path name. The +- function checks for device as well. */ +- strncpy(sdp->device_name, opts.device, +- sizeof(sdp->device_name)); +- sdp->path_name = sdp->device_name; /* This gets overwritten */ +- is_mounted = is_pathname_mounted(sdp->path_name, sdp->device_name, &ro); +- /* If the device is busy, but not because it's mounted, fail. ++ allow it.) ++ If the device is busy, but not because it's mounted, fail. + This protects against cases where the file system is LVM +- and perhaps mounted on a different node. */ +- if (!is_mounted) ++ and perhaps mounted on a different node. ++ Try opening without O_EXCL. */ ++ sdp->device_fd = lgfs2_open_mnt_dev(opts.device, O_RDWR, &mnt); ++ if (sdp->device_fd < 0) + goto mount_fail; + /* If the device is mounted, but not mounted RO, fail. This + protects them against cases where the file system is + mounted RW, but still allows us to check our own root + file system. */ +- if (!ro) +- goto mount_fail; ++ if (!hasmntopt(mnt, MNTOPT_RO)) ++ goto close_fail; + /* The device is mounted RO, so it's likely our own root + file system. We can only do so much to protect the users +- from themselves. Try opening without O_EXCL. */ +- if ((sdp->device_fd = open(opts.device, O_RDWR)) < 0) +- goto mount_fail; +- ++ from themselves. */ + was_mounted_ro = 1; + } + +@@ -1591,6 +1583,8 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, + + return FSCK_OK; + ++close_fail: ++ close(sdp->device_fd); + mount_fail: + log_crit( _("Device %s is busy.\n"), opts.device); + return FSCK_USAGE; +diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c +index 5db91d9..541b0f2 100644 +--- a/gfs2/mkfs/main_grow.c ++++ b/gfs2/mkfs/main_grow.c +@@ -323,7 +323,7 @@ main_grow(int argc, char *argv[]) + int rgcount, rindex_fd; + char rindex_name[PATH_MAX]; + int error = EXIT_SUCCESS; +- int ro_mnt = 0; ++ int devflags = (test ? O_RDONLY : O_RDWR) | O_CLOEXEC; + + memset(sdp, 0, sizeof(struct gfs2_sbd)); + sdp->bsize = GFS2_DEFAULT_BSIZE; +@@ -333,30 +333,23 @@ main_grow(int argc, char *argv[]) + sdp->md.journals = 1; + decode_arguments(argc, argv, sdp); + +- while ((argc - optind) > 0) { ++ for(; (argc - optind) > 0; optind++) { + int sane; ++ struct mntent *mnt; + struct rgrp_tree *last_rgrp; + +- strncpy(sdp->device_name, argv[optind], PATH_MAX - 1); +- sdp->path_name = argv[optind++]; +- +- if ((!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt))) { +- perror(sdp->path_name); +- exit(EXIT_FAILURE); +- } +- +- sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); +- if (sdp->path_fd < 0){ +- perror(sdp->path_name); ++ error = lgfs2_open_mnt(argv[optind], O_RDONLY|O_CLOEXEC, &sdp->path_fd, ++ devflags, &sdp->device_fd, &mnt); ++ if (error != 0) { ++ fprintf(stderr, _("Error looking up mount '%s': %s\n"), argv[optind], strerror(errno)); + exit(EXIT_FAILURE); + } +- +- sdp->device_fd = open(sdp->device_name, +- (test ? O_RDONLY : O_RDWR) | O_CLOEXEC); +- if (sdp->device_fd < 0){ +- perror(sdp->device_name); +- exit(EXIT_FAILURE); ++ if (mnt == NULL) { ++ fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), argv[optind]); ++ continue; + } ++ sdp->path_name = mnt->mnt_dir; ++ strncpy(sdp->device_name, mnt->mnt_fsname, PATH_MAX - 1); + + if (lgfs2_get_dev_info(sdp->device_fd, &sdp->dinfo) < 0) { + perror(sdp->device_name); +diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c +index b6cd8e4..815dd52 100644 +--- a/gfs2/mkfs/main_jadd.c ++++ b/gfs2/mkfs/main_jadd.c +@@ -490,8 +490,8 @@ add_j(struct gfs2_sbd *sdp) + void main_jadd(int argc, char *argv[]) + { + struct gfs2_sbd sbd, *sdp = &sbd; ++ struct mntent *mnt; + unsigned int total; +- int ro_mnt = 0; + + memset(sdp, 0, sizeof(struct gfs2_sbd)); + sdp->jsize = GFS2_DEFAULT_JSIZE; +@@ -500,17 +500,18 @@ void main_jadd(int argc, char *argv[]) + + decode_arguments(argc, argv, sdp); + verify_arguments(sdp); +- +- sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); +- if (sdp->path_fd < 0){ +- perror(sdp->path_name); ++ ++ sbd.path_fd = lgfs2_open_mnt_dir(sbd.path_name, O_RDONLY|O_CLOEXEC, &mnt); ++ if (sbd.path_fd < 0) { ++ fprintf(stderr, _("Error looking up mount '%s': %s\n"), sbd.path_name, strerror(errno)); + exit(EXIT_FAILURE); + } +- +- if (!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt)) { +- perror(sdp->path_name); ++ if (mnt == NULL) { ++ fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), sbd.path_name); + exit(EXIT_FAILURE); + } ++ sbd.path_name = mnt->mnt_dir; ++ strncpy(sbd.device_name, mnt->mnt_fsname, PATH_MAX - 1); + + gather_info(sdp); + diff --git a/SOURCES/bz991204-4-libgfs2_Remove_is_pathname_mounted.patch b/SOURCES/bz991204-4-libgfs2_Remove_is_pathname_mounted.patch new file mode 100644 index 0000000..e703721 --- /dev/null +++ b/SOURCES/bz991204-4-libgfs2_Remove_is_pathname_mounted.patch @@ -0,0 +1,96 @@ +commit 0d5b21adc867da3c738474ec2bcd1cfa625f8bb6 +Author: Andrew Price +Date: Sat Nov 16 02:21:36 2013 -0600 + + libgfs2: Remove is_pathname_mounted + + All callers are now using lgfs2_open_mnt* instead. + + Resolves: bz#991204 + + Signed-off-by: Andrew Price + +diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h +index 3e5d09c..e785017 100644 +--- a/gfs2/libgfs2/libgfs2.h ++++ b/gfs2/libgfs2/libgfs2.h +@@ -715,7 +715,6 @@ extern int metafs_interrupted; + extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, + uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs); + extern int compute_constants(struct gfs2_sbd *sdp); +-extern int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount); + extern int lgfs2_open_mnt(const char *path, int dirflags, int *dirfd, int devflags, int *devfd, struct mntent **mnt); + extern int lgfs2_open_mnt_dev(const char *path, int flags, struct mntent **mnt); + extern int lgfs2_open_mnt_dir(const char *path, int flags, struct mntent **mnt); +diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c +index 195b983..c4ed722 100644 +--- a/gfs2/libgfs2/misc.c ++++ b/gfs2/libgfs2/misc.c +@@ -102,67 +102,6 @@ int compute_constants(struct gfs2_sbd *sdp) + return 0; + } + +-int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount) +-{ +- FILE *fp; +- struct mntent *mnt; +- dev_t file_dev=0, file_rdev=0; +- ino_t file_ino=0; +- struct stat st_buf; +- +- *ro_mount = 0; +- if ((fp = setmntent("/proc/mounts", "r")) == NULL) { +- perror("open: /proc/mounts"); +- return 0; +- } +- if (stat(path_name, &st_buf) == 0) { +- if (S_ISBLK(st_buf.st_mode)) { +-#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ +- file_rdev = st_buf.st_rdev; +-#endif /* __GNU__ */ +- } else { +- file_dev = st_buf.st_dev; +- file_ino = st_buf.st_ino; +- } +- } +- while ((mnt = getmntent (fp)) != NULL) { +- /* Check if they specified the device instead of mnt point */ +- if (strcmp(device_name, mnt->mnt_fsname) == 0) { +- strcpy(path_name, mnt->mnt_dir); /* fix it */ +- break; +- } +- if (strcmp(path_name, mnt->mnt_dir) == 0) { +- strcpy(device_name, mnt->mnt_fsname); /* fix it */ +- break; +- } +- if (stat(mnt->mnt_fsname, &st_buf) == 0) { +- if (S_ISBLK(st_buf.st_mode)) { +-#ifndef __GNU__ +- if (file_rdev && (file_rdev == st_buf.st_rdev)) +- break; +-#endif /* __GNU__ */ +- } else { +- if (file_dev && ((file_dev == st_buf.st_dev) && +- (file_ino == st_buf.st_ino))) +- break; +- } +- } +- } +- endmntent (fp); +- if (mnt == NULL) +- return 0; +- if (stat(mnt->mnt_dir, &st_buf) < 0) { +- if (errno == ENOENT) +- return 0; +- } +- /* Can't trust fstype because / has "rootfs". */ +- if (file_rdev && (st_buf.st_dev != file_rdev)) +- return 0; +- if (hasmntopt(mnt, MNTOPT_RO)) +- *ro_mount = 1; +- return 1; /* mounted */ +-} +- + /* Returns 0 if fd1 and fd2 refer to the same device/file, 1 otherwise, or -1 on error */ + static int fdcmp(int fd1, int fd2) + { diff --git a/SOURCES/bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch b/SOURCES/bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch deleted file mode 100644 index dc5e4de..0000000 --- a/SOURCES/bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch +++ /dev/null @@ -1,185 +0,0 @@ -commit 43da4b0b6a55cfad8f78a703fb3359cac0c4968a -Author: Andrew Price -Date: Thu Aug 8 17:50:47 2013 +0100 - - gfs2_grow: Don't try to open an empty string - - sdp->device_name wasn't getting set in gfs2_grow so is_gfs2() (called - via check_for_gfs2()) fails to open "" and so we get an ENOENT. - - This fixes the open("") by setting sdp->device_name before passing it to - is_pathname_mounted(), which has been updated to make it more clear - which args will be modified by it. - - is_gfs2() and check_for_gfs2() have also been removed from libgfs2 as - these were the only places they were being called and they aren't - needed: superblock checking is done further along via other functions - calling check_sb(). - - Resolves: rhbz#991204 - - Signed-off-by: Andrew Price - -diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c -index b45ae08..6612fe7 100644 ---- a/gfs2/fsck/initialize.c -+++ b/gfs2/fsck/initialize.c -@@ -1491,7 +1491,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen, - strncpy(sdp->device_name, opts.device, - sizeof(sdp->device_name)); - sdp->path_name = sdp->device_name; /* This gets overwritten */ -- is_mounted = is_pathname_mounted(sdp, &ro); -+ is_mounted = is_pathname_mounted(sdp->path_name, sdp->device_name, &ro); - /* If the device is busy, but not because it's mounted, fail. - This protects against cases where the file system is LVM - and perhaps mounted on a different node. */ -diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h -index fe7129a..e994d3b 100644 ---- a/gfs2/libgfs2/libgfs2.h -+++ b/gfs2/libgfs2/libgfs2.h -@@ -716,11 +716,9 @@ extern void decrease_verbosity(void); - extern int compute_heightsize(struct gfs2_sbd *sdp, uint64_t *heightsize, - uint32_t *maxheight, uint32_t bsize1, int diptrs, int inptrs); - extern int compute_constants(struct gfs2_sbd *sdp); --extern int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount); --extern int is_gfs2(struct gfs2_sbd *sdp); -+extern int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount); - extern int find_gfs2_meta(struct gfs2_sbd *sdp); - extern int dir_exists(const char *dir); --extern int check_for_gfs2(struct gfs2_sbd *sdp); - extern int mount_gfs2_meta(struct gfs2_sbd *sdp); - extern void cleanup_metafs(struct gfs2_sbd *sdp); - extern int set_sysfs(const char *fsname, const char *filename, const char *val); -diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c -index c05a770..6f2dbdb 100644 ---- a/gfs2/libgfs2/misc.c -+++ b/gfs2/libgfs2/misc.c -@@ -99,7 +99,7 @@ int compute_constants(struct gfs2_sbd *sdp) - return 0; - } - --int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) -+int is_pathname_mounted(char *path_name, char *device_name, int *ro_mount) - { - FILE *fp; - struct mntent *mnt; -@@ -112,7 +112,7 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) - perror("open: /proc/mounts"); - return 0; - } -- if (stat(sdp->path_name, &st_buf) == 0) { -+ if (stat(path_name, &st_buf) == 0) { - if (S_ISBLK(st_buf.st_mode)) { - #ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ - file_rdev = st_buf.st_rdev; -@@ -124,12 +124,12 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) - } - while ((mnt = getmntent (fp)) != NULL) { - /* Check if they specified the device instead of mnt point */ -- if (strcmp(sdp->device_name, mnt->mnt_fsname) == 0) { -- strcpy(sdp->path_name, mnt->mnt_dir); /* fix it */ -+ if (strcmp(device_name, mnt->mnt_fsname) == 0) { -+ strcpy(path_name, mnt->mnt_dir); /* fix it */ - break; - } -- if (strcmp(sdp->path_name, mnt->mnt_dir) == 0) { -- strcpy(sdp->device_name, mnt->mnt_fsname); /* fix it */ -+ if (strcmp(path_name, mnt->mnt_dir) == 0) { -+ strcpy(device_name, mnt->mnt_fsname); /* fix it */ - break; - } - if (stat(mnt->mnt_fsname, &st_buf) == 0) { -@@ -160,36 +160,6 @@ int is_pathname_mounted(struct gfs2_sbd *sdp, int *ro_mount) - return 1; /* mounted */ - } - --int is_gfs2(struct gfs2_sbd *sdp) --{ -- int fd, rc; -- struct gfs2_sb sb; -- -- fd = open(sdp->device_name, O_RDWR); -- if (fd < 0) -- return 0; -- -- rc = 0; -- if (lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK, SEEK_SET) >= 0 && -- read(fd, &sb, sizeof(sb)) == sizeof(sb) && -- be32_to_cpu(sb.sb_header.mh_magic) == GFS2_MAGIC && -- be32_to_cpu(sb.sb_header.mh_type) == GFS2_METATYPE_SB) -- rc = 1; -- close(fd); -- return rc; --} -- --int check_for_gfs2(struct gfs2_sbd *sdp) --{ -- int ro; -- -- if (!is_pathname_mounted(sdp, &ro)) -- return -1; -- if (!is_gfs2(sdp)) -- return -1; -- return 0; --} -- - static int lock_for_admin(struct gfs2_sbd *sdp) - { - int error; -diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c -index 73c7f84..d324af9 100644 ---- a/gfs2/mkfs/main_grow.c -+++ b/gfs2/mkfs/main_grow.c -@@ -323,6 +323,7 @@ main_grow(int argc, char *argv[]) - int rgcount, rindex_fd; - char rindex_name[PATH_MAX]; - int error = EXIT_SUCCESS; -+ int ro_mnt = 0; - - memset(sdp, 0, sizeof(struct gfs2_sbd)); - sdp->bsize = GFS2_DEFAULT_BSIZE; -@@ -336,17 +337,20 @@ main_grow(int argc, char *argv[]) - int sane; - struct rgrp_tree *last_rgrp; - -+ strncpy(sdp->device_name, argv[optind], PATH_MAX - 1); - sdp->path_name = argv[optind++]; -- sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); -- if (sdp->path_fd < 0){ -+ -+ if ((!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt))) { - perror(sdp->path_name); - exit(EXIT_FAILURE); - } - -- if (check_for_gfs2(sdp)) { -+ sdp->path_fd = open(sdp->path_name, O_RDONLY | O_CLOEXEC); -+ if (sdp->path_fd < 0){ - perror(sdp->path_name); - exit(EXIT_FAILURE); - } -+ - sdp->device_fd = open(sdp->device_name, - (test ? O_RDONLY : O_RDWR) | O_CLOEXEC); - if (sdp->device_fd < 0){ -diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c -index 58fb046..2646829 100644 ---- a/gfs2/mkfs/main_jadd.c -+++ b/gfs2/mkfs/main_jadd.c -@@ -491,6 +491,7 @@ void main_jadd(int argc, char *argv[]) - { - struct gfs2_sbd sbd, *sdp = &sbd; - unsigned int total; -+ int ro_mnt = 0; - - memset(sdp, 0, sizeof(struct gfs2_sbd)); - sdp->jsize = GFS2_DEFAULT_JSIZE; -@@ -506,7 +507,7 @@ void main_jadd(int argc, char *argv[]) - exit(EXIT_FAILURE); - } - -- if (check_for_gfs2(sdp)) { -+ if (!is_pathname_mounted(sdp->path_name, sdp->device_name, &ro_mnt)) { - perror(sdp->path_name); - exit(EXIT_FAILURE); - } diff --git a/SPECS/gfs2-utils.spec b/SPECS/gfs2-utils.spec index 4799851..94fe6ee 100644 --- a/SPECS/gfs2-utils.spec +++ b/SPECS/gfs2-utils.spec @@ -12,7 +12,7 @@ Name: gfs2-utils Version: 3.1.6 -Release: 8%{?dist} +Release: 13%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Kernel Summary: Utilities for managing the global file system (GFS2) @@ -39,24 +39,46 @@ URL: https://fedorahosted.org/cluster/wiki/HomePage # Source0: https://fedorahosted.org/released/gfs2-utils/gfs2-utils-%{version}.tar.gz Patch0: bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption.patch -Patch1: bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string.patch +Patch1: bz991204-1-gfs2_grow_Don_t_try_to_open_an_empty_string.patch Patch2: bz1000066-gfs2_utils_tests_Switch_to_autotest.patch Patch3: bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch Patch4: bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch Patch5: bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted.patch Patch6: bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX.patch +Patch7: bz1028388-1-libgfs2_Add_sd_heightsize_bounds_checking_in_read_sb.patch +Patch8: bz1028388-2-fsck_gfs2_Fix_block_size_validation.patch +Patch9: bz1028388-3-gfs2l_Build_with_D_FILE_OFFSET_BITS_64.patch +Patch10: bz991204-2-libgfs2_Add_lgfs2_open_mnt_functions.patch +Patch11: bz991204-3-Switch_is_pathname_mounted_callers_to_lgfs2_open_mnt.patch +Patch12: bz991204-4-libgfs2_Remove_is_pathname_mounted.patch +Patch13: bz1059443-1-gfs2_edit_Convert_fssize_to_bytes_before_reporting_fs_size.patch +Patch14: bz1059443-2-mkfs_gfs2_tests_Enable_debug_output.patch +Patch15: bz1063842-1-libgfs2_Superblock_building_and_writing_improvements.patch +Patch16: bz1063842-2-gfs2_utils_Ensure_sb_uuid_uses_are_guarded.patch +Patch17: bz1063842-3-libgfs2_Add_support_for_new_leaf_hint_fields.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %prep %setup -q -n gfs2-utils %patch0 -p1 -b .bz990683-fsck_gfs2_Add_ability_to_detect_journal_inode_indirect_block_corruption -%patch1 -p1 -b .bz991204-gfs2_grow_Don_t_try_to_open_an_empty_string +%patch1 -p1 -b .bz991204-1-gfs2_grow_Don_t_try_to_open_an_empty_string %patch2 -p1 -b .bz1000066-gfs2_utils_tests_Switch_to_autotest.patch %patch3 -p1 -b .bz1001583-1-fsck_gfs2_Allocate_enough_space_for_the_block_map.patch %patch4 -p1 -b .bz1001583-2-libgfs2_Move_the_BLOCKMAP_macros_into_fsck_gfs2.patch %patch5 -p1 -b .bz996236-gfs2_tool_catch_interrupts_while_the_metafs_is_mounted %patch6 -p1 -b .bz1003059-fsck_gfs2_Check_and_repair_per_node_contents_such_as_quota_changeX +%patch7 -p1 -b .bz1028388-1-libgfs2_Add_sd_heightsize_bounds_checking_in_read_sb +%patch8 -p1 -b .bz1028388-2-fsck_gfs2_Fix_block_size_validation +%patch9 -p1 -b .bz1028388-3-gfs2l_Build_with_D_FILE_OFFSET_BITS_64 +%patch10 -p1 -b .bz991204-2-libgfs2_Add_lgfs2_open_mnt_functions +%patch11 -p1 -b .bz991204-3-Switch_is_pathname_mounted_callers_to_lgfs2_open_mnt +%patch12 -p1 -b .bz991204-4-libgfs2_Remove_is_pathname_mounted +%patch13 -p1 -b .bz1059443-1-gfs2_edit_Convert_fssize_to_bytes_before_reporting_fs_size +%patch14 -p1 -b .bz1059443-2-mkfs_gfs2_tests_Enable_debug_output +%patch15 -p1 -b .bz1063842-1-libgfs2_Superblock_building_and_writing_improvements +%patch16 -p1 -b .bz1063842-2-gfs2_utils_Ensure_sb_uuid_uses_are_guarded +%patch17 -p1 -b .bz1063842-3-libgfs2_Add_support_for_new_leaf_hint_fields %build ./autogen.sh @@ -103,6 +125,31 @@ file systems. %{_mandir}/man5/* %changelog +* Fri Mar 07 2014 Andrew Price - 3.1.6-13 +- gfs2_edit: Convert fssize to bytes before reporting fs size +- mkfs.gfs2 tests: Enable debug output + Resolves: rhbz#1059443 +- libgfs2: Superblock building and writing improvements +- gfs2-utils: Ensure sb_uuid uses are guarded +- libgfs2: Add support for new leaf hint fields + Resolves: rhbz#1063842 + +* Fri Jan 24 2014 Daniel Mach - 3.1.6-12 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 3.1.6-11 +- Mass rebuild 2013-12-27 + +* Mon Nov 18 2013 Andrew Price - 3.1.6-10 +- libgfs2: Add lgfs2_open_mnt* functions +- Switch is_pathname_mounted callers to lgfs2_open_mnt* +- libgfs2: Remove is_pathname_mounted + Resolves: rhbz#991204 + +* Wed Nov 13 2013 Andrew Price - 3.1.6-9 +- libgfs2: Add sd_heightsize bounds checking in read_sb (3 patches) + Resolves: rhbz#1028388 + * Tue Sep 17 2013 Andrew Price - 3.1.6-8 - Don't use README.* for docs (it can pick up some patch files) Related: rhbz#1000066