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) {
