]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: add bmapi nodiscard flag
authorBrian Foster <bfoster@redhat.com>
Thu, 28 Jun 2018 20:11:56 +0000 (15:11 -0500)
committerEric Sandeen <sandeen@redhat.com>
Thu, 28 Jun 2018 20:11:56 +0000 (15:11 -0500)
Source kernel commit: fcb762f5de2e534ab47b5f034fe484c2b25b4d51

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: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_priv.h
libxfs/xfs_alloc.c
libxfs/xfs_alloc.h
libxfs/xfs_bmap.c
libxfs/xfs_bmap.h

index 1508d9a21b8ae241a22e56ab1fc7fc0ccf4d81b7..995ea644d1aae006ccf1738021647ec51213850c 100644 (file)
@@ -437,6 +437,9 @@ roundup_64(uint64_t x, uint32_t y)
 })
 
 /* space allocation */
+#define XFS_EXTENT_BUSY_DISCARDED      0x01    /* undergoing a discard op. */
+#define XFS_EXTENT_BUSY_SKIP_DISCARD   0x02    /* do not discard */
+
 #define xfs_extent_busy_reuse(mp,ag,bno,len,user)      ((void) 0)
 /* avoid unused variable warning */
 #define xfs_extent_busy_insert(tp,ag,bno,len,flags)({  \
index b2108c3422854dca3fab28fa4821ea963d7aea3d..a5a65849a9b33467ba8b6fe81ec9f57f233fc867 100644 (file)
@@ -3006,18 +3006,20 @@ out:
  * after fixing up the freelist.
  */
 int                            /* error */
-xfs_free_extent(
+__xfs_free_extent(
        struct xfs_trans        *tp,    /* transaction pointer */
        xfs_fsblock_t           bno,    /* starting block number of extent */
        xfs_extlen_t            len,    /* length of extent */
        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_buf          *agbp;
        xfs_agnumber_t          agno = XFS_FSB_TO_AGNO(mp, bno);
        xfs_agblock_t           agbno = XFS_FSB_TO_AGBNO(mp, bno);
        int                     error;
+       unsigned int            busy_flags = 0;
 
        ASSERT(len != 0);
        ASSERT(type != XFS_AG_RESV_AGFL);
@@ -3041,7 +3043,9 @@ xfs_free_extent(
        if (error)
                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;
 
 err:
index 949e21326066ffa67427fee9409e3379791f044e..1dcac78586b46ede7d7e48a159feb35940badd36 100644 (file)
@@ -191,12 +191,35 @@ xfs_alloc_vextent(
  * Free an extent.
  */
 int                            /* error */
-xfs_free_extent(
+__xfs_free_extent(
        struct xfs_trans        *tp,    /* transaction pointer */
        xfs_fsblock_t           bno,    /* starting block number of extent */
        xfs_extlen_t            len,    /* length of extent */
        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 */
 xfs_alloc_lookup_le(
index ebd3671424a183c6af4510fd60f60006c4cb7ccf..d8f54deaf27e82cc23673a254e0c64f8caf5466a 100644 (file)
@@ -535,12 +535,13 @@ xfs_bmap_validate_ret(
  * The list is maintained sorted (by block number).
  */
 void
-xfs_bmap_add_free(
+__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)
+       struct xfs_owner_info           *oinfo,
+       bool                            skip_discard)
 {
        struct xfs_extent_free_item     *new;           /* new element */
 #ifdef DEBUG
@@ -567,6 +568,7 @@ xfs_bmap_add_free(
                new->xefi_oinfo = *oinfo;
        else
                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,
                        XFS_FSB_TO_AGBNO(mp, bno), len);
        xfs_defer_add(dfops, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list);
@@ -5097,9 +5099,16 @@ xfs_bmap_del_extent_real(
                        error = xfs_refcount_decrease_extent(mp, dfops, del);
                        if (error)
                                goto done;
-               } else
-                       xfs_bmap_add_free(mp, dfops, del->br_startblock,
+               } else {
+                       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);
+                       }
+               }
        }
 
        /*
index 2b766b37096d213e7170b34101210304606c2885..8d8946bfdd8cd6c30fc9bbb6619866721941acd4 100644 (file)
@@ -68,6 +68,7 @@ struct xfs_extent_free_item
        xfs_extlen_t            xefi_blockcount;/* number of blocks in extent */
        struct list_head        xefi_list;
        struct xfs_owner_info   xefi_oinfo;     /* extent owner */
+       bool                    xefi_skip_discard;
 };
 
 #define        XFS_BMAP_MAX_NMAP       4
@@ -116,6 +117,9 @@ struct xfs_extent_free_item
 /* Only convert unwritten extents, don't allocate new blocks */
 #define XFS_BMAPI_CONVERT_ONLY 0x800
 
+/* Skip online discard of freed extents */
+#define XFS_BMAPI_NODISCARD    0x1000
+
 #define XFS_BMAPI_FLAGS \
        { XFS_BMAPI_ENTIRE,     "ENTIRE" }, \
        { XFS_BMAPI_METADATA,   "METADATA" }, \
@@ -128,7 +132,8 @@ struct xfs_extent_free_item
        { XFS_BMAPI_REMAP,      "REMAP" }, \
        { XFS_BMAPI_COWFORK,    "COWFORK" }, \
        { 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)
@@ -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 *);
 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_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,
-                         struct xfs_owner_info *oinfo);
+                         struct xfs_owner_info *oinfo, bool skip_discard);
 void   xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
 int    xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
                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,
                struct xfs_bmbt_irec *got, struct xfs_iext_cursor *cur,
                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 {
        XFS_BMAP_MAP = 1,
        XFS_BMAP_UNMAP,