mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 22:24:11 +08:00
xfs: make xfs_bmapi_convert_delalloc() to allocate the target offset
Since xfs_bmapi_convert_delalloc() only attempts to allocate the entire delalloc extent and require multiple invocations to allocate the target offset. So xfs_convert_blocks() add a loop to do this job and we call it in the write back path, but xfs_convert_blocks() isn't a common helper. Let's do it in xfs_bmapi_convert_delalloc() and drop xfs_convert_blocks(), preparing for the post EOF delalloc blocks converting in the buffered write begin path. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
This commit is contained in:
parent
fc8d0ba0ff
commit
2e08371a83
@ -4590,8 +4590,8 @@ error0:
|
||||
* invocations to allocate the target offset if a large enough physical extent
|
||||
* is not available.
|
||||
*/
|
||||
int
|
||||
xfs_bmapi_convert_delalloc(
|
||||
static int
|
||||
xfs_bmapi_convert_one_delalloc(
|
||||
struct xfs_inode *ip,
|
||||
int whichfork,
|
||||
xfs_off_t offset,
|
||||
@ -4724,6 +4724,36 @@ out_trans_cancel:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass in a dellalloc extent and convert it to real extents, return the real
|
||||
* extent that maps offset_fsb in iomap.
|
||||
*/
|
||||
int
|
||||
xfs_bmapi_convert_delalloc(
|
||||
struct xfs_inode *ip,
|
||||
int whichfork,
|
||||
loff_t offset,
|
||||
struct iomap *iomap,
|
||||
unsigned int *seq)
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Attempt to allocate whatever delalloc extent currently backs offset
|
||||
* and put the result into iomap. Allocate in a loop because it may
|
||||
* take several attempts to allocate real blocks for a contiguous
|
||||
* delalloc extent if free space is sufficiently fragmented.
|
||||
*/
|
||||
do {
|
||||
error = xfs_bmapi_convert_one_delalloc(ip, whichfork, offset,
|
||||
iomap, seq);
|
||||
if (error)
|
||||
return error;
|
||||
} while (iomap->offset + iomap->length <= offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_bmapi_remap(
|
||||
struct xfs_trans *tp,
|
||||
|
@ -233,45 +233,6 @@ xfs_imap_valid(
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass in a dellalloc extent and convert it to real extents, return the real
|
||||
* extent that maps offset_fsb in wpc->iomap.
|
||||
*
|
||||
* The current page is held locked so nothing could have removed the block
|
||||
* backing offset_fsb, although it could have moved from the COW to the data
|
||||
* fork by another thread.
|
||||
*/
|
||||
static int
|
||||
xfs_convert_blocks(
|
||||
struct iomap_writepage_ctx *wpc,
|
||||
struct xfs_inode *ip,
|
||||
int whichfork,
|
||||
loff_t offset)
|
||||
{
|
||||
int error;
|
||||
unsigned *seq;
|
||||
|
||||
if (whichfork == XFS_COW_FORK)
|
||||
seq = &XFS_WPC(wpc)->cow_seq;
|
||||
else
|
||||
seq = &XFS_WPC(wpc)->data_seq;
|
||||
|
||||
/*
|
||||
* Attempt to allocate whatever delalloc extent currently backs offset
|
||||
* and put the result into wpc->iomap. Allocate in a loop because it
|
||||
* may take several attempts to allocate real blocks for a contiguous
|
||||
* delalloc extent if free space is sufficiently fragmented.
|
||||
*/
|
||||
do {
|
||||
error = xfs_bmapi_convert_delalloc(ip, whichfork, offset,
|
||||
&wpc->iomap, seq);
|
||||
if (error)
|
||||
return error;
|
||||
} while (wpc->iomap.offset + wpc->iomap.length <= offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xfs_map_blocks(
|
||||
struct iomap_writepage_ctx *wpc,
|
||||
@ -290,6 +251,7 @@ xfs_map_blocks(
|
||||
struct xfs_iext_cursor icur;
|
||||
int retries = 0;
|
||||
int error = 0;
|
||||
unsigned int *seq;
|
||||
|
||||
if (xfs_is_shutdown(mp))
|
||||
return -EIO;
|
||||
@ -387,7 +349,19 @@ retry:
|
||||
trace_xfs_map_blocks_found(ip, offset, count, whichfork, &imap);
|
||||
return 0;
|
||||
allocate_blocks:
|
||||
error = xfs_convert_blocks(wpc, ip, whichfork, offset);
|
||||
/*
|
||||
* Convert a dellalloc extent to a real one. The current page is held
|
||||
* locked so nothing could have removed the block backing offset_fsb,
|
||||
* although it could have moved from the COW to the data fork by another
|
||||
* thread.
|
||||
*/
|
||||
if (whichfork == XFS_COW_FORK)
|
||||
seq = &XFS_WPC(wpc)->cow_seq;
|
||||
else
|
||||
seq = &XFS_WPC(wpc)->data_seq;
|
||||
|
||||
error = xfs_bmapi_convert_delalloc(ip, whichfork, offset,
|
||||
&wpc->iomap, seq);
|
||||
if (error) {
|
||||
/*
|
||||
* If we failed to find the extent in the COW fork we might have
|
||||
|
Loading…
Reference in New Issue
Block a user