[PATCH v2 01/25] libxfs: open-code "exit on buffer read failure" in upper level callers

Darrick J. Wong
2020-02-25T19:27:07Z

Make all functions that use LIBXFS_EXIT_ON_FAILURE to abort on buffer
read errors implement that logic themselves. This also removes places
where libxfs can abort the program with no warning.

Note that in libxfs_mount, the "!(flags & DEBUGGER)" code would
indirectly select LIBXFS_EXIT_ON_FAILURE, so we're replacing the hidden
library exit(1) with a null xfs_mount return, which should cause the
utilities to exit with an error.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
v2: improve commit message
---
libxfs/init.c | 40 ++++++++++++++++++++--------------------
libxfs/rdwr.c | 4 ----
mkfs/xfs_mkfs.c | 16 ++++++++++++----
3 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index 913f546f..485ab8f8 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -639,19 +639,20 @@ libxfs_buftarg_init(
* such that the numerous XFS_* macros can be used. If dev is zero,
* no IO will be performed (no size checks, read root inodes).
*/
-xfs_mount_t *
+struct xfs_mount *
libxfs_mount(
- xfs_mount_t *mp,
- xfs_sb_t *sb,
- dev_t dev,
- dev_t logdev,
- dev_t rtdev,
- int flags)
+ struct xfs_mount *mp,
+ struct xfs_sb *sb,
+ dev_t dev,
+ dev_t logdev,
+ dev_t rtdev,
+ int flags)
{
- xfs_daddr_t d;
- xfs_buf_t *bp;
- xfs_sb_t *sbp;
- int error;
+ struct xfs_buf *bp;
+ struct xfs_sb *sbp;
+ xfs_daddr_t d;
+ bool debugger = (flags & LIBXFS_MOUNT_DEBUGGER);
+ int error;

libxfs_buftarg_init(mp, dev, logdev, rtdev);

@@ -728,12 +729,12 @@ libxfs_mount(
if (dev == 0) /* maxtrres, we have no device so leave now */
return mp;

- bp = libxfs_readbuf(mp->m_dev,
- d - XFS_FSS_TO_BB(mp, 1), XFS_FSS_TO_BB(mp, 1),
- !(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
+ /* device size checks must pass unless we're a debugger. */
+ bp = libxfs_readbuf(mp->m_dev, d - XFS_FSS_TO_BB(mp, 1),
+ XFS_FSS_TO_BB(mp, 1), 0, NULL);
if (!bp) {
fprintf(stderr, _("%s: data size check failed\n"), progname);
- if (!(flags & LIBXFS_MOUNT_DEBUGGER))
+ if (!debugger)
return NULL;
} else
libxfs_putbuf(bp);
@@ -744,11 +745,10 @@ libxfs_mount(
if ( (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) ||
(!(bp = libxfs_readbuf(mp->m_logdev_targp,
d - XFS_FSB_TO_BB(mp, 1),
- XFS_FSB_TO_BB(mp, 1),
- !(flags & LIBXFS_MOUNT_DEBUGGER), NULL))) ) {
+ XFS_FSB_TO_BB(mp, 1), 0, NULL)))) {
fprintf(stderr, _("%s: log size checks failed\n"),
progname);
- if (!(flags & LIBXFS_MOUNT_DEBUGGER))
+ if (!debugger)
return NULL;
}
if (bp)
@@ -772,11 +772,11 @@ libxfs_mount(
if (sbp->sb_agcount > 1000000) {
bp = libxfs_readbuf(mp->m_dev,
XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1,
- !(flags & LIBXFS_MOUNT_DEBUGGER), NULL);
+ 0, NULL);
if (bp->b_error) {
fprintf(stderr, _("%s: read of AG %u failed\n"),
progname, sbp->sb_agcount);
- if (!(flags & LIBXFS_MOUNT_DEBUGGER))
+ if (!debugger)
return NULL;
fprintf(stderr, _("%s: limiting reads to AG 0\n"),
progname);
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 4253b890..474fceb0 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -911,14 +911,10 @@ __read_buf(int fd, void *buf, int len, off64_t offset, int flags)
int error = errno;
fprintf(stderr, _("%s: read failed: %s\n"),
progname, strerror(error));
- if (flags & LIBXFS_EXIT_ON_FAILURE)
- exit(1);
return -error;
} else if (sts != len) {
fprintf(stderr, _("%s: error - read only %d of %d bytes\n"),
progname, sts, len);
- if (flags & LIBXFS_EXIT_ON_FAILURE)
- exit(1);
return -EIO;
}
return 0;
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 7f315d8a..3de73fc6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3576,8 +3576,12 @@ rewrite_secondary_superblocks(
buf = libxfs_readbuf(mp->m_dev,
XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount - 1,
XFS_SB_DADDR),
- XFS_FSS_TO_BB(mp, 1),
- LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
+ XFS_FSS_TO_BB(mp, 1), 0, &xfs_sb_buf_ops);
+ if (!buf) {
+ fprintf(stderr, _("%s: could not re-read AG %u superblock\n"),
+ progname, mp->m_sb.sb_agcount - 1);
+ exit(1);
+ }
XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);

@@ -3588,8 +3592,12 @@ rewrite_secondary_superblocks(
buf = libxfs_readbuf(mp->m_dev,
XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount - 1) / 2,
XFS_SB_DADDR),
- XFS_FSS_TO_BB(mp, 1),
- LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
+ XFS_FSS_TO_BB(mp, 1), 0, &xfs_sb_buf_ops);
+ if (!buf) {
+ fprintf(stderr, _("%s: could not re-read AG %u superblock\n"),
+ progname, (mp->m_sb.sb_agcount - 1) / 2);
+ exit(1);
+ }
XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
}