This fixes fatal signals getting into the way and corrupting the bio chain and removes the need to handle synchronous errors. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/xfs/xfs_discard.c | 47 ++++++++++++++------------------------------ fs/xfs/xfs_discard.h | 2 +- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index d5787991bb5b46..6396a4e14809a2 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -102,33 +102,26 @@ xfs_discard_endio( * list. We plug and chain the bios so that we only need a single completion * call to clear all the busy extents once the discards are complete. */ -int +void xfs_discard_extents( struct xfs_mount *mp, struct xfs_busy_extents *extents) { + struct block_device *bdev = mp->m_ddev_targp->bt_bdev; struct xfs_extent_busy *busyp; struct bio *bio = NULL; struct blk_plug plug; - int error = 0; blk_start_plug(&plug); list_for_each_entry(busyp, &extents->extent_list, list) { + sector_t sector = XFS_AGB_TO_DADDR(mp, busyp->agno, busyp->bno); + sector_t nr_sects = XFS_FSB_TO_BB(mp, busyp->length); + trace_xfs_discard_extent(mp, busyp->agno, busyp->bno, busyp->length); - - error = __blkdev_issue_discard(mp->m_ddev_targp->bt_bdev, - XFS_AGB_TO_DADDR(mp, busyp->agno, busyp->bno), - XFS_FSB_TO_BB(mp, busyp->length), - GFP_NOFS, &bio); - if (error && error != -EOPNOTSUPP) { - xfs_info(mp, - "discard failed for extent [0x%llx,%u], error %d", - (unsigned long long)busyp->bno, - busyp->length, - error); - break; - } + while (blk_next_discard_bio(bdev, &bio, §or, &nr_sects, + GFP_NOFS)) + ; } if (bio) { @@ -139,11 +132,8 @@ xfs_discard_extents( xfs_discard_endio_work(&extents->endio_work); } blk_finish_plug(&plug); - - return error; } - static int xfs_trim_gather_extents( struct xfs_perag *pag, @@ -306,16 +296,14 @@ xfs_trim_extents( .ar_blockcount = pag->pagf_longest, .ar_startblock = NULLAGBLOCK, }; - int error = 0; do { struct xfs_busy_extents *extents; + int error; extents = kzalloc(sizeof(*extents), GFP_KERNEL); - if (!extents) { - error = -ENOMEM; - break; - } + if (!extents) + return -ENOMEM; extents->mount = pag->pag_mount; extents->owner = extents; @@ -325,7 +313,7 @@ xfs_trim_extents( &tcur, extents, blocks_trimmed); if (error) { kfree(extents); - break; + return error; } /* @@ -338,17 +326,12 @@ xfs_trim_extents( * list after this function call, as it may have been freed by * the time control returns to us. */ - error = xfs_discard_extents(pag->pag_mount, extents); - if (error) - break; - + xfs_discard_extents(pag->pag_mount, extents); if (xfs_trim_should_stop()) - break; - + return 0; } while (tcur.ar_blockcount != 0); - return error; - + return 0; } /* diff --git a/fs/xfs/xfs_discard.h b/fs/xfs/xfs_discard.h index 2b1a85223a56c6..8c5cc4af6a0787 100644 --- a/fs/xfs/xfs_discard.h +++ b/fs/xfs/xfs_discard.h @@ -6,7 +6,7 @@ struct fstrim_range; struct xfs_mount; struct xfs_busy_extents; -int xfs_discard_extents(struct xfs_mount *mp, struct xfs_busy_extents *busy); +void xfs_discard_extents(struct xfs_mount *mp, struct xfs_busy_extents *busy); int xfs_ioc_trim(struct xfs_mount *mp, struct fstrim_range __user *fstrim); #endif /* XFS_DISCARD_H */ -- 2.39.2