summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_pnfs.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-10-30 12:24:59 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2019-11-03 10:22:30 -0800
commite696663a97e89f88d085ff84b8a373989ae613b1 (patch)
tree89b73dd4b10dddb2198ff318f86b7264a697caf0 /fs/xfs/xfs_pnfs.c
parent307cdb54b80e036978b7b717abcbcfdac0b34e38 (diff)
downloadlinux-stable-e696663a97e89f88d085ff84b8a373989ae613b1.tar.gz
linux-stable-e696663a97e89f88d085ff84b8a373989ae613b1.tar.bz2
linux-stable-e696663a97e89f88d085ff84b8a373989ae613b1.zip
xfs: simplify the xfs_iomap_write_direct calling
Move the EOF alignment and checking for the next allocated extent into the callers to avoid the need to pass the byte based offset and count as well as looking at the incoming imap. The added benefit is that the caller can unlock the incoming ilock and the function doesn't have funny unbalanced locking contexts. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_pnfs.c')
-rw-r--r--fs/xfs/xfs_pnfs.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index ada46e9f5ff1..ae3f00cb6a43 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -143,21 +143,20 @@ xfs_fs_map_blocks(
lock_flags = xfs_ilock_data_map_shared(ip);
error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
&imap, &nimaps, bmapi_flags);
- xfs_iunlock(ip, lock_flags);
-
- if (error)
- goto out_unlock;
ASSERT(!nimaps || imap.br_startblock != DELAYSTARTBLOCK);
- if (write && (!nimaps || imap.br_startblock == HOLESTARTBLOCK)) {
- /*
- * xfs_iomap_write_direct() expects to take ownership of the
- * shared ilock.
- */
- xfs_ilock(ip, XFS_ILOCK_SHARED);
- error = xfs_iomap_write_direct(ip, offset, length, &imap,
- nimaps);
+ if (!error && write &&
+ (!nimaps || imap.br_startblock == HOLESTARTBLOCK)) {
+ if (offset + length > XFS_ISIZE(ip))
+ end_fsb = xfs_iomap_eof_align_last_fsb(ip, end_fsb);
+ else if (nimaps && imap.br_startblock == HOLESTARTBLOCK)
+ end_fsb = min(end_fsb, imap.br_startoff +
+ imap.br_blockcount);
+ xfs_iunlock(ip, lock_flags);
+
+ error = xfs_iomap_write_direct(ip, offset_fsb,
+ end_fsb - offset_fsb, &imap);
if (error)
goto out_unlock;
@@ -170,6 +169,8 @@ xfs_fs_map_blocks(
XFS_PREALLOC_SET | XFS_PREALLOC_SYNC);
if (error)
goto out_unlock;
+ } else {
+ xfs_iunlock(ip, lock_flags);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL);