mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
xfs: move cow_replace_mapping to xfs_bmap_util.c
Move the actual details of (partially) replacing a COW fork mapping to xfs_bmap_util.c so that all the code doing hairy operations on subsets of bmbt_irecs are kept together. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
parent
bcb0621204
commit
60a1dde9d2
|
|
@ -29,6 +29,7 @@
|
|||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "xfs_rtgroup.h"
|
||||
#include "xfs_bmap_util.h"
|
||||
#include "scrub/xfs_scrub.h"
|
||||
#include "scrub/scrub.h"
|
||||
#include "scrub/common.h"
|
||||
|
|
@ -537,98 +538,6 @@ xrep_cow_find_mapping(
|
|||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
#define REPLACE_LEFT_SIDE (1U << 0)
|
||||
#define REPLACE_RIGHT_SIDE (1U << 1)
|
||||
|
||||
/*
|
||||
* Given a CoW fork mapping @got and a replacement mapping @rep, map the space
|
||||
* described by @rep into the cow fork, pushing aside @got as necessary. @icur
|
||||
* must point to iext tree leaf containing @got.
|
||||
*/
|
||||
static inline void
|
||||
xrep_cow_replace_mapping(
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_iext_cursor *icur,
|
||||
struct xfs_bmbt_irec *got,
|
||||
struct xfs_bmbt_irec *rep)
|
||||
{
|
||||
struct xfs_ifork *ifp = xfs_ifork_ptr(ip, XFS_COW_FORK);
|
||||
xfs_fileoff_t rep_endoff =
|
||||
rep->br_startoff + rep->br_blockcount;
|
||||
xfs_fileoff_t got_endoff =
|
||||
got->br_startoff + got->br_blockcount;
|
||||
uint32_t state = BMAP_COWFORK;
|
||||
|
||||
ASSERT(rep->br_blockcount > 0);
|
||||
ASSERT(!isnullstartblock(got->br_startblock));
|
||||
ASSERT(got->br_startoff <= rep->br_startoff);
|
||||
ASSERT(got_endoff >= rep_endoff);
|
||||
|
||||
trace_xrep_cow_replace_mapping(ip, got, rep);
|
||||
|
||||
if (got->br_startoff == rep->br_startoff)
|
||||
state |= BMAP_LEFT_FILLING;
|
||||
if (got_endoff == rep_endoff)
|
||||
state |= BMAP_RIGHT_FILLING;
|
||||
|
||||
switch (state & (BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) {
|
||||
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
|
||||
/*
|
||||
* Replacement matches the whole mapping, update the record.
|
||||
*/
|
||||
xfs_iext_update_extent(ip, state, icur, rep);
|
||||
break;
|
||||
case BMAP_LEFT_FILLING:
|
||||
/*
|
||||
* Replace the first part of the mapping: Update the cursor
|
||||
* position with the new mapping, then add a record with the
|
||||
* tail of the old mapping.
|
||||
*/
|
||||
got->br_startoff = rep_endoff;
|
||||
got->br_blockcount -= rep->br_blockcount;
|
||||
got->br_startblock += rep->br_blockcount;
|
||||
|
||||
xfs_iext_update_extent(ip, state, icur, rep);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, got, state);
|
||||
break;
|
||||
case BMAP_RIGHT_FILLING:
|
||||
/*
|
||||
* Replacing the last part of the mapping. Shorten the current
|
||||
* mapping then add a record with the new mapping.
|
||||
*/
|
||||
got->br_blockcount -= rep->br_blockcount;
|
||||
|
||||
xfs_iext_update_extent(ip, state, icur, got);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, rep, state);
|
||||
break;
|
||||
case 0:
|
||||
/*
|
||||
* Replacing the middle of the extent. Shorten the current
|
||||
* mapping, add a new record with the new mapping, and add a
|
||||
* second new record with the tail of the old mapping.
|
||||
*/
|
||||
got->br_blockcount = rep->br_startoff - got->br_startoff;
|
||||
|
||||
struct xfs_bmbt_irec new = {
|
||||
.br_startoff = rep_endoff,
|
||||
.br_blockcount = got_endoff - rep_endoff,
|
||||
.br_state = got->br_state,
|
||||
.br_startblock = got->br_startblock +
|
||||
rep->br_blockcount +
|
||||
got->br_blockcount,
|
||||
};
|
||||
|
||||
xfs_iext_update_extent(ip, state, icur, got);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, rep, state);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, &new, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace the unwritten CoW staging extent backing the given file range with a
|
||||
* new space extent that isn't as problematic.
|
||||
|
|
@ -671,7 +580,7 @@ xrep_cow_replace_range(
|
|||
* Replace the old mapping with the new one, and commit the metadata
|
||||
* changes made so far.
|
||||
*/
|
||||
xrep_cow_replace_mapping(sc->ip, &icur, &got, &rep);
|
||||
xfs_bmap_replace_cow_mapping(sc->ip, &icur, &got, &rep);
|
||||
|
||||
xfs_inode_set_cowblocks_tag(sc->ip);
|
||||
error = xfs_defer_finish(&sc->tp);
|
||||
|
|
|
|||
|
|
@ -2671,47 +2671,6 @@ TRACE_EVENT(xrep_cow_mark_file_range,
|
|||
__entry->blockcount)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xrep_cow_replace_mapping,
|
||||
TP_PROTO(struct xfs_inode *ip, const struct xfs_bmbt_irec *got,
|
||||
const struct xfs_bmbt_irec *rep),
|
||||
TP_ARGS(ip, got, rep),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(xfs_ino_t, ino)
|
||||
__field(xfs_fsblock_t, startblock)
|
||||
__field(xfs_fileoff_t, startoff)
|
||||
__field(xfs_filblks_t, blockcount)
|
||||
__field(xfs_exntst_t, state)
|
||||
__field(xfs_fileoff_t, new_startoff)
|
||||
__field(xfs_fsblock_t, new_startblock)
|
||||
__field(xfs_extlen_t, new_blockcount)
|
||||
__field(xfs_exntst_t, new_state)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = ip->i_mount->m_super->s_dev;
|
||||
__entry->ino = I_INO(ip);
|
||||
__entry->startoff = got->br_startoff;
|
||||
__entry->startblock = got->br_startblock;
|
||||
__entry->blockcount = got->br_blockcount;
|
||||
__entry->state = got->br_state;
|
||||
__entry->new_startoff = rep->br_startoff;
|
||||
__entry->new_startblock = rep->br_startblock;
|
||||
__entry->new_blockcount = rep->br_blockcount;
|
||||
__entry->new_state = rep->br_state;
|
||||
),
|
||||
TP_printk("dev %d:%d ino 0x%llx startoff 0x%llx startblock 0x%llx fsbcount 0x%llx state 0x%x new_startoff 0x%llx new_startblock 0x%llx new_fsbcount 0x%x new_state 0x%x",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->ino,
|
||||
__entry->startoff,
|
||||
__entry->startblock,
|
||||
__entry->blockcount,
|
||||
__entry->state,
|
||||
__entry->new_startoff,
|
||||
__entry->new_startblock,
|
||||
__entry->new_blockcount,
|
||||
__entry->new_state)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xrep_cow_free_staging,
|
||||
TP_PROTO(const struct xfs_perag *pag, xfs_agblock_t agbno,
|
||||
xfs_extlen_t blockcount),
|
||||
|
|
|
|||
|
|
@ -1744,3 +1744,92 @@ xfs_swap_extents(
|
|||
xfs_trans_cancel(tp);
|
||||
goto out_unlock_ilock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a CoW fork mapping @got and a replacement mapping @rep, map the space
|
||||
* described by @rep into the cow fork, pushing aside @got as necessary. @icur
|
||||
* must point to iext tree leaf containing @got.
|
||||
*/
|
||||
void
|
||||
xfs_bmap_replace_cow_mapping(
|
||||
struct xfs_inode *ip,
|
||||
struct xfs_iext_cursor *icur,
|
||||
struct xfs_bmbt_irec *got,
|
||||
struct xfs_bmbt_irec *rep)
|
||||
{
|
||||
struct xfs_ifork *ifp = xfs_ifork_ptr(ip, XFS_COW_FORK);
|
||||
xfs_fileoff_t rep_endoff =
|
||||
rep->br_startoff + rep->br_blockcount;
|
||||
xfs_fileoff_t got_endoff =
|
||||
got->br_startoff + got->br_blockcount;
|
||||
uint32_t state = BMAP_COWFORK;
|
||||
|
||||
ASSERT(rep->br_blockcount > 0);
|
||||
ASSERT(!isnullstartblock(got->br_startblock));
|
||||
ASSERT(got->br_startoff <= rep->br_startoff);
|
||||
ASSERT(got_endoff >= rep_endoff);
|
||||
|
||||
trace_xfs_bmap_replace_cow_mapping(ip, got, rep);
|
||||
|
||||
if (got->br_startoff == rep->br_startoff)
|
||||
state |= BMAP_LEFT_FILLING;
|
||||
if (got_endoff == rep_endoff)
|
||||
state |= BMAP_RIGHT_FILLING;
|
||||
|
||||
switch (state & (BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING)) {
|
||||
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
|
||||
/*
|
||||
* Replacement matches the whole mapping, update the record.
|
||||
*/
|
||||
xfs_iext_update_extent(ip, state, icur, rep);
|
||||
break;
|
||||
case BMAP_LEFT_FILLING:
|
||||
/*
|
||||
* Replace the first part of the mapping: Update the cursor
|
||||
* position with the new mapping, then add a record with the
|
||||
* tail of the old mapping.
|
||||
*/
|
||||
got->br_startoff = rep_endoff;
|
||||
got->br_blockcount -= rep->br_blockcount;
|
||||
got->br_startblock += rep->br_blockcount;
|
||||
|
||||
xfs_iext_update_extent(ip, state, icur, rep);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, got, state);
|
||||
break;
|
||||
case BMAP_RIGHT_FILLING:
|
||||
/*
|
||||
* Replacing the last part of the mapping. Shorten the current
|
||||
* mapping then add a record with the new mapping.
|
||||
*/
|
||||
got->br_blockcount -= rep->br_blockcount;
|
||||
|
||||
xfs_iext_update_extent(ip, state, icur, got);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, rep, state);
|
||||
break;
|
||||
case 0:
|
||||
/*
|
||||
* Replacing the middle of the extent. Shorten the current
|
||||
* mapping, add a new record with the new mapping, and add a
|
||||
* second new record with the tail of the old mapping.
|
||||
*/
|
||||
got->br_blockcount = rep->br_startoff - got->br_startoff;
|
||||
|
||||
struct xfs_bmbt_irec new = {
|
||||
.br_startoff = rep_endoff,
|
||||
.br_blockcount = got_endoff - rep_endoff,
|
||||
.br_state = got->br_state,
|
||||
.br_startblock = got->br_startblock +
|
||||
rep->br_blockcount +
|
||||
got->br_blockcount,
|
||||
};
|
||||
|
||||
xfs_iext_update_extent(ip, state, icur, got);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, rep, state);
|
||||
xfs_iext_next(ifp, icur);
|
||||
xfs_iext_insert(ip, icur, &new, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,4 +81,8 @@ int xfs_bmap_count_blocks(struct xfs_trans *tp, struct xfs_inode *ip,
|
|||
int xfs_flush_unmap_range(struct xfs_inode *ip, xfs_off_t offset,
|
||||
xfs_off_t len);
|
||||
|
||||
void xfs_bmap_replace_cow_mapping(struct xfs_inode *ip,
|
||||
struct xfs_iext_cursor *icur, struct xfs_bmbt_irec *got,
|
||||
struct xfs_bmbt_irec *rep);
|
||||
|
||||
#endif /* __XFS_BMAP_UTIL_H__ */
|
||||
|
|
|
|||
|
|
@ -6439,6 +6439,47 @@ TRACE_EVENT(xfs_verify_media_error,
|
|||
__entry->error)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xfs_bmap_replace_cow_mapping,
|
||||
TP_PROTO(struct xfs_inode *ip, const struct xfs_bmbt_irec *got,
|
||||
const struct xfs_bmbt_irec *rep),
|
||||
TP_ARGS(ip, got, rep),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(xfs_ino_t, ino)
|
||||
__field(xfs_fsblock_t, startblock)
|
||||
__field(xfs_fileoff_t, startoff)
|
||||
__field(xfs_filblks_t, blockcount)
|
||||
__field(xfs_exntst_t, state)
|
||||
__field(xfs_fileoff_t, new_startoff)
|
||||
__field(xfs_fsblock_t, new_startblock)
|
||||
__field(xfs_extlen_t, new_blockcount)
|
||||
__field(xfs_exntst_t, new_state)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = ip->i_mount->m_super->s_dev;
|
||||
__entry->ino = I_INO(ip);
|
||||
__entry->startoff = got->br_startoff;
|
||||
__entry->startblock = got->br_startblock;
|
||||
__entry->blockcount = got->br_blockcount;
|
||||
__entry->state = got->br_state;
|
||||
__entry->new_startoff = rep->br_startoff;
|
||||
__entry->new_startblock = rep->br_startblock;
|
||||
__entry->new_blockcount = rep->br_blockcount;
|
||||
__entry->new_state = rep->br_state;
|
||||
),
|
||||
TP_printk("dev %d:%d ino 0x%llx startoff 0x%llx startblock 0x%llx fsbcount 0x%llx state 0x%x new_startoff 0x%llx new_startblock 0x%llx new_fsbcount 0x%x new_state 0x%x",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->ino,
|
||||
__entry->startoff,
|
||||
__entry->startblock,
|
||||
__entry->blockcount,
|
||||
__entry->state,
|
||||
__entry->new_startoff,
|
||||
__entry->new_startblock,
|
||||
__entry->new_blockcount,
|
||||
__entry->new_state)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_XFS_H */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user