[PATCH 07/12] xfs: switch the buffer get/read API to use irec methods

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Dave Chinner <dchinner@xxxxxxxxxx>

Before implementing multiple irec support, switch the non-irec
interface to use the irec interface internally. This allows the
buffer initialisation code to be swtiched to an irec interface to
enable multiple irec buffers to be implemented without duplicating
lots of code.

To be able to support sub-fsb addressed blocks (various AG headers)
add a special in-memory only state flag to the xfs_bmbt_irec
structure to allow the structure to hold different unit types. If no
flag is set, the unit type if FSB (as used everywhere right now).
Internally to the buffer cache the XFS_EXT_DADDR flag is used to
indicate the bmbt_irec values are in disk address format rather than
FSB to allow sub-FSB block support.

Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
---
 fs/xfs/xfs_bmap_btree.h |    6 ++-
 fs/xfs/xfs_buf.c        |  182 ++++++++++++++++++++++-------------------------
 2 files changed, 89 insertions(+), 99 deletions(-)

diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 0e66c4e..f888c8f 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -99,10 +99,14 @@ typedef enum {
 
 /*
  * Possible extent states.
+ *
+ * XFS_EXT_DADDR does not exist on disk - it is only used in memory to indicate
+ * that the contents of the bmbt_irec are in daddr units, not fsb units.
  */
 typedef enum {
 	XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
-	XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
+	XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID,
+	XFS_EXT_DADDR,
 } xfs_exntst_t;
 
 /*
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index aebe954..2ca9086 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -542,10 +542,60 @@ xfs_buf_get(
 	size_t			numblks,
 	xfs_buf_flags_t		flags)
 {
+	struct xfs_bmbt_irec	map = {
+		.br_startblock = blkno,
+		.br_blockcount = numblks,
+		.br_state = XFS_EXT_DADDR,
+	};
+
+	return xfs_buf_get_irec(target, &map, 1, flags);
+}
+
+STATIC int
+_xfs_buf_read(
+	xfs_buf_t		*bp,
+	xfs_buf_flags_t		flags)
+{
+	int			status;
+
+	ASSERT(!(flags & (XBF_DELWRI|XBF_WRITE)));
+	ASSERT(bp->b_vec[0].bv_bn != XFS_BUF_DADDR_NULL);
+
+	bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_DELWRI | XBF_READ_AHEAD);
+	bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD);
+
+	status = xfs_buf_iorequest(bp);
+	if (status || bp->b_error || (flags & XBF_ASYNC))
+		return status;
+	return xfs_buf_iowait(bp);
+}
+
+/*
+ * XXX: only supports a single map for now
+ */
+struct xfs_buf *
+xfs_buf_get_irec(
+	struct xfs_buftarg	*target,
+	struct xfs_bmbt_irec	*map,
+	int			nmaps,
+	xfs_buf_flags_t		flags)
+{
+	xfs_daddr_t		blkno;
+	size_t			numblks;
 	struct xfs_buf		*bp;
 	struct xfs_buf		*new_bp;
 	int			error = 0;
 
+	ASSERT_ALWAYS(nmaps == 1);
+
+	if (map->br_state == XFS_EXT_DADDR) {
+		blkno = map->br_startblock;
+		numblks = map->br_blockcount;
+	} else {
+		blkno = XFS_FSB_TO_DADDR(target->bt_mount, map->br_startblock);
+		numblks = XFS_FSB_TO_BB(target->bt_mount, map->br_blockcount);
+	}
+
 	bp = _xfs_buf_find(target, blkno, numblks, flags, NULL);
 	if (likely(bp))
 		goto found;
@@ -596,37 +646,18 @@ no_buffer:
 	return NULL;
 }
 
-STATIC int
-_xfs_buf_read(
-	xfs_buf_t		*bp,
-	xfs_buf_flags_t		flags)
-{
-	int			status;
-
-	ASSERT(!(flags & (XBF_DELWRI|XBF_WRITE)));
-	ASSERT(bp->b_vec[0].bv_bn != XFS_BUF_DADDR_NULL);
-
-	bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_DELWRI | XBF_READ_AHEAD);
-	bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD);
-
-	status = xfs_buf_iorequest(bp);
-	if (status || bp->b_error || (flags & XBF_ASYNC))
-		return status;
-	return xfs_buf_iowait(bp);
-}
-
-xfs_buf_t *
-xfs_buf_read(
-	xfs_buftarg_t		*target,
-	xfs_daddr_t		blkno,
-	size_t			numblks,
+struct xfs_buf *
+xfs_buf_read_irec(
+	struct xfs_buftarg	*target,
+	struct xfs_bmbt_irec	*map,
+	int			nmaps,
 	xfs_buf_flags_t		flags)
 {
 	xfs_buf_t		*bp;
 
 	flags |= XBF_READ;
 
-	bp = xfs_buf_get(target, blkno, numblks, flags);
+	bp = xfs_buf_get_irec(target, map, nmaps, flags);
 	if (bp) {
 		trace_xfs_buf_read(bp, flags, _RET_IP_);
 
@@ -654,96 +685,51 @@ xfs_buf_read(
 	return NULL;
 }
 
-/*
- *	If we are not low on memory then do the readahead in a deadlock
- *	safe manner.
- */
 void
-xfs_buf_readahead(
-	xfs_buftarg_t		*target,
-	xfs_daddr_t		blkno,
-	size_t			numblks)
+xfs_buf_readahead_irec(
+	struct xfs_buftarg	*target,
+	struct xfs_bmbt_irec	*map,
+	int			nmaps)
 {
 	if (bdi_read_congested(target->bt_bdi))
 		return;
 
-	xfs_buf_read(target, blkno, numblks,
+	xfs_buf_read_irec(target, map, nmaps,
 		     XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD|XBF_DONT_BLOCK);
 }
 
-/*
- * XXX: only supports a single map for now
- */
-struct xfs_buf *
-xfs_buf_get_irec(
-	struct xfs_buftarg	*target,
-	struct xfs_bmbt_irec	*map,
-	int			nmaps,
+xfs_buf_t *
+xfs_buf_read(
+	xfs_buftarg_t		*target,
+	xfs_daddr_t		blkno,
+	size_t			numblks,
 	xfs_buf_flags_t		flags)
 {
-	xfs_daddr_t		blkno;
-	size_t			numblks;
-	struct xfs_buf		*bp;
-
-	ASSERT_ALWAYS(nmaps == 1);
-
-	blkno = XFS_FSB_TO_DADDR(target->bt_mount, map->br_startblock);
-	numblks = XFS_FSB_TO_BB(target->bt_mount, map->br_blockcount);
-
-	bp = xfs_buf_get(target, blkno, numblks, flags);
+	struct xfs_bmbt_irec	map = {
+		.br_startblock = blkno,
+		.br_blockcount = numblks,
+		.br_state = XFS_EXT_DADDR,
+	};
 
-	return bp;
-}
-
-struct xfs_buf *
-xfs_buf_read_irec(
-	struct xfs_buftarg	*target,
-	struct xfs_bmbt_irec	*map,
-	int			nmaps,
-	xfs_buf_flags_t		flags)
-{
-	xfs_buf_t		*bp;
-
-	flags |= XBF_READ;
-
-	bp = xfs_buf_get_irec(target, map, nmaps, flags);
-	if (bp) {
-		trace_xfs_buf_read(bp, flags, _RET_IP_);
-
-		if (!XFS_BUF_ISDONE(bp)) {
-			XFS_STATS_INC(xb_get_read);
-			_xfs_buf_read(bp, flags);
-		} else if (flags & XBF_ASYNC) {
-			/*
-			 * Read ahead call which is already satisfied,
-			 * drop the buffer
-			 */
-			goto no_buffer;
-		} else {
-			/* We do not want read in the flags */
-			bp->b_flags &= ~XBF_READ;
-		}
-	}
-
-	return bp;
-
- no_buffer:
-	if (flags & (XBF_LOCK | XBF_TRYLOCK))
-		xfs_buf_unlock(bp);
-	xfs_buf_rele(bp);
-	return NULL;
+	return xfs_buf_read_irec(target, &map, 1, flags);
 }
 
 void
-xfs_buf_readahead_irec(
-	struct xfs_buftarg	*target,
-	struct xfs_bmbt_irec	*map,
-	int			nmaps)
-{
+xfs_buf_readahead(
+	xfs_buftarg_t		*target,
+	xfs_daddr_t		blkno,
+	size_t			numblks)
+ {
+	struct xfs_bmbt_irec	map = {
+		.br_startblock = blkno,
+		.br_blockcount = numblks,
+		.br_state = XFS_EXT_DADDR,
+	};
+
 	if (bdi_read_congested(target->bt_bdi))
 		return;
 
-	xfs_buf_read_irec(target, map, nmaps,
+	xfs_buf_read_irec(target, &map, 1,
 		     XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD|XBF_DONT_BLOCK);
 }
 
-- 
1.7.5.4

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux