Linux-XFS Archive on lore.kernel.org
 help / color / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH 17/27] xfsprogs: convert libxfs_readbufr to libxfs_buf_read_uncached
Date: Thu, 15 Oct 2020 18:21:45 +1100
Message-ID: <20201015072155.1631135-18-david@fromorbit.com> (raw)
In-Reply-To: <20201015072155.1631135-1-david@fromorbit.com>

From: Dave Chinner <dchinner@redhat.com>

libxfs_readbufr()  and libxfs_readbufr_map() are messy ways of
reading an existing buffer. We have xfs_bwrite() already, so
introduced this function, implement it with the new buftarg based IO
engine, and call it xfs_bread().

Note that to make this new code be discontiguous buffer agnostic
and still play nice with rdwr.c's LIBXFS_B_DISCONTIG buffoonery,
we need to ensure buffers init both bp->b_bn and bp->b_maps[0].bm_bn
correctly.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
 db/io.c                   | 29 ++++------------------
 libxfs/buftarg.c          | 51 ++++++++++++++++++++++++++++++++-------
 libxfs/libxfs_api_defs.h  |  1 +
 libxfs/libxfs_io.h        |  4 +--
 libxfs/libxfs_priv.h      |  1 -
 libxfs/rdwr.c             | 24 ++++++++++--------
 libxfs/xfs_buftarg.h      | 15 ++++++++----
 libxlog/xfs_log_recover.c |  7 ++----
 repair/prefetch.c         | 22 +++++++++++------
 9 files changed, 89 insertions(+), 65 deletions(-)

diff --git a/db/io.c b/db/io.c
index c79cf1059b9e..6ba2540d89ef 100644
--- a/db/io.c
+++ b/db/io.c
@@ -424,31 +424,15 @@ ring_add(void)
 static void
 write_cur_buf(void)
 {
-	int ret;
+	struct xfs_buf	*bp = iocur_top->bp;
+	int		ret;
 
-	ret = -libxfs_bwrite(iocur_top->bp);
+	ret = -libxfs_bwrite(bp);
 	if (ret != 0)
 		dbprintf(_("write error: %s\n"), strerror(ret));
 
 	/* re-read buffer from disk */
-	ret = -libxfs_readbufr(mp->m_ddev_targp, iocur_top->bb, iocur_top->bp,
-			      iocur_top->blen, 0);
-	if (ret != 0)
-		dbprintf(_("read error: %s\n"), strerror(ret));
-}
-
-static void
-write_cur_bbs(void)
-{
-	int ret;
-
-	ret = -libxfs_bwrite(iocur_top->bp);
-	if (ret != 0)
-		dbprintf(_("write error: %s\n"), strerror(ret));
-
-
-	/* re-read buffer from disk */
-	ret = -libxfs_readbufr_map(mp->m_ddev_targp, iocur_top->bp, 0);
+	ret = -libxfs_bread(bp, bp->b_length);
 	if (ret != 0)
 		dbprintf(_("read error: %s\n"), strerror(ret));
 }
@@ -488,10 +472,7 @@ write_cur(void)
 		else if (iocur_top->dquot_buf)
 			xfs_dquot_set_crc(iocur_top->bp);
 	}
-	if (iocur_top->bbmap)
-		write_cur_bbs();
-	else
-		write_cur_buf();
+	write_cur_buf();
 
 	/* If we didn't write the crc automatically, re-check inode validity */
 	if (xfs_sb_version_hascrc(&mp->m_sb) &&
diff --git a/libxfs/buftarg.c b/libxfs/buftarg.c
index d98952940ee8..62c2bea87b5c 100644
--- a/libxfs/buftarg.c
+++ b/libxfs/buftarg.c
@@ -125,6 +125,9 @@ xfs_buf_ioend(
 		ASSERT(!bp->b_iodone);
 		bp->b_ops->verify_read(bp);
 	}
+
+	if (!bp->b_error)
+		bp->b_flags |= XBF_DONE;
 }
 
 static void
@@ -293,12 +296,47 @@ xfs_buf_get_uncached_daddr(
 
 	INIT_LIST_HEAD(&bp->b_node.cn_hash);
 	bp->b_node.cn_count = 1;
-	bp->b_bn = daddr;
+	bp->b_bn = XFS_BUF_DADDR_NULL;
         bp->b_maps[0].bm_bn = daddr;
 	*bpp = bp;
 	return 0;
 }
 
+/*
+ * Run the IO requested on a pre-configured uncached buffer. The length of the
+ * IO is capped by @bblen, so a shorter IO than the entire buffer can be done
+ * easily.
+ */
+static int
+xfs_buf_uncached_submit(
+	struct xfs_buftarg	*target,
+	struct xfs_buf		*bp,
+	size_t			bblen,
+	int			flags)
+{
+	ASSERT(bp->b_bn == XFS_BUF_DADDR_NULL);
+
+	bp->b_flags &= ~(XBF_READ | XBF_WRITE);
+	bp->b_flags |= flags;
+	bp->b_length = bblen;
+	bp->b_error = 0;
+
+	xfs_buftarg_submit_io(bp);
+	return bp->b_error;
+}
+
+int
+xfs_bread(
+	struct xfs_buf		*bp,
+	size_t			bblen)
+{
+	return xfs_buf_uncached_submit(bp->b_target, bp, bblen, XBF_READ);
+}
+
+/*
+ * Read a single contiguous range of a buftarg and return the buffer to the
+ * caller. This buffer is not cached.
+ */
 int
 xfs_buf_read_uncached(
 	struct xfs_buftarg	*target,
@@ -311,24 +349,19 @@ xfs_buf_read_uncached(
 	struct xfs_buf		 *bp;
 	int			error;
 
-
 	error = xfs_buf_get_uncached(target, bblen, flags, &bp);
 	if (error)
 		return error;
 
-	/* set up the buffer for a read IO */
 	ASSERT(bp->b_map_count == 1);
-	bp->b_maps[0].bm_bn = daddr;
-	bp->b_flags |= XBF_READ;
 	bp->b_ops = ops;
+	bp->b_maps[0].bm_bn = daddr;
 
-	xfs_buftarg_submit_io(bp);
-	if (bp->b_error) {
-		error = bp->b_error;
+	error = xfs_bread(bp, bblen);
+	if (error) {
 		xfs_buf_relse(bp);
 		return error;
 	}
-
 	*bpp = bp;
 	return 0;
 }
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index e7e42e93a07e..f4a31782020c 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -42,6 +42,7 @@
 #define xfs_bmbt_maxrecs		libxfs_bmbt_maxrecs
 #define xfs_bmdr_maxrecs		libxfs_bmdr_maxrecs
 
+#define xfs_bread			libxfs_bread
 #define xfs_btree_bload			libxfs_btree_bload
 #define xfs_btree_bload_compute_geometry libxfs_btree_bload_compute_geometry
 #define xfs_btree_del_cursor		libxfs_btree_del_cursor
diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index 8408f436e5a5..c59d42e02040 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -80,9 +80,7 @@ bool xfs_verify_magic16(struct xfs_buf *bp, __be16 dmagic);
 typedef unsigned int xfs_buf_flags_t;
 
 #define xfs_buf_offset(bp, offset)	((bp)->b_addr + (offset))
-#define XFS_BUF_ADDR(bp)		((bp)->b_bn)
-
-#define XFS_BUF_SET_ADDR(bp,blk)	((bp)->b_bn = (blk))
+#define XFS_BUF_ADDR(bp)		((bp)->b_maps[0].bm_bn)
 
 void libxfs_buf_set_priority(struct xfs_buf *bp, int priority);
 int libxfs_buf_priority(struct xfs_buf *bp);
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 72665f71098e..dce77024b5de 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -408,7 +408,6 @@ howmany_64(uint64_t x, uint32_t y)
 /* buffer management */
 #define XBF_TRYLOCK			0
 #define XBF_UNMAPPED			0
-#define XBF_DONE			0
 #define xfs_buf_stale(bp)		((bp)->b_flags |= LIBXFS_B_STALE)
 #define XFS_BUF_UNDELAYWRITE(bp)	((bp)->b_flags &= ~LIBXFS_B_DIRTY)
 
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 3e755402b024..af70dbe339e4 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -247,19 +247,17 @@ __initbuf(struct xfs_buf *bp, struct xfs_buftarg *btp, xfs_daddr_t bno,
 	bp->b_recur = 0;
 	bp->b_ops = NULL;
 	INIT_LIST_HEAD(&bp->b_li_list);
-
-	if (!bp->b_maps) {
-		bp->b_map_count = 1;
-		bp->b_maps = &bp->__b_map;
-		bp->b_maps[0].bm_bn = bp->b_bn;
-		bp->b_maps[0].bm_len = bp->b_length;
-	}
 }
 
 static void
 libxfs_initbuf(struct xfs_buf *bp, struct xfs_buftarg *btp, xfs_daddr_t bno,
 		unsigned int bytes)
 {
+	bp->b_map_count = 1;
+	bp->b_maps = &bp->__b_map;
+	bp->b_maps[0].bm_bn = bno;
+	bp->b_maps[0].bm_len = bytes;
+
 	__initbuf(bp, btp, bno, bytes);
 }
 
@@ -270,6 +268,11 @@ libxfs_initbuf_map(struct xfs_buf *bp, struct xfs_buftarg *btp,
 	unsigned int bytes = 0;
 	int i;
 
+	if (nmaps == 1) {
+		libxfs_initbuf(bp, btp, map[0].bm_bn, map[0].bm_len);
+		return;
+	}
+
 	bytes = sizeof(struct xfs_buf_map) * nmaps;
 	bp->b_maps = malloc(bytes);
 	if (!bp->b_maps) {
@@ -573,7 +576,7 @@ __read_buf(int fd, void *buf, int len, off64_t offset, int flags)
 	return 0;
 }
 
-int
+static int
 libxfs_readbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, struct xfs_buf *bp,
 		int len, int flags)
 {
@@ -607,7 +610,7 @@ libxfs_readbuf_verify(
 	return bp->b_error;
 }
 
-int
+static int
 libxfs_readbufr_map(struct xfs_buftarg *btp, struct xfs_buf *bp, int flags)
 {
 	int	fd;
@@ -762,7 +765,8 @@ libxfs_bwrite(
 
 	if (!(bp->b_flags & LIBXFS_B_DISCONTIG)) {
 		bp->b_error = __write_buf(fd, bp->b_addr, BBTOB(bp->b_length),
-				    LIBXFS_BBTOOFF64(bp->b_bn), bp->b_flags);
+				    LIBXFS_BBTOOFF64(bp->b_maps[0].bm_bn),
+				    bp->b_flags);
 	} else {
 		int	i;
 		void	*buf = bp->b_addr;
diff --git a/libxfs/xfs_buftarg.h b/libxfs/xfs_buftarg.h
index b6e365c4f5be..71054317ee9d 100644
--- a/libxfs/xfs_buftarg.h
+++ b/libxfs/xfs_buftarg.h
@@ -79,8 +79,16 @@ int xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr,
 			  size_t bblen, int flags, struct xfs_buf **bpp,
 			  const struct xfs_buf_ops *ops);
 
-#define XBF_READ	(1 << 0)
-#define XBF_WRITE	(1 << 1)
+int xfs_bread(struct xfs_buf *bp, size_t bblen);
+
+/*
+ * Temporary: these need to be the same as the LIBXFS_B_* flags until we change
+ * over to the kernel structures. For those that aren't the same or don't yet
+ * exist, start the numbering from the top down.
+ */
+#define XBF_READ	(1 << 31)
+#define XBF_WRITE	(1 << 30)
+#define XBF_DONE	(1 << 3)	// LIBXFS_B_UPTODATE 0x0008
 
 /*
  * Raw buffer access functions. These exist as temporary bridges for uncached IO
@@ -89,8 +97,5 @@ int xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr,
  */
 struct xfs_buf *libxfs_getbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno,
 			int bblen);
-int libxfs_readbufr(struct xfs_buftarg *, xfs_daddr_t, struct xfs_buf *, int,
-			int);
-int libxfs_readbufr_map(struct xfs_buftarg *, struct xfs_buf *, int);
 
 #endif /* __XFS_BUFTARG_H */
diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c
index f566c3b54bd0..28487e233aec 100644
--- a/libxlog/xfs_log_recover.c
+++ b/libxlog/xfs_log_recover.c
@@ -110,15 +110,12 @@ xlog_bread_noalign(
 
 	blk_no = round_down(blk_no, log->l_sectBBsize);
 	nbblks = round_up(nbblks, log->l_sectBBsize);
-
 	ASSERT(nbblks > 0);
 	ASSERT(nbblks <= bp->b_length);
 
-	XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
-	bp->b_length = nbblks;
-	bp->b_error = 0;
+	bp->b_maps[0].bm_bn = log->l_logBBstart + blk_no;
 
-	return libxfs_readbufr(log->l_dev, XFS_BUF_ADDR(bp), bp, nbblks, 0);
+	return libxfs_bread(bp, nbblks);
 }
 
 int
diff --git a/repair/prefetch.c b/repair/prefetch.c
index 22a0c0c902d9..aacb96cec0da 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -474,6 +474,7 @@ pf_batch_read(
 	void			*buf)
 {
 	struct xfs_buf		*bplist[MAX_BUFS];
+	struct xfs_buf		*lbp;
 	unsigned int		num;
 	off64_t			first_off, last_off, next_off;
 	int			len, size;
@@ -518,18 +519,21 @@ pf_batch_read(
 		if (!num)
 			return;
 
+
 		/*
 		 * do a big read if 25% of the potential buffer is useful,
 		 * otherwise, find as many close together blocks and
 		 * read them in one read
 		 */
+		lbp = bplist[num - 1];
 		first_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[0]));
-		last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[num-1])) +
-			BBTOB(bplist[num-1]->b_length);
+		last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(lbp)) +
+							BBTOB(lbp->b_length);
 		while (num > 1 && last_off - first_off > pf_max_bytes) {
 			num--;
-			last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(bplist[num-1])) +
-				BBTOB(bplist[num-1]->b_length);
+			lbp = bplist[num - 1];
+			last_off = LIBXFS_BBTOOFF64(XFS_BUF_ADDR(lbp)) +
+							BBTOB(lbp->b_length);
 		}
 		if (num < ((last_off - first_off) >> (mp->m_sb.sb_blocklog + 3))) {
 			/*
@@ -545,6 +549,7 @@ pf_batch_read(
 				last_off = next_off;
 			}
 			num = i;
+			lbp = bplist[num - 1];
 		}
 
 		for (i = 0; i < num; i++) {
@@ -583,11 +588,12 @@ pf_batch_read(
 		 * guarantees that only the last buffer in the list will be a
 		 * discontiguous buffer.
 		 */
-		if ((bplist[num - 1]->b_flags & LIBXFS_B_DISCONTIG)) {
-			libxfs_readbufr_map(mp->m_ddev_targp, bplist[num - 1], 0);
-			bplist[num - 1]->b_flags |= LIBXFS_B_UNCHECKED;
-			libxfs_buf_relse(bplist[num - 1]);
+		if (lbp->b_flags & LIBXFS_B_DISCONTIG) {
+			libxfs_bread(lbp, lbp->b_length);
+			lbp->b_flags |= LIBXFS_B_UNCHECKED;
+			libxfs_buf_relse(lbp);
 			num--;
+			lbp = bplist[num - 1];
 		}
 
 		if (len > 0) {
-- 
2.28.0


  parent reply index

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-15  7:21 [PATCH 00/27] [RFC, WIP] xfsprogs: xfs_buf unification and AIO Dave Chinner
2020-10-15  7:21 ` [PATCH 01/27] xfsprogs: remove unused buffer tracing code Dave Chinner
2020-10-15  7:21 ` [PATCH 02/27] xfsprogs: remove unused IO_DEBUG functionality Dave Chinner
2020-11-16  2:31   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 03/27] libxfs: get rid of b_bcount from xfs_buf Dave Chinner
2020-11-23 19:53   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 04/27] libxfs: rename buftarg->dev to btdev Dave Chinner
2020-11-16  2:33   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 05/27] xfsprogs: get rid of ancient btree tracing fragments Dave Chinner
2020-11-16  2:35   ` Eric Sandeen
2020-10-15  7:21 ` [PATCH 06/27] xfsprogs: remove xfs_buf_t typedef Dave Chinner
2020-10-15 15:22   ` Darrick J. Wong
2020-10-15 20:54     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 07/27] xfsprogs: introduce liburcu support Dave Chinner
2020-10-15  7:21 ` [PATCH 08/27] libxfs: add spinlock_t wrapper Dave Chinner
2020-10-15  7:21 ` [PATCH 09/27] atomic: convert to uatomic Dave Chinner
2020-10-15  7:21 ` [PATCH 10/27] libxfs: add kernel-compatible completion API Dave Chinner
2020-10-15 17:09   ` Darrick J. Wong
2020-10-19 22:21     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 11/27] libxfs: add wrappers for kernel semaphores Dave Chinner
2020-10-15  7:21 ` [PATCH 12/27] xfsprogs: convert use-once buffer reads to uncached IO Dave Chinner
2020-10-15 17:12   ` Darrick J. Wong
2020-10-19 22:36     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 13/27] libxfs: introduce userspace buftarg infrastructure Dave Chinner
2020-10-15  7:21 ` [PATCH 14/27] xfs: rename libxfs_buftarg_init to libxfs_open_devices() Dave Chinner
2020-10-15  7:21 ` [PATCH 15/27] libxfs: introduce userspace buftarg infrastructure Dave Chinner
2020-10-15 17:16   ` Darrick J. Wong
2020-10-15  7:21 ` [PATCH 16/27] libxfs: add a synchronous IO engine to the buftarg Dave Chinner
2020-10-15  7:21 ` Dave Chinner [this message]
2020-10-15  7:21 ` [PATCH 18/27] libxfs: convert libxfs_bwrite to buftarg IO Dave Chinner
2020-10-15  7:21 ` [PATCH 19/27] libxfs: add cache infrastructure to buftarg Dave Chinner
2020-10-15  7:21 ` [PATCH 20/27] libxfs: add internal lru to btcache Dave Chinner
2020-10-15  7:21 ` [PATCH 21/27] libxfs: Add kernel list_lru wrapper Dave Chinner
2020-10-15  7:21 ` [PATCH 22/27] libxfs: introduce new buffer cache infrastructure Dave Chinner
2020-10-15 17:46   ` Darrick J. Wong
2020-10-15  7:21 ` [PATCH 23/27] libxfs: use PSI information to detect memory pressure Dave Chinner
2020-10-15 17:56   ` Darrick J. Wong
2020-10-15 21:20     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 24/27] libxfs: add a buftarg cache shrinker implementation Dave Chinner
2020-10-15 18:01   ` Darrick J. Wong
2020-10-15 21:33     ` Dave Chinner
2020-10-15  7:21 ` [PATCH 25/27] libxfs: switch buffer cache implementations Dave Chinner
2020-10-15  7:21 ` [PATCH 26/27] build: set platform_defs.h.in dependency correctly Dave Chinner
2020-10-15  7:21 ` [PATCH 27/27] libxfs: convert sync IO buftarg engine to AIO Dave Chinner
2020-10-15 18:26   ` Darrick J. Wong
2020-10-15 21:42     ` Dave Chinner
2020-10-15  7:29 ` [PATCH 00/27] [RFC, WIP] xfsprogs: xfs_buf unification and AIO Dave Chinner
2020-10-15 18:37 ` Darrick J. Wong
2020-10-15 22:35   ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201015072155.1631135-18-david@fromorbit.com \
    --to=david@fromorbit.com \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-XFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-xfs/0 linux-xfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-xfs linux-xfs/ https://lore.kernel.org/linux-xfs \
		linux-xfs@vger.kernel.org
	public-inbox-index linux-xfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-xfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git