Skip to content

Commit

Permalink
xfs: call xfs_buf_iodone directly
Browse files Browse the repository at this point in the history
All unmarked dirty buffers should be in the AIL and have log items
attached to them. Hence when they are written, we will run a
callback to remove the item from the AIL if appropriate. Now that
we've handled inode and dquot buffers, all remaining calls are to
xfs_buf_iodone() and so we can hard code this rather than use an
indirect call.

Signed-off-by: Dave Chinner <[email protected]>
Reviewed-by: Darrick J. Wong <[email protected]>
Reviewed-by: Amir Goldstein <[email protected]>
Reviewed-by: Brian Foster <[email protected]>
Signed-off-by: Darrick J. Wong <[email protected]>
  • Loading branch information
Dave Chinner authored and djwong committed Jul 6, 2020
1 parent 9fe5c77 commit b01d146
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 63 deletions.
24 changes: 8 additions & 16 deletions fs/xfs/xfs_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,6 @@ xfs_buf_find(
*/
if (bp->b_flags & XBF_STALE) {
ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);
ASSERT(bp->b_iodone == NULL);
bp->b_flags &= _XBF_KMEM | _XBF_PAGES;
bp->b_ops = NULL;
}
Expand Down Expand Up @@ -1194,20 +1193,20 @@ xfs_buf_ioend(
if (!bp->b_error && bp->b_io_error)
xfs_buf_ioerror(bp, bp->b_io_error);

/* Only validate buffers that were read without errors */
if (read && !bp->b_error && bp->b_ops) {
ASSERT(!bp->b_iodone);
bp->b_ops->verify_read(bp);
if (read) {
if (!bp->b_error && bp->b_ops)
bp->b_ops->verify_read(bp);
if (!bp->b_error)
bp->b_flags |= XBF_DONE;
xfs_buf_ioend_finish(bp);
return;
}

if (!bp->b_error) {
bp->b_flags &= ~XBF_WRITE_FAIL;
bp->b_flags |= XBF_DONE;
}

if (read)
goto out_finish;

/*
* If this is a log recovery buffer, we aren't doing transactional IO
* yet so we need to let it handle IO completions.
Expand All @@ -1226,14 +1225,7 @@ xfs_buf_ioend(
xfs_buf_dquot_iodone(bp);
return;
}

if (bp->b_iodone) {
(*(bp->b_iodone))(bp);
return;
}

out_finish:
xfs_buf_ioend_finish(bp);
xfs_buf_iodone(bp);
}

static void
Expand Down
6 changes: 1 addition & 5 deletions fs/xfs/xfs_buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
/*
* Base types
*/
struct xfs_buf;

#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL))

Expand Down Expand Up @@ -102,10 +103,6 @@ typedef struct xfs_buftarg {
struct ratelimit_state bt_ioerror_rl;
} xfs_buftarg_t;

struct xfs_buf;
typedef void (*xfs_buf_iodone_t)(struct xfs_buf *);


#define XB_PAGES 2

struct xfs_buf_map {
Expand Down Expand Up @@ -158,7 +155,6 @@ typedef struct xfs_buf {
xfs_buftarg_t *b_target; /* buffer target (device) */
void *b_addr; /* virtual address of buffer */
struct work_struct b_ioend_work;
xfs_buf_iodone_t b_iodone; /* I/O completion function */
struct completion b_iowait; /* queue for I/O waiters */
struct xfs_buf_log_item *b_log_item;
struct list_head b_li_list; /* Log items list head */
Expand Down
40 changes: 10 additions & 30 deletions fs/xfs/xfs_buf_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,6 @@ xfs_buf_item_unpin(
xfs_buf_do_callbacks(bp);
bp->b_log_item = NULL;
list_del_init(&bp->b_li_list);
bp->b_iodone = NULL;
} else {
xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
xfs_buf_item_relse(bp);
Expand Down Expand Up @@ -936,11 +935,7 @@ xfs_buf_item_free(
}

/*
* This is called when the buf log item is no longer needed. It should
* free the buf log item associated with the given buffer and clear
* the buffer's pointer to the buf log item. If there are no more
* items in the list, clear the b_iodone field of the buffer (see
* xfs_buf_attach_iodone() below).
* xfs_buf_item_relse() is called when the buf log item is no longer needed.
*/
void
xfs_buf_item_relse(
Expand All @@ -952,20 +947,14 @@ xfs_buf_item_relse(
ASSERT(!test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags));

bp->b_log_item = NULL;
if (list_empty(&bp->b_li_list))
bp->b_iodone = NULL;

xfs_buf_rele(bp);
xfs_buf_item_free(bip);
}


/*
* Add the given log item with its callback to the list of callbacks
* to be called when the buffer's I/O completes. If it is not set
* already, set the buffer's b_iodone() routine to be
* xfs_buf_iodone_callbacks() and link the log item into the list of
* items rooted at b_li_list.
* to be called when the buffer's I/O completes.
*/
void
xfs_buf_attach_iodone(
Expand All @@ -977,10 +966,6 @@ xfs_buf_attach_iodone(

lip->li_cb = cb;
list_add_tail(&lip->li_bio_list, &bp->b_li_list);

ASSERT(bp->b_iodone == NULL ||
bp->b_iodone == xfs_buf_iodone_callbacks);
bp->b_iodone = xfs_buf_iodone_callbacks;
}

/*
Expand Down Expand Up @@ -1096,7 +1081,6 @@ xfs_buf_iodone_callback_error(
goto out_stale;

trace_xfs_buf_item_iodone_async(bp, _RET_IP_);
ASSERT(bp->b_iodone != NULL);

cfg = xfs_error_get_cfg(mp, XFS_ERR_METADATA, bp->b_error);

Expand Down Expand Up @@ -1182,39 +1166,35 @@ xfs_buf_run_callbacks(
xfs_buf_do_callbacks(bp);
bp->b_log_item = NULL;
list_del_init(&bp->b_li_list);
bp->b_iodone = NULL;
}

/*
* This is the iodone() function for buffers which have had callbacks attached
* to them by xfs_buf_attach_iodone(). We need to iterate the items on the
* callback list, mark the buffer as having no more callbacks and then push the
* buffer through IO completion processing.
* Inode buffer iodone callback function.
*/
void
xfs_buf_iodone_callbacks(
xfs_buf_inode_iodone(
struct xfs_buf *bp)
{
xfs_buf_run_callbacks(bp);
xfs_buf_ioend(bp);
xfs_buf_ioend_finish(bp);
}

/*
* Inode buffer iodone callback function.
* Dquot buffer iodone callback function.
*/
void
xfs_buf_inode_iodone(
xfs_buf_dquot_iodone(
struct xfs_buf *bp)
{
xfs_buf_run_callbacks(bp);
xfs_buf_ioend_finish(bp);
}

/*
* Dquot buffer iodone callback function.
* Dirty buffer iodone callback function.
*/
void
xfs_buf_dquot_iodone(
xfs_buf_iodone(
struct xfs_buf *bp)
{
xfs_buf_run_callbacks(bp);
Expand All @@ -1229,7 +1209,7 @@ xfs_buf_dquot_iodone(
* care of cleaning up the buffer itself.
*/
void
xfs_buf_iodone(
xfs_buf_item_iodone(
struct xfs_buf *bp,
struct xfs_log_item *lip)
{
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/xfs_buf_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ bool xfs_buf_item_dirty_format(struct xfs_buf_log_item *);
void xfs_buf_attach_iodone(struct xfs_buf *,
void(*)(struct xfs_buf *, struct xfs_log_item *),
struct xfs_log_item *);
void xfs_buf_iodone_callbacks(struct xfs_buf *);
void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *);
void xfs_buf_item_iodone(struct xfs_buf *, struct xfs_log_item *);
void xfs_buf_inode_iodone(struct xfs_buf *);
void xfs_buf_dquot_iodone(struct xfs_buf *);
void xfs_buf_iodone(struct xfs_buf *);
bool xfs_buf_log_check_iovec(struct xfs_log_iovec *iovec);

extern kmem_zone_t *xfs_buf_item_zone;
Expand Down
13 changes: 3 additions & 10 deletions fs/xfs/xfs_trans_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,24 +465,17 @@ xfs_trans_dirty_buf(

ASSERT(bp->b_transp == tp);
ASSERT(bip != NULL);
ASSERT(bp->b_iodone == NULL ||
bp->b_iodone == xfs_buf_iodone_callbacks);

/*
* Mark the buffer as needing to be written out eventually,
* and set its iodone function to remove the buffer's buf log
* item from the AIL and free it when the buffer is flushed
* to disk. See xfs_buf_attach_iodone() for more details
* on li_cb and xfs_buf_iodone_callbacks().
* If we end up aborting this transaction, we trap this buffer
* inside the b_bdstrat callback so that this won't get written to
* disk.
* to disk.
*/
bp->b_flags |= XBF_DONE;

ASSERT(atomic_read(&bip->bli_refcount) > 0);
bp->b_iodone = xfs_buf_iodone_callbacks;
bip->bli_item.li_cb = xfs_buf_iodone;
bip->bli_item.li_cb = xfs_buf_item_iodone;

/*
* If we invalidated the buffer within this transaction, then
Expand Down Expand Up @@ -651,7 +644,7 @@ xfs_trans_stale_inode_buf(
ASSERT(atomic_read(&bip->bli_refcount) > 0);

bip->bli_flags |= XFS_BLI_STALE_INODE;
bip->bli_item.li_cb = xfs_buf_iodone;
bip->bli_item.li_cb = xfs_buf_item_iodone;
bp->b_flags |= _XBF_INODES;
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
}
Expand Down

0 comments on commit b01d146

Please sign in to comment.