diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 8cd8c412f52dd46696634017cb6c3804d159e368..696c3b6bd2c95868eaf9f06688da78c36fd7835d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -871,8 +871,8 @@ xfs_free_eofblocks( * contents of the file are flushed to disk then the files * may be full of holes (ie NULL files bug). */ - error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, - XFS_ISIZE(ip)); + error = xfs_itruncate_extents_nodiscard(&tp, ip, XFS_DATA_FORK, + XFS_ISIZE(ip)); if (error) { /* * If we get an error at this point we simply don't diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 42781bae6794a485981930041ba27d1843b19756..5b2e08488107d0008c90e9f54910e0c68ba73880 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1548,11 +1548,12 @@ xfs_itruncate_clear_reflink_flags( * dirty on error so that transactions can be easily aborted if possible. */ int -xfs_itruncate_extents( +__xfs_itruncate_extents( struct xfs_trans **tpp, struct xfs_inode *ip, int whichfork, - xfs_fsize_t new_size) + xfs_fsize_t new_size, + bool skip_discard) { struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp = *tpp; @@ -1563,6 +1564,7 @@ xfs_itruncate_extents( xfs_filblks_t unmap_len; int error = 0; int done = 0; + int flags; ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ASSERT(!atomic_read(&VFS_I(ip)->i_count) || @@ -1575,6 +1577,10 @@ xfs_itruncate_extents( trace_xfs_itruncate_extents_start(ip, new_size); + flags = xfs_bmapi_aflag(whichfork); + if (skip_discard) + flags |= XFS_BMAPI_NODISCARD; + /* * Since it is possible for space to become allocated beyond * the end of the file (in a crash where the space is allocated @@ -1593,12 +1599,9 @@ xfs_itruncate_extents( unmap_len = last_block - first_unmap_block + 1; while (!done) { xfs_defer_init(&dfops, &first_block); - error = xfs_bunmapi(tp, ip, - first_unmap_block, unmap_len, - xfs_bmapi_aflag(whichfork), - XFS_ITRUNC_MAX_EXTENTS, - &first_block, &dfops, - &done); + error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, flags, + XFS_ITRUNC_MAX_EXTENTS, &first_block, + &dfops, &done); if (error) goto out_bmap_cancel; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 1eebc53df7d72f91e5b465d0b2295c3dafccfd89..3dd3201f44095663db5ab9b3a2155328d4ea554e 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -415,8 +415,8 @@ uint xfs_ilock_attr_map_shared(struct xfs_inode *); uint xfs_ip2xflags(struct xfs_inode *); int xfs_ifree(struct xfs_trans *, xfs_inode_t *, struct xfs_defer_ops *); -int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *, - int, xfs_fsize_t); +int __xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *, + int, xfs_fsize_t, bool); void xfs_iext_realloc(xfs_inode_t *, int, int); void xfs_iunpin_wait(xfs_inode_t *); @@ -433,6 +433,26 @@ int xfs_dir_ialloc(struct xfs_trans **, struct xfs_inode *, umode_t, xfs_nlink_t, dev_t, prid_t, struct xfs_inode **); +static inline int +xfs_itruncate_extents( + struct xfs_trans **tpp, + struct xfs_inode *ip, + int whichfork, + xfs_fsize_t new_size) +{ + return __xfs_itruncate_extents(tpp, ip, whichfork, new_size, false); +} + +static inline int +xfs_itruncate_extents_nodiscard( + struct xfs_trans **tpp, + struct xfs_inode *ip, + int whichfork, + xfs_fsize_t new_size) +{ + return __xfs_itruncate_extents(tpp, ip, whichfork, new_size, true); +} + /* from xfs_file.c */ enum xfs_prealloc_flags { XFS_PREALLOC_SET = (1 << 1),