diff --git a/SOURCES/bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool.patch b/SOURCES/bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool.patch new file mode 100644 index 0000000..a3c77c1 --- /dev/null +++ b/SOURCES/bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool.patch @@ -0,0 +1,31 @@ +commit 6a5d984b2d5deb989faae2ce567e886b400f257d +Author: Andrew Price +Date: Tue Apr 7 15:25:06 2020 +0100 + + gfs2.5: Update some mentions of gfs2_tool + + Resolves: rhbz#1818983 + Signed-off-by: Andrew Price + +diff --git a/gfs2/man/gfs2.5 b/gfs2/man/gfs2.5 +index 436abc09..8f67ce23 100644 +--- a/gfs2/man/gfs2.5 ++++ b/gfs2/man/gfs2.5 +@@ -48,7 +48,7 @@ currently these are \fIlock_nolock\fR and \fIlock_dlm\fR. + + The default lock protocol name is written to disk initially when creating the + filesystem with \fBmkfs.gfs2\fP(8), -p option. It can be changed on-disk by +-using the \fBgfs2_tool\fP(8) utility's \fBsb proto\fP command. ++using the \fBtunegfs2\fP(8) command. + + The \fBlockproto\fP mount option should be used only under special + circumstances in which you want to temporarily use a different lock protocol +@@ -70,7 +70,7 @@ The format of \fILockTableName\fR is lock-module-specific. For + + The default cluster/filesystem name is written to disk initially when creating + the filesystem with \fBmkfs.gfs2\fP(8), -t option. It can be changed on-disk +-by using the \fBgfs2_tool\fP(8) utility's \fBsb table\fP command. ++by using the \fBtunegfs2\fP(8) command. + + The \fBlocktable\fP mount option should be used only under special + circumstances in which you want to mount the filesystem in a different cluster, diff --git a/SOURCES/bz1833141-1-gfs2_jadd_Handle_out_of_space_issues.patch b/SOURCES/bz1833141-1-gfs2_jadd_Handle_out_of_space_issues.patch new file mode 100644 index 0000000..55372b0 --- /dev/null +++ b/SOURCES/bz1833141-1-gfs2_jadd_Handle_out_of_space_issues.patch @@ -0,0 +1,113 @@ +commit d033351753e1c45e6be74342d05de0a2501d5211 +Author: Abhi Das +Date: Mon May 11 09:22:31 2020 -0500 + + 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. + + Resolves: rhbz#1833141 + + Signed-off-by: Abhi Das + +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; + } diff --git a/SOURCES/bz1833141-2-gfs2_jadd_error_handling_overhaul.patch b/SOURCES/bz1833141-2-gfs2_jadd_error_handling_overhaul.patch new file mode 100644 index 0000000..3d3d667 --- /dev/null +++ b/SOURCES/bz1833141-2-gfs2_jadd_error_handling_overhaul.patch @@ -0,0 +1,608 @@ +commit 206b040657b5125c2f2efe35dddcb7463fb49788 +Author: Abhi Das +Date: Mon May 11 14:41:06 2020 -0500 + + gfs2_jadd: error handling overhaul + + Handle error conditions better and fail gracefully. + + Resolves: rhbz#1833141 + + Signed-off-by: Abhi Das + +diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c +index c5424803..ea89c96b 100644 +--- a/gfs2/mkfs/main_jadd.c ++++ b/gfs2/mkfs/main_jadd.c +@@ -42,15 +42,13 @@ struct jadd_opts { + + #define JA_FL_SET 0 + #define JA_FL_CLEAR 1 +-static void set_flags(int fd, int op, uint32_t flags) ++static int set_flags(int fd, int op, uint32_t flags) + { +- int err; + uint32_t val; + +- err = ioctl(fd, FS_IOC_GETFLAGS, &val); +- if (err) { ++ if (ioctl(fd, FS_IOC_GETFLAGS, &val)) { + perror("GETFLAGS"); +- exit(EXIT_FAILURE); ++ return -1; + } + + if (op == JA_FL_SET) +@@ -58,11 +56,11 @@ static void set_flags(int fd, int op, uint32_t flags) + else if (op == JA_FL_CLEAR) + val &= ~flags; + +- err = ioctl(fd, FS_IOC_SETFLAGS, &val); +- if (err) { ++ if (ioctl(fd, FS_IOC_SETFLAGS, &val)) { + perror("SETFLAGS"); +- exit(EXIT_FAILURE); ++ return -1; + } ++ return 0; + } + + static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name) +@@ -243,188 +241,214 @@ static void print_results(struct jadd_opts *opts) + static int create_new_inode(struct jadd_opts *opts, uint64_t *addr) + { + char *name = opts->new_inode; +- int fd; +- int error; ++ int fd, error = 0; + + for (;;) { + fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600); + if (fd >= 0) + break; + if (errno == EEXIST) { +- error = unlink(name); +- if (error){ ++ if (unlink(name)) { + perror("unlink"); +- exit(EXIT_FAILURE); ++ return -1; + } +- } else{ +- perror("create"); +- exit(EXIT_FAILURE); ++ continue; + } ++ perror("create"); ++ return -1; + } ++ + if (addr != NULL) { + struct stat st; + +- fstat(fd, &st); ++ if ((error = fstat(fd, &st))) { ++ perror("fstat"); ++ return close(fd); ++ } + *addr = st.st_ino; + } + + return fd; + } + +-static void add_ir(struct jadd_opts *opts) ++static int add_ir(struct jadd_opts *opts) + { +- int fd; ++ int fd, error = 0; + char new_name[256]; +- int error; ++ struct gfs2_inum_range ir; + +- fd = create_new_inode(opts, NULL); ++ if ((fd = create_new_inode(opts, NULL)) < 0) ++ return fd; + +- { +- struct gfs2_inum_range ir; ++ if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL))) ++ goto close_fd; + +- set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); +- memset(&ir, 0, sizeof(struct gfs2_inum_range)); +- if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != +- sizeof(struct gfs2_inum_range)) { +- perror("add_ir"); +- exit(EXIT_FAILURE); +- } ++ memset(&ir, 0, sizeof(struct gfs2_inum_range)); ++ if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) != ++ sizeof(struct gfs2_inum_range)) { ++ perror("add_ir write"); ++ error = -1; ++ goto close_fd; ++ } ++ ++ if ((error = fsync(fd))) { ++ perror("add_ir fsync"); ++ goto close_fd; + } + +- close(fd); + + sprintf(new_name, "inum_range%u", opts->journals); + error = rename2system(opts, opts->per_node, new_name); +- if (error < 0 && errno != EEXIST){ ++ if (error < 0 && errno != EEXIST) { + perror("add_ir rename2system"); +- exit(EXIT_FAILURE); ++ goto close_fd; + } ++close_fd: ++ return close(fd) || error; + } + +-static void add_sc(struct jadd_opts *opts) ++static int add_sc(struct jadd_opts *opts) + { +- int fd; ++ int fd, error = 0; + char new_name[256]; +- int error; ++ struct gfs2_statfs_change sc; + +- fd = create_new_inode(opts, NULL); ++ if ((fd = create_new_inode(opts, NULL)) < 0) ++ return fd; + +- { +- struct gfs2_statfs_change sc; +- set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL); ++ if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL))) ++ goto close_fd; + +- memset(&sc, 0, sizeof(struct gfs2_statfs_change)); +- if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != +- sizeof(struct gfs2_statfs_change)) { +- perror("add_sc"); +- exit(EXIT_FAILURE); +- } ++ memset(&sc, 0, sizeof(struct gfs2_statfs_change)); ++ if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) != ++ sizeof(struct gfs2_statfs_change)) { ++ perror("add_sc write"); ++ error = -1; ++ goto close_fd; + } + +- close(fd); ++ if ((error = fsync(fd))) { ++ perror("add_sc fsync"); ++ goto close_fd; ++ } + + sprintf(new_name, "statfs_change%u", opts->journals); + error = rename2system(opts, opts->per_node, new_name); + if (error < 0 && errno != EEXIST){ + perror("add_sc rename2system"); +- exit(EXIT_FAILURE); ++ goto close_fd; + } ++close_fd: ++ return close(fd) || error; + } + +-static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) ++static int add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts) + { +- int fd; +- char new_name[256]; +- int error; +- +- fd = create_new_inode(opts, NULL); +- +- { +- char buf[sdp->bsize]; +- unsigned int blocks = +- sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); +- unsigned int x; +- struct gfs2_meta_header mh; +- +- set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); +- memset(buf, 0, sdp->bsize); +- +- for (x=0; xbsize) != sdp->bsize) { +- perror("add_qc"); +- exit(EXIT_FAILURE); +- } ++ int fd, error = 0; ++ char new_name[256], buf[sdp->bsize]; ++ unsigned int blocks = ++ sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift); ++ unsigned int x; ++ struct gfs2_meta_header mh; ++ ++ if ((fd = create_new_inode(opts, NULL)) < 0) ++ return fd; ++ ++ if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL))) ++ goto close_fd; ++ ++ memset(buf, 0, sdp->bsize); ++ for (x=0; xbsize) != sdp->bsize) { ++ perror("add_qc write"); ++ error = -1; ++ goto close_fd; + } ++ } + +- lseek(fd, 0, SEEK_SET); +- +- memset(&mh, 0, sizeof(struct gfs2_meta_header)); +- mh.mh_magic = GFS2_MAGIC; +- mh.mh_type = GFS2_METATYPE_QC; +- mh.mh_format = GFS2_FORMAT_QC; +- gfs2_meta_header_out(&mh, buf); ++ if ((error = lseek(fd, 0, SEEK_SET)) < 0) { ++ perror("add_qc lseek"); ++ goto close_fd; ++ } + +- for (x=0; xbsize) != sdp->bsize) { +- perror("add_qc"); +- exit(EXIT_FAILURE); +- } ++ memset(&mh, 0, sizeof(struct gfs2_meta_header)); ++ mh.mh_magic = GFS2_MAGIC; ++ mh.mh_type = GFS2_METATYPE_QC; ++ mh.mh_format = GFS2_FORMAT_QC; ++ gfs2_meta_header_out(&mh, buf); ++ ++ for (x=0; xbsize) != sdp->bsize) { ++ perror("add_qc write"); ++ error = 1; ++ goto close_fd; + } +- +- error = fsync(fd); +- if (error){ ++ if ((error = fsync(fd))) { + perror("add_qc fsync"); +- exit(EXIT_FAILURE); ++ goto close_fd; + } + } + +- close(fd); +- + sprintf(new_name, "quota_change%u", opts->journals); + error = rename2system(opts, opts->per_node, new_name); + if (error < 0 && errno != EEXIST){ + perror("add_qc rename2system"); +- exit(EXIT_FAILURE); ++ goto close_fd; + } ++close_fd: ++ return close(fd) || error; + } + +-static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) ++static int gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts) + { + struct statfs statbuf; ++ + if (statfs(opts->path, &statbuf) < 0) { + perror(opts->path); +- exit(EXIT_FAILURE); ++ return -1; + } ++ + sdp->bsize = statbuf.f_bsize; + sdp->blks_total = statbuf.f_blocks; + sdp->blks_alloced = sdp->blks_total - statbuf.f_bfree; ++ ++ return 0; + } + +-static void find_current_journals(struct jadd_opts *opts) ++static int find_current_journals(struct jadd_opts *opts) + { + struct dirent *dp; + DIR *dirp; + unsigned existing_journals = 0; ++ int ret = 0; + + dirp = opendir(opts->jindex); + if (!dirp) { + perror("jindex"); +- exit(EXIT_FAILURE); ++ ret = -1; ++ goto out; + } + while (dirp) { + if ((dp = readdir(dirp)) != NULL) { + if (strncmp(dp->d_name, "journal", 7) == 0) + existing_journals++; + } else +- goto close; ++ goto close_fd; + } +-close: +- closedir(dirp); ++close_fd: ++ if ((ret = closedir(dirp))) ++ goto out; ++ + if (existing_journals == 0) { +- die( _("No journals found. Did you run mkfs.gfs2 correctly?\n")); ++ errno = EINVAL; ++ perror("No journals found. Did you run mkfs.gfs2 correctly?\n"); ++ ret = -1; ++ goto out; + } + + opts->orig_journals = existing_journals; ++out: ++ return ret; + } + + #ifdef GFS2_HAS_LH_V2 +@@ -450,83 +474,88 @@ static uint64_t find_block_address(int fd, off_t offset, unsigned bsize) + } + #endif + +-static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) ++static int add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts) + { +- int fd; +- char new_name[256]; +- int error; +- uint64_t addr; +- +- fd = create_new_inode(opts, &addr); +- +- { +- char buf[sdp->bsize]; +- unsigned int blocks = +- sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); +- unsigned int x; +- struct gfs2_log_header lh; +- uint64_t seq = RANDOM(blocks); +- off_t off = 0; +- +- set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL); +- memset(buf, 0, sdp->bsize); +- for (x=0; xbsize) != sdp->bsize) { +- perror("add_j"); +- exit(EXIT_FAILURE); +- } ++ int fd, error = 0; ++ char new_name[256], buf[sdp->bsize]; ++ unsigned int x, blocks = ++ sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift); ++ struct gfs2_log_header lh; ++ uint64_t seq = RANDOM(blocks), addr; ++ off_t off = 0; ++ ++ if ((fd = create_new_inode(opts, &addr)) < 0) ++ return fd; ++ ++ if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL))) ++ goto close_fd; ++ ++ memset(buf, 0, sdp->bsize); ++ for (x=0; xbsize) != sdp->bsize) { ++ perror("add_j write"); ++ error = -1; ++ goto close_fd; + } ++ } + +- lseek(fd, 0, SEEK_SET); ++ if ((error = lseek(fd, 0, SEEK_SET)) < 0) { ++ perror("add_j lseek"); ++ goto close_fd; ++ } + +- memset(&lh, 0, sizeof(struct gfs2_log_header)); +- lh.lh_header.mh_magic = GFS2_MAGIC; +- lh.lh_header.mh_type = GFS2_METATYPE_LH; +- lh.lh_header.mh_format = GFS2_FORMAT_LH; +- lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; ++ memset(&lh, 0, sizeof(struct gfs2_log_header)); ++ lh.lh_header.mh_magic = GFS2_MAGIC; ++ lh.lh_header.mh_type = GFS2_METATYPE_LH; ++ lh.lh_header.mh_format = GFS2_FORMAT_LH; ++ lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT; + #ifdef GFS2_HAS_LH_V2 +- lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE; +- lh.lh_jinode = addr; ++ lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE; ++ lh.lh_jinode = addr; + #endif +- for (x=0; xlh_hash = cpu_to_be32(hash); ++ for (x=0; xlh_addr = cpu_to_be64( +- find_block_address(fd, off, sdp->bsize)); +- hash = lgfs2_log_header_crc(buf, sdp->bsize); +- ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); ++ uint64_t blk_addr = 0; + #endif +- if (write(fd, buf, sdp->bsize) != sdp->bsize) { +- perror("add_j"); +- exit(EXIT_FAILURE); +- } +- +- if (++seq == blocks) +- seq = 0; +- off += sdp->bsize; ++ lh.lh_sequence = seq; ++ lh.lh_blkno = x; ++ gfs2_log_header_out(&lh, buf); ++ hash = lgfs2_log_header_hash(buf); ++ ((struct gfs2_log_header *)buf)->lh_hash = cpu_to_be32(hash); ++#ifdef GFS2_HAS_LH_V2 ++ if (!(blk_addr = find_block_address(fd, off, sdp->bsize))) { ++ error = -1; ++ goto close_fd; ++ } ++ ((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64(blk_addr); ++ hash = lgfs2_log_header_crc(buf, sdp->bsize); ++ ((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash); ++#endif ++ if (write(fd, buf, sdp->bsize) != sdp->bsize) { ++ perror("add_j write"); ++ error = -1; ++ goto close_fd; + } + +- error = fsync(fd); +- if (error){ ++ if (++seq == blocks) ++ seq = 0; ++ off += sdp->bsize; ++ ++ if ((error = fsync(fd))) { + perror("add_j fsync"); +- exit(EXIT_FAILURE); ++ goto close_fd; + } + } + +- close(fd); +- + sprintf(new_name, "journal%u", opts->journals); + error = rename2system(opts, opts->jindex, new_name); + if (error < 0 && errno != EEXIST){ + perror("add_j rename2system"); +- exit(EXIT_FAILURE); ++ goto close_fd; + } ++close_fd: ++ return close(fd) || error; + } + + static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts) +@@ -554,7 +583,7 @@ static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts) + printf( _("Available space : %*lu blks\n\n"), 10, + sdp->blks_total - sdp->blks_alloced); + errno = ENOSPC; +- return 1; ++ return -1; + } + return 0; + } +@@ -581,35 +610,42 @@ int main(int argc, char *argv[]) + + sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt); + if (sbd.path_fd < 0) { +- fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, strerror(errno)); +- exit(EXIT_FAILURE); ++ fprintf(stderr, "Error looking up mount '%s': %s\n", ++ opts.path, strerror(errno)); ++ ret = -1; ++ goto out; + } + if (mnt == NULL) { +- fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), opts.path); +- exit(EXIT_FAILURE); ++ fprintf(stderr, "%s: not a mounted gfs2 file system\n", opts.path); ++ ret = -1; ++ goto close_sb; + } +- gather_info(sdp, &opts); ++ ++ if ((ret = gather_info(sdp, &opts))) ++ goto close_sb; ++ + mfs.context = copy_context_opt(mnt); +- if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) { ++ if ((ret = mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug))) { + perror("GFS2 metafs"); +- exit(EXIT_FAILURE); ++ goto close_sb; + } + +- if (build_paths(mfs.path, &opts)) { ++ if ((ret = build_paths(mfs.path, &opts))) { + perror(_("Failed to build paths")); +- exit(EXIT_FAILURE); ++ goto umount_meta; + } + +- if (compute_constants(sdp)) { ++ if ((ret = compute_constants(sdp))) { + perror(_("Failed to compute file system constants")); +- exit(EXIT_FAILURE); ++ goto free_paths; + } +- find_current_journals(&opts); + +- ret = check_fit(sdp, &opts); +- if (ret) { ++ if ((ret = find_current_journals(&opts))) ++ goto free_paths; ++ ++ if ((ret = check_fit(sdp, &opts))) { + perror(_("Failed to add journals")); +- goto out; ++ goto free_paths; + } + + total = opts.orig_journals + opts.journals; +@@ -617,23 +653,29 @@ int main(int argc, char *argv[]) + opts.journals < total; + opts.journals++) { + if (metafs_interrupted) { +- cleanup_metafs(&mfs); +- exit(130); ++ errno = 130; ++ goto free_paths; + } +- add_ir(&opts); +- add_sc(&opts); +- add_qc(sdp, &opts); +- add_j(sdp, &opts); ++ if ((ret = add_ir(&opts))) ++ goto free_paths; ++ if ((ret = add_sc(&opts))) ++ goto free_paths; ++ if ((ret = add_qc(sdp, &opts))) ++ goto free_paths; ++ if ((ret = add_j(sdp, &opts))) ++ goto free_paths; + } + +-out: ++free_paths: + free(opts.new_inode); + free(opts.per_node); + free(opts.jindex); +- close(sdp->path_fd); +- cleanup_metafs(&mfs); ++umount_meta: + sync(); +- ++ cleanup_metafs(&mfs); ++close_sb: ++ close(sdp->path_fd); ++out: + if (!ret) + print_results(&opts); + diff --git a/SOURCES/bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size.patch b/SOURCES/bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size.patch new file mode 100644 index 0000000..f4884ff --- /dev/null +++ b/SOURCES/bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size.patch @@ -0,0 +1,41 @@ +commit b33f8871a821b7f0461dec89f0066a9cb6aa1c71 +Author: Andrew Price +Date: Wed May 27 12:31:58 2020 +0100 + + mkfs.gfs2: Don't use i/o limits hints <4K for block size + + Some devices report an optimal_io_size less than 4K. Currently mkfs.gfs2 + uses the non-zero value to choose the block size, which is almost + certainly a bad choice when it's less than 4K. Update choose_blocksize() + to avoid using device topology hints for the block size choice when + they're less than the default block size (4K). Test case included. + + Resolves: rhbz#1839219 + Signed-off-by: Andrew Price + +diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c +index 846b341f..412d4701 100644 +--- a/gfs2/mkfs/main_mkfs.c ++++ b/gfs2/mkfs/main_mkfs.c +@@ -505,7 +505,7 @@ static unsigned choose_blocksize(struct mkfs_opts *opts) + } + if (!opts->got_bsize && got_topol) { + if (dev->optimal_io_size <= getpagesize() && +- dev->optimal_io_size >= dev->minimum_io_size) ++ dev->optimal_io_size >= GFS2_DEFAULT_BSIZE) + bsize = dev->optimal_io_size; + else if (dev->physical_sector_size <= getpagesize() && + dev->physical_sector_size >= GFS2_DEFAULT_BSIZE) +diff --git a/tests/mkfs.at b/tests/mkfs.at +index 57785a0d..4c8b2249 100644 +--- a/tests/mkfs.at ++++ b/tests/mkfs.at +@@ -112,6 +112,8 @@ AT_CLEANUP + AT_SETUP([Device i/o limits handling]) + AT_KEYWORDS(mkfs.gfs2 mkfs) + AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:0:0:0:0 $GFS_TGT], 0, [ignore], [ignore]) ++AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=0:512:512:512:512 $GFS_TGT], 0, [ignore], [ignore]) ++AT_CHECK([gfs2_edit -p sb field sb_bsize $GFS_TGT | tr -d '\n' ], 0, [4096], [ignore]) + AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:0:33553920:512 $GFS_TGT], 0, [ignore], [ignore]) + AT_CHECK([$GFS_MKFS -p lock_nolock -o test_topology=7168:512:8192:33553920:512 $GFS_TGT], 0, [ignore], [Warning: device is not properly aligned. This may harm performance. + ]) diff --git a/SPECS/gfs2-utils.spec b/SPECS/gfs2-utils.spec index 274ce31..dbadd01 100644 --- a/SPECS/gfs2-utils.spec +++ b/SPECS/gfs2-utils.spec @@ -12,7 +12,7 @@ Name: gfs2-utils Version: 3.2.0 -Release: 7%{?dist} +Release: 9%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Kernel Summary: Utilities for managing the global file system (GFS2) @@ -39,6 +39,10 @@ Patch2: bz1659490-gfs2_utils_Wrong_hash_value_used_to_clean_journals.patch Patch3: bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group.patch Patch4: bz1757115-gfs2_5_General_updates_and_layout_improvements.patch Patch5: bz1693000-fsck_gfs2_8_Manpage_updates.patch +Patch6: bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size.patch +Patch7: bz1833141-1-gfs2_jadd_Handle_out_of_space_issues.patch +Patch8: bz1833141-2-gfs2_jadd_error_handling_overhaul.patch +Patch9: bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool.patch %prep %setup -q -n gfs2-utils-%{version} @@ -48,6 +52,10 @@ Patch5: bz1693000-fsck_gfs2_8_Manpage_updates.patch %patch3 -p1 -b .bz1698858-mkfs_gfs2_Improve_alignment_of_first_resource_group %patch4 -p1 -b .bz1757115-gfs2_5_General_updates_and_layout_improvements %patch5 -p1 -b .bz1693000-fsck_gfs2_8_Manpage_updates +%patch6 -p1 -b .bz1839219-mkfs_gfs2_Don_t_use_i_o_limits_hints_4K_for_block_size +%patch7 -p1 -b .bz1833141-1-gfs2_jadd_Handle_out_of_space_issues +%patch8 -p1 -b .bz1833141-2-gfs2_jadd_error_handling_overhaul +%patch9 -p1 -b .bz1818983-gfs2_5_Update_some_mentions_of_gfs2_tool %build ./autogen.sh @@ -87,6 +95,17 @@ modifying, and correcting inconsistencies in GFS2 file systems. %{_prefix}/lib/udev/rules.d/82-gfs2-withdraw.rules %changelog +* Tue Jun 09 2020 Andrew Price - 3.2.0-9 +- gfs2_jadd: Handle out-of-space issues +- gfs2_jadd: error handling overhaul + Resolves: rhbz#1833141 +- gfs2.5: Update some mentions of gfs2_tool + Resolves: rhbz#1818983 + +* Tue Jun 02 2020 Andrew Price - 3.2.0-8 +- mkfs.gfs2: Don't use i/o limits hints <4K for block size + Resolves: rhbz#1839219 + * Fri Oct 18 2019 Andrew Price - 3.2.0-7 - fsck.gfs2(8): Manpage updates Resolves: rhbz#1693000