mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
xfs: pass the xfs_bmbt_irec directly through the log intent code
Instead of repeatedly boxing and unboxing the incore extent mapping structure as it passes through the BUI code, pass the pointer directly through. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
8954c44ff4
commit
ddccb81b26
@ -6146,39 +6146,37 @@ xfs_bmap_unmap_extent(
|
||||
int
|
||||
xfs_bmap_finish_one(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *ip,
|
||||
enum xfs_bmap_intent_type type,
|
||||
int whichfork,
|
||||
xfs_fileoff_t startoff,
|
||||
xfs_fsblock_t startblock,
|
||||
xfs_filblks_t *blockcount,
|
||||
xfs_exntst_t state)
|
||||
struct xfs_bmap_intent *bi)
|
||||
{
|
||||
struct xfs_bmbt_irec *bmap = &bi->bi_bmap;
|
||||
int error = 0;
|
||||
|
||||
ASSERT(tp->t_firstblock == NULLFSBLOCK);
|
||||
|
||||
trace_xfs_bmap_deferred(tp->t_mountp,
|
||||
XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type,
|
||||
XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
|
||||
ip->i_ino, whichfork, startoff, *blockcount, state);
|
||||
XFS_FSB_TO_AGNO(tp->t_mountp, bmap->br_startblock),
|
||||
bi->bi_type,
|
||||
XFS_FSB_TO_AGBNO(tp->t_mountp, bmap->br_startblock),
|
||||
bi->bi_owner->i_ino, bi->bi_whichfork,
|
||||
bmap->br_startoff, bmap->br_blockcount,
|
||||
bmap->br_state);
|
||||
|
||||
if (WARN_ON_ONCE(whichfork != XFS_DATA_FORK))
|
||||
if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK))
|
||||
return -EFSCORRUPTED;
|
||||
|
||||
if (XFS_TEST_ERROR(false, tp->t_mountp,
|
||||
XFS_ERRTAG_BMAP_FINISH_ONE))
|
||||
return -EIO;
|
||||
|
||||
switch (type) {
|
||||
switch (bi->bi_type) {
|
||||
case XFS_BMAP_MAP:
|
||||
error = xfs_bmapi_remap(tp, ip, startoff, *blockcount,
|
||||
startblock, 0);
|
||||
*blockcount = 0;
|
||||
error = xfs_bmapi_remap(tp, bi->bi_owner, bmap->br_startoff,
|
||||
bmap->br_blockcount, bmap->br_startblock, 0);
|
||||
bmap->br_blockcount = 0;
|
||||
break;
|
||||
case XFS_BMAP_UNMAP:
|
||||
error = __xfs_bunmapi(tp, ip, startoff, blockcount,
|
||||
XFS_BMAPI_REMAP, 1);
|
||||
error = __xfs_bunmapi(tp, bi->bi_owner, bmap->br_startoff,
|
||||
&bmap->br_blockcount, XFS_BMAPI_REMAP, 1);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
|
@ -234,10 +234,7 @@ struct xfs_bmap_intent {
|
||||
struct xfs_bmbt_irec bi_bmap;
|
||||
};
|
||||
|
||||
int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_inode *ip,
|
||||
enum xfs_bmap_intent_type type, int whichfork,
|
||||
xfs_fileoff_t startoff, xfs_fsblock_t startblock,
|
||||
xfs_filblks_t *blockcount, xfs_exntst_t state);
|
||||
int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi);
|
||||
void xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
|
||||
struct xfs_bmbt_irec *imap);
|
||||
void xfs_bmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip,
|
||||
|
@ -246,18 +246,11 @@ static int
|
||||
xfs_trans_log_finish_bmap_update(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_bud_log_item *budp,
|
||||
enum xfs_bmap_intent_type type,
|
||||
struct xfs_inode *ip,
|
||||
int whichfork,
|
||||
xfs_fileoff_t startoff,
|
||||
xfs_fsblock_t startblock,
|
||||
xfs_filblks_t *blockcount,
|
||||
xfs_exntst_t state)
|
||||
struct xfs_bmap_intent *bi)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = xfs_bmap_finish_one(tp, ip, type, whichfork, startoff,
|
||||
startblock, blockcount, state);
|
||||
error = xfs_bmap_finish_one(tp, bi);
|
||||
|
||||
/*
|
||||
* Mark the transaction dirty, even on error. This ensures the
|
||||
@ -378,25 +371,17 @@ xfs_bmap_update_finish_item(
|
||||
struct list_head *item,
|
||||
struct xfs_btree_cur **state)
|
||||
{
|
||||
struct xfs_bmap_intent *bmap;
|
||||
xfs_filblks_t count;
|
||||
struct xfs_bmap_intent *bi;
|
||||
int error;
|
||||
|
||||
bmap = container_of(item, struct xfs_bmap_intent, bi_list);
|
||||
count = bmap->bi_bmap.br_blockcount;
|
||||
error = xfs_trans_log_finish_bmap_update(tp, BUD_ITEM(done),
|
||||
bmap->bi_type,
|
||||
bmap->bi_owner, bmap->bi_whichfork,
|
||||
bmap->bi_bmap.br_startoff,
|
||||
bmap->bi_bmap.br_startblock,
|
||||
&count,
|
||||
bmap->bi_bmap.br_state);
|
||||
if (!error && count > 0) {
|
||||
ASSERT(bmap->bi_type == XFS_BMAP_UNMAP);
|
||||
bmap->bi_bmap.br_blockcount = count;
|
||||
bi = container_of(item, struct xfs_bmap_intent, bi_list);
|
||||
|
||||
error = xfs_trans_log_finish_bmap_update(tp, BUD_ITEM(done), bi);
|
||||
if (!error && bi->bi_bmap.br_blockcount > 0) {
|
||||
ASSERT(bi->bi_type == XFS_BMAP_UNMAP);
|
||||
return -EAGAIN;
|
||||
}
|
||||
kmem_cache_free(xfs_bmap_intent_cache, bmap);
|
||||
kmem_cache_free(xfs_bmap_intent_cache, bi);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -471,17 +456,13 @@ xfs_bui_item_recover(
|
||||
struct xfs_log_item *lip,
|
||||
struct list_head *capture_list)
|
||||
{
|
||||
struct xfs_bmbt_irec irec;
|
||||
struct xfs_bmap_intent fake = { };
|
||||
struct xfs_bui_log_item *buip = BUI_ITEM(lip);
|
||||
struct xfs_trans *tp;
|
||||
struct xfs_inode *ip = NULL;
|
||||
struct xfs_mount *mp = lip->li_log->l_mp;
|
||||
struct xfs_map_extent *bmap;
|
||||
struct xfs_map_extent *map;
|
||||
struct xfs_bud_log_item *budp;
|
||||
xfs_filblks_t count;
|
||||
xfs_exntst_t state;
|
||||
unsigned int bui_type;
|
||||
int whichfork;
|
||||
int iext_delta;
|
||||
int error = 0;
|
||||
|
||||
@ -491,14 +472,12 @@ xfs_bui_item_recover(
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
bmap = &buip->bui_format.bui_extents[0];
|
||||
state = (bmap->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
|
||||
XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
|
||||
whichfork = (bmap->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
|
||||
map = &buip->bui_format.bui_extents[0];
|
||||
fake.bi_whichfork = (map->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
|
||||
XFS_ATTR_FORK : XFS_DATA_FORK;
|
||||
bui_type = bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
|
||||
fake.bi_type = map->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
|
||||
|
||||
error = xlog_recover_iget(mp, bmap->me_owner, &ip);
|
||||
error = xlog_recover_iget(mp, map->me_owner, &ip);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@ -512,34 +491,34 @@ xfs_bui_item_recover(
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ijoin(tp, ip, 0);
|
||||
|
||||
if (bui_type == XFS_BMAP_MAP)
|
||||
if (fake.bi_type == XFS_BMAP_MAP)
|
||||
iext_delta = XFS_IEXT_ADD_NOSPLIT_CNT;
|
||||
else
|
||||
iext_delta = XFS_IEXT_PUNCH_HOLE_CNT;
|
||||
|
||||
error = xfs_iext_count_may_overflow(ip, whichfork, iext_delta);
|
||||
error = xfs_iext_count_may_overflow(ip, fake.bi_whichfork, iext_delta);
|
||||
if (error == -EFBIG)
|
||||
error = xfs_iext_count_upgrade(tp, ip, iext_delta);
|
||||
if (error)
|
||||
goto err_cancel;
|
||||
|
||||
count = bmap->me_len;
|
||||
error = xfs_trans_log_finish_bmap_update(tp, budp, bui_type, ip,
|
||||
whichfork, bmap->me_startoff, bmap->me_startblock,
|
||||
&count, state);
|
||||
fake.bi_owner = ip;
|
||||
fake.bi_bmap.br_startblock = map->me_startblock;
|
||||
fake.bi_bmap.br_startoff = map->me_startoff;
|
||||
fake.bi_bmap.br_blockcount = map->me_len;
|
||||
fake.bi_bmap.br_state = (map->me_flags & XFS_BMAP_EXTENT_UNWRITTEN) ?
|
||||
XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
|
||||
|
||||
error = xfs_trans_log_finish_bmap_update(tp, budp, &fake);
|
||||
if (error == -EFSCORRUPTED)
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bmap,
|
||||
sizeof(*bmap));
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, map,
|
||||
sizeof(*map));
|
||||
if (error)
|
||||
goto err_cancel;
|
||||
|
||||
if (count > 0) {
|
||||
ASSERT(bui_type == XFS_BMAP_UNMAP);
|
||||
irec.br_startblock = bmap->me_startblock;
|
||||
irec.br_blockcount = count;
|
||||
irec.br_startoff = bmap->me_startoff;
|
||||
irec.br_state = state;
|
||||
xfs_bmap_unmap_extent(tp, ip, &irec);
|
||||
if (fake.bi_bmap.br_blockcount > 0) {
|
||||
ASSERT(fake.bi_type == XFS_BMAP_UNMAP);
|
||||
xfs_bmap_unmap_extent(tp, ip, &fake.bi_bmap);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user