[PATCH 12/27] xfsprogs: convert use-once buffer reads to uncached IO

Dave Chinner
2020-10-15T07:22:13Z

db/init.c | 2 +-
libxfs/init.c | 93 ++++++++++++++++++++++++++++++---------------------
2 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/db/init.c b/db/init.c
index 19f0900a862b..f797df8a768b 100644
--- a/db/init.c
+++ b/db/init.c
@@ -153,7 +153,7 @@ init(
*/
if (sbp->sb_rootino != NULLFSINO &&
xfs_sb_version_haslazysbcount(&mp->m_sb)) {
- int error = -libxfs_initialize_perag_data(mp, sbp->sb_agcount);
+ error = -libxfs_initialize_perag_data(mp, sbp->sb_agcount);
if (error) {
fprintf(stderr,
_("%s: cannot init perag data (%d). Continuing anyway.\n"),
diff --git a/libxfs/init.c b/libxfs/init.c
index fe784940c299..fc30f92d6fb2 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -419,7 +419,7 @@ done:
*/
static int
rtmount_init(
- xfs_mount_t *mp, /* file system mount structure */
+ struct xfs_mount *mp,
int flags)
{
struct xfs_buf *bp; /* buffer for last block of subvolume */
@@ -473,8 +473,9 @@ rtmount_init(
(unsigned long long) mp->m_sb.sb_rblocks);
return -1;
}
- error = libxfs_buf_read(mp->m_rtdev, d - XFS_FSB_TO_BB(mp, 1),
- XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
+ error = libxfs_buf_read_uncached(mp->m_rtdev_targp,
+ d - XFS_FSB_TO_BB(mp, 1),
+ XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
if (error) {
fprintf(stderr, _("%s: realtime size check failed\n"),
progname);
@@ -657,6 +658,52 @@ libxfs_buftarg_init(
mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, rtdev);
}

+/*
+ * Check that the data (and log if separate) is an ok size.
+ *
+ * XXX: copied from kernel, needs to be moved to shared code
+ */
+STATIC int
+xfs_check_sizes(
+ struct xfs_mount *mp)
+{
+ struct xfs_buf *bp;
+ xfs_daddr_t d;
+ int error;
+
+ d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
+ if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
+ xfs_warn(mp, "filesystem size mismatch detected");
+ return -EFBIG;
+ }
+ error = libxfs_buf_read_uncached(mp->m_ddev_targp,
+ d - XFS_FSS_TO_BB(mp, 1),
+ XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
+ if (error) {
+ xfs_warn(mp, "last sector read failed");
+ return error;
+ }
+ libxfs_buf_relse(bp);
+
+ if (mp->m_logdev_targp == mp->m_ddev_targp)
+ return 0;
+
+ d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
+ if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
+ xfs_warn(mp, "log size mismatch detected");
+ return -EFBIG;
+ }
+ error = libxfs_buf_read_uncached(mp->m_logdev_targp,
+ d - XFS_FSB_TO_BB(mp, 1),
+ XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
+ if (error) {
+ xfs_warn(mp, "log device read failed");
+ return error;
+ }
+ libxfs_buf_relse(bp);
+ return 0;
+}
+
/*
* Mount structure initialization, provides a filled-in xfs_mount_t
* such that the numerous XFS_* macros can be used. If dev is zero,
@@ -673,7 +720,6 @@ libxfs_mount(
{
struct xfs_buf *bp;
struct xfs_sb *sbp;
- xfs_daddr_t d;
bool debugger = (flags & LIBXFS_MOUNT_DEBUGGER);
int error;

@@ -704,16 +750,6 @@ libxfs_mount(
xfs_rmapbt_compute_maxlevels(mp);
xfs_refcountbt_compute_maxlevels(mp);

- /*
- * Check that the data (and log if separate) are an ok size.
- */
- d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
- if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
- fprintf(stderr, _("%s: size check failed\n"), progname);
- if (!(flags & LIBXFS_MOUNT_DEBUGGER))
- return NULL;
- }
-
/*
* We automatically convert v1 inodes to v2 inodes now, so if
* the NLINK bit is not set we can't operate on the filesystem.
@@ -755,30 +791,9 @@ libxfs_mount(
return mp;

/* device size checks must pass unless we're a debugger. */
- error = libxfs_buf_read(mp->m_dev, d - XFS_FSS_TO_BB(mp, 1),
- XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
- if (error) {
- fprintf(stderr, _("%s: data size check failed\n"), progname);
- if (!debugger)
- return NULL;
- } else
- libxfs_buf_relse(bp);
-
- if (mp->m_logdev_targp->bt_bdev &&
- mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev) {
- d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
- if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks ||
- libxfs_buf_read(mp->m_logdev_targp,
- d - XFS_FSB_TO_BB(mp, 1), XFS_FSB_TO_BB(mp, 1),
- 0, &bp, NULL)) {
- fprintf(stderr, _("%s: log size checks failed\n"),
- progname);
- if (!debugger)
- return NULL;
- }
- if (bp)
- libxfs_buf_relse(bp);
- }
+ error = xfs_check_sizes(mp);
+ if (error && !debugger)
+ return NULL;

/* Initialize realtime fields in the mount structure */
if (rtmount_init(mp, flags)) {
@@ -795,7 +810,7 @@ libxfs_mount(
* read the first one and let the user know to check the geometry.
*/
if (sbp->sb_agcount > 1000000) {
- error = libxfs_buf_read(mp->m_dev,
+ error = libxfs_buf_read_uncached(mp->m_ddev_targp,
XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1,
0, &bp, NULL);
if (error) {
--
2.28.0