diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-16 09:04:54 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-16 09:04:54 +0200 |
| commit | 83cf9cd6d50ed4f7e6ae265e80e38b235c792f5f (patch) | |
| tree | 6016c386c321cd6a3e8575e01ed9f10834fc5081 /fs/xfs/xfs_iomap.c | |
| parent | 34bcfdac8c92cc7971254ba5856afd12047c50b2 (diff) | |
| parent | 9d3cce1e8b8561fed5f383d22a4d6949db4eadbe (diff) | |
| download | blackbird-obmc-linux-83cf9cd6d50ed4f7e6ae265e80e38b235c792f5f.tar.gz blackbird-obmc-linux-83cf9cd6d50ed4f7e6ae265e80e38b235c792f5f.zip | |
Merge 4.18-rc5 into char-misc-next
We want the char-misc fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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; } |

