Blame SOURCES/bz1833141-2-gfs2_jadd_error_handling_overhaul.patch

feb2d6
commit 206b040657b5125c2f2efe35dddcb7463fb49788
feb2d6
Author: Abhi Das <adas@redhat.com>
feb2d6
Date:   Mon May 11 14:41:06 2020 -0500
feb2d6
feb2d6
    gfs2_jadd: error handling overhaul
feb2d6
    
feb2d6
    Handle error conditions better and fail gracefully.
feb2d6
    
feb2d6
    Resolves: rhbz#1833141
feb2d6
    
feb2d6
    Signed-off-by: Abhi Das <adas@redhat.com>
feb2d6
feb2d6
diff --git a/gfs2/mkfs/main_jadd.c b/gfs2/mkfs/main_jadd.c
feb2d6
index c5424803..ea89c96b 100644
feb2d6
--- a/gfs2/mkfs/main_jadd.c
feb2d6
+++ b/gfs2/mkfs/main_jadd.c
feb2d6
@@ -42,15 +42,13 @@ struct jadd_opts {
feb2d6
 
feb2d6
 #define JA_FL_SET   0
feb2d6
 #define JA_FL_CLEAR 1
feb2d6
-static void set_flags(int fd, int op, uint32_t flags)
feb2d6
+static int set_flags(int fd, int op, uint32_t flags)
feb2d6
 {
feb2d6
-        int err;
feb2d6
 	uint32_t val;
feb2d6
 
feb2d6
-        err = ioctl(fd, FS_IOC_GETFLAGS, &val;;
feb2d6
-        if (err) {
feb2d6
+        if (ioctl(fd, FS_IOC_GETFLAGS, &val)) {
feb2d6
 		perror("GETFLAGS");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		return -1;
feb2d6
 	}
feb2d6
 
feb2d6
         if (op == JA_FL_SET)
feb2d6
@@ -58,11 +56,11 @@ static void set_flags(int fd, int op, uint32_t flags)
feb2d6
         else if (op == JA_FL_CLEAR)
feb2d6
                 val &= ~flags;
feb2d6
 
feb2d6
-        err = ioctl(fd, FS_IOC_SETFLAGS, &val;;
feb2d6
-        if (err) {
feb2d6
+        if (ioctl(fd, FS_IOC_SETFLAGS, &val)) {
feb2d6
 		perror("SETFLAGS");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		return -1;
feb2d6
 	}
feb2d6
+	return 0;
feb2d6
 }
feb2d6
 
feb2d6
 static int rename2system(struct jadd_opts *opts, const char *new_dir, const char *new_name)
feb2d6
@@ -243,188 +241,214 @@ static void print_results(struct jadd_opts *opts)
feb2d6
 static int create_new_inode(struct jadd_opts *opts, uint64_t *addr)
feb2d6
 {
feb2d6
 	char *name = opts->new_inode;
feb2d6
-	int fd;
feb2d6
-	int error;
feb2d6
+	int fd, error = 0;
feb2d6
 
feb2d6
 	for (;;) {
feb2d6
 		fd = open(name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC, 0600);
feb2d6
 		if (fd >= 0)
feb2d6
 			break;
feb2d6
 		if (errno == EEXIST) {
feb2d6
-			error = unlink(name);
feb2d6
-			if (error){
feb2d6
+			if (unlink(name)) {
feb2d6
 				perror("unlink");
feb2d6
-				exit(EXIT_FAILURE);
feb2d6
+				return -1;
feb2d6
 			}
feb2d6
-		} else{
feb2d6
-			perror("create");
feb2d6
-			exit(EXIT_FAILURE);
feb2d6
+			continue;
feb2d6
 		}
feb2d6
+		perror("create");
feb2d6
+		return -1;
feb2d6
 	}
feb2d6
+
feb2d6
 	if (addr != NULL) {
feb2d6
 		struct stat st;
feb2d6
 
feb2d6
-		fstat(fd, &st);
feb2d6
+		if ((error = fstat(fd, &st))) {
feb2d6
+			perror("fstat");
feb2d6
+			return close(fd);
feb2d6
+		}
feb2d6
 		*addr = st.st_ino;
feb2d6
 	}
feb2d6
 
feb2d6
 	return fd;
feb2d6
 }
feb2d6
 
feb2d6
-static void add_ir(struct jadd_opts *opts)
feb2d6
+static int add_ir(struct jadd_opts *opts)
feb2d6
 {
feb2d6
-	int fd;
feb2d6
+	int fd, error = 0;
feb2d6
 	char new_name[256];
feb2d6
-	int error;
feb2d6
+	struct gfs2_inum_range ir;
feb2d6
 
feb2d6
-	fd = create_new_inode(opts, NULL);
feb2d6
+	if ((fd = create_new_inode(opts, NULL)) < 0)
feb2d6
+		return fd;
feb2d6
 
feb2d6
-	{
feb2d6
-		struct gfs2_inum_range ir;
feb2d6
+	if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL)))
feb2d6
+		goto close_fd;
feb2d6
 
feb2d6
-		set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL);
feb2d6
-		memset(&ir, 0, sizeof(struct gfs2_inum_range));
feb2d6
-		if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) !=
feb2d6
-		    sizeof(struct gfs2_inum_range)) {
feb2d6
-			perror("add_ir");
feb2d6
-			exit(EXIT_FAILURE);
feb2d6
-		}
feb2d6
+	memset(&ir, 0, sizeof(struct gfs2_inum_range));
feb2d6
+	if (write(fd, (void*)&ir, sizeof(struct gfs2_inum_range)) !=
feb2d6
+	    sizeof(struct gfs2_inum_range)) {
feb2d6
+		perror("add_ir write");
feb2d6
+		error = -1;
feb2d6
+		goto close_fd;
feb2d6
+	}
feb2d6
+
feb2d6
+	if ((error = fsync(fd))) {
feb2d6
+		perror("add_ir fsync");
feb2d6
+		goto close_fd;
feb2d6
 	}
feb2d6
 
feb2d6
-	close(fd);
feb2d6
 
feb2d6
 	sprintf(new_name, "inum_range%u", opts->journals);
feb2d6
 	error = rename2system(opts, opts->per_node, new_name);
feb2d6
-	if (error < 0 && errno != EEXIST){
feb2d6
+	if (error < 0 && errno != EEXIST) {
feb2d6
 		perror("add_ir rename2system");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto close_fd;
feb2d6
 	}
feb2d6
+close_fd:
feb2d6
+	return close(fd) || error;
feb2d6
 }
feb2d6
 
feb2d6
-static void add_sc(struct jadd_opts *opts)
feb2d6
+static int add_sc(struct jadd_opts *opts)
feb2d6
 {
feb2d6
-	int fd;
feb2d6
+	int fd, error = 0;
feb2d6
 	char new_name[256];
feb2d6
-	int error;
feb2d6
+	struct gfs2_statfs_change sc;
feb2d6
 
feb2d6
-	fd = create_new_inode(opts, NULL);
feb2d6
+	if ((fd = create_new_inode(opts, NULL)) < 0)
feb2d6
+		return fd;
feb2d6
 
feb2d6
-	{
feb2d6
-		struct gfs2_statfs_change sc;
feb2d6
-		set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL);
feb2d6
+	if ((error = set_flags(fd, JA_FL_SET, FS_JOURNAL_DATA_FL)))
feb2d6
+		goto close_fd;
feb2d6
 
feb2d6
-		memset(&sc, 0, sizeof(struct gfs2_statfs_change));
feb2d6
-		if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) !=
feb2d6
-		    sizeof(struct gfs2_statfs_change)) {
feb2d6
-			perror("add_sc");
feb2d6
-			exit(EXIT_FAILURE);
feb2d6
-		}
feb2d6
+	memset(&sc, 0, sizeof(struct gfs2_statfs_change));
feb2d6
+	if (write(fd, (void*)&sc, sizeof(struct gfs2_statfs_change)) !=
feb2d6
+	    sizeof(struct gfs2_statfs_change)) {
feb2d6
+		perror("add_sc write");
feb2d6
+		error = -1;
feb2d6
+		goto close_fd;
feb2d6
 	}
feb2d6
 
feb2d6
-	close(fd);
feb2d6
+	if ((error = fsync(fd))) {
feb2d6
+		perror("add_sc fsync");
feb2d6
+		goto close_fd;
feb2d6
+	}
feb2d6
 
feb2d6
 	sprintf(new_name, "statfs_change%u", opts->journals);
feb2d6
 	error = rename2system(opts, opts->per_node, new_name);
feb2d6
 	if (error < 0 && errno != EEXIST){
feb2d6
 		perror("add_sc rename2system");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto close_fd;
feb2d6
 	}
feb2d6
+close_fd:
feb2d6
+	return close(fd) || error;
feb2d6
 }
feb2d6
 
feb2d6
-static void add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
+static int add_qc(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
 {
feb2d6
-	int fd;
feb2d6
-	char new_name[256];
feb2d6
-	int error;
feb2d6
-
feb2d6
-	fd = create_new_inode(opts, NULL);
feb2d6
-
feb2d6
-	{
feb2d6
-		char buf[sdp->bsize];
feb2d6
-		unsigned int blocks =
feb2d6
-			sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift);
feb2d6
-		unsigned int x;
feb2d6
-		struct gfs2_meta_header mh;
feb2d6
-
feb2d6
-		set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL);
feb2d6
-		memset(buf, 0, sdp->bsize);
feb2d6
-
feb2d6
-		for (x=0; x
feb2d6
-			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
-				perror("add_qc");
feb2d6
-				exit(EXIT_FAILURE);
feb2d6
-			}
feb2d6
+	int fd, error = 0;
feb2d6
+	char new_name[256], buf[sdp->bsize];
feb2d6
+	unsigned int blocks =
feb2d6
+		sdp->qcsize << (20 - sdp->sd_sb.sb_bsize_shift);
feb2d6
+	unsigned int x;
feb2d6
+	struct gfs2_meta_header mh;
feb2d6
+
feb2d6
+	if ((fd = create_new_inode(opts, NULL)) < 0)
feb2d6
+		return fd;
feb2d6
+
feb2d6
+	if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL)))
feb2d6
+		goto close_fd;
feb2d6
+
feb2d6
+	memset(buf, 0, sdp->bsize);
feb2d6
+	for (x=0; x
feb2d6
+		if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
+			perror("add_qc write");
feb2d6
+			error = -1;
feb2d6
+			goto close_fd;
feb2d6
 		}
feb2d6
+	}
feb2d6
 
feb2d6
-		lseek(fd, 0, SEEK_SET);
feb2d6
-
feb2d6
-		memset(&mh, 0, sizeof(struct gfs2_meta_header));
feb2d6
-		mh.mh_magic = GFS2_MAGIC;
feb2d6
-		mh.mh_type = GFS2_METATYPE_QC;
feb2d6
-		mh.mh_format = GFS2_FORMAT_QC;
feb2d6
-		gfs2_meta_header_out(&mh, buf);
feb2d6
+	if ((error = lseek(fd, 0, SEEK_SET)) < 0) {
feb2d6
+		perror("add_qc lseek");
feb2d6
+		goto close_fd;
feb2d6
+	}
feb2d6
 
feb2d6
-		for (x=0; x
feb2d6
-			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
-				perror("add_qc");
feb2d6
-				exit(EXIT_FAILURE);
feb2d6
-			}
feb2d6
+	memset(&mh, 0, sizeof(struct gfs2_meta_header));
feb2d6
+	mh.mh_magic = GFS2_MAGIC;
feb2d6
+	mh.mh_type = GFS2_METATYPE_QC;
feb2d6
+	mh.mh_format = GFS2_FORMAT_QC;
feb2d6
+	gfs2_meta_header_out(&mh, buf);
feb2d6
+
feb2d6
+	for (x=0; x
feb2d6
+		if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
+			perror("add_qc write");
feb2d6
+			error = 1;
feb2d6
+			goto close_fd;
feb2d6
 		}
feb2d6
-
feb2d6
-		error = fsync(fd);
feb2d6
-		if (error){
feb2d6
+		if ((error = fsync(fd))) {
feb2d6
 			perror("add_qc fsync");
feb2d6
-			exit(EXIT_FAILURE);
feb2d6
+			goto close_fd;
feb2d6
 		}
feb2d6
 	}
feb2d6
 
feb2d6
-	close(fd);
feb2d6
-
feb2d6
 	sprintf(new_name, "quota_change%u", opts->journals);
feb2d6
 	error = rename2system(opts, opts->per_node, new_name);
feb2d6
 	if (error < 0 && errno != EEXIST){
feb2d6
 		perror("add_qc rename2system");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto close_fd;
feb2d6
 	}
feb2d6
+close_fd:
feb2d6
+	return close(fd) || error;
feb2d6
 }
feb2d6
 
feb2d6
-static void gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
+static int gather_info(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
 {
feb2d6
 	struct statfs statbuf;
feb2d6
+
feb2d6
 	if (statfs(opts->path, &statbuf) < 0) {
feb2d6
 		perror(opts->path);
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		return -1;
feb2d6
 	}
feb2d6
+
feb2d6
 	sdp->bsize = statbuf.f_bsize;
feb2d6
 	sdp->blks_total = statbuf.f_blocks;
feb2d6
 	sdp->blks_alloced = sdp->blks_total - statbuf.f_bfree;
feb2d6
+
feb2d6
+	return 0;
feb2d6
 }
feb2d6
 
feb2d6
-static void find_current_journals(struct jadd_opts *opts)
feb2d6
+static int find_current_journals(struct jadd_opts *opts)
feb2d6
 {
feb2d6
 	struct dirent *dp;
feb2d6
 	DIR *dirp;
feb2d6
 	unsigned existing_journals = 0;
feb2d6
+	int ret = 0;
feb2d6
 
feb2d6
 	dirp = opendir(opts->jindex);
feb2d6
 	if (!dirp) {
feb2d6
 		perror("jindex");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		ret = -1;
feb2d6
+		goto out;
feb2d6
 	}
feb2d6
 	while (dirp) {
feb2d6
 		if ((dp = readdir(dirp)) != NULL) {
feb2d6
 			if (strncmp(dp->d_name, "journal", 7) == 0)
feb2d6
 				existing_journals++;
feb2d6
 		} else
feb2d6
-			goto close;
feb2d6
+			goto close_fd;
feb2d6
 	}
feb2d6
-close:
feb2d6
-	closedir(dirp);
feb2d6
+close_fd:
feb2d6
+	if ((ret = closedir(dirp)))
feb2d6
+		goto out;
feb2d6
+
feb2d6
 	if (existing_journals == 0) {
feb2d6
-		die( _("No journals found. Did you run mkfs.gfs2 correctly?\n"));
feb2d6
+		errno = EINVAL;
feb2d6
+		perror("No journals found. Did you run mkfs.gfs2 correctly?\n");
feb2d6
+		ret = -1;
feb2d6
+		goto out;
feb2d6
 	}
feb2d6
 
feb2d6
 	opts->orig_journals = existing_journals;
feb2d6
+out:
feb2d6
+	return ret;
feb2d6
 }
feb2d6
 
feb2d6
 #ifdef GFS2_HAS_LH_V2
feb2d6
@@ -450,83 +474,88 @@ static uint64_t find_block_address(int fd, off_t offset, unsigned bsize)
feb2d6
 }
feb2d6
 #endif
feb2d6
 
feb2d6
-static void add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
+static int add_j(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
 {
feb2d6
-	int fd;
feb2d6
-	char new_name[256];
feb2d6
-	int error;
feb2d6
-	uint64_t addr;
feb2d6
-
feb2d6
-	fd = create_new_inode(opts, &addr);
feb2d6
-
feb2d6
-	{
feb2d6
-		char buf[sdp->bsize];
feb2d6
-		unsigned int blocks =
feb2d6
-			sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift);
feb2d6
-		unsigned int x;
feb2d6
-		struct gfs2_log_header lh;
feb2d6
-		uint64_t seq = RANDOM(blocks);
feb2d6
-		off_t off = 0;
feb2d6
-
feb2d6
-		set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL);
feb2d6
-		memset(buf, 0, sdp->bsize);
feb2d6
-		for (x=0; x
feb2d6
-			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
-				perror("add_j");
feb2d6
-				exit(EXIT_FAILURE);
feb2d6
-			}
feb2d6
+	int fd, error = 0;
feb2d6
+	char new_name[256], buf[sdp->bsize];
feb2d6
+	unsigned int x, blocks =
feb2d6
+		sdp->jsize << (20 - sdp->sd_sb.sb_bsize_shift);
feb2d6
+	struct gfs2_log_header lh;
feb2d6
+	uint64_t seq = RANDOM(blocks), addr;
feb2d6
+	off_t off = 0;
feb2d6
+
feb2d6
+	if ((fd = create_new_inode(opts, &addr)) < 0)
feb2d6
+		return fd;
feb2d6
+
feb2d6
+	if ((error = set_flags(fd, JA_FL_CLEAR, FS_JOURNAL_DATA_FL)))
feb2d6
+		goto close_fd;
feb2d6
+
feb2d6
+	memset(buf, 0, sdp->bsize);
feb2d6
+	for (x=0; x
feb2d6
+		if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
+			perror("add_j write");
feb2d6
+			error = -1;
feb2d6
+			goto close_fd;
feb2d6
 		}
feb2d6
+	}
feb2d6
 
feb2d6
-		lseek(fd, 0, SEEK_SET);
feb2d6
+	if ((error = lseek(fd, 0, SEEK_SET)) < 0) {
feb2d6
+		perror("add_j lseek");
feb2d6
+		goto close_fd;
feb2d6
+	}
feb2d6
 
feb2d6
-		memset(&lh, 0, sizeof(struct gfs2_log_header));
feb2d6
-		lh.lh_header.mh_magic = GFS2_MAGIC;
feb2d6
-		lh.lh_header.mh_type = GFS2_METATYPE_LH;
feb2d6
-		lh.lh_header.mh_format = GFS2_FORMAT_LH;
feb2d6
-		lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT;
feb2d6
+	memset(&lh, 0, sizeof(struct gfs2_log_header));
feb2d6
+	lh.lh_header.mh_magic = GFS2_MAGIC;
feb2d6
+	lh.lh_header.mh_type = GFS2_METATYPE_LH;
feb2d6
+	lh.lh_header.mh_format = GFS2_FORMAT_LH;
feb2d6
+	lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT;
feb2d6
 #ifdef GFS2_HAS_LH_V2
feb2d6
-		lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE;
feb2d6
-		lh.lh_jinode = addr;
feb2d6
+	lh.lh_flags |= GFS2_LOG_HEAD_USERSPACE;
feb2d6
+	lh.lh_jinode = addr;
feb2d6
 #endif
feb2d6
-		for (x=0; x
feb2d6
-			uint32_t hash;
feb2d6
-
feb2d6
-			lh.lh_sequence = seq;
feb2d6
-			lh.lh_blkno = x;
feb2d6
-			gfs2_log_header_out(&lh, buf);
feb2d6
-			hash = lgfs2_log_header_hash(buf);
feb2d6
-			((struct gfs2_log_header *)buf)->lh_hash = cpu_to_be32(hash);
feb2d6
+	for (x=0; x
feb2d6
+		uint32_t hash;
feb2d6
 #ifdef GFS2_HAS_LH_V2
feb2d6
-			((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64(
feb2d6
-			                           find_block_address(fd, off, sdp->bsize));
feb2d6
-			hash = lgfs2_log_header_crc(buf, sdp->bsize);
feb2d6
-			((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash);
feb2d6
+		uint64_t blk_addr = 0;
feb2d6
 #endif
feb2d6
-			if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
-				perror("add_j");
feb2d6
-				exit(EXIT_FAILURE);
feb2d6
-			}
feb2d6
-
feb2d6
-			if (++seq == blocks)
feb2d6
-				seq = 0;
feb2d6
-			off += sdp->bsize;
feb2d6
+		lh.lh_sequence = seq;
feb2d6
+		lh.lh_blkno = x;
feb2d6
+		gfs2_log_header_out(&lh, buf);
feb2d6
+		hash = lgfs2_log_header_hash(buf);
feb2d6
+		((struct gfs2_log_header *)buf)->lh_hash = cpu_to_be32(hash);
feb2d6
+#ifdef GFS2_HAS_LH_V2
feb2d6
+		if (!(blk_addr = find_block_address(fd, off, sdp->bsize))) {
feb2d6
+			error = -1;
feb2d6
+			goto close_fd;
feb2d6
+		}
feb2d6
+		((struct gfs2_log_header *)buf)->lh_addr = cpu_to_be64(blk_addr);
feb2d6
+		hash = lgfs2_log_header_crc(buf, sdp->bsize);
feb2d6
+		((struct gfs2_log_header *)buf)->lh_crc = cpu_to_be32(hash);
feb2d6
+#endif
feb2d6
+		if (write(fd, buf, sdp->bsize) != sdp->bsize) {
feb2d6
+			perror("add_j write");
feb2d6
+			error = -1;
feb2d6
+			goto close_fd;
feb2d6
 		}
feb2d6
 
feb2d6
-		error = fsync(fd);
feb2d6
-		if (error){
feb2d6
+		if (++seq == blocks)
feb2d6
+			seq = 0;
feb2d6
+		off += sdp->bsize;
feb2d6
+
feb2d6
+		if ((error = fsync(fd))) {
feb2d6
 			perror("add_j fsync");
feb2d6
-			exit(EXIT_FAILURE);
feb2d6
+			goto close_fd;
feb2d6
 		}
feb2d6
 	}
feb2d6
 
feb2d6
-	close(fd);
feb2d6
-
feb2d6
 	sprintf(new_name, "journal%u", opts->journals);
feb2d6
 	error = rename2system(opts, opts->jindex, new_name);
feb2d6
 	if (error < 0 && errno != EEXIST){
feb2d6
 		perror("add_j rename2system");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto close_fd;
feb2d6
 	}
feb2d6
+close_fd:
feb2d6
+	return close(fd) || error;
feb2d6
 }
feb2d6
 
feb2d6
 static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
@@ -554,7 +583,7 @@ static int check_fit(struct gfs2_sbd *sdp, struct jadd_opts *opts)
feb2d6
 		printf( _("Available space : %*lu blks\n\n"), 10,
feb2d6
 			sdp->blks_total - sdp->blks_alloced);
feb2d6
 		errno = ENOSPC;
feb2d6
-		return 1;
feb2d6
+		return -1;
feb2d6
 	}
feb2d6
 	return 0;
feb2d6
 }
feb2d6
@@ -581,35 +610,42 @@ int main(int argc, char *argv[])
feb2d6
 
feb2d6
 	sbd.path_fd = lgfs2_open_mnt_dir(opts.path, O_RDONLY|O_CLOEXEC, &mnt;;
feb2d6
 	if (sbd.path_fd < 0) {
feb2d6
-		fprintf(stderr, _("Error looking up mount '%s': %s\n"), opts.path, strerror(errno));
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		fprintf(stderr, "Error looking up mount '%s': %s\n",
feb2d6
+			opts.path, strerror(errno));
feb2d6
+		ret = -1;
feb2d6
+		goto out;
feb2d6
 	}
feb2d6
 	if (mnt == NULL) {
feb2d6
-		fprintf(stderr, _("%s: not a mounted gfs2 file system\n"), opts.path);
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		fprintf(stderr, "%s: not a mounted gfs2 file system\n", opts.path);
feb2d6
+		ret = -1;
feb2d6
+		goto close_sb;
feb2d6
 	}
feb2d6
-	gather_info(sdp, &opts);
feb2d6
+
feb2d6
+	if ((ret = gather_info(sdp, &opts)))
feb2d6
+		goto close_sb;
feb2d6
+
feb2d6
 	mfs.context = copy_context_opt(mnt);
feb2d6
-	if (mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug)) {
feb2d6
+	if ((ret = mount_gfs2_meta(&mfs, mnt->mnt_dir, opts.debug))) {
feb2d6
 		perror("GFS2 metafs");
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto close_sb;
feb2d6
 	}
feb2d6
 
feb2d6
-	if (build_paths(mfs.path, &opts)) {
feb2d6
+	if ((ret = build_paths(mfs.path, &opts))) {
feb2d6
 		perror(_("Failed to build paths"));
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto umount_meta;
feb2d6
 	}
feb2d6
 
feb2d6
-	if (compute_constants(sdp)) {
feb2d6
+	if ((ret = compute_constants(sdp))) {
feb2d6
 		perror(_("Failed to compute file system constants"));
feb2d6
-		exit(EXIT_FAILURE);
feb2d6
+		goto free_paths;
feb2d6
 	}
feb2d6
-	find_current_journals(&opts);
feb2d6
 
feb2d6
-	ret = check_fit(sdp, &opts);
feb2d6
-	if (ret) {
feb2d6
+	if ((ret = find_current_journals(&opts)))
feb2d6
+		goto free_paths;
feb2d6
+
feb2d6
+	if ((ret = check_fit(sdp, &opts))) {
feb2d6
 		perror(_("Failed to add journals"));
feb2d6
-		goto out;
feb2d6
+		goto free_paths;
feb2d6
 	}
feb2d6
 
feb2d6
 	total = opts.orig_journals + opts.journals;
feb2d6
@@ -617,23 +653,29 @@ int main(int argc, char *argv[])
feb2d6
 	     opts.journals < total;
feb2d6
 	     opts.journals++) {
feb2d6
 		if (metafs_interrupted) {
feb2d6
-			cleanup_metafs(&mfs;;
feb2d6
-			exit(130);
feb2d6
+			errno = 130;
feb2d6
+			goto free_paths;
feb2d6
 		}
feb2d6
-		add_ir(&opts);
feb2d6
-		add_sc(&opts);
feb2d6
-		add_qc(sdp, &opts);
feb2d6
-		add_j(sdp, &opts);
feb2d6
+		if ((ret = add_ir(&opts)))
feb2d6
+			goto free_paths;
feb2d6
+		if ((ret = add_sc(&opts)))
feb2d6
+			goto free_paths;
feb2d6
+		if ((ret = add_qc(sdp, &opts)))
feb2d6
+			goto free_paths;
feb2d6
+		if ((ret = add_j(sdp, &opts)))
feb2d6
+			goto free_paths;
feb2d6
 	}
feb2d6
 
feb2d6
-out:
feb2d6
+free_paths:
feb2d6
 	free(opts.new_inode);
feb2d6
 	free(opts.per_node);
feb2d6
 	free(opts.jindex);
feb2d6
-	close(sdp->path_fd);
feb2d6
-	cleanup_metafs(&mfs;;
feb2d6
+umount_meta:
feb2d6
 	sync();
feb2d6
-
feb2d6
+	cleanup_metafs(&mfs;;
feb2d6
+close_sb:
feb2d6
+	close(sdp->path_fd);
feb2d6
+out:
feb2d6
 	if (!ret)
feb2d6
 		print_results(&opts);
feb2d6