提交 8ff2957d 编写于 作者: C Christoph Hellwig 提交者: Alex Elder

xfs: simplify xfs_map_blocks

No need to lock the extent map exclusive when performing an
overwrite, we know the extent map must already have been loaded by
get_blocks.  Apply the non-blocking inode semantics to all mapping
types instead of just delayed allocations.  Remove the handling of
not yet allocated blocks for the IO_UNWRITTEN case - if an extent is
marked as unwritten allocated in the buffer it must already have an
extent on disk.

Add asserts to verify all the assumptions above in debug builds.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Reviewed-by: NDave Chinner <dchinner@redhat.com>
Signed-off-by: NAlex Elder <aelder@sgi.com>
上级 a206c817
...@@ -313,81 +313,54 @@ xfs_map_blocks( ...@@ -313,81 +313,54 @@ xfs_map_blocks(
struct xfs_mount *mp = ip->i_mount; struct xfs_mount *mp = ip->i_mount;
xfs_fileoff_t offset_fsb, end_fsb; xfs_fileoff_t offset_fsb, end_fsb;
int error = 0; int error = 0;
int lockmode = 0;
int bmapi_flags = XFS_BMAPI_ENTIRE; int bmapi_flags = XFS_BMAPI_ENTIRE;
int nimaps = 1; int nimaps = 1;
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return -XFS_ERROR(EIO); return -XFS_ERROR(EIO);
switch (type) { if (type == IO_UNWRITTEN)
case IO_OVERWRITE:
lockmode = xfs_ilock_map_shared(ip);
break;
case IO_UNWRITTEN:
lockmode = XFS_ILOCK_EXCL;
bmapi_flags |= XFS_BMAPI_IGSTATE; bmapi_flags |= XFS_BMAPI_IGSTATE;
xfs_ilock(ip, lockmode);
break; if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
case IO_DELALLOC: if (nonblocking)
lockmode = XFS_ILOCK_SHARED; return -XFS_ERROR(EAGAIN);
xfs_ilock(ip, XFS_ILOCK_SHARED);
if (!xfs_ilock_nowait(ip, lockmode)) {
if (nonblocking)
return -XFS_ERROR(EAGAIN);
xfs_ilock(ip, lockmode);
}
break;
} }
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
(ip->i_df.if_flags & XFS_IFEXTENTS));
ASSERT(offset <= mp->m_maxioffset); ASSERT(offset <= mp->m_maxioffset);
if (offset + count > mp->m_maxioffset) if (offset + count > mp->m_maxioffset)
count = mp->m_maxioffset - offset; count = mp->m_maxioffset - offset;
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
offset_fsb = XFS_B_TO_FSBT(mp, offset); offset_fsb = XFS_B_TO_FSBT(mp, offset);
error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb,
bmapi_flags, NULL, 0, imap, &nimaps, NULL); bmapi_flags, NULL, 0, imap, &nimaps, NULL);
if (error) xfs_iunlock(ip, XFS_ILOCK_SHARED);
goto out;
switch (type) {
case IO_UNWRITTEN:
/* If we found an extent, return it */
if (nimaps &&
(imap->br_startblock != HOLESTARTBLOCK) &&
(imap->br_startblock != DELAYSTARTBLOCK)) {
trace_xfs_map_blocks_found(ip, offset, count, type, imap);
break;
}
error = xfs_iomap_write_delay(ip, offset, count, imap); if (error)
if (!error) return -XFS_ERROR(error);
trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
break;
case IO_DELALLOC:
/* If we found an extent, return it */
xfs_iunlock(ip, lockmode);
lockmode = 0;
if (nimaps && !isnullstartblock(imap->br_startblock)) {
trace_xfs_map_blocks_found(ip, offset, count, type, imap);
break;
}
if (type == IO_DELALLOC &&
(!nimaps || isnullstartblock(imap->br_startblock))) {
error = xfs_iomap_write_allocate(ip, offset, count, imap); error = xfs_iomap_write_allocate(ip, offset, count, imap);
if (!error) if (!error)
trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
break; return -XFS_ERROR(error);
default:
if (nimaps)
trace_xfs_map_blocks_found(ip, offset, count, type, imap);
} }
out: #ifdef DEBUG
if (lockmode) if (type == IO_UNWRITTEN) {
xfs_iunlock(ip, lockmode); ASSERT(nimaps);
return -XFS_ERROR(error); ASSERT(imap->br_startblock != HOLESTARTBLOCK);
ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
}
#endif
if (nimaps)
trace_xfs_map_blocks_found(ip, offset, count, type, imap);
return 0;
} }
STATIC int STATIC int
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册