Commit fcb762f5 authored by Brian Foster's avatar Brian Foster Committed by Darrick J. Wong

xfs: add bmapi nodiscard flag

Freed extents are unconditionally discarded when online discard is
enabled. Define XFS_BMAPI_NODISCARD to allow callers to bypass
discards when unnecessary. For example, this will be useful for
eofblocks trimming.

This patch does not change behavior.
Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent e6631f85
...@@ -3009,18 +3009,20 @@ xfs_free_extent_fix_freelist( ...@@ -3009,18 +3009,20 @@ xfs_free_extent_fix_freelist(
* after fixing up the freelist. * after fixing up the freelist.
*/ */
int /* error */ int /* error */
xfs_free_extent( __xfs_free_extent(
struct xfs_trans *tp, /* transaction pointer */ struct xfs_trans *tp, /* transaction pointer */
xfs_fsblock_t bno, /* starting block number of extent */ xfs_fsblock_t bno, /* starting block number of extent */
xfs_extlen_t len, /* length of extent */ xfs_extlen_t len, /* length of extent */
struct xfs_owner_info *oinfo, /* extent owner */ struct xfs_owner_info *oinfo, /* extent owner */
enum xfs_ag_resv_type type) /* block reservation type */ enum xfs_ag_resv_type type, /* block reservation type */
bool skip_discard)
{ {
struct xfs_mount *mp = tp->t_mountp; struct xfs_mount *mp = tp->t_mountp;
struct xfs_buf *agbp; struct xfs_buf *agbp;
xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno); xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, bno);
xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno); xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, bno);
int error; int error;
unsigned int busy_flags = 0;
ASSERT(len != 0); ASSERT(len != 0);
ASSERT(type != XFS_AG_RESV_AGFL); ASSERT(type != XFS_AG_RESV_AGFL);
...@@ -3044,7 +3046,9 @@ xfs_free_extent( ...@@ -3044,7 +3046,9 @@ xfs_free_extent(
if (error) if (error)
goto err; goto err;
xfs_extent_busy_insert(tp, agno, agbno, len, 0); if (skip_discard)
busy_flags |= XFS_EXTENT_BUSY_SKIP_DISCARD;
xfs_extent_busy_insert(tp, agno, agbno, len, busy_flags);
return 0; return 0;
err: err:
......
...@@ -191,12 +191,35 @@ xfs_alloc_vextent( ...@@ -191,12 +191,35 @@ xfs_alloc_vextent(
* Free an extent. * Free an extent.
*/ */
int /* error */ int /* error */
xfs_free_extent( __xfs_free_extent(
struct xfs_trans *tp, /* transaction pointer */ struct xfs_trans *tp, /* transaction pointer */
xfs_fsblock_t bno, /* starting block number of extent */ xfs_fsblock_t bno, /* starting block number of extent */
xfs_extlen_t len, /* length of extent */ xfs_extlen_t len, /* length of extent */
struct xfs_owner_info *oinfo, /* extent owner */ struct xfs_owner_info *oinfo, /* extent owner */
enum xfs_ag_resv_type type); /* block reservation type */ enum xfs_ag_resv_type type, /* block reservation type */
bool skip_discard);
static inline int
xfs_free_extent(
struct xfs_trans *tp,
xfs_fsblock_t bno,
xfs_extlen_t len,
struct xfs_owner_info *oinfo,
enum xfs_ag_resv_type type)
{
return __xfs_free_extent(tp, bno, len, oinfo, type, false);
}
static inline int
xfs_free_extent_nodiscard(
struct xfs_trans *tp,
xfs_fsblock_t bno,
xfs_extlen_t len,
struct xfs_owner_info *oinfo,
enum xfs_ag_resv_type type)
{
return __xfs_free_extent(tp, bno, len, oinfo, type, true);
}
int /* error */ int /* error */
xfs_alloc_lookup_le( xfs_alloc_lookup_le(
......
...@@ -544,12 +544,13 @@ xfs_bmap_validate_ret( ...@@ -544,12 +544,13 @@ xfs_bmap_validate_ret(
* The list is maintained sorted (by block number). * The list is maintained sorted (by block number).
*/ */
void void
xfs_bmap_add_free( __xfs_bmap_add_free(
struct xfs_mount *mp, struct xfs_mount *mp,
struct xfs_defer_ops *dfops, struct xfs_defer_ops *dfops,
xfs_fsblock_t bno, xfs_fsblock_t bno,
xfs_filblks_t len, xfs_filblks_t len,
struct xfs_owner_info *oinfo) struct xfs_owner_info *oinfo,
bool skip_discard)
{ {
struct xfs_extent_free_item *new; /* new element */ struct xfs_extent_free_item *new; /* new element */
#ifdef DEBUG #ifdef DEBUG
...@@ -576,6 +577,7 @@ xfs_bmap_add_free( ...@@ -576,6 +577,7 @@ xfs_bmap_add_free(
new->xefi_oinfo = *oinfo; new->xefi_oinfo = *oinfo;
else else
xfs_rmap_skip_owner_update(&new->xefi_oinfo); xfs_rmap_skip_owner_update(&new->xefi_oinfo);
new->xefi_skip_discard = skip_discard;
trace_xfs_bmap_free_defer(mp, XFS_FSB_TO_AGNO(mp, bno), 0, trace_xfs_bmap_free_defer(mp, XFS_FSB_TO_AGNO(mp, bno), 0,
XFS_FSB_TO_AGBNO(mp, bno), len); XFS_FSB_TO_AGBNO(mp, bno), len);
xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list); xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
...@@ -5106,9 +5108,16 @@ xfs_bmap_del_extent_real( ...@@ -5106,9 +5108,16 @@ xfs_bmap_del_extent_real(
error = xfs_refcount_decrease_extent(mp, dfops, del); error = xfs_refcount_decrease_extent(mp, dfops, del);
if (error) if (error)
goto done; goto done;
} else } else {
xfs_bmap_add_free(mp, dfops, del->br_startblock, if (bflags & XFS_BMAPI_NODISCARD) {
xfs_bmap_add_free_nodiscard(mp, dfops,
del->br_startblock, del->br_blockcount,
NULL);
} else {
xfs_bmap_add_free(mp, dfops, del->br_startblock,
del->br_blockcount, NULL); del->br_blockcount, NULL);
}
}
} }
/* /*
......
...@@ -68,6 +68,7 @@ struct xfs_extent_free_item ...@@ -68,6 +68,7 @@ struct xfs_extent_free_item
xfs_extlen_t xefi_blockcount;/* number of blocks in extent */ xfs_extlen_t xefi_blockcount;/* number of blocks in extent */
struct list_head xefi_list; struct list_head xefi_list;
struct xfs_owner_info xefi_oinfo; /* extent owner */ struct xfs_owner_info xefi_oinfo; /* extent owner */
bool xefi_skip_discard;
}; };
#define XFS_BMAP_MAX_NMAP 4 #define XFS_BMAP_MAX_NMAP 4
...@@ -116,6 +117,9 @@ struct xfs_extent_free_item ...@@ -116,6 +117,9 @@ struct xfs_extent_free_item
/* Only convert unwritten extents, don't allocate new blocks */ /* Only convert unwritten extents, don't allocate new blocks */
#define XFS_BMAPI_CONVERT_ONLY 0x800 #define XFS_BMAPI_CONVERT_ONLY 0x800
/* Skip online discard of freed extents */
#define XFS_BMAPI_NODISCARD 0x1000
#define XFS_BMAPI_FLAGS \ #define XFS_BMAPI_FLAGS \
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \
{ XFS_BMAPI_METADATA, "METADATA" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \
...@@ -128,7 +132,8 @@ struct xfs_extent_free_item ...@@ -128,7 +132,8 @@ struct xfs_extent_free_item
{ XFS_BMAPI_REMAP, "REMAP" }, \ { XFS_BMAPI_REMAP, "REMAP" }, \
{ XFS_BMAPI_COWFORK, "COWFORK" }, \ { XFS_BMAPI_COWFORK, "COWFORK" }, \
{ XFS_BMAPI_DELALLOC, "DELALLOC" }, \ { XFS_BMAPI_DELALLOC, "DELALLOC" }, \
{ XFS_BMAPI_CONVERT_ONLY, "CONVERT_ONLY" } { XFS_BMAPI_CONVERT_ONLY, "CONVERT_ONLY" }, \
{ XFS_BMAPI_NODISCARD, "NODISCARD" }
static inline int xfs_bmapi_aflag(int w) static inline int xfs_bmapi_aflag(int w)
...@@ -192,9 +197,9 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, ...@@ -192,9 +197,9 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,
void xfs_trim_extent_eof(struct xfs_bmbt_irec *, struct xfs_inode *); void xfs_trim_extent_eof(struct xfs_bmbt_irec *, struct xfs_inode *);
int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);
void xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_defer_ops *dfops, void __xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
xfs_fsblock_t bno, xfs_filblks_t len, xfs_fsblock_t bno, xfs_filblks_t len,
struct xfs_owner_info *oinfo); struct xfs_owner_info *oinfo, bool skip_discard);
void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork);
...@@ -240,6 +245,28 @@ int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, ...@@ -240,6 +245,28 @@ int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork,
struct xfs_bmbt_irec *got, struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, struct xfs_iext_cursor *cur,
int eof); int eof);
static inline void
xfs_bmap_add_free(
struct xfs_mount *mp,
struct xfs_defer_ops *dfops,
xfs_fsblock_t bno,
xfs_filblks_t len,
struct xfs_owner_info *oinfo)
{
__xfs_bmap_add_free(mp, dfops, bno, len, oinfo, false);
}
static inline void
xfs_bmap_add_free_nodiscard(
struct xfs_mount *mp,
struct xfs_defer_ops *dfops,
xfs_fsblock_t bno,
xfs_filblks_t len,
struct xfs_owner_info *oinfo)
{
__xfs_bmap_add_free(mp, dfops, bno, len, oinfo, true);
}
enum xfs_bmap_intent_type { enum xfs_bmap_intent_type {
XFS_BMAP_MAP = 1, XFS_BMAP_MAP = 1,
XFS_BMAP_UNMAP, XFS_BMAP_UNMAP,
......
...@@ -542,7 +542,7 @@ xfs_efi_recover( ...@@ -542,7 +542,7 @@ xfs_efi_recover(
for (i = 0; i < efip->efi_format.efi_nextents; i++) { for (i = 0; i < efip->efi_format.efi_nextents; i++) {
extp = &efip->efi_format.efi_extents[i]; extp = &efip->efi_format.efi_extents[i];
error = xfs_trans_free_extent(tp, efdp, extp->ext_start, error = xfs_trans_free_extent(tp, efdp, extp->ext_start,
extp->ext_len, &oinfo); extp->ext_len, &oinfo, false);
if (error) if (error)
goto abort_error; goto abort_error;
......
...@@ -235,7 +235,8 @@ struct xfs_efd_log_item *xfs_trans_get_efd(struct xfs_trans *, ...@@ -235,7 +235,8 @@ struct xfs_efd_log_item *xfs_trans_get_efd(struct xfs_trans *,
uint); uint);
int xfs_trans_free_extent(struct xfs_trans *, int xfs_trans_free_extent(struct xfs_trans *,
struct xfs_efd_log_item *, xfs_fsblock_t, struct xfs_efd_log_item *, xfs_fsblock_t,
xfs_extlen_t, struct xfs_owner_info *); xfs_extlen_t, struct xfs_owner_info *,
bool);
int xfs_trans_commit(struct xfs_trans *); int xfs_trans_commit(struct xfs_trans *);
int xfs_trans_roll(struct xfs_trans **); int xfs_trans_roll(struct xfs_trans **);
int xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *); int xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *);
......
...@@ -68,7 +68,8 @@ xfs_trans_free_extent( ...@@ -68,7 +68,8 @@ xfs_trans_free_extent(
struct xfs_efd_log_item *efdp, struct xfs_efd_log_item *efdp,
xfs_fsblock_t start_block, xfs_fsblock_t start_block,
xfs_extlen_t ext_len, xfs_extlen_t ext_len,
struct xfs_owner_info *oinfo) struct xfs_owner_info *oinfo,
bool skip_discard)
{ {
struct xfs_mount *mp = tp->t_mountp; struct xfs_mount *mp = tp->t_mountp;
uint next_extent; uint next_extent;
...@@ -79,8 +80,12 @@ xfs_trans_free_extent( ...@@ -79,8 +80,12 @@ xfs_trans_free_extent(
trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len); trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
error = xfs_free_extent(tp, start_block, ext_len, oinfo, if (skip_discard)
XFS_AG_RESV_NONE); error = xfs_free_extent_nodiscard(tp, start_block, ext_len,
oinfo, XFS_AG_RESV_NONE);
else
error = xfs_free_extent(tp, start_block, ext_len, oinfo,
XFS_AG_RESV_NONE);
/* /*
* Mark the transaction dirty, even on error. This ensures the * Mark the transaction dirty, even on error. This ensures the
...@@ -195,7 +200,7 @@ xfs_extent_free_finish_item( ...@@ -195,7 +200,7 @@ xfs_extent_free_finish_item(
error = xfs_trans_free_extent(tp, done_item, error = xfs_trans_free_extent(tp, done_item,
free->xefi_startblock, free->xefi_startblock,
free->xefi_blockcount, free->xefi_blockcount,
&free->xefi_oinfo); &free->xefi_oinfo, free->xefi_skip_discard);
kmem_free(free); kmem_free(free);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment