diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-08-12 09:55:01 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-08-12 09:55:10 +0300 |
commit | 73b383141d296c55bfbc0ce336a4a946627e7780 (patch) | |
tree | df0840c4ea4bbd5aa453931a594936bd9adab61d /fs/xfs/xfs_iomap.c | |
parent | 627661ced8246c8e833f3bc3817070e934cd79ba (diff) | |
parent | 91c6e15efc1756b068dc6e945c1626397e60a119 (diff) | |
download | linux-73b383141d296c55bfbc0ce336a4a946627e7780.tar.xz |
Merge branch 'for-next' into for-linus
Preparation for 4.19 merge material.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r-- | fs/xfs/xfs_iomap.c | 15 |
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; } |