diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-10-03 18:11:39 +0200 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2016-10-06 01:26:05 +0200 |
commit | 174edb0e46e520230791a1a894397b7c824cefc4 (patch) | |
tree | c15257ff7f762c89bc3ddebe5bba23538a57cbcf /fs/xfs/xfs_reflink.h | |
parent | xfs: cancel pending CoW reservations when destroying inodes (diff) | |
download | linux-174edb0e46e520230791a1a894397b7c824cefc4.tar.xz linux-174edb0e46e520230791a1a894397b7c824cefc4.zip |
xfs: store in-progress CoW allocations in the refcount btree
Due to the way the CoW algorithm in XFS works, there's an interval
during which blocks allocated to handle a CoW can be lost -- if the FS
goes down after the blocks are allocated but before the block
remapping takes place. This is exacerbated by the cowextsz hint --
allocated reservations can sit around for a while, waiting to get
used.
Since the refcount btree doesn't normally store records with refcount
of 1, we can use it to record these in-progress extents. In-progress
blocks cannot be shared because they're not user-visible, so there
shouldn't be any conflicts with other programs. This is a better
solution than holding EFIs during writeback because (a) EFIs can't be
relogged currently, (b) even if they could, EFIs are bound by
available log space, which puts an unnecessary upper bound on how much
CoW we can have in flight, and (c) we already have a mechanism to
track blocks.
At mount time, read the refcount records and free anything we find
with a refcount of 1 because those were in-progress when the FS went
down.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_reflink.h')
-rw-r--r-- | fs/xfs/xfs_reflink.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index c0c989ae84bc..1d2f180f9eca 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -42,5 +42,6 @@ extern int xfs_reflink_cancel_cow_range(struct xfs_inode *ip, xfs_off_t offset, xfs_off_t count); extern int xfs_reflink_end_cow(struct xfs_inode *ip, xfs_off_t offset, xfs_off_t count); +extern int xfs_reflink_recover_cow(struct xfs_mount *mp); #endif /* __XFS_REFLINK_H */ |