diff mbox series

[13/18] libxfs: straighten out libxfs_writebuf confusion

Message ID 158216303592.602314.4622638173533560298.stgit@magnolia (mailing list archive)
State Deferred, archived
Headers show
Series xfsprogs: refactor buffer function names | expand

Commit Message

Darrick J. Wong Feb. 20, 2020, 1:43 a.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

libxfs_writebuf is not a well named function -- it marks the buffer
dirty and then releases the caller's reference.  The actual write comes
when the cache is flushed, either because someone explicitly told the
cache to flush or because we started buffer reclaim.

Make the buffer release explicit in the callers and rename the function
to say what it actually does -- it marks the buffer dirty outside of
transaction context.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/libxfs_io.h   |   10 +++++-----
 libxfs/rdwr.c        |   21 ++++++++++++++-------
 libxfs/trans.c       |    3 ++-
 mkfs/proto.c         |    6 ++++--
 mkfs/xfs_mkfs.c      |   21 ++++++++++++++-------
 repair/attr_repair.c |   17 +++++++++--------
 repair/da_util.c     |   12 ++++++++----
 repair/dino_chunks.c |    6 ++++--
 repair/dinode.c      |   12 ++++++++----
 repair/dir2.c        |    9 ++++++---
 repair/phase3.c      |    6 ++++--
 repair/phase5.c      |   42 ++++++++++++++++++++++++++++--------------
 repair/rmap.c        |    3 ++-
 repair/scan.c        |   21 ++++++++++++++-------
 repair/xfs_repair.c  |    3 ++-
 15 files changed, 124 insertions(+), 68 deletions(-)

Comments

Christoph Hellwig Feb. 21, 2020, 2:53 p.m. UTC | #1
On Wed, Feb 19, 2020 at 05:43:55PM -0800, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> libxfs_writebuf is not a well named function -- it marks the buffer
> dirty and then releases the caller's reference.  The actual write comes
> when the cache is flushed, either because someone explicitly told the
> cache to flush or because we started buffer reclaim.
> 
> Make the buffer release explicit in the callers and rename the function
> to say what it actually does -- it marks the buffer dirty outside of
> transaction context.

FYI, before we made all buffer writes delwri or sync in the kernel the
equivalent function was called xfs_buf_bawrite.  But I'm not sure that
was a better name.  But maybe libxfs_buf_mark_dirty is a tad better?

Otherwise looks good.
Darrick J. Wong Feb. 21, 2020, 3:54 p.m. UTC | #2
On Fri, Feb 21, 2020 at 06:53:05AM -0800, Christoph Hellwig wrote:
> On Wed, Feb 19, 2020 at 05:43:55PM -0800, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > libxfs_writebuf is not a well named function -- it marks the buffer
> > dirty and then releases the caller's reference.  The actual write comes
> > when the cache is flushed, either because someone explicitly told the
> > cache to flush or because we started buffer reclaim.
> > 
> > Make the buffer release explicit in the callers and rename the function
> > to say what it actually does -- it marks the buffer dirty outside of
> > transaction context.
> 
> FYI, before we made all buffer writes delwri or sync in the kernel the
> equivalent function was called xfs_buf_bawrite.

Heh, yeah... I've been reviewing old Unixen books lately and finally
know where all those weird names came from.

> But I'm not sure that
> was a better name.  But maybe libxfs_buf_mark_dirty is a tad better?

Ok.

--D

> Otherwise looks good.
>
diff mbox series

Patch

diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index 6598dba7..ad8acc1e 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -138,8 +138,8 @@  extern struct cache_operations	libxfs_bcache_operations;
 #define libxfs_readbuf_map(dev, map, nmaps, flags, ops) \
 	libxfs_trace_readbuf_map(__FUNCTION__, __FILE__, __LINE__, \
 			    (dev), (map), (nmaps), (flags), (ops))
-#define libxfs_writebuf(buf, flags) \
-	libxfs_trace_writebuf(__FUNCTION__, __FILE__, __LINE__, \
+#define libxfs_buf_dirty(buf, flags) \
+	libxfs_trace_dirtybuf(__FUNCTION__, __FILE__, __LINE__, \
 			      (buf), (flags))
 #define libxfs_buf_get(dev, daddr, len) \
 	libxfs_trace_getbuf(__FUNCTION__, __FILE__, __LINE__, \
@@ -159,8 +159,8 @@  struct xfs_buf *libxfs_trace_readbuf(const char *func, const char *file,
 extern xfs_buf_t *libxfs_trace_readbuf_map(const char *, const char *, int,
 			struct xfs_buftarg *, struct xfs_buf_map *, int, int,
 			const struct xfs_buf_ops *);
-extern int	libxfs_trace_writebuf(const char *, const char *, int,
-			xfs_buf_t *, int);
+void libxfs_trace_dirtybuf(const char *func, const char *file, int line,
+			struct xfs_buf *bp, int flags);
 struct xfs_buf *libxfs_trace_getbuf(const char *func, const char *file,
 			int line, struct xfs_buftarg *btp, xfs_daddr_t daddr,
 			size_t len);
@@ -175,7 +175,7 @@  extern void	libxfs_trace_putbuf (const char *, const char *, int,
 
 extern xfs_buf_t *libxfs_readbuf_map(struct xfs_buftarg *, struct xfs_buf_map *,
 			int, int, const struct xfs_buf_ops *);
-extern int	libxfs_writebuf(xfs_buf_t *, int);
+void libxfs_buf_dirty(struct xfs_buf *bp, int flags);
 extern xfs_buf_t *libxfs_getbuf_map(struct xfs_buftarg *,
 			struct xfs_buf_map *, int, int);
 extern xfs_buf_t *libxfs_getbuf_flags(struct xfs_buftarg *, xfs_daddr_t,
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 20a8b0ce..af363bef 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -425,11 +425,16 @@  libxfs_trace_readbuf(
 	return bp;
 }
 
-int
-libxfs_trace_writebuf(const char *func, const char *file, int line, xfs_buf_t *bp, int flags)
+void
+libxfs_trace_dirtybuf(
+	const char		*func,
+	const char		*file,
+	int			line,
+	struct xfs_buf		*bp,
+	int			flags)
 {
 	__add_trace(bp, func, file, line);
-	return libxfs_writebuf(bp, flags);
+	libxfs_buf_dirty(bp, flags);
 }
 
 struct xfs_buf *
@@ -1233,8 +1238,12 @@  libxfs_writebuf_int(xfs_buf_t *bp, int flags)
 	return 0;
 }
 
-int
-libxfs_writebuf(
+/*
+ * Mark a buffer dirty.  The dirty data will be written out when the cache
+ * is flushed (or at release time if the buffer is uncached).
+ */
+void
+libxfs_buf_dirty(
 	struct xfs_buf	*bp,
 	int		flags)
 {
@@ -1256,8 +1265,6 @@  libxfs_writebuf(
 	bp->b_error = 0;
 	bp->b_flags &= ~LIBXFS_B_STALE;
 	bp->b_flags |= bflags;
-	libxfs_buf_relse(bp);
-	return 0;
 }
 
 void
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 59cb897f..4c208422 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -843,7 +843,8 @@  inode_item_done(
 		goto free;
 	}
 
-	libxfs_writebuf(bp, 0);
+	libxfs_buf_dirty(bp, 0);
+	libxfs_buf_relse(bp);
 free:
 	xfs_inode_item_put(iip);
 }
diff --git a/mkfs/proto.c b/mkfs/proto.c
index 0025fa08..de5ae306 100644
--- a/mkfs/proto.c
+++ b/mkfs/proto.c
@@ -261,8 +261,10 @@  newfile(
 			memset((char *)bp->b_addr + len, 0, bp->b_bcount - len);
 		if (logit)
 			libxfs_trans_log_buf(tp, bp, 0, bp->b_bcount - 1);
-		else
-			libxfs_writebuf(bp, LIBXFS_WRITEBUF_FAIL_EXIT);
+		else {
+			libxfs_buf_dirty(bp, LIBXFS_WRITEBUF_FAIL_EXIT);
+			libxfs_buf_relse(bp);
+		}
 	}
 	ip->i_d.di_size = len;
 	return flags;
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index f58f235d..b50b8b3a 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3462,7 +3462,8 @@  prepare_devices(
 	buf = get_write_buf(mp->m_ddev_targp, (xi->dsize - whack_blks),
 			whack_blks);
 	memset(buf->b_addr, 0, WHACK_SIZE);
-	libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_relse(buf);
 
 	/*
 	 * Now zero out the beginning of the device, to obliterate any old
@@ -3472,7 +3473,8 @@  prepare_devices(
 	 */
 	buf = get_write_buf(mp->m_ddev_targp, 0, whack_blks);
 	memset(buf->b_addr, 0, WHACK_SIZE);
-	libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_relse(buf);
 
 	/* OK, now write the superblock... */
 	buf = get_write_buf(mp->m_ddev_targp, XFS_SB_DADDR,
@@ -3480,7 +3482,8 @@  prepare_devices(
 	buf->b_ops = &xfs_sb_buf_ops;
 	memset(buf->b_addr, 0, cfg->sectorsize);
 	libxfs_sb_to_disk(buf->b_addr, sbp);
-	libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_relse(buf);
 
 	/* ...and zero the log.... */
 	lsunit = sbp->sb_logsunit;
@@ -3499,7 +3502,8 @@  prepare_devices(
 				XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
 				BTOBB(cfg->blocksize));
 		memset(buf->b_addr, 0, cfg->blocksize);
-		libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+		libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+		libxfs_buf_relse(buf);
 	}
 
 }
@@ -3591,7 +3595,8 @@  rewrite_secondary_superblocks(
 			XFS_FSS_TO_BB(mp, 1),
 			LIBXFS_READBUF_FAIL_EXIT, &xfs_sb_buf_ops);
 	XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
-	libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_relse(buf);
 
 	/* and one in the middle for luck if there's enough AGs for that */
 	if (mp->m_sb.sb_agcount <= 2)
@@ -3603,7 +3608,8 @@  rewrite_secondary_superblocks(
 			XFS_FSS_TO_BB(mp, 1),
 			LIBXFS_READBUF_FAIL_EXIT, &xfs_sb_buf_ops);
 	XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
-	libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_relse(buf);
 }
 
 static void
@@ -3951,7 +3957,8 @@  main(
 	if (!buf || buf->b_error)
 		exit(1);
 	(XFS_BUF_TO_SBP(buf))->sb_inprogress = 0;
-	libxfs_writebuf(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_dirty(buf, LIBXFS_WRITEBUF_FAIL_EXIT);
+	libxfs_buf_relse(buf);
 
 	/* Make sure our new fs made it to stable storage. */
 	libxfs_flush_devices(mp, &d, &l, &r);
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index cc20b1a1..fb64b0be 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -835,8 +835,10 @@  process_leaf_attr_level(xfs_mount_t	*mp,
 		if (!no_modify && bp->b_error == -EFSBADCRC)
 			repair++;
 
-		if (repair && !no_modify)
-			libxfs_writebuf(bp, 0);
+		if (repair && !no_modify) {
+			libxfs_buf_dirty(bp, 0);
+			libxfs_buf_relse(bp);
+		}
 		else
 			libxfs_buf_relse(bp);
 	} while (da_bno != 0);
@@ -999,9 +1001,8 @@  _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "
 	*repair = *repair || repairlinks;
 
 	if (*repair && !no_modify)
-		libxfs_writebuf(bp, 0);
-	else
-		libxfs_buf_relse(bp);
+		libxfs_buf_dirty(bp, 0);
+	libxfs_buf_relse(bp);
 
 	return 0;
 }
@@ -1043,9 +1044,9 @@  _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "
 	/* must do this now, to release block 0 before the traversal */
 	if ((*repair || repairlinks) && !no_modify) {
 		*repair = 1;
-		libxfs_writebuf(bp, 0);
-	} else
-		libxfs_buf_relse(bp);
+		libxfs_buf_dirty(bp, 0);
+	}
+	libxfs_buf_relse(bp);
 	error = process_node_attr(mp, ino, dip, blkmap); /* + repair */
 	if (error)
 		*repair = 0;
diff --git a/repair/da_util.c b/repair/da_util.c
index c02d621c..d1e17ec3 100644
--- a/repair/da_util.c
+++ b/repair/da_util.c
@@ -403,8 +403,10 @@  _("would correct bad hashval in non-leaf %s block\n"
 	ASSERT(cursor->level[this_level].dirty == 0 ||
 		(cursor->level[this_level].dirty && !no_modify));
 
-	if (cursor->level[this_level].dirty && !no_modify)
-		libxfs_writebuf(cursor->level[this_level].bp, 0);
+	if (cursor->level[this_level].dirty && !no_modify) {
+		libxfs_buf_dirty(cursor->level[this_level].bp, 0);
+		libxfs_buf_relse(cursor->level[this_level].bp);
+	}
 	else
 		libxfs_buf_relse(cursor->level[this_level].bp);
 
@@ -619,8 +621,10 @@  _("bad level %d in %s block %u for inode %" PRIu64 "\n"),
 		    cursor->level[this_level].bp->b_error == -EFSBADCRC)
 			cursor->level[this_level].dirty = 1;
 
-		if (cursor->level[this_level].dirty && !no_modify)
-			libxfs_writebuf(cursor->level[this_level].bp, 0);
+		if (cursor->level[this_level].dirty && !no_modify) {
+			libxfs_buf_dirty(cursor->level[this_level].bp, 0);
+			libxfs_buf_relse(cursor->level[this_level].bp);
+		}
 		else
 			libxfs_buf_relse(cursor->level[this_level].bp);
 
diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c
index 76e9f773..1378fc59 100644
--- a/repair/dino_chunks.c
+++ b/repair/dino_chunks.c
@@ -939,8 +939,10 @@  process_inode_chunk(
 					bplist[bp_index], (long long)
 					XFS_BUF_ADDR(bplist[bp_index]), agno);
 
-				if (dirty && !no_modify)
-					libxfs_writebuf(bplist[bp_index], 0);
+				if (dirty && !no_modify) {
+					libxfs_buf_dirty(bplist[bp_index], 0);
+					libxfs_buf_relse(bplist[bp_index]);
+				}
 				else
 					libxfs_buf_relse(bplist[bp_index]);
 			}
diff --git a/repair/dinode.c b/repair/dinode.c
index 848eac09..276dd2e1 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -1231,8 +1231,10 @@  _("cannot read inode %" PRIu64 ", file block %" PRIu64 ", disk block %" PRIu64 "
 			}
 		}
 
-		if (writebuf && !no_modify)
-			libxfs_writebuf(bp, 0);
+		if (writebuf && !no_modify) {
+			libxfs_buf_dirty(bp, 0);
+			libxfs_buf_relse(bp);
+		}
 		else
 			libxfs_buf_relse(bp);
 	}
@@ -1328,8 +1330,10 @@  _("bad symlink header ino %" PRIu64 ", file block %d, disk block %" PRIu64 "\n")
 		offset += byte_cnt;
 		i++;
 
-		if (badcrc && !no_modify)
-			libxfs_writebuf(bp, 0);
+		if (badcrc && !no_modify) {
+			libxfs_buf_dirty(bp, 0);
+			libxfs_buf_relse(bp);
+		}
 		else
 			libxfs_buf_relse(bp);
 	}
diff --git a/repair/dir2.c b/repair/dir2.c
index 769e341c..a8b8de58 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -1010,7 +1010,8 @@  _("bad directory block magic # %#x in block %u for directory inode %" PRIu64 "\n
 		dirty = 1;
 	if (dirty && !no_modify) {
 		*repair = 1;
-		libxfs_writebuf(bp, 0);
+		libxfs_buf_dirty(bp, 0);
+		libxfs_buf_relse(bp);
 	} else
 		libxfs_buf_relse(bp);
 	return rval;
@@ -1180,7 +1181,8 @@  _("bad sibling back pointer for block %u in directory inode %" PRIu64 "\n"),
 		ASSERT(buf_dirty == 0 || (buf_dirty && !no_modify));
 		if (buf_dirty && !no_modify) {
 			*repair = 1;
-			libxfs_writebuf(bp, 0);
+			libxfs_buf_dirty(bp, 0);
+			libxfs_buf_relse(bp);
 		} else
 			libxfs_buf_relse(bp);
 	} while (da_bno != 0);
@@ -1339,7 +1341,8 @@  _("bad directory block magic # %#x in block %" PRIu64 " for directory inode %" P
 		}
 		if (dirty && !no_modify) {
 			*repair = 1;
-			libxfs_writebuf(bp, 0);
+			libxfs_buf_dirty(bp, 0);
+			libxfs_buf_relse(bp);
 		} else
 			libxfs_buf_relse(bp);
 	}
diff --git a/repair/phase3.c b/repair/phase3.c
index 886acd1f..396743a4 100644
--- a/repair/phase3.c
+++ b/repair/phase3.c
@@ -46,8 +46,10 @@  process_agi_unlinked(
 		}
 	}
 
-	if (agi_dirty)
-		libxfs_writebuf(bp, 0);
+	if (agi_dirty) {
+		libxfs_buf_dirty(bp, 0);
+		libxfs_buf_relse(bp);
+	}
 	else
 		libxfs_buf_relse(bp);
 }
diff --git a/repair/phase5.c b/repair/phase5.c
index cdbf6697..561a6b3f 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -321,9 +321,11 @@  write_cursor(bt_status_t *curs)
 			fprintf(stderr, "writing bt prev block %u\n",
 						curs->level[i].prev_agbno);
 #endif
-			libxfs_writebuf(curs->level[i].prev_buf_p, 0);
+			libxfs_buf_dirty(curs->level[i].prev_buf_p, 0);
+			libxfs_buf_relse(curs->level[i].prev_buf_p);
 		}
-		libxfs_writebuf(curs->level[i].buf_p, 0);
+		libxfs_buf_dirty(curs->level[i].buf_p, 0);
+		libxfs_buf_relse(curs->level[i].buf_p);
 	}
 }
 
@@ -681,7 +683,8 @@  prop_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
 #endif
 		if (lptr->prev_agbno != NULLAGBLOCK) {
 			ASSERT(lptr->prev_buf_p != NULL);
-			libxfs_writebuf(lptr->prev_buf_p, 0);
+			libxfs_buf_dirty(lptr->prev_buf_p, 0);
+			libxfs_buf_relse(lptr->prev_buf_p);
 		}
 		lptr->prev_agbno = lptr->agbno;;
 		lptr->prev_buf_p = lptr->buf_p;
@@ -870,7 +873,8 @@  build_freespace_tree(xfs_mount_t *mp, xfs_agnumber_t agno,
 					lptr->prev_agbno);
 #endif
 				ASSERT(lptr->prev_agbno != NULLAGBLOCK);
-				libxfs_writebuf(lptr->prev_buf_p, 0);
+				libxfs_buf_dirty(lptr->prev_buf_p, 0);
+				libxfs_buf_relse(lptr->prev_buf_p);
 			}
 			lptr->prev_buf_p = lptr->buf_p;
 			lptr->prev_agbno = lptr->agbno;
@@ -1046,7 +1050,8 @@  prop_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs,
 #endif
 		if (lptr->prev_agbno != NULLAGBLOCK)  {
 			ASSERT(lptr->prev_buf_p != NULL);
-			libxfs_writebuf(lptr->prev_buf_p, 0);
+			libxfs_buf_dirty(lptr->prev_buf_p, 0);
+			libxfs_buf_relse(lptr->prev_buf_p);
 		}
 		lptr->prev_agbno = lptr->agbno;;
 		lptr->prev_buf_p = lptr->buf_p;
@@ -1137,7 +1142,8 @@  build_agi(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs,
 		agi->agi_free_level = cpu_to_be32(finobt_curs->num_levels);
 	}
 
-	libxfs_writebuf(agi_buf, 0);
+	libxfs_buf_dirty(agi_buf, 0);
+	libxfs_buf_relse(agi_buf);
 }
 
 /*
@@ -1299,7 +1305,8 @@  build_ino_tree(xfs_mount_t *mp, xfs_agnumber_t agno,
 					lptr->prev_agbno);
 #endif
 				ASSERT(lptr->prev_agbno != NULLAGBLOCK);
-				libxfs_writebuf(lptr->prev_buf_p, 0);
+				libxfs_buf_dirty(lptr->prev_buf_p, 0);
+				libxfs_buf_relse(lptr->prev_buf_p);
 			}
 			lptr->prev_buf_p = lptr->buf_p;
 			lptr->prev_agbno = lptr->agbno;
@@ -1451,7 +1458,8 @@  prop_rmap_cursor(
 #endif
 		if (lptr->prev_agbno != NULLAGBLOCK)  {
 			ASSERT(lptr->prev_buf_p != NULL);
-			libxfs_writebuf(lptr->prev_buf_p, 0);
+			libxfs_buf_dirty(lptr->prev_buf_p, 0);
+			libxfs_buf_relse(lptr->prev_buf_p);
 		}
 		lptr->prev_agbno = lptr->agbno;
 		lptr->prev_buf_p = lptr->buf_p;
@@ -1661,7 +1669,8 @@  _("Insufficient memory to construct reverse-map cursor."));
 					lptr->prev_agbno);
 #endif
 				ASSERT(lptr->prev_agbno != NULLAGBLOCK);
-				libxfs_writebuf(lptr->prev_buf_p, 0);
+				libxfs_buf_dirty(lptr->prev_buf_p, 0);
+				libxfs_buf_relse(lptr->prev_buf_p);
 			}
 			lptr->prev_buf_p = lptr->buf_p;
 			lptr->prev_agbno = lptr->agbno;
@@ -1801,7 +1810,8 @@  prop_refc_cursor(
 #endif
 		if (lptr->prev_agbno != NULLAGBLOCK)  {
 			ASSERT(lptr->prev_buf_p != NULL);
-			libxfs_writebuf(lptr->prev_buf_p, 0);
+			libxfs_buf_dirty(lptr->prev_buf_p, 0);
+			libxfs_buf_relse(lptr->prev_buf_p);
 		}
 		lptr->prev_agbno = lptr->agbno;
 		lptr->prev_buf_p = lptr->buf_p;
@@ -1954,7 +1964,8 @@  _("Insufficient memory to construct refcount cursor."));
 					lptr->prev_agbno);
 #endif
 				ASSERT(lptr->prev_agbno != NULLAGBLOCK);
-				libxfs_writebuf(lptr->prev_buf_p, 0);
+				libxfs_buf_dirty(lptr->prev_buf_p, 0);
+				libxfs_buf_relse(lptr->prev_buf_p);
 			}
 			lptr->prev_buf_p = lptr->buf_p;
 			lptr->prev_agbno = lptr->agbno;
@@ -2142,7 +2153,8 @@  _("Insufficient memory saving lost blocks.\n"));
 		agf->agf_flcount = 0;
 	}
 
-	libxfs_writebuf(agfl_buf, 0);
+	libxfs_buf_dirty(agfl_buf, 0);
+	libxfs_buf_relse(agfl_buf);
 
 	ext_ptr = findbiggest_bcnt_extent(agno);
 	agf->agf_longest = cpu_to_be32((ext_ptr != NULL) ?
@@ -2155,7 +2167,8 @@  _("Insufficient memory saving lost blocks.\n"));
 	ASSERT(be32_to_cpu(agf->agf_refcount_root) !=
 		be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi]));
 
-	libxfs_writebuf(agf_buf, 0);
+	libxfs_buf_dirty(agf_buf, 0);
+	libxfs_buf_relse(agf_buf);
 
 	/*
 	 * now fix up the free list appropriately
@@ -2189,7 +2202,8 @@  sync_sb(xfs_mount_t *mp)
 	update_sb_version(mp);
 
 	libxfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb);
-	libxfs_writebuf(bp, 0);
+	libxfs_buf_dirty(bp, 0);
+	libxfs_buf_relse(bp);
 }
 
 /*
diff --git a/repair/rmap.c b/repair/rmap.c
index bc53e6c0..c8c851a6 100644
--- a/repair/rmap.c
+++ b/repair/rmap.c
@@ -1231,7 +1231,8 @@  _("setting reflink flag on inode %"PRIu64"\n"),
 	else
 		dino->di_flags2 &= cpu_to_be64(~XFS_DIFLAG2_REFLINK);
 	libxfs_dinode_calc_crc(mp, dino);
-	libxfs_writebuf(buf, 0);
+	libxfs_buf_dirty(buf, 0);
+	libxfs_buf_relse(buf);
 
 	return 0;
 }
diff --git a/repair/scan.c b/repair/scan.c
index f4e4fef5..8b91b27e 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -151,8 +151,10 @@  scan_lbtree(
 
 	ASSERT(dirty == 0 || (dirty && !no_modify));
 
-	if ((dirty || badcrc) && !no_modify)
-		libxfs_writebuf(bp, 0);
+	if ((dirty || badcrc) && !no_modify) {
+		libxfs_buf_dirty(bp, 0);
+		libxfs_buf_relse(bp);
+	}
 	else
 		libxfs_buf_relse(bp);
 
@@ -2429,13 +2431,17 @@  scan_ag(
 		sb_dirty += (sbbuf->b_error == -EFSBADCRC);
 	}
 
-	if (agi_dirty && !no_modify)
-		libxfs_writebuf(agibuf, 0);
+	if (agi_dirty && !no_modify) {
+		libxfs_buf_dirty(agibuf, 0);
+		libxfs_buf_relse(agibuf);
+	}
 	else
 		libxfs_buf_relse(agibuf);
 
-	if (agf_dirty && !no_modify)
-		libxfs_writebuf(agfbuf, 0);
+	if (agf_dirty && !no_modify) {
+		libxfs_buf_dirty(agfbuf, 0);
+		libxfs_buf_relse(agfbuf);
+	}
 	else
 		libxfs_buf_relse(agfbuf);
 
@@ -2443,7 +2449,8 @@  scan_ag(
 		if (agno == 0)
 			memcpy(&mp->m_sb, sb, sizeof(xfs_sb_t));
 		libxfs_sb_to_disk(XFS_BUF_TO_SBP(sbbuf), sb);
-		libxfs_writebuf(sbbuf, 0);
+		libxfs_buf_dirty(sbbuf, 0);
+		libxfs_buf_relse(sbbuf);
 	} else
 		libxfs_buf_relse(sbbuf);
 	free(sb);
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 8642c5cd..2189c9fd 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -1126,7 +1126,8 @@  _("Note - stripe unit (%d) and width (%d) were copied from a backup superblock.\
 			be32_to_cpu(dsb->sb_unit), be32_to_cpu(dsb->sb_width));
 	}
 
-	libxfs_writebuf(sbp, 0);
+	libxfs_buf_dirty(sbp, 0);
+	libxfs_buf_relse(sbp);
 
 	/*
 	 * Done. Flush all cached buffers and inodes first to ensure all