diff --git a/0004-gfs2_jadd-Handle-out-of-space-issues.patch b/0004-gfs2_jadd-Handle-out-of-space-issues.patch new file mode 100644 index 0000000000000000000000000000000000000000..29fb44122f0e82e3ee8e9e34a5edfb4685485507 --- /dev/null +++ b/0004-gfs2_jadd-Handle-out-of-space-issues.patch @@ -0,0 +1,116 @@ +From deb6206755c515086a91faa6b728b076f5b4dc30 Mon Sep 17 00:00:00 2001 +From: Abhi Das +Date: Mon, 11 May 2020 09:22:31 -0500 +Subject: [PATCH] gfs2_jadd: Handle out-of-space issues + +If gfs2_jadd runs out of disk space while adding journals, it does +not exit gracefully. It partially does its job and bails out when +it hits -ENOSPC. This leaves the metafs mounted and most likely a +corrupted filesystem that even fsck.gfs2 can't fix. + +This patch adds a pre-check that ensures that the journals requested +will fit in the available space before proceeding. Note that this is +not foolproof because gfs2_jadd operates on a mounted filesystem. +While it is required that the filesystem be idle (and mounted on only +one node) while gfs2_jadd is being run, there is nothing stopping a +user from having some I/O process competing with gfs2_jadd for disk +blocks and consequently crashing it. + +Signed-off-by: Abhi Das +--- + gfs2/mkfs/main_jadd.c | 47 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 44 insertions(+), 3 deletions(-) + +diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c +index efe91e30..c5424803 100644 +--- a/gfs2/mkfs/main_jadd.c ++++ b/gfs2/mkfs/main_jadd.c +@@ -396,6 +396,8 @@ static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) + exit(EXIT_FAILURE); + } + sdp->bsize = statbuf.f_bsize; ++ sdp->blks_total = statbuf.f_blocks; ++ sdp->blks_alloced = sdp->blks_total - statbuf.f_bfree; + } + + static void find_current_journals(struct jadd_opts *opts) +@@ -527,13 +529,43 @@ static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) + } + } + ++static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts) ++{ ++ /* Compute how much space we'll need for the new journals ++ * Number of blocks needed per added journal: ++ * 1 block for the ir inode ++ * 1 block for the sc inode ++ * for sizes of the qc and journal inodes, use lgfs2_space_for_data() ++ * to calculate. ++ */ ++ uint64_t blks_per_j, total_blks; ++ ++ blks_per_j = 1 + 1 + ++ lgfs2_space_for_data(sdp, sdp->bsize, sdp->qcsize << 20) + ++ lgfs2_space_for_data(sdp, sdp->bsize, sdp->jsize << 20); ++ total_blks = opts->journals * blks_per_j; ++ ++ if (total_blks > (sdp->blks_total - sdp->blks_alloced)) { ++ printf( _("\nInsufficient space on the device to add %u %uMB " ++ "journals (%uMB QC size)\n\n"), ++ opts->journals, sdp->jsize, sdp->qcsize); ++ printf( _("Required space : %*lu blks (%lu blks per " ++ "journal)\n"), 10, total_blks, blks_per_j); ++ printf( _("Available space : %*lu blks\n\n"), 10, ++ sdp->blks_total - sdp->blks_alloced); ++ errno = ENOSPC; ++ return 1; ++ } ++ return 0; ++} ++ + int main(int argc, char *argv[]) + { + struct jadd_opts opts = {0}; + struct gfs2_sbd sbd, *sdp = &sbd; + struct metafs mfs = {0}; + struct mntent *mnt; +- unsigned int total; ++ unsigned int total, ret = 0; + + setlocale(LC_ALL, ""); + textdomain("gfs2-utils"); +@@ -574,6 +606,12 @@ int main(int argc, char *argv[]) + } + find_current_journals(&opts); + ++ ret = check_fit(sdp, &opts); ++ if (ret) { ++ perror(_("Failed to add journals")); ++ goto out; ++ } ++ + total = opts.orig_journals + opts.journals; + for (opts.journals = opts.orig_journals; + opts.journals < total; +@@ -588,13 +626,16 @@ int main(int argc, char *argv[]) + add_j(sdp, &opts); + } + ++out: + free(opts.new_inode); + free(opts.per_node); + free(opts.jindex); + close(sdp->path_fd); + cleanup_metafs(&mfs); + sync(); +- print_results(&opts); + +- return 0; ++ if (!ret) ++ print_results(&opts); ++ ++ return ret; + } +-- +2.33.0 + diff --git a/gfs2-utils.spec b/gfs2-utils.spec index 2dbe388d0e38c8e5c3a652573851b469235bcd8c..4c3349e855e771595ab19f4e602163afc936ff8a 100644 --- a/gfs2-utils.spec +++ b/gfs2-utils.spec @@ -1,6 +1,6 @@ Name: gfs2-utils Version: 3.2.0 -Release: 8 +Release: 9 Summary: Global Filesystem Utilities License: GPLv2+ and LGPLv2+ @@ -10,6 +10,7 @@ Source0: https://releases.pagure.org/gfs2-utils/gfs2-utils-%{version}.tar Patch0001: 0001-libgfs2-Fix-pointer-cast-byte-order-issue.patch Patch0002: 0002-libgfs2-Fix-gfs-2-_log_header-metadata-description.patch Patch0003: 0003-fsck.gfs2-Fix-segfault-in-build_and_check_metalist.patch +Patch0004: 0004-gfs2_jadd-Handle-out-of-space-issues.patch BuildRequires: ncurses-devel kernel-headers automake libtool zlib-devel gettext-devel BuildRequires: bison flex libblkid-devel libuuid-devel check-devel @@ -55,6 +56,9 @@ make -C gfs2 install DESTDIR=%{buildroot} %exclude %{_mandir}/man8/gfs2_lockcapture.8.gz %changelog +* Thu Nov 09 2023 liyuanyuan - 3.2.0-9 +- gfs2_jadd: Handle out-of-space issues + * Thu Nov 02 2023 liyuanyuan - 3.2.0-8 - fsck.gfs2: Fix segfault in build_and_check_metalist