diff mbox series

[4/6] libxfs: fix buffer refcounting in delwri_queue

Message ID 156114704472.1643538.14565976860288969023.stgit@magnolia (mailing list archive)
State Superseded
Headers show
Series xfs: help mkfs shed its AG initialization code | expand

Commit Message

Darrick J. Wong June 21, 2019, 7:57 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

In the kernel, xfs_buf_delwri_queue increments the buffer reference
count before putting the buffer on the buffer list, and the refcount is
decremented after the io completes for a net refcount change of zero.

In userspace, delwri_queue calls libxfs_writebuf, which puts the buffer.
delwri_queue is a no-op, for a net refcount change of -1.  This creates
problems for any callers that expect a net change of zero, so increment
the buffer refcount before calling writebuf.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/libxfs_io.h   |    7 +++++++
 libxfs/libxfs_priv.h |    1 -
 2 files changed, 7 insertions(+), 1 deletion(-)

Comments

Christoph Hellwig June 25, 2019, 10:40 a.m. UTC | #1
On Fri, Jun 21, 2019 at 12:57:24PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> In the kernel, xfs_buf_delwri_queue increments the buffer reference
> count before putting the buffer on the buffer list, and the refcount is
> decremented after the io completes for a net refcount change of zero.
> 
> In userspace, delwri_queue calls libxfs_writebuf, which puts the buffer.
> delwri_queue is a no-op, for a net refcount change of -1.  This creates
> problems for any callers that expect a net change of zero, so increment
> the buffer refcount before calling writebuf.

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index b6f8756a..c47a435d 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -243,4 +243,11 @@  xfs_buf_get_uncached(struct xfs_buftarg *targ, size_t bblen, int flags)
 	return bp;
 }
 
+static inline void
+xfs_buf_delwri_queue(struct xfs_buf *bp, struct list_head *buffer_list)
+{
+	bp->b_node.cn_count++;
+	libxfs_writebuf(bp, 0);
+}
+
 #endif	/* __LIBXFS_IO_H__ */
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index eb92942a..fd420f4f 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -381,7 +381,6 @@  roundup_64(uint64_t x, uint32_t y)
 #define xfs_buf_relse(bp)		libxfs_putbuf(bp)
 #define xfs_buf_get(devp,blkno,len)	(libxfs_getbuf((devp), (blkno), (len)))
 #define xfs_bwrite(bp)			libxfs_writebuf((bp), 0)
-#define xfs_buf_delwri_queue(bp, bl)	libxfs_writebuf((bp), 0)
 #define xfs_buf_delwri_submit(bl)	(0)
 #define xfs_buf_oneshot(bp)		((void) 0)