aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-27 12:21:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-27 12:21:06 -0700
commitf57494321cbf5b1e7769b6135407d2995a369e28 (patch)
tree7bf9db5346219ed048499d54a73b70f98f258d45 /fs/xfs/xfs_iomap.c
parentMAINTAINERS: Timur has a kernel.org address (diff)
parentxfs: fix fdblocks accounting w/ RMAPBT per-AG reservation (diff)
downloadlinux-dev-f57494321cbf5b1e7769b6135407d2995a369e28.tar.xz
linux-dev-f57494321cbf5b1e7769b6135407d2995a369e28.zip
Merge tag 'xfs-4.18-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Darrick Wong: "Here are some patches for 4.18 to fix regressions, accounting problems, overflow problems, and to strengthen metadata validation to prevent corruption. This series has been run through a full xfstests run over the weekend and through a quick xfstests run against this morning's master, with no major failures reported. Changes since last update: - more metadata validation strengthening to prevent crashes. - fix extent offset overflow problem when insert_range on a 512b block fs - fix some off-by-one errors in the realtime fsmap code - fix some math errors in the default resblks calculation when free space is low - fix a problem where stale page contents are exposed via mmap read after a zero_range at eof - fix accounting problems with per-ag reservations causing statfs reports to vary incorrectly" * tag 'xfs-4.18-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: fix fdblocks accounting w/ RMAPBT per-AG reservation xfs: ensure post-EOF zeroing happens after zeroing part of a file xfs: fix off-by-one error in xfs_rtalloc_query_range xfs: fix uninitialized field in rtbitmap fsmap backend xfs: recheck reflink state after grabbing ILOCK_SHARED for a write xfs: don't allow insert-range to shift extents past the maximum offset xfs: don't trip over negative free space in xfs_reserve_blocks xfs: allow empty transactions while frozen xfs: xfs_iflush_abort() can be called twice on cluster writeback failure xfs: More robust inode extent count validation xfs: simplify xfs_bmap_punch_delalloc_range
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 49f5492eed3b..55876dd02f0c 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -963,12 +963,13 @@ xfs_ilock_for_iomap(
unsigned *lockmode)
{
unsigned mode = XFS_ILOCK_SHARED;
+ bool is_write = flags & (IOMAP_WRITE | IOMAP_ZERO);
/*
* COW writes may allocate delalloc space or convert unwritten COW
* extents, so we need to make sure to take the lock exclusively here.
*/
- if (xfs_is_reflink_inode(ip) && (flags & (IOMAP_WRITE | IOMAP_ZERO))) {
+ if (xfs_is_reflink_inode(ip) && is_write) {
/*
* FIXME: It could still overwrite on unshared extents and not
* need allocation.
@@ -989,6 +990,7 @@ xfs_ilock_for_iomap(
mode = XFS_ILOCK_EXCL;
}
+relock:
if (flags & IOMAP_NOWAIT) {
if (!xfs_ilock_nowait(ip, mode))
return -EAGAIN;
@@ -996,6 +998,17 @@ xfs_ilock_for_iomap(
xfs_ilock(ip, mode);
}
+ /*
+ * The reflink iflag could have changed since the earlier unlocked
+ * check, so if we got ILOCK_SHARED for a write and but we're now a
+ * reflink inode we have to switch to ILOCK_EXCL and relock.
+ */
+ if (mode == XFS_ILOCK_SHARED && is_write && xfs_is_reflink_inode(ip)) {
+ xfs_iunlock(ip, mode);
+ mode = XFS_ILOCK_EXCL;
+ goto relock;
+ }
+
*lockmode = mode;
return 0;
}