diff options
author | Christoph Hellwig <hch@lst.de> | 2019-10-30 20:24:59 +0100 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2019-11-03 19:22:30 +0100 |
commit | e696663a97e89f88d085ff84b8a373989ae613b1 (patch) | |
tree | 89b73dd4b10dddb2198ff318f86b7264a697caf0 /fs/xfs/xfs_pnfs.c | |
parent | xfs: don't log the inode in xfs_fs_map_blocks if it (diff) | |
download | linux-e696663a97e89f88d085ff84b8a373989ae613b1.tar.xz linux-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.c | 25 |
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); |