mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
Merge 870e3066fe ("Input: i8042 - swap old quirk combination with new quirk for more devices") into android14-6.1-lts
Steps on the way to 6.1.132 Change-Id: Ia2d3d402dafb292ae1ce15725f8a8372a9fb845a Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -1080,16 +1080,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/* Mivvy M310 */
|
||||
@@ -1159,9 +1157,7 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
},
|
||||
/*
|
||||
* A lot of modern Clevo barebones have touchpad and/or keyboard issues
|
||||
* after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
|
||||
* none of them have an external PS/2 port so this can safely be set for
|
||||
* all of them.
|
||||
* after suspend fixable with the forcenorestore quirk.
|
||||
* Clevo barebones come with board_vendor and/or system_vendor set to
|
||||
* either the very generic string "Notebook" and/or a different value
|
||||
* for each individual reseller. The only somewhat universal way to
|
||||
@@ -1171,29 +1167,25 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N140CU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "N141CU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
@@ -1205,29 +1197,19 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes
|
||||
* the keyboard very laggy for ~5 seconds after boot and
|
||||
* sometimes also after resume.
|
||||
* However both are required for the keyboard to not fail
|
||||
* completely sometimes after boot or resume.
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NHxxRZQ"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
/*
|
||||
* At least one modern Clevo barebone has the touchpad connected both
|
||||
@@ -1243,17 +1225,15 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NS50MU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX |
|
||||
SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
|
||||
SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOAUX |
|
||||
SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX |
|
||||
SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
|
||||
SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOAUX |
|
||||
SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
@@ -1265,8 +1245,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "P640RE"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
@@ -1277,16 +1262,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P65xH"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
@@ -1297,8 +1280,7 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P65_P67H"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
@@ -1309,8 +1291,7 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RP"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
@@ -1321,8 +1302,7 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P65_67RS"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
@@ -1333,22 +1313,43 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P67xRP"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PB51RF"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PB71RD"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PC70DR"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "PCX0DX_GN20"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
/* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */
|
||||
{
|
||||
@@ -1361,15 +1362,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X170SM"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
|
||||
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
|
||||
.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
|
||||
},
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -259,6 +259,30 @@ xfs_agino_range(
|
||||
return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free perag within the specified AG range, it is only used to free unused
|
||||
* perags under the error handling path.
|
||||
*/
|
||||
void
|
||||
xfs_free_unused_perag_range(
|
||||
struct xfs_mount *mp,
|
||||
xfs_agnumber_t agstart,
|
||||
xfs_agnumber_t agend)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t index;
|
||||
|
||||
for (index = agstart; index < agend; index++) {
|
||||
spin_lock(&mp->m_perag_lock);
|
||||
pag = radix_tree_delete(&mp->m_perag_tree, index);
|
||||
spin_unlock(&mp->m_perag_lock);
|
||||
if (!pag)
|
||||
break;
|
||||
xfs_buf_hash_destroy(pag);
|
||||
kmem_free(pag);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
xfs_initialize_perag(
|
||||
struct xfs_mount *mp,
|
||||
@@ -345,18 +369,14 @@ xfs_initialize_perag(
|
||||
return 0;
|
||||
|
||||
out_remove_pag:
|
||||
spin_lock(&mp->m_perag_lock);
|
||||
radix_tree_delete(&mp->m_perag_tree, index);
|
||||
spin_unlock(&mp->m_perag_lock);
|
||||
out_free_pag:
|
||||
kmem_free(pag);
|
||||
out_unwind_new_pags:
|
||||
/* unwind any prior newly initialized pags */
|
||||
for (index = first_initialised; index < agcount; index++) {
|
||||
pag = radix_tree_delete(&mp->m_perag_tree, index);
|
||||
if (!pag)
|
||||
break;
|
||||
xfs_buf_hash_destroy(pag);
|
||||
kmem_free(pag);
|
||||
}
|
||||
xfs_free_unused_perag_range(mp, first_initialised, agcount);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -906,7 +926,10 @@ xfs_ag_shrink_space(
|
||||
if (err2 != -ENOSPC)
|
||||
goto resv_err;
|
||||
|
||||
__xfs_free_extent_later(*tpp, args.fsbno, delta, NULL, true);
|
||||
err2 = __xfs_free_extent_later(*tpp, args.fsbno, delta, NULL,
|
||||
XFS_AG_RESV_NONE, true);
|
||||
if (err2)
|
||||
goto resv_err;
|
||||
|
||||
/*
|
||||
* Roll the transaction before trying to re-init the per-ag
|
||||
@@ -981,10 +1004,8 @@ xfs_ag_extend_space(
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = xfs_free_extent(tp, XFS_AGB_TO_FSB(pag->pag_mount, pag->pag_agno,
|
||||
be32_to_cpu(agf->agf_length) - len),
|
||||
len, &XFS_RMAP_OINFO_SKIP_UPDATE,
|
||||
XFS_AG_RESV_NONE);
|
||||
error = xfs_free_extent(tp, pag, be32_to_cpu(agf->agf_length) - len,
|
||||
len, &XFS_RMAP_OINFO_SKIP_UPDATE, XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ struct xfs_perag {
|
||||
#endif /* __KERNEL__ */
|
||||
};
|
||||
|
||||
|
||||
void xfs_free_unused_perag_range(struct xfs_mount *mp, xfs_agnumber_t agstart,
|
||||
xfs_agnumber_t agend);
|
||||
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t agcount,
|
||||
xfs_rfsblock_t dcount, xfs_agnumber_t *maxagi);
|
||||
int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
|
||||
|
||||
@@ -2485,43 +2485,50 @@ xfs_agfl_reset(
|
||||
* the real allocation can proceed. Deferring the free disconnects freeing up
|
||||
* the AGFL slot from freeing the block.
|
||||
*/
|
||||
STATIC void
|
||||
static int
|
||||
xfs_defer_agfl_block(
|
||||
struct xfs_trans *tp,
|
||||
xfs_agnumber_t agno,
|
||||
xfs_fsblock_t agbno,
|
||||
xfs_agblock_t agbno,
|
||||
struct xfs_owner_info *oinfo)
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_extent_free_item *new; /* new element */
|
||||
struct xfs_extent_free_item *xefi;
|
||||
xfs_fsblock_t fsbno = XFS_AGB_TO_FSB(mp, agno, agbno);
|
||||
|
||||
ASSERT(xfs_extfree_item_cache != NULL);
|
||||
ASSERT(oinfo != NULL);
|
||||
|
||||
new = kmem_cache_zalloc(xfs_extfree_item_cache,
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, fsbno)))
|
||||
return -EFSCORRUPTED;
|
||||
|
||||
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
|
||||
GFP_KERNEL | __GFP_NOFAIL);
|
||||
new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
|
||||
new->xefi_blockcount = 1;
|
||||
new->xefi_owner = oinfo->oi_owner;
|
||||
xefi->xefi_startblock = fsbno;
|
||||
xefi->xefi_blockcount = 1;
|
||||
xefi->xefi_owner = oinfo->oi_owner;
|
||||
xefi->xefi_agresv = XFS_AG_RESV_AGFL;
|
||||
|
||||
trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
|
||||
|
||||
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
|
||||
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &xefi->xefi_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the extent to the list of extents to be free at transaction end.
|
||||
* The list is maintained sorted (by block number).
|
||||
*/
|
||||
void
|
||||
int
|
||||
__xfs_free_extent_later(
|
||||
struct xfs_trans *tp,
|
||||
xfs_fsblock_t bno,
|
||||
xfs_filblks_t len,
|
||||
const struct xfs_owner_info *oinfo,
|
||||
enum xfs_ag_resv_type type,
|
||||
bool skip_discard)
|
||||
{
|
||||
struct xfs_extent_free_item *new; /* new element */
|
||||
struct xfs_extent_free_item *xefi;
|
||||
#ifdef DEBUG
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
xfs_agnumber_t agno;
|
||||
@@ -2539,28 +2546,34 @@ __xfs_free_extent_later(
|
||||
ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
|
||||
#endif
|
||||
ASSERT(xfs_extfree_item_cache != NULL);
|
||||
ASSERT(type != XFS_AG_RESV_AGFL);
|
||||
|
||||
new = kmem_cache_zalloc(xfs_extfree_item_cache,
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbext(mp, bno, len)))
|
||||
return -EFSCORRUPTED;
|
||||
|
||||
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
|
||||
GFP_KERNEL | __GFP_NOFAIL);
|
||||
new->xefi_startblock = bno;
|
||||
new->xefi_blockcount = (xfs_extlen_t)len;
|
||||
xefi->xefi_startblock = bno;
|
||||
xefi->xefi_blockcount = (xfs_extlen_t)len;
|
||||
xefi->xefi_agresv = type;
|
||||
if (skip_discard)
|
||||
new->xefi_flags |= XFS_EFI_SKIP_DISCARD;
|
||||
xefi->xefi_flags |= XFS_EFI_SKIP_DISCARD;
|
||||
if (oinfo) {
|
||||
ASSERT(oinfo->oi_offset == 0);
|
||||
|
||||
if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
|
||||
new->xefi_flags |= XFS_EFI_ATTR_FORK;
|
||||
xefi->xefi_flags |= XFS_EFI_ATTR_FORK;
|
||||
if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
|
||||
new->xefi_flags |= XFS_EFI_BMBT_BLOCK;
|
||||
new->xefi_owner = oinfo->oi_owner;
|
||||
xefi->xefi_flags |= XFS_EFI_BMBT_BLOCK;
|
||||
xefi->xefi_owner = oinfo->oi_owner;
|
||||
} else {
|
||||
new->xefi_owner = XFS_RMAP_OWN_NULL;
|
||||
xefi->xefi_owner = XFS_RMAP_OWN_NULL;
|
||||
}
|
||||
trace_xfs_bmap_free_defer(tp->t_mountp,
|
||||
XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
|
||||
XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
|
||||
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
|
||||
xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &xefi->xefi_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -2720,7 +2733,9 @@ xfs_alloc_fix_freelist(
|
||||
goto out_agbp_relse;
|
||||
|
||||
/* defer agfl frees */
|
||||
xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo);
|
||||
error = xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo);
|
||||
if (error)
|
||||
goto out_agbp_relse;
|
||||
}
|
||||
|
||||
targs.tp = tp;
|
||||
@@ -3447,7 +3462,8 @@ xfs_free_extent_fix_freelist(
|
||||
int
|
||||
__xfs_free_extent(
|
||||
struct xfs_trans *tp,
|
||||
xfs_fsblock_t bno,
|
||||
struct xfs_perag *pag,
|
||||
xfs_agblock_t agbno,
|
||||
xfs_extlen_t len,
|
||||
const struct xfs_owner_info *oinfo,
|
||||
enum xfs_ag_resv_type type,
|
||||
@@ -3455,12 +3471,9 @@ __xfs_free_extent(
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_buf *agbp;
|
||||
xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
|
||||
xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
|
||||
struct xfs_agf *agf;
|
||||
int error;
|
||||
unsigned int busy_flags = 0;
|
||||
struct xfs_perag *pag;
|
||||
|
||||
ASSERT(len != 0);
|
||||
ASSERT(type != XFS_AG_RESV_AGFL);
|
||||
@@ -3469,10 +3482,9 @@ __xfs_free_extent(
|
||||
XFS_ERRTAG_FREE_EXTENT))
|
||||
return -EIO;
|
||||
|
||||
pag = xfs_perag_get(mp, agno);
|
||||
error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
|
||||
if (error)
|
||||
goto err;
|
||||
return error;
|
||||
agf = agbp->b_addr;
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
|
||||
@@ -3486,20 +3498,18 @@ __xfs_free_extent(
|
||||
goto err_release;
|
||||
}
|
||||
|
||||
error = xfs_free_ag_extent(tp, agbp, agno, agbno, len, oinfo, type);
|
||||
error = xfs_free_ag_extent(tp, agbp, pag->pag_agno, agbno, len, oinfo,
|
||||
type);
|
||||
if (error)
|
||||
goto err_release;
|
||||
|
||||
if (skip_discard)
|
||||
busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
|
||||
xfs_extent_busy_insert(tp, pag, agbno, len, busy_flags);
|
||||
xfs_perag_put(pag);
|
||||
return 0;
|
||||
|
||||
err_release:
|
||||
xfs_trans_brelse(tp, agbp);
|
||||
err:
|
||||
xfs_perag_put(pag);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,8 @@ xfs_alloc_vextent(
|
||||
int /* error */
|
||||
__xfs_free_extent(
|
||||
struct xfs_trans *tp, /* transaction pointer */
|
||||
xfs_fsblock_t bno, /* starting block number of extent */
|
||||
struct xfs_perag *pag,
|
||||
xfs_agblock_t agbno,
|
||||
xfs_extlen_t len, /* length of extent */
|
||||
const struct xfs_owner_info *oinfo, /* extent owner */
|
||||
enum xfs_ag_resv_type type, /* block reservation type */
|
||||
@@ -139,12 +140,13 @@ __xfs_free_extent(
|
||||
static inline int
|
||||
xfs_free_extent(
|
||||
struct xfs_trans *tp,
|
||||
xfs_fsblock_t bno,
|
||||
struct xfs_perag *pag,
|
||||
xfs_agblock_t agbno,
|
||||
xfs_extlen_t len,
|
||||
const struct xfs_owner_info *oinfo,
|
||||
enum xfs_ag_resv_type type)
|
||||
{
|
||||
return __xfs_free_extent(tp, bno, len, oinfo, type, false);
|
||||
return __xfs_free_extent(tp, pag, agbno, len, oinfo, type, false);
|
||||
}
|
||||
|
||||
int /* error */
|
||||
@@ -211,9 +213,9 @@ xfs_buf_to_agfl_bno(
|
||||
return bp->b_addr;
|
||||
}
|
||||
|
||||
void __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
|
||||
int __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
|
||||
xfs_filblks_t len, const struct xfs_owner_info *oinfo,
|
||||
bool skip_discard);
|
||||
enum xfs_ag_resv_type type, bool skip_discard);
|
||||
|
||||
/*
|
||||
* List of extents to be free "later".
|
||||
@@ -225,20 +227,22 @@ struct xfs_extent_free_item {
|
||||
xfs_fsblock_t xefi_startblock;/* starting fs block number */
|
||||
xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
|
||||
unsigned int xefi_flags;
|
||||
enum xfs_ag_resv_type xefi_agresv;
|
||||
};
|
||||
|
||||
#define XFS_EFI_SKIP_DISCARD (1U << 0) /* don't issue discard */
|
||||
#define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */
|
||||
#define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */
|
||||
|
||||
static inline void
|
||||
static inline int
|
||||
xfs_free_extent_later(
|
||||
struct xfs_trans *tp,
|
||||
xfs_fsblock_t bno,
|
||||
xfs_filblks_t len,
|
||||
const struct xfs_owner_info *oinfo)
|
||||
const struct xfs_owner_info *oinfo,
|
||||
enum xfs_ag_resv_type type)
|
||||
{
|
||||
__xfs_free_extent_later(tp, bno, len, oinfo, false);
|
||||
return __xfs_free_extent_later(tp, bno, len, oinfo, type, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -421,10 +421,10 @@ xfs_attr_complete_op(
|
||||
bool do_replace = args->op_flags & XFS_DA_OP_REPLACE;
|
||||
|
||||
args->op_flags &= ~XFS_DA_OP_REPLACE;
|
||||
if (do_replace) {
|
||||
args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
|
||||
args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
|
||||
if (do_replace)
|
||||
return replace_state;
|
||||
}
|
||||
|
||||
return XFS_DAS_DONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "xfs_bmap.h"
|
||||
#include "xfs_bmap_util.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "xfs_errortag.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_quota.h"
|
||||
@@ -572,8 +572,13 @@ xfs_bmap_btree_to_extents(
|
||||
cblock = XFS_BUF_TO_BLOCK(cbp);
|
||||
if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))
|
||||
return error;
|
||||
|
||||
xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork);
|
||||
xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo);
|
||||
error = xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo,
|
||||
XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ip->i_nblocks--;
|
||||
xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
|
||||
xfs_trans_binval(tp, cbp);
|
||||
@@ -4992,7 +4997,6 @@ xfs_bmap_del_extent_real(
|
||||
xfs_fileoff_t del_endoff; /* first offset past del */
|
||||
int do_fx; /* free extent at end of routine */
|
||||
int error; /* error return value */
|
||||
int flags = 0;/* inode logging flags */
|
||||
struct xfs_bmbt_irec got; /* current extent entry */
|
||||
xfs_fileoff_t got_endoff; /* first offset past got */
|
||||
int i; /* temp state */
|
||||
@@ -5005,6 +5009,8 @@ xfs_bmap_del_extent_real(
|
||||
uint32_t state = xfs_bmap_fork_to_state(whichfork);
|
||||
struct xfs_bmbt_irec old;
|
||||
|
||||
*logflagsp = 0;
|
||||
|
||||
mp = ip->i_mount;
|
||||
XFS_STATS_INC(mp, xs_del_exlist);
|
||||
|
||||
@@ -5017,7 +5023,6 @@ xfs_bmap_del_extent_real(
|
||||
ASSERT(got_endoff >= del_endoff);
|
||||
ASSERT(!isnullstartblock(got.br_startblock));
|
||||
qfield = 0;
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
* If it's the case where the directory code is running with no block
|
||||
@@ -5033,13 +5038,13 @@ xfs_bmap_del_extent_real(
|
||||
del->br_startoff > got.br_startoff && del_endoff < got_endoff)
|
||||
return -ENOSPC;
|
||||
|
||||
flags = XFS_ILOG_CORE;
|
||||
*logflagsp = XFS_ILOG_CORE;
|
||||
if (whichfork == XFS_DATA_FORK && XFS_IS_REALTIME_INODE(ip)) {
|
||||
if (!(bflags & XFS_BMAPI_REMAP)) {
|
||||
error = xfs_rtfree_blocks(tp, del->br_startblock,
|
||||
del->br_blockcount);
|
||||
if (error)
|
||||
goto done;
|
||||
return error;
|
||||
}
|
||||
|
||||
do_fx = 0;
|
||||
@@ -5054,11 +5059,9 @@ xfs_bmap_del_extent_real(
|
||||
if (cur) {
|
||||
error = xfs_bmbt_lookup_eq(cur, &got, &i);
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (got.br_startoff == del->br_startoff)
|
||||
@@ -5075,17 +5078,15 @@ xfs_bmap_del_extent_real(
|
||||
xfs_iext_prev(ifp, icur);
|
||||
ifp->if_nextents--;
|
||||
|
||||
flags |= XFS_ILOG_CORE;
|
||||
*logflagsp |= XFS_ILOG_CORE;
|
||||
if (!cur) {
|
||||
flags |= xfs_ilog_fext(whichfork);
|
||||
*logflagsp |= xfs_ilog_fext(whichfork);
|
||||
break;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
return -EFSCORRUPTED;
|
||||
break;
|
||||
case BMAP_LEFT_FILLING:
|
||||
/*
|
||||
@@ -5096,12 +5097,12 @@ xfs_bmap_del_extent_real(
|
||||
got.br_blockcount -= del->br_blockcount;
|
||||
xfs_iext_update_extent(ip, state, icur, &got);
|
||||
if (!cur) {
|
||||
flags |= xfs_ilog_fext(whichfork);
|
||||
*logflagsp |= xfs_ilog_fext(whichfork);
|
||||
break;
|
||||
}
|
||||
error = xfs_bmbt_update(cur, &got);
|
||||
if (error)
|
||||
goto done;
|
||||
return error;
|
||||
break;
|
||||
case BMAP_RIGHT_FILLING:
|
||||
/*
|
||||
@@ -5110,12 +5111,12 @@ xfs_bmap_del_extent_real(
|
||||
got.br_blockcount -= del->br_blockcount;
|
||||
xfs_iext_update_extent(ip, state, icur, &got);
|
||||
if (!cur) {
|
||||
flags |= xfs_ilog_fext(whichfork);
|
||||
*logflagsp |= xfs_ilog_fext(whichfork);
|
||||
break;
|
||||
}
|
||||
error = xfs_bmbt_update(cur, &got);
|
||||
if (error)
|
||||
goto done;
|
||||
return error;
|
||||
break;
|
||||
case 0:
|
||||
/*
|
||||
@@ -5132,18 +5133,18 @@ xfs_bmap_del_extent_real(
|
||||
new.br_state = got.br_state;
|
||||
new.br_startblock = del_endblock;
|
||||
|
||||
flags |= XFS_ILOG_CORE;
|
||||
*logflagsp |= XFS_ILOG_CORE;
|
||||
if (cur) {
|
||||
error = xfs_bmbt_update(cur, &got);
|
||||
if (error)
|
||||
goto done;
|
||||
return error;
|
||||
error = xfs_btree_increment(cur, 0, &i);
|
||||
if (error)
|
||||
goto done;
|
||||
return error;
|
||||
cur->bc_rec.b = new;
|
||||
error = xfs_btree_insert(cur, &i);
|
||||
if (error && error != -ENOSPC)
|
||||
goto done;
|
||||
return error;
|
||||
/*
|
||||
* If get no-space back from btree insert, it tried a
|
||||
* split, and we have a zero block reservation. Fix up
|
||||
@@ -5156,33 +5157,28 @@ xfs_bmap_del_extent_real(
|
||||
*/
|
||||
error = xfs_bmbt_lookup_eq(cur, &got, &i);
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
return -EFSCORRUPTED;
|
||||
/*
|
||||
* Update the btree record back
|
||||
* to the original value.
|
||||
*/
|
||||
error = xfs_bmbt_update(cur, &old);
|
||||
if (error)
|
||||
goto done;
|
||||
return error;
|
||||
/*
|
||||
* Reset the extent record back
|
||||
* to the original value.
|
||||
*/
|
||||
xfs_iext_update_extent(ip, state, icur, &old);
|
||||
flags = 0;
|
||||
error = -ENOSPC;
|
||||
goto done;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
*logflagsp = 0;
|
||||
return -ENOSPC;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
return -EFSCORRUPTED;
|
||||
} else
|
||||
flags |= xfs_ilog_fext(whichfork);
|
||||
*logflagsp |= xfs_ilog_fext(whichfork);
|
||||
|
||||
ifp->if_nextents++;
|
||||
xfs_iext_next(ifp, icur);
|
||||
@@ -5200,10 +5196,13 @@ xfs_bmap_del_extent_real(
|
||||
if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {
|
||||
xfs_refcount_decrease_extent(tp, del);
|
||||
} else {
|
||||
__xfs_free_extent_later(tp, del->br_startblock,
|
||||
error = __xfs_free_extent_later(tp, del->br_startblock,
|
||||
del->br_blockcount, NULL,
|
||||
(bflags & XFS_BMAPI_NODISCARD) ||
|
||||
del->br_state == XFS_EXT_UNWRITTEN);
|
||||
XFS_AG_RESV_NONE,
|
||||
((bflags & XFS_BMAPI_NODISCARD) ||
|
||||
del->br_state == XFS_EXT_UNWRITTEN));
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5218,9 +5217,7 @@ xfs_bmap_del_extent_real(
|
||||
if (qfield && !(bflags & XFS_BMAPI_REMAP))
|
||||
xfs_trans_mod_dquot_byino(tp, ip, qfield, (long)-nblks);
|
||||
|
||||
done:
|
||||
*logflagsp = flags;
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6117,39 +6114,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);
|
||||
|
||||
@@ -236,10 +236,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,
|
||||
|
||||
@@ -285,11 +285,15 @@ xfs_bmbt_free_block(
|
||||
struct xfs_trans *tp = cur->bc_tp;
|
||||
xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
|
||||
struct xfs_owner_info oinfo;
|
||||
int error;
|
||||
|
||||
xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_ino.whichfork);
|
||||
xfs_free_extent_later(cur->bc_tp, fsbno, 1, &oinfo);
|
||||
ip->i_nblocks--;
|
||||
error = xfs_free_extent_later(cur->bc_tp, fsbno, 1, &oinfo,
|
||||
XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ip->i_nblocks--;
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
|
||||
return 0;
|
||||
|
||||
@@ -342,9 +342,7 @@ xfs_btree_bload_drop_buf(
|
||||
if (*bpp == NULL)
|
||||
return;
|
||||
|
||||
if (!xfs_buf_delwri_queue(*bpp, buffers_list))
|
||||
ASSERT(0);
|
||||
|
||||
xfs_buf_delwri_queue_here(*bpp, buffers_list);
|
||||
xfs_buf_relse(*bpp);
|
||||
*bpp = NULL;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,6 @@ struct xbtree_ifakeroot {
|
||||
|
||||
/* Number of bytes available for this fork in the inode. */
|
||||
unsigned int if_fork_size;
|
||||
|
||||
/* Fork format. */
|
||||
unsigned int if_format;
|
||||
|
||||
/* Number of records. */
|
||||
unsigned int if_extents;
|
||||
};
|
||||
|
||||
/* Cursor interactions with fake roots for inode-rooted btrees. */
|
||||
|
||||
@@ -2316,10 +2316,17 @@ xfs_da3_swap_lastblock(
|
||||
return error;
|
||||
/*
|
||||
* Copy the last block into the dead buffer and log it.
|
||||
* On CRC-enabled file systems, also update the stamped in blkno.
|
||||
*/
|
||||
memcpy(dead_buf->b_addr, last_buf->b_addr, args->geo->blksize);
|
||||
if (xfs_has_crc(mp)) {
|
||||
struct xfs_da3_blkinfo *da3 = dead_buf->b_addr;
|
||||
|
||||
da3->blkno = cpu_to_be64(xfs_buf_daddr(dead_buf));
|
||||
}
|
||||
xfs_trans_log_buf(tp, dead_buf, 0, args->geo->blksize - 1);
|
||||
dead_info = dead_buf->b_addr;
|
||||
|
||||
/*
|
||||
* Get values from the moved block.
|
||||
*/
|
||||
|
||||
@@ -98,7 +98,7 @@ typedef struct xfs_sb {
|
||||
uint32_t sb_blocksize; /* logical block size, bytes */
|
||||
xfs_rfsblock_t sb_dblocks; /* number of data blocks */
|
||||
xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */
|
||||
xfs_rtblock_t sb_rextents; /* number of realtime extents */
|
||||
xfs_rtbxlen_t sb_rextents; /* number of realtime extents */
|
||||
uuid_t sb_uuid; /* user-visible file system unique id */
|
||||
xfs_fsblock_t sb_logstart; /* starting block of log if internal */
|
||||
xfs_ino_t sb_rootino; /* root inode number */
|
||||
|
||||
@@ -1827,7 +1827,7 @@ xfs_dialloc(
|
||||
* might be sparse and only free the regions that are allocated as part of the
|
||||
* chunk.
|
||||
*/
|
||||
STATIC void
|
||||
static int
|
||||
xfs_difree_inode_chunk(
|
||||
struct xfs_trans *tp,
|
||||
xfs_agnumber_t agno,
|
||||
@@ -1844,10 +1844,10 @@ xfs_difree_inode_chunk(
|
||||
|
||||
if (!xfs_inobt_issparse(rec->ir_holemask)) {
|
||||
/* not sparse, calculate extent info directly */
|
||||
xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
|
||||
M_IGEO(mp)->ialloc_blks,
|
||||
&XFS_RMAP_OINFO_INODES);
|
||||
return;
|
||||
return xfs_free_extent_later(tp,
|
||||
XFS_AGB_TO_FSB(mp, agno, sagbno),
|
||||
M_IGEO(mp)->ialloc_blks, &XFS_RMAP_OINFO_INODES,
|
||||
XFS_AG_RESV_NONE);
|
||||
}
|
||||
|
||||
/* holemask is only 16-bits (fits in an unsigned long) */
|
||||
@@ -1864,6 +1864,8 @@ xfs_difree_inode_chunk(
|
||||
XFS_INOBT_HOLEMASK_BITS);
|
||||
nextbit = startidx + 1;
|
||||
while (startidx < XFS_INOBT_HOLEMASK_BITS) {
|
||||
int error;
|
||||
|
||||
nextbit = find_next_zero_bit(holemask, XFS_INOBT_HOLEMASK_BITS,
|
||||
nextbit);
|
||||
/*
|
||||
@@ -1889,8 +1891,11 @@ xfs_difree_inode_chunk(
|
||||
|
||||
ASSERT(agbno % mp->m_sb.sb_spino_align == 0);
|
||||
ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
|
||||
xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
|
||||
contigblk, &XFS_RMAP_OINFO_INODES);
|
||||
error = xfs_free_extent_later(tp,
|
||||
XFS_AGB_TO_FSB(mp, agno, agbno), contigblk,
|
||||
&XFS_RMAP_OINFO_INODES, XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* reset range to current bit and carry on... */
|
||||
startidx = endidx = nextbit;
|
||||
@@ -1898,6 +1903,7 @@ xfs_difree_inode_chunk(
|
||||
next:
|
||||
nextbit++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
@@ -1998,7 +2004,9 @@ xfs_difree_inobt(
|
||||
goto error0;
|
||||
}
|
||||
|
||||
xfs_difree_inode_chunk(tp, pag->pag_agno, &rec);
|
||||
error = xfs_difree_inode_chunk(tp, pag->pag_agno, &rec);
|
||||
if (error)
|
||||
goto error0;
|
||||
} else {
|
||||
xic->deleted = false;
|
||||
|
||||
|
||||
@@ -156,9 +156,11 @@ __xfs_inobt_free_block(
|
||||
struct xfs_buf *bp,
|
||||
enum xfs_ag_resv_type resv)
|
||||
{
|
||||
xfs_fsblock_t fsbno;
|
||||
|
||||
xfs_inobt_mod_blockcount(cur, -1);
|
||||
return xfs_free_extent(cur->bc_tp,
|
||||
XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp)), 1,
|
||||
fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp));
|
||||
return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
|
||||
&XFS_RMAP_OINFO_INOBT, resv);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,4 +131,26 @@ void xlog_check_buf_cancel_table(struct xlog *log);
|
||||
#define xlog_check_buf_cancel_table(log) do { } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Transform a regular reservation into one suitable for recovery of a log
|
||||
* intent item.
|
||||
*
|
||||
* Intent recovery only runs a single step of the transaction chain and defers
|
||||
* the rest to a separate transaction. Therefore, we reduce logcount to 1 here
|
||||
* to avoid livelocks if the log grant space is nearly exhausted due to the
|
||||
* recovered intent pinning the tail. Keep the same logflags to avoid tripping
|
||||
* asserts elsewhere. Struct copies abound below.
|
||||
*/
|
||||
static inline struct xfs_trans_res
|
||||
xlog_recover_resv(const struct xfs_trans_res *r)
|
||||
{
|
||||
struct xfs_trans_res ret = {
|
||||
.tr_logres = r->tr_logres,
|
||||
.tr_logcount = 1,
|
||||
.tr_logflags = r->tr_logflags,
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __XFS_LOG_RECOVER_H__ */
|
||||
|
||||
@@ -1129,8 +1129,11 @@ xfs_refcount_adjust_extents(
|
||||
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
|
||||
cur->bc_ag.pag->pag_agno,
|
||||
tmp.rc_startblock);
|
||||
xfs_free_extent_later(cur->bc_tp, fsbno,
|
||||
tmp.rc_blockcount, NULL);
|
||||
error = xfs_free_extent_later(cur->bc_tp, fsbno,
|
||||
tmp.rc_blockcount, NULL,
|
||||
XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
(*agbno) += tmp.rc_blockcount;
|
||||
@@ -1188,8 +1191,11 @@ xfs_refcount_adjust_extents(
|
||||
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
|
||||
cur->bc_ag.pag->pag_agno,
|
||||
ext.rc_startblock);
|
||||
xfs_free_extent_later(cur->bc_tp, fsbno,
|
||||
ext.rc_blockcount, NULL);
|
||||
error = xfs_free_extent_later(cur->bc_tp, fsbno,
|
||||
ext.rc_blockcount, NULL,
|
||||
XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
skip:
|
||||
@@ -1213,37 +1219,33 @@ out_error:
|
||||
STATIC int
|
||||
xfs_refcount_adjust(
|
||||
struct xfs_btree_cur *cur,
|
||||
xfs_agblock_t agbno,
|
||||
xfs_extlen_t aglen,
|
||||
xfs_agblock_t *new_agbno,
|
||||
xfs_extlen_t *new_aglen,
|
||||
xfs_agblock_t *agbno,
|
||||
xfs_extlen_t *aglen,
|
||||
enum xfs_refc_adjust_op adj)
|
||||
{
|
||||
bool shape_changed;
|
||||
int shape_changes = 0;
|
||||
int error;
|
||||
|
||||
*new_agbno = agbno;
|
||||
*new_aglen = aglen;
|
||||
if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
|
||||
trace_xfs_refcount_increase(cur->bc_mp, cur->bc_ag.pag->pag_agno,
|
||||
agbno, aglen);
|
||||
trace_xfs_refcount_increase(cur->bc_mp,
|
||||
cur->bc_ag.pag->pag_agno, *agbno, *aglen);
|
||||
else
|
||||
trace_xfs_refcount_decrease(cur->bc_mp, cur->bc_ag.pag->pag_agno,
|
||||
agbno, aglen);
|
||||
trace_xfs_refcount_decrease(cur->bc_mp,
|
||||
cur->bc_ag.pag->pag_agno, *agbno, *aglen);
|
||||
|
||||
/*
|
||||
* Ensure that no rcextents cross the boundary of the adjustment range.
|
||||
*/
|
||||
error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
|
||||
agbno, &shape_changed);
|
||||
*agbno, &shape_changed);
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (shape_changed)
|
||||
shape_changes++;
|
||||
|
||||
error = xfs_refcount_split_extent(cur, XFS_REFC_DOMAIN_SHARED,
|
||||
agbno + aglen, &shape_changed);
|
||||
*agbno + *aglen, &shape_changed);
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (shape_changed)
|
||||
@@ -1253,7 +1255,7 @@ xfs_refcount_adjust(
|
||||
* Try to merge with the left or right extents of the range.
|
||||
*/
|
||||
error = xfs_refcount_merge_extents(cur, XFS_REFC_DOMAIN_SHARED,
|
||||
new_agbno, new_aglen, adj, &shape_changed);
|
||||
agbno, aglen, adj, &shape_changed);
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (shape_changed)
|
||||
@@ -1262,7 +1264,7 @@ xfs_refcount_adjust(
|
||||
cur->bc_ag.refc.shape_changes++;
|
||||
|
||||
/* Now that we've taken care of the ends, adjust the middle extents */
|
||||
error = xfs_refcount_adjust_extents(cur, new_agbno, new_aglen, adj);
|
||||
error = xfs_refcount_adjust_extents(cur, agbno, aglen, adj);
|
||||
if (error)
|
||||
goto out_error;
|
||||
|
||||
@@ -1298,21 +1300,20 @@ xfs_refcount_finish_one_cleanup(
|
||||
static inline int
|
||||
xfs_refcount_continue_op(
|
||||
struct xfs_btree_cur *cur,
|
||||
xfs_fsblock_t startblock,
|
||||
xfs_agblock_t new_agbno,
|
||||
xfs_extlen_t new_len,
|
||||
xfs_fsblock_t *new_fsbno)
|
||||
struct xfs_refcount_intent *ri,
|
||||
xfs_agblock_t new_agbno)
|
||||
{
|
||||
struct xfs_mount *mp = cur->bc_mp;
|
||||
struct xfs_perag *pag = cur->bc_ag.pag;
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno, new_len)))
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno,
|
||||
ri->ri_blockcount)))
|
||||
return -EFSCORRUPTED;
|
||||
|
||||
*new_fsbno = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
|
||||
ri->ri_startblock = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
|
||||
|
||||
ASSERT(xfs_verify_fsbext(mp, *new_fsbno, new_len));
|
||||
ASSERT(pag->pag_agno == XFS_FSB_TO_AGNO(mp, *new_fsbno));
|
||||
ASSERT(xfs_verify_fsbext(mp, ri->ri_startblock, ri->ri_blockcount));
|
||||
ASSERT(pag->pag_agno == XFS_FSB_TO_AGNO(mp, ri->ri_startblock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1327,11 +1328,7 @@ xfs_refcount_continue_op(
|
||||
int
|
||||
xfs_refcount_finish_one(
|
||||
struct xfs_trans *tp,
|
||||
enum xfs_refcount_intent_type type,
|
||||
xfs_fsblock_t startblock,
|
||||
xfs_extlen_t blockcount,
|
||||
xfs_fsblock_t *new_fsb,
|
||||
xfs_extlen_t *new_len,
|
||||
struct xfs_refcount_intent *ri,
|
||||
struct xfs_btree_cur **pcur)
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
@@ -1339,17 +1336,16 @@ xfs_refcount_finish_one(
|
||||
struct xfs_buf *agbp = NULL;
|
||||
int error = 0;
|
||||
xfs_agblock_t bno;
|
||||
xfs_agblock_t new_agbno;
|
||||
unsigned long nr_ops = 0;
|
||||
int shape_changes = 0;
|
||||
struct xfs_perag *pag;
|
||||
|
||||
pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
|
||||
bno = XFS_FSB_TO_AGBNO(mp, startblock);
|
||||
pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock));
|
||||
bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);
|
||||
|
||||
trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, startblock),
|
||||
type, XFS_FSB_TO_AGBNO(mp, startblock),
|
||||
blockcount);
|
||||
trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock),
|
||||
ri->ri_type, XFS_FSB_TO_AGBNO(mp, ri->ri_startblock),
|
||||
ri->ri_blockcount);
|
||||
|
||||
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) {
|
||||
error = -EIO;
|
||||
@@ -1380,42 +1376,42 @@ xfs_refcount_finish_one(
|
||||
}
|
||||
*pcur = rcur;
|
||||
|
||||
switch (type) {
|
||||
switch (ri->ri_type) {
|
||||
case XFS_REFCOUNT_INCREASE:
|
||||
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
|
||||
new_len, XFS_REFCOUNT_ADJUST_INCREASE);
|
||||
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
|
||||
XFS_REFCOUNT_ADJUST_INCREASE);
|
||||
if (error)
|
||||
goto out_drop;
|
||||
if (*new_len > 0)
|
||||
error = xfs_refcount_continue_op(rcur, startblock,
|
||||
new_agbno, *new_len, new_fsb);
|
||||
if (ri->ri_blockcount > 0)
|
||||
error = xfs_refcount_continue_op(rcur, ri, bno);
|
||||
break;
|
||||
case XFS_REFCOUNT_DECREASE:
|
||||
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
|
||||
new_len, XFS_REFCOUNT_ADJUST_DECREASE);
|
||||
error = xfs_refcount_adjust(rcur, &bno, &ri->ri_blockcount,
|
||||
XFS_REFCOUNT_ADJUST_DECREASE);
|
||||
if (error)
|
||||
goto out_drop;
|
||||
if (*new_len > 0)
|
||||
error = xfs_refcount_continue_op(rcur, startblock,
|
||||
new_agbno, *new_len, new_fsb);
|
||||
if (ri->ri_blockcount > 0)
|
||||
error = xfs_refcount_continue_op(rcur, ri, bno);
|
||||
break;
|
||||
case XFS_REFCOUNT_ALLOC_COW:
|
||||
*new_fsb = startblock + blockcount;
|
||||
*new_len = 0;
|
||||
error = __xfs_refcount_cow_alloc(rcur, bno, blockcount);
|
||||
error = __xfs_refcount_cow_alloc(rcur, bno, ri->ri_blockcount);
|
||||
if (error)
|
||||
goto out_drop;
|
||||
ri->ri_blockcount = 0;
|
||||
break;
|
||||
case XFS_REFCOUNT_FREE_COW:
|
||||
*new_fsb = startblock + blockcount;
|
||||
*new_len = 0;
|
||||
error = __xfs_refcount_cow_free(rcur, bno, blockcount);
|
||||
error = __xfs_refcount_cow_free(rcur, bno, ri->ri_blockcount);
|
||||
if (error)
|
||||
goto out_drop;
|
||||
ri->ri_blockcount = 0;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
error = -EFSCORRUPTED;
|
||||
}
|
||||
if (!error && *new_len > 0)
|
||||
trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno, type,
|
||||
bno, blockcount, new_agbno, *new_len);
|
||||
if (!error && ri->ri_blockcount > 0)
|
||||
trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno,
|
||||
ri->ri_type, bno, ri->ri_blockcount);
|
||||
out_drop:
|
||||
xfs_perag_put(pag);
|
||||
return error;
|
||||
@@ -1968,7 +1964,11 @@ xfs_refcount_recover_cow_leftovers(
|
||||
rr->rr_rrec.rc_blockcount);
|
||||
|
||||
/* Free the block. */
|
||||
xfs_free_extent_later(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);
|
||||
error = xfs_free_extent_later(tp, fsb,
|
||||
rr->rr_rrec.rc_blockcount, NULL,
|
||||
XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
goto out_trans;
|
||||
|
||||
error = xfs_trans_commit(tp);
|
||||
if (error)
|
||||
|
||||
@@ -75,9 +75,7 @@ void xfs_refcount_decrease_extent(struct xfs_trans *tp,
|
||||
extern void xfs_refcount_finish_one_cleanup(struct xfs_trans *tp,
|
||||
struct xfs_btree_cur *rcur, int error);
|
||||
extern int xfs_refcount_finish_one(struct xfs_trans *tp,
|
||||
enum xfs_refcount_intent_type type, xfs_fsblock_t startblock,
|
||||
xfs_extlen_t blockcount, xfs_fsblock_t *new_fsb,
|
||||
xfs_extlen_t *new_len, struct xfs_btree_cur **pcur);
|
||||
struct xfs_refcount_intent *ri, struct xfs_btree_cur **pcur);
|
||||
|
||||
extern int xfs_refcount_find_shared(struct xfs_btree_cur *cur,
|
||||
xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno,
|
||||
|
||||
@@ -106,18 +106,13 @@ xfs_refcountbt_free_block(
|
||||
struct xfs_buf *agbp = cur->bc_ag.agbp;
|
||||
struct xfs_agf *agf = agbp->b_addr;
|
||||
xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
|
||||
int error;
|
||||
|
||||
trace_xfs_refcountbt_free_block(cur->bc_mp, cur->bc_ag.pag->pag_agno,
|
||||
XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno), 1);
|
||||
be32_add_cpu(&agf->agf_refcount_blocks, -1);
|
||||
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
|
||||
error = xfs_free_extent(cur->bc_tp, fsbno, 1, &XFS_RMAP_OINFO_REFC,
|
||||
XFS_AG_RESV_METADATA);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return error;
|
||||
return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
|
||||
&XFS_RMAP_OINFO_REFC, XFS_AG_RESV_METADATA);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
|
||||
/*
|
||||
* Realtime allocator bitmap functions shared with userspace.
|
||||
@@ -1129,3 +1130,4 @@ xfs_rtalloc_extent_is_free(
|
||||
*is_free = matches;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
83
fs/xfs/libxfs/xfs_rtbitmap.h
Normal file
83
fs/xfs/libxfs/xfs_rtbitmap.h
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
#ifndef __XFS_RTBITMAP_H__
|
||||
#define __XFS_RTBITMAP_H__
|
||||
|
||||
/*
|
||||
* XXX: Most of the realtime allocation functions deal in units of realtime
|
||||
* extents, not realtime blocks. This looks funny when paired with the type
|
||||
* name and screams for a larger cleanup.
|
||||
*/
|
||||
struct xfs_rtalloc_rec {
|
||||
xfs_rtblock_t ar_startext;
|
||||
xfs_rtbxlen_t ar_extcount;
|
||||
};
|
||||
|
||||
typedef int (*xfs_rtalloc_query_range_fn)(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_trans *tp,
|
||||
const struct xfs_rtalloc_rec *rec,
|
||||
void *priv);
|
||||
|
||||
#ifdef CONFIG_XFS_RT
|
||||
int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t block, int issum, struct xfs_buf **bpp);
|
||||
int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len, int val,
|
||||
xfs_rtblock_t *new, int *stat);
|
||||
int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_rtblock_t limit,
|
||||
xfs_rtblock_t *rtblock);
|
||||
int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_rtblock_t limit,
|
||||
xfs_rtblock_t *rtblock);
|
||||
int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len, int val);
|
||||
int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
int log, xfs_rtblock_t bbno, int delta,
|
||||
struct xfs_buf **rbpp, xfs_fsblock_t *rsb,
|
||||
xfs_suminfo_t *sum);
|
||||
int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
|
||||
xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp,
|
||||
xfs_fsblock_t *rsb);
|
||||
int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len,
|
||||
struct xfs_buf **rbpp, xfs_fsblock_t *rsb);
|
||||
int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
const struct xfs_rtalloc_rec *low_rec,
|
||||
const struct xfs_rtalloc_rec *high_rec,
|
||||
xfs_rtalloc_query_range_fn fn, void *priv);
|
||||
int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtalloc_query_range_fn fn,
|
||||
void *priv);
|
||||
bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
|
||||
int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len,
|
||||
bool *is_free);
|
||||
/*
|
||||
* Free an extent in the realtime subvolume. Length is expressed in
|
||||
* realtime extents, as is the block number.
|
||||
*/
|
||||
int /* error */
|
||||
xfs_rtfree_extent(
|
||||
struct xfs_trans *tp, /* transaction pointer */
|
||||
xfs_rtblock_t bno, /* starting block number to free */
|
||||
xfs_extlen_t len); /* length of extent freed */
|
||||
|
||||
/* Same as above, but in units of rt blocks. */
|
||||
int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
|
||||
xfs_filblks_t rtlen);
|
||||
|
||||
#else /* CONFIG_XFS_RT */
|
||||
# define xfs_rtfree_extent(t,b,l) (-ENOSYS)
|
||||
# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
|
||||
# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS)
|
||||
# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS)
|
||||
# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS)
|
||||
# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS)
|
||||
#endif /* CONFIG_XFS_RT */
|
||||
|
||||
#endif /* __XFS_RTBITMAP_H__ */
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_health.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
|
||||
/*
|
||||
* Physical superblock buffer manipulations. Shared with libxfs in userspace.
|
||||
@@ -501,8 +502,9 @@ xfs_validate_sb_common(
|
||||
rbmblocks = howmany_64(sbp->sb_rextents,
|
||||
NBBY * sbp->sb_blocksize);
|
||||
|
||||
if (sbp->sb_rextents != rexts ||
|
||||
sbp->sb_rextslog != xfs_highbit32(sbp->sb_rextents) ||
|
||||
if (!xfs_validate_rtextents(rexts) ||
|
||||
sbp->sb_rextents != rexts ||
|
||||
sbp->sb_rextslog != xfs_compute_rextslog(rexts) ||
|
||||
sbp->sb_rbmblocks != rbmblocks) {
|
||||
xfs_notice(mp,
|
||||
"realtime geometry sanity check failed");
|
||||
@@ -1365,3 +1367,17 @@ xfs_validate_stripe_geometry(
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the maximum level number of the realtime summary file, as defined by
|
||||
* mkfs. The historic use of highbit32 on a 64-bit quantity prohibited correct
|
||||
* use of rt volumes with more than 2^32 extents.
|
||||
*/
|
||||
uint8_t
|
||||
xfs_compute_rextslog(
|
||||
xfs_rtbxlen_t rtextents)
|
||||
{
|
||||
if (!rtextents)
|
||||
return 0;
|
||||
return xfs_highbit64(rtextents);
|
||||
}
|
||||
|
||||
@@ -38,4 +38,6 @@ extern int xfs_sb_get_secondary(struct xfs_mount *mp,
|
||||
extern bool xfs_validate_stripe_geometry(struct xfs_mount *mp,
|
||||
__s64 sunit, __s64 swidth, int sectorsize, bool silent);
|
||||
|
||||
uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents);
|
||||
|
||||
#endif /* __XFS_SB_H__ */
|
||||
|
||||
@@ -31,6 +31,7 @@ typedef uint64_t xfs_rfsblock_t; /* blockno in filesystem (raw) */
|
||||
typedef uint64_t xfs_rtblock_t; /* extent (block) in realtime area */
|
||||
typedef uint64_t xfs_fileoff_t; /* block number in a file */
|
||||
typedef uint64_t xfs_filblks_t; /* number of blocks in a file */
|
||||
typedef uint64_t xfs_rtbxlen_t; /* rtbitmap extent length in rtextents */
|
||||
|
||||
typedef int64_t xfs_srtblock_t; /* signed version of xfs_rtblock_t */
|
||||
|
||||
@@ -227,4 +228,16 @@ bool xfs_verify_fileoff(struct xfs_mount *mp, xfs_fileoff_t off);
|
||||
bool xfs_verify_fileext(struct xfs_mount *mp, xfs_fileoff_t off,
|
||||
xfs_fileoff_t len);
|
||||
|
||||
/* Do we support an rt volume having this number of rtextents? */
|
||||
static inline bool
|
||||
xfs_validate_rtextents(
|
||||
xfs_rtbxlen_t rtextents)
|
||||
{
|
||||
/* No runt rt volumes */
|
||||
if (rtextents == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __XFS_TYPES_H__ */
|
||||
|
||||
@@ -582,7 +582,8 @@ xrep_reap_block(
|
||||
else if (resv == XFS_AG_RESV_AGFL)
|
||||
error = xrep_put_freelist(sc, agbno);
|
||||
else
|
||||
error = xfs_free_extent(sc->tp, fsbno, 1, oinfo, resv);
|
||||
error = xfs_free_extent(sc->tp, sc->sa.pag, agbno, 1, oinfo,
|
||||
resv);
|
||||
if (agf_bp != sc->sa.agf_bp)
|
||||
xfs_trans_brelse(sc->tp, agf_bp);
|
||||
if (error)
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_log_format.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_bmap.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "scrub/scrub.h"
|
||||
#include "scrub/common.h"
|
||||
|
||||
|
||||
@@ -329,6 +329,13 @@ xfs_xattri_finish_update(
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If an attr removal is trivially complete, we're done. */
|
||||
if (attr->xattri_op_flags == XFS_ATTRI_OP_FLAGS_REMOVE &&
|
||||
!xfs_inode_hasattr(args->dp)) {
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = xfs_attr_set_iter(attr);
|
||||
if (!error && attr->xattri_dela_state != XFS_DAS_DONE)
|
||||
error = -EAGAIN;
|
||||
@@ -547,7 +554,7 @@ xfs_attri_item_recover(
|
||||
struct xfs_inode *ip;
|
||||
struct xfs_da_args *args;
|
||||
struct xfs_trans *tp;
|
||||
struct xfs_trans_res tres;
|
||||
struct xfs_trans_res resv;
|
||||
struct xfs_attri_log_format *attrp;
|
||||
struct xfs_attri_log_nameval *nv = attrip->attri_nameval;
|
||||
int error;
|
||||
@@ -608,8 +615,6 @@ xfs_attri_item_recover(
|
||||
attr->xattri_dela_state = xfs_attr_init_add_state(args);
|
||||
break;
|
||||
case XFS_ATTRI_OP_FLAGS_REMOVE:
|
||||
if (!xfs_inode_hasattr(args->dp))
|
||||
goto out;
|
||||
attr->xattri_dela_state = xfs_attr_init_remove_state(args);
|
||||
break;
|
||||
default:
|
||||
@@ -618,8 +623,9 @@ xfs_attri_item_recover(
|
||||
goto out;
|
||||
}
|
||||
|
||||
xfs_init_attr_trans(args, &tres, &total);
|
||||
error = xfs_trans_alloc(mp, &tres, total, 0, XFS_TRANS_RESERVE, &tp);
|
||||
xfs_init_attr_trans(args, &resv, &total);
|
||||
resv = xlog_recover_resv(&resv);
|
||||
error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -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,14 @@ 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_trans_res resv;
|
||||
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,19 +473,18 @@ 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;
|
||||
|
||||
/* Allocate transaction and do the work. */
|
||||
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
|
||||
resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate);
|
||||
error = xfs_trans_alloc(mp, &resv,
|
||||
XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp);
|
||||
if (error)
|
||||
goto err_rele;
|
||||
@@ -512,34 +493,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2040,6 +2040,14 @@ error_free:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
xfs_buf_list_del(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
list_del_init(&bp->b_list);
|
||||
wake_up_var(&bp->b_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel a delayed write list.
|
||||
*
|
||||
@@ -2057,7 +2065,7 @@ xfs_buf_delwri_cancel(
|
||||
|
||||
xfs_buf_lock(bp);
|
||||
bp->b_flags &= ~_XBF_DELWRI_Q;
|
||||
list_del_init(&bp->b_list);
|
||||
xfs_buf_list_del(bp);
|
||||
xfs_buf_relse(bp);
|
||||
}
|
||||
}
|
||||
@@ -2110,6 +2118,34 @@ xfs_buf_delwri_queue(
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue a buffer to this delwri list as part of a data integrity operation.
|
||||
* If the buffer is on any other delwri list, we'll wait for that to clear
|
||||
* so that the caller can submit the buffer for IO and wait for the result.
|
||||
* Callers must ensure the buffer is not already on the list.
|
||||
*/
|
||||
void
|
||||
xfs_buf_delwri_queue_here(
|
||||
struct xfs_buf *bp,
|
||||
struct list_head *buffer_list)
|
||||
{
|
||||
/*
|
||||
* We need this buffer to end up on the /caller's/ delwri list, not any
|
||||
* old list. This can happen if the buffer is marked stale (which
|
||||
* clears DELWRI_Q) after the AIL queues the buffer to its list but
|
||||
* before the AIL has a chance to submit the list.
|
||||
*/
|
||||
while (!list_empty(&bp->b_list)) {
|
||||
xfs_buf_unlock(bp);
|
||||
wait_var_event(&bp->b_list, list_empty(&bp->b_list));
|
||||
xfs_buf_lock(bp);
|
||||
}
|
||||
|
||||
ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));
|
||||
|
||||
xfs_buf_delwri_queue(bp, buffer_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare function is more complex than it needs to be because
|
||||
* the return value is only 32 bits and we are doing comparisons
|
||||
@@ -2172,7 +2208,7 @@ xfs_buf_delwri_submit_buffers(
|
||||
* reference and remove it from the list here.
|
||||
*/
|
||||
if (!(bp->b_flags & _XBF_DELWRI_Q)) {
|
||||
list_del_init(&bp->b_list);
|
||||
xfs_buf_list_del(bp);
|
||||
xfs_buf_relse(bp);
|
||||
continue;
|
||||
}
|
||||
@@ -2192,7 +2228,7 @@ xfs_buf_delwri_submit_buffers(
|
||||
list_move_tail(&bp->b_list, wait_list);
|
||||
} else {
|
||||
bp->b_flags |= XBF_ASYNC;
|
||||
list_del_init(&bp->b_list);
|
||||
xfs_buf_list_del(bp);
|
||||
}
|
||||
__xfs_buf_submit(bp, false);
|
||||
}
|
||||
@@ -2246,7 +2282,7 @@ xfs_buf_delwri_submit(
|
||||
while (!list_empty(&wait_list)) {
|
||||
bp = list_first_entry(&wait_list, struct xfs_buf, b_list);
|
||||
|
||||
list_del_init(&bp->b_list);
|
||||
xfs_buf_list_del(bp);
|
||||
|
||||
/*
|
||||
* Wait on the locked buffer, check for errors and unlock and
|
||||
|
||||
@@ -305,6 +305,7 @@ extern void xfs_buf_stale(struct xfs_buf *bp);
|
||||
/* Delayed Write Buffer Routines */
|
||||
extern void xfs_buf_delwri_cancel(struct list_head *);
|
||||
extern bool xfs_buf_delwri_queue(struct xfs_buf *, struct list_head *);
|
||||
void xfs_buf_delwri_queue_here(struct xfs_buf *bp, struct list_head *bl);
|
||||
extern int xfs_buf_delwri_submit(struct list_head *);
|
||||
extern int xfs_buf_delwri_submit_nowait(struct list_head *);
|
||||
extern int xfs_buf_delwri_pushbuf(struct xfs_buf *, struct list_head *);
|
||||
|
||||
@@ -345,23 +345,34 @@ static int
|
||||
xfs_trans_free_extent(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_efd_log_item *efdp,
|
||||
xfs_fsblock_t start_block,
|
||||
xfs_extlen_t ext_len,
|
||||
const struct xfs_owner_info *oinfo,
|
||||
bool skip_discard)
|
||||
struct xfs_extent_free_item *xefi)
|
||||
{
|
||||
struct xfs_owner_info oinfo = { };
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_extent *extp;
|
||||
struct xfs_perag *pag;
|
||||
uint next_extent;
|
||||
xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, start_block);
|
||||
xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp,
|
||||
xefi->xefi_startblock);
|
||||
xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp,
|
||||
start_block);
|
||||
xefi->xefi_startblock);
|
||||
int error;
|
||||
|
||||
trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
|
||||
oinfo.oi_owner = xefi->xefi_owner;
|
||||
if (xefi->xefi_flags & XFS_EFI_ATTR_FORK)
|
||||
oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
|
||||
if (xefi->xefi_flags & XFS_EFI_BMBT_BLOCK)
|
||||
oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
|
||||
|
||||
trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno,
|
||||
xefi->xefi_blockcount);
|
||||
|
||||
pag = xfs_perag_get(mp, agno);
|
||||
error = __xfs_free_extent(tp, pag, agbno, xefi->xefi_blockcount,
|
||||
&oinfo, xefi->xefi_agresv,
|
||||
xefi->xefi_flags & XFS_EFI_SKIP_DISCARD);
|
||||
xfs_perag_put(pag);
|
||||
|
||||
error = __xfs_free_extent(tp, start_block, ext_len,
|
||||
oinfo, XFS_AG_RESV_NONE, skip_discard);
|
||||
/*
|
||||
* Mark the transaction dirty, even on error. This ensures the
|
||||
* transaction is aborted, which:
|
||||
@@ -375,8 +386,8 @@ xfs_trans_free_extent(
|
||||
next_extent = efdp->efd_next_extent;
|
||||
ASSERT(next_extent < efdp->efd_format.efd_nextents);
|
||||
extp = &(efdp->efd_format.efd_extents[next_extent]);
|
||||
extp->ext_start = start_block;
|
||||
extp->ext_len = ext_len;
|
||||
extp->ext_start = xefi->xefi_startblock;
|
||||
extp->ext_len = xefi->xefi_blockcount;
|
||||
efdp->efd_next_extent++;
|
||||
|
||||
return error;
|
||||
@@ -404,7 +415,7 @@ STATIC void
|
||||
xfs_extent_free_log_item(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_efi_log_item *efip,
|
||||
struct xfs_extent_free_item *free)
|
||||
struct xfs_extent_free_item *xefi)
|
||||
{
|
||||
uint next_extent;
|
||||
struct xfs_extent *extp;
|
||||
@@ -420,8 +431,8 @@ xfs_extent_free_log_item(
|
||||
next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
|
||||
ASSERT(next_extent < efip->efi_format.efi_nextents);
|
||||
extp = &efip->efi_format.efi_extents[next_extent];
|
||||
extp->ext_start = free->xefi_startblock;
|
||||
extp->ext_len = free->xefi_blockcount;
|
||||
extp->ext_start = xefi->xefi_startblock;
|
||||
extp->ext_len = xefi->xefi_blockcount;
|
||||
}
|
||||
|
||||
static struct xfs_log_item *
|
||||
@@ -433,15 +444,15 @@ xfs_extent_free_create_intent(
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_efi_log_item *efip = xfs_efi_init(mp, count);
|
||||
struct xfs_extent_free_item *free;
|
||||
struct xfs_extent_free_item *xefi;
|
||||
|
||||
ASSERT(count > 0);
|
||||
|
||||
xfs_trans_add_item(tp, &efip->efi_item);
|
||||
if (sort)
|
||||
list_sort(mp, items, xfs_extent_free_diff_items);
|
||||
list_for_each_entry(free, items, xefi_list)
|
||||
xfs_extent_free_log_item(tp, efip, free);
|
||||
list_for_each_entry(xefi, items, xefi_list)
|
||||
xfs_extent_free_log_item(tp, efip, xefi);
|
||||
return &efip->efi_item;
|
||||
}
|
||||
|
||||
@@ -463,21 +474,13 @@ xfs_extent_free_finish_item(
|
||||
struct list_head *item,
|
||||
struct xfs_btree_cur **state)
|
||||
{
|
||||
struct xfs_owner_info oinfo = { };
|
||||
struct xfs_extent_free_item *free;
|
||||
struct xfs_extent_free_item *xefi;
|
||||
int error;
|
||||
|
||||
free = container_of(item, struct xfs_extent_free_item, xefi_list);
|
||||
oinfo.oi_owner = free->xefi_owner;
|
||||
if (free->xefi_flags & XFS_EFI_ATTR_FORK)
|
||||
oinfo.oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
|
||||
if (free->xefi_flags & XFS_EFI_BMBT_BLOCK)
|
||||
oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
|
||||
error = xfs_trans_free_extent(tp, EFD_ITEM(done),
|
||||
free->xefi_startblock,
|
||||
free->xefi_blockcount,
|
||||
&oinfo, free->xefi_flags & XFS_EFI_SKIP_DISCARD);
|
||||
kmem_cache_free(xfs_extfree_item_cache, free);
|
||||
xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
|
||||
|
||||
error = xfs_trans_free_extent(tp, EFD_ITEM(done), xefi);
|
||||
kmem_cache_free(xfs_extfree_item_cache, xefi);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -494,10 +497,10 @@ STATIC void
|
||||
xfs_extent_free_cancel_item(
|
||||
struct list_head *item)
|
||||
{
|
||||
struct xfs_extent_free_item *free;
|
||||
struct xfs_extent_free_item *xefi;
|
||||
|
||||
free = container_of(item, struct xfs_extent_free_item, xefi_list);
|
||||
kmem_cache_free(xfs_extfree_item_cache, free);
|
||||
xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
|
||||
kmem_cache_free(xfs_extfree_item_cache, xefi);
|
||||
}
|
||||
|
||||
const struct xfs_defer_op_type xfs_extent_free_defer_type = {
|
||||
@@ -523,7 +526,7 @@ xfs_agfl_free_finish_item(
|
||||
struct xfs_owner_info oinfo = { };
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_efd_log_item *efdp = EFD_ITEM(done);
|
||||
struct xfs_extent_free_item *free;
|
||||
struct xfs_extent_free_item *xefi;
|
||||
struct xfs_extent *extp;
|
||||
struct xfs_buf *agbp;
|
||||
int error;
|
||||
@@ -532,13 +535,13 @@ xfs_agfl_free_finish_item(
|
||||
uint next_extent;
|
||||
struct xfs_perag *pag;
|
||||
|
||||
free = container_of(item, struct xfs_extent_free_item, xefi_list);
|
||||
ASSERT(free->xefi_blockcount == 1);
|
||||
agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
|
||||
agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
|
||||
oinfo.oi_owner = free->xefi_owner;
|
||||
xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
|
||||
ASSERT(xefi->xefi_blockcount == 1);
|
||||
agno = XFS_FSB_TO_AGNO(mp, xefi->xefi_startblock);
|
||||
agbno = XFS_FSB_TO_AGBNO(mp, xefi->xefi_startblock);
|
||||
oinfo.oi_owner = xefi->xefi_owner;
|
||||
|
||||
trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
|
||||
trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, xefi->xefi_blockcount);
|
||||
|
||||
pag = xfs_perag_get(mp, agno);
|
||||
error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
|
||||
@@ -559,11 +562,11 @@ xfs_agfl_free_finish_item(
|
||||
next_extent = efdp->efd_next_extent;
|
||||
ASSERT(next_extent < efdp->efd_format.efd_nextents);
|
||||
extp = &(efdp->efd_format.efd_extents[next_extent]);
|
||||
extp->ext_start = free->xefi_startblock;
|
||||
extp->ext_len = free->xefi_blockcount;
|
||||
extp->ext_start = xefi->xefi_startblock;
|
||||
extp->ext_len = xefi->xefi_blockcount;
|
||||
efdp->efd_next_extent++;
|
||||
|
||||
kmem_cache_free(xfs_extfree_item_cache, free);
|
||||
kmem_cache_free(xfs_extfree_item_cache, xefi);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -595,11 +598,11 @@ xfs_efi_item_recover(
|
||||
struct xfs_log_item *lip,
|
||||
struct list_head *capture_list)
|
||||
{
|
||||
struct xfs_trans_res resv;
|
||||
struct xfs_efi_log_item *efip = EFI_ITEM(lip);
|
||||
struct xfs_mount *mp = lip->li_log->l_mp;
|
||||
struct xfs_efd_log_item *efdp;
|
||||
struct xfs_trans *tp;
|
||||
struct xfs_extent *extp;
|
||||
int i;
|
||||
int error = 0;
|
||||
|
||||
@@ -618,16 +621,25 @@ xfs_efi_item_recover(
|
||||
}
|
||||
}
|
||||
|
||||
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
|
||||
resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate);
|
||||
error = xfs_trans_alloc(mp, &resv, 0, 0, 0, &tp);
|
||||
if (error)
|
||||
return error;
|
||||
efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
|
||||
|
||||
for (i = 0; i < efip->efi_format.efi_nextents; i++) {
|
||||
struct xfs_extent_free_item fake = {
|
||||
.xefi_owner = XFS_RMAP_OWN_UNKNOWN,
|
||||
.xefi_agresv = XFS_AG_RESV_NONE,
|
||||
};
|
||||
struct xfs_extent *extp;
|
||||
|
||||
extp = &efip->efi_format.efi_extents[i];
|
||||
error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
|
||||
extp->ext_len,
|
||||
&XFS_RMAP_OINFO_ANY_OWNER, false);
|
||||
|
||||
fake.xefi_startblock = extp->ext_start;
|
||||
fake.xefi_blockcount = extp->ext_len;
|
||||
|
||||
error = xfs_trans_free_extent(tp, efdp, &fake);
|
||||
if (error == -EFSCORRUPTED)
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
|
||||
extp, sizeof(*extp));
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "xfs_refcount.h"
|
||||
#include "xfs_refcount_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "xfs_ag.h"
|
||||
|
||||
/* Convert an xfs_fsmap to an fsmap. */
|
||||
|
||||
@@ -153,7 +153,7 @@ xfs_growfs_data_private(
|
||||
(delta > 0 ? XFS_GROWFS_SPACE_RES(mp) : -delta), 0,
|
||||
XFS_TRANS_RESERVE, &tp);
|
||||
if (error)
|
||||
return error;
|
||||
goto out_free_unused_perag;
|
||||
|
||||
last_pag = xfs_perag_get(mp, oagcount - 1);
|
||||
if (delta > 0) {
|
||||
@@ -227,6 +227,9 @@ xfs_growfs_data_private(
|
||||
|
||||
out_trans_cancel:
|
||||
xfs_trans_cancel(tp);
|
||||
out_free_unused_perag:
|
||||
if (nagcount > oagcount)
|
||||
xfs_free_unused_perag_range(mp, oagcount, nagcount);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -556,6 +556,9 @@ xfs_inode_to_log_dinode(
|
||||
memset(to->di_pad2, 0, sizeof(to->di_pad2));
|
||||
uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
|
||||
to->di_v3_pad = 0;
|
||||
|
||||
/* dummy value for initialisation */
|
||||
to->di_crc = 0;
|
||||
} else {
|
||||
to->di_version = 2;
|
||||
to->di_flushiter = ip->i_flushiter;
|
||||
|
||||
@@ -252,17 +252,12 @@ static int
|
||||
xfs_trans_log_finish_refcount_update(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_cud_log_item *cudp,
|
||||
enum xfs_refcount_intent_type type,
|
||||
xfs_fsblock_t startblock,
|
||||
xfs_extlen_t blockcount,
|
||||
xfs_fsblock_t *new_fsb,
|
||||
xfs_extlen_t *new_len,
|
||||
struct xfs_refcount_intent *ri,
|
||||
struct xfs_btree_cur **pcur)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = xfs_refcount_finish_one(tp, type, startblock,
|
||||
blockcount, new_fsb, new_len, pcur);
|
||||
error = xfs_refcount_finish_one(tp, ri, pcur);
|
||||
|
||||
/*
|
||||
* Mark the transaction dirty, even on error. This ensures the
|
||||
@@ -378,25 +373,20 @@ xfs_refcount_update_finish_item(
|
||||
struct list_head *item,
|
||||
struct xfs_btree_cur **state)
|
||||
{
|
||||
struct xfs_refcount_intent *refc;
|
||||
xfs_fsblock_t new_fsb;
|
||||
xfs_extlen_t new_aglen;
|
||||
struct xfs_refcount_intent *ri;
|
||||
int error;
|
||||
|
||||
refc = container_of(item, struct xfs_refcount_intent, ri_list);
|
||||
error = xfs_trans_log_finish_refcount_update(tp, CUD_ITEM(done),
|
||||
refc->ri_type, refc->ri_startblock, refc->ri_blockcount,
|
||||
&new_fsb, &new_aglen, state);
|
||||
ri = container_of(item, struct xfs_refcount_intent, ri_list);
|
||||
error = xfs_trans_log_finish_refcount_update(tp, CUD_ITEM(done), ri,
|
||||
state);
|
||||
|
||||
/* Did we run out of reservation? Requeue what we didn't finish. */
|
||||
if (!error && new_aglen > 0) {
|
||||
ASSERT(refc->ri_type == XFS_REFCOUNT_INCREASE ||
|
||||
refc->ri_type == XFS_REFCOUNT_DECREASE);
|
||||
refc->ri_startblock = new_fsb;
|
||||
refc->ri_blockcount = new_aglen;
|
||||
if (!error && ri->ri_blockcount > 0) {
|
||||
ASSERT(ri->ri_type == XFS_REFCOUNT_INCREASE ||
|
||||
ri->ri_type == XFS_REFCOUNT_DECREASE);
|
||||
return -EAGAIN;
|
||||
}
|
||||
kmem_cache_free(xfs_refcount_intent_cache, refc);
|
||||
kmem_cache_free(xfs_refcount_intent_cache, ri);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -463,18 +453,14 @@ xfs_cui_item_recover(
|
||||
struct xfs_log_item *lip,
|
||||
struct list_head *capture_list)
|
||||
{
|
||||
struct xfs_bmbt_irec irec;
|
||||
struct xfs_trans_res resv;
|
||||
struct xfs_cui_log_item *cuip = CUI_ITEM(lip);
|
||||
struct xfs_phys_extent *refc;
|
||||
struct xfs_cud_log_item *cudp;
|
||||
struct xfs_trans *tp;
|
||||
struct xfs_btree_cur *rcur = NULL;
|
||||
struct xfs_mount *mp = lip->li_log->l_mp;
|
||||
xfs_fsblock_t new_fsb;
|
||||
xfs_extlen_t new_len;
|
||||
unsigned int refc_type;
|
||||
bool requeue_only = false;
|
||||
enum xfs_refcount_intent_type type;
|
||||
int i;
|
||||
int error = 0;
|
||||
|
||||
@@ -505,14 +491,18 @@ xfs_cui_item_recover(
|
||||
* doesn't fit. We need to reserve enough blocks to handle a
|
||||
* full btree split on either end of the refcount range.
|
||||
*/
|
||||
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
|
||||
mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp);
|
||||
resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate);
|
||||
error = xfs_trans_alloc(mp, &resv, mp->m_refc_maxlevels * 2, 0,
|
||||
XFS_TRANS_RESERVE, &tp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
cudp = xfs_trans_get_cud(tp, cuip);
|
||||
|
||||
for (i = 0; i < cuip->cui_format.cui_nextents; i++) {
|
||||
struct xfs_refcount_intent fake = { };
|
||||
struct xfs_phys_extent *refc;
|
||||
|
||||
refc = &cuip->cui_format.cui_extents[i];
|
||||
refc_type = refc->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK;
|
||||
switch (refc_type) {
|
||||
@@ -520,7 +510,7 @@ xfs_cui_item_recover(
|
||||
case XFS_REFCOUNT_DECREASE:
|
||||
case XFS_REFCOUNT_ALLOC_COW:
|
||||
case XFS_REFCOUNT_FREE_COW:
|
||||
type = refc_type;
|
||||
fake.ri_type = refc_type;
|
||||
break;
|
||||
default:
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
|
||||
@@ -529,13 +519,12 @@ xfs_cui_item_recover(
|
||||
error = -EFSCORRUPTED;
|
||||
goto abort_error;
|
||||
}
|
||||
if (requeue_only) {
|
||||
new_fsb = refc->pe_startblock;
|
||||
new_len = refc->pe_len;
|
||||
} else
|
||||
|
||||
fake.ri_startblock = refc->pe_startblock;
|
||||
fake.ri_blockcount = refc->pe_len;
|
||||
if (!requeue_only)
|
||||
error = xfs_trans_log_finish_refcount_update(tp, cudp,
|
||||
type, refc->pe_startblock, refc->pe_len,
|
||||
&new_fsb, &new_len, &rcur);
|
||||
&fake, &rcur);
|
||||
if (error == -EFSCORRUPTED)
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
|
||||
&cuip->cui_format,
|
||||
@@ -544,10 +533,13 @@ xfs_cui_item_recover(
|
||||
goto abort_error;
|
||||
|
||||
/* Requeue what we didn't finish. */
|
||||
if (new_len > 0) {
|
||||
irec.br_startblock = new_fsb;
|
||||
irec.br_blockcount = new_len;
|
||||
switch (type) {
|
||||
if (fake.ri_blockcount > 0) {
|
||||
struct xfs_bmbt_irec irec = {
|
||||
.br_startblock = fake.ri_startblock,
|
||||
.br_blockcount = fake.ri_blockcount,
|
||||
};
|
||||
|
||||
switch (fake.ri_type) {
|
||||
case XFS_REFCOUNT_INCREASE:
|
||||
xfs_refcount_increase_extent(tp, &irec);
|
||||
break;
|
||||
|
||||
@@ -618,8 +618,11 @@ xfs_reflink_cancel_cow_blocks(
|
||||
xfs_refcount_free_cow_extent(*tpp, del.br_startblock,
|
||||
del.br_blockcount);
|
||||
|
||||
xfs_free_extent_later(*tpp, del.br_startblock,
|
||||
del.br_blockcount, NULL);
|
||||
error = xfs_free_extent_later(*tpp, del.br_startblock,
|
||||
del.br_blockcount, NULL,
|
||||
XFS_AG_RESV_NONE);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
/* Roll the transaction */
|
||||
error = xfs_defer_finish(tpp);
|
||||
|
||||
@@ -492,6 +492,7 @@ xfs_rui_item_recover(
|
||||
struct xfs_log_item *lip,
|
||||
struct list_head *capture_list)
|
||||
{
|
||||
struct xfs_trans_res resv;
|
||||
struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
|
||||
struct xfs_map_extent *rmap;
|
||||
struct xfs_rud_log_item *rudp;
|
||||
@@ -519,8 +520,9 @@ xfs_rui_item_recover(
|
||||
}
|
||||
}
|
||||
|
||||
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
|
||||
mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp);
|
||||
resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate);
|
||||
error = xfs_trans_alloc(mp, &resv, mp->m_rmap_maxlevels, 0,
|
||||
XFS_TRANS_RESERVE, &tp);
|
||||
if (error)
|
||||
return error;
|
||||
rudp = xfs_trans_get_rud(tp, ruip);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "xfs_icache.h"
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
|
||||
/*
|
||||
* Read and return the summary information for a given extent size,
|
||||
@@ -317,7 +318,7 @@ xfs_rtallocate_extent_block(
|
||||
/*
|
||||
* Searched the whole thing & didn't find a maxlen free extent.
|
||||
*/
|
||||
if (minlen < maxlen && besti != -1) {
|
||||
if (minlen <= maxlen && besti != -1) {
|
||||
xfs_extlen_t p; /* amount to trim length by */
|
||||
|
||||
/*
|
||||
@@ -997,8 +998,10 @@ xfs_growfs_rt(
|
||||
*/
|
||||
nrextents = nrblocks;
|
||||
do_div(nrextents, in->extsize);
|
||||
if (!xfs_validate_rtextents(nrextents))
|
||||
return -EINVAL;
|
||||
nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
|
||||
nrextslog = xfs_highbit32(nrextents);
|
||||
nrextslog = xfs_compute_rextslog(nrextents);
|
||||
nrsumlevels = nrextslog + 1;
|
||||
nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
|
||||
nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
|
||||
@@ -1060,13 +1063,16 @@ xfs_growfs_rt(
|
||||
nsbp->sb_rextents = nsbp->sb_rblocks;
|
||||
do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
|
||||
ASSERT(nsbp->sb_rextents != 0);
|
||||
nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
|
||||
nsbp->sb_rextslog = xfs_compute_rextslog(nsbp->sb_rextents);
|
||||
nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
|
||||
nrsumsize =
|
||||
(uint)sizeof(xfs_suminfo_t) * nrsumlevels *
|
||||
nsbp->sb_rbmblocks;
|
||||
nrsumblocks = XFS_B_TO_FSB(mp, nrsumsize);
|
||||
nmp->m_rsumsize = nrsumsize = XFS_FSB_TO_B(mp, nrsumblocks);
|
||||
/* recompute growfsrt reservation from new rsumsize */
|
||||
xfs_trans_resv_calc(nmp, &nmp->m_resv);
|
||||
|
||||
/*
|
||||
* Start a transaction, get the log reservation.
|
||||
*/
|
||||
@@ -1150,6 +1156,8 @@ error_cancel:
|
||||
*/
|
||||
mp->m_rsumlevels = nrsumlevels;
|
||||
mp->m_rsumsize = nrsumsize;
|
||||
/* recompute growfsrt reservation from new rsumsize */
|
||||
xfs_trans_resv_calc(mp, &mp->m_resv);
|
||||
|
||||
error = xfs_trans_commit(tp);
|
||||
if (error)
|
||||
|
||||
@@ -11,22 +11,6 @@
|
||||
struct xfs_mount;
|
||||
struct xfs_trans;
|
||||
|
||||
/*
|
||||
* XXX: Most of the realtime allocation functions deal in units of realtime
|
||||
* extents, not realtime blocks. This looks funny when paired with the type
|
||||
* name and screams for a larger cleanup.
|
||||
*/
|
||||
struct xfs_rtalloc_rec {
|
||||
xfs_rtblock_t ar_startext;
|
||||
xfs_rtblock_t ar_extcount;
|
||||
};
|
||||
|
||||
typedef int (*xfs_rtalloc_query_range_fn)(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_trans *tp,
|
||||
const struct xfs_rtalloc_rec *rec,
|
||||
void *priv);
|
||||
|
||||
#ifdef CONFIG_XFS_RT
|
||||
/*
|
||||
* Function prototypes for exported functions.
|
||||
@@ -48,19 +32,6 @@ xfs_rtallocate_extent(
|
||||
xfs_extlen_t prod, /* extent product factor */
|
||||
xfs_rtblock_t *rtblock); /* out: start block allocated */
|
||||
|
||||
/*
|
||||
* Free an extent in the realtime subvolume. Length is expressed in
|
||||
* realtime extents, as is the block number.
|
||||
*/
|
||||
int /* error */
|
||||
xfs_rtfree_extent(
|
||||
struct xfs_trans *tp, /* transaction pointer */
|
||||
xfs_rtblock_t bno, /* starting block number to free */
|
||||
xfs_extlen_t len); /* length of extent freed */
|
||||
|
||||
/* Same as above, but in units of rt blocks. */
|
||||
int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
|
||||
xfs_filblks_t rtlen);
|
||||
|
||||
/*
|
||||
* Initialize realtime fields in the mount structure.
|
||||
@@ -102,55 +73,11 @@ xfs_growfs_rt(
|
||||
struct xfs_mount *mp, /* file system mount structure */
|
||||
xfs_growfs_rt_t *in); /* user supplied growfs struct */
|
||||
|
||||
/*
|
||||
* From xfs_rtbitmap.c
|
||||
*/
|
||||
int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t block, int issum, struct xfs_buf **bpp);
|
||||
int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len, int val,
|
||||
xfs_rtblock_t *new, int *stat);
|
||||
int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_rtblock_t limit,
|
||||
xfs_rtblock_t *rtblock);
|
||||
int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_rtblock_t limit,
|
||||
xfs_rtblock_t *rtblock);
|
||||
int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len, int val);
|
||||
int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
int log, xfs_rtblock_t bbno, int delta,
|
||||
struct xfs_buf **rbpp, xfs_fsblock_t *rsb,
|
||||
xfs_suminfo_t *sum);
|
||||
int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log,
|
||||
xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp,
|
||||
xfs_fsblock_t *rsb);
|
||||
int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len,
|
||||
struct xfs_buf **rbpp, xfs_fsblock_t *rsb);
|
||||
int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
const struct xfs_rtalloc_rec *low_rec,
|
||||
const struct xfs_rtalloc_rec *high_rec,
|
||||
xfs_rtalloc_query_range_fn fn, void *priv);
|
||||
int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtalloc_query_range_fn fn,
|
||||
void *priv);
|
||||
bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
|
||||
int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||
xfs_rtblock_t start, xfs_extlen_t len,
|
||||
bool *is_free);
|
||||
int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp);
|
||||
#else
|
||||
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (-ENOSYS)
|
||||
# define xfs_rtfree_extent(t,b,l) (-ENOSYS)
|
||||
# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
|
||||
# define xfs_rtpick_extent(m,t,l,rb) (-ENOSYS)
|
||||
# define xfs_growfs_rt(mp,in) (-ENOSYS)
|
||||
# define xfs_rtalloc_query_range(m,t,l,h,f,p) (-ENOSYS)
|
||||
# define xfs_rtalloc_query_all(m,t,f,p) (-ENOSYS)
|
||||
# define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS)
|
||||
# define xfs_verify_rtbno(m, r) (false)
|
||||
# define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS)
|
||||
# define xfs_rtalloc_reinit_frextents(m) (0)
|
||||
static inline int /* error */
|
||||
xfs_rtmount_init(
|
||||
|
||||
@@ -3208,17 +3208,14 @@ DEFINE_REFCOUNT_DEFERRED_EVENT(xfs_refcount_deferred);
|
||||
|
||||
TRACE_EVENT(xfs_refcount_finish_one_leftover,
|
||||
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno,
|
||||
int type, xfs_agblock_t agbno, xfs_extlen_t len,
|
||||
xfs_agblock_t new_agbno, xfs_extlen_t new_len),
|
||||
TP_ARGS(mp, agno, type, agbno, len, new_agbno, new_len),
|
||||
int type, xfs_agblock_t agbno, xfs_extlen_t len),
|
||||
TP_ARGS(mp, agno, type, agbno, len),
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(xfs_agnumber_t, agno)
|
||||
__field(int, type)
|
||||
__field(xfs_agblock_t, agbno)
|
||||
__field(xfs_extlen_t, len)
|
||||
__field(xfs_agblock_t, new_agbno)
|
||||
__field(xfs_extlen_t, new_len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->dev = mp->m_super->s_dev;
|
||||
@@ -3226,17 +3223,13 @@ TRACE_EVENT(xfs_refcount_finish_one_leftover,
|
||||
__entry->type = type;
|
||||
__entry->agbno = agbno;
|
||||
__entry->len = len;
|
||||
__entry->new_agbno = new_agbno;
|
||||
__entry->new_len = new_len;
|
||||
),
|
||||
TP_printk("dev %d:%d type %d agno 0x%x agbno 0x%x fsbcount 0x%x new_agbno 0x%x new_fsbcount 0x%x",
|
||||
TP_printk("dev %d:%d type %d agno 0x%x agbno 0x%x fsbcount 0x%x",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->type,
|
||||
__entry->agno,
|
||||
__entry->agbno,
|
||||
__entry->len,
|
||||
__entry->new_agbno,
|
||||
__entry->new_len)
|
||||
__entry->len)
|
||||
);
|
||||
|
||||
/* simple inode-based error/%ip tracepoint class */
|
||||
|
||||
Reference in New Issue
Block a user