Message ID | 158258949476.451378.9569854305232356529.stgit@magnolia (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | xfsprogs: refactor buffer function names | expand |
On Mon, Feb 24, 2020 at 04:11:34PM -0800, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > 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. How are the libxfs_mount changes related to this commit message? All the other bits looks fine, but those changes seem to have slipt in without a good reason.
On Tue, Feb 25, 2020 at 09:42:52AM -0800, Christoph Hellwig wrote: > On Mon, Feb 24, 2020 at 04:11:34PM -0800, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@oracle.com> > > > > 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. > > How are the libxfs_mount changes related to this commit message? > > All the other bits looks fine, but those changes seem to have slipt in > without a good reason. Prior to this patch, the "!(flags & DEBUGGER)" expressions in the call sites evaluate to 0 or 1, and this effectively results in libxfs_mount passing EXIT_ON_FAILURE to the buffer read functions as the flag value. The flag value is passed all the way down to __read_buf, and when it sees an IO failure, it exits. After this patch, libxfs_mount passes flags==0, which means that we get a buffer back, possibly with b_error set. If b_error is set, we log a warning about the screwed up filesystem and return a null mount if the libxfs_mount caller didn't indicate that it is a debugger. Presumably the libxfs_mount caller will exit with error if we return a null mount. IOWs, I'm doing exactly what the commit message says, but in a rather subtle way. I'll clarify that, if you'd like. --D
On Tue, Feb 25, 2020 at 10:40:23AM -0800, Darrick J. Wong wrote: > Prior to this patch, the "!(flags & DEBUGGER)" expressions in the call > sites evaluate to 0 or 1, and this effectively results in libxfs_mount > passing EXIT_ON_FAILURE to the buffer read functions as the flag value. > The flag value is passed all the way down to __read_buf, and when it > sees an IO failure, it exits. > > After this patch, libxfs_mount passes flags==0, which means that we get > a buffer back, possibly with b_error set. If b_error is set, we log a > warning about the screwed up filesystem and return a null mount if the > libxfs_mount caller didn't indicate that it is a debugger. Presumably > the libxfs_mount caller will exit with error if we return a null mount. > > IOWs, I'm doing exactly what the commit message says, but in a rather > subtle way. I'll clarify that, if you'd like. Ok, with a proper commit message this looks good to me: Reviewed-by: Christoph Hellwig <hch@lst.de>
On Tue, Feb 25, 2020 at 10:42:40AM -0800, Christoph Hellwig wrote: > On Tue, Feb 25, 2020 at 10:40:23AM -0800, Darrick J. Wong wrote: > > Prior to this patch, the "!(flags & DEBUGGER)" expressions in the call > > sites evaluate to 0 or 1, and this effectively results in libxfs_mount > > passing EXIT_ON_FAILURE to the buffer read functions as the flag value. > > The flag value is passed all the way down to __read_buf, and when it > > sees an IO failure, it exits. > > > > After this patch, libxfs_mount passes flags==0, which means that we get > > a buffer back, possibly with b_error set. If b_error is set, we log a > > warning about the screwed up filesystem and return a null mount if the > > libxfs_mount caller didn't indicate that it is a debugger. Presumably > > the libxfs_mount caller will exit with error if we return a null mount. > > > > IOWs, I'm doing exactly what the commit message says, but in a rather > > subtle way. I'll clarify that, if you'd like. > > Ok, with a proper commit message this looks good to me: > > Reviewed-by: Christoph Hellwig <hch@lst.de> The new commit message reads as follows: "libxfs: open-code "exit on buffer read failure" in upper level callers "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." --D
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); }