Skip to content

Commit 45feef8

Browse files
Christoph Hellwigdjwong
authored andcommitted
xfs: refactor xfs_dabuf_map
Merge xfs_buf_map_from_irec and xfs_da_map_covers_blocks into a single loop in the caller. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent fa0d44e commit 45feef8

File tree

1 file changed

+54
-102
lines changed

1 file changed

+54
-102
lines changed

fs/xfs/libxfs/xfs_da_btree.c

Lines changed: 54 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2460,74 +2460,6 @@ xfs_da_shrink_inode(
24602460
return error;
24612461
}
24622462

2463-
/*
2464-
* See if the mapping(s) for this btree block are valid, i.e.
2465-
* don't contain holes, are logically contiguous, and cover the whole range.
2466-
*/
2467-
STATIC int
2468-
xfs_da_map_covers_blocks(
2469-
int nmap,
2470-
xfs_bmbt_irec_t *mapp,
2471-
xfs_dablk_t bno,
2472-
int count)
2473-
{
2474-
int i;
2475-
xfs_fileoff_t off;
2476-
2477-
for (i = 0, off = bno; i < nmap; i++) {
2478-
if (mapp[i].br_startblock == HOLESTARTBLOCK ||
2479-
mapp[i].br_startblock == DELAYSTARTBLOCK) {
2480-
return 0;
2481-
}
2482-
if (off != mapp[i].br_startoff) {
2483-
return 0;
2484-
}
2485-
off += mapp[i].br_blockcount;
2486-
}
2487-
return off == bno + count;
2488-
}
2489-
2490-
/*
2491-
* Convert a struct xfs_bmbt_irec to a struct xfs_buf_map.
2492-
*
2493-
* For the single map case, it is assumed that the caller has provided a pointer
2494-
* to a valid xfs_buf_map. For the multiple map case, this function will
2495-
* allocate the xfs_buf_map to hold all the maps and replace the caller's single
2496-
* map pointer with the allocated map.
2497-
*/
2498-
static int
2499-
xfs_buf_map_from_irec(
2500-
struct xfs_mount *mp,
2501-
struct xfs_buf_map **mapp,
2502-
int *nmaps,
2503-
struct xfs_bmbt_irec *irecs,
2504-
int nirecs)
2505-
{
2506-
struct xfs_buf_map *map;
2507-
int i;
2508-
2509-
ASSERT(*nmaps == 1);
2510-
ASSERT(nirecs >= 1);
2511-
2512-
if (nirecs > 1) {
2513-
map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map),
2514-
KM_NOFS);
2515-
if (!map)
2516-
return -ENOMEM;
2517-
*mapp = map;
2518-
}
2519-
2520-
*nmaps = nirecs;
2521-
map = *mapp;
2522-
for (i = 0; i < *nmaps; i++) {
2523-
ASSERT(irecs[i].br_startblock != DELAYSTARTBLOCK &&
2524-
irecs[i].br_startblock != HOLESTARTBLOCK);
2525-
map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);
2526-
map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);
2527-
}
2528-
return 0;
2529-
}
2530-
25312463
/*
25322464
* Map the block we are given ready for reading. There are three possible return
25332465
* values:
@@ -2542,58 +2474,78 @@ xfs_dabuf_map(
25422474
xfs_dablk_t bno,
25432475
xfs_daddr_t mappedbno,
25442476
int whichfork,
2545-
struct xfs_buf_map **map,
2477+
struct xfs_buf_map **mapp,
25462478
int *nmaps)
25472479
{
25482480
struct xfs_mount *mp = dp->i_mount;
25492481
int nfsb = xfs_dabuf_nfsb(mp, whichfork);
2550-
int error = 0;
2551-
struct xfs_bmbt_irec irec;
2552-
struct xfs_bmbt_irec *irecs = &irec;
2553-
int nirecs;
2554-
2555-
ASSERT(map && *map);
2556-
ASSERT(*nmaps == 1);
2482+
struct xfs_bmbt_irec irec, *irecs = &irec;
2483+
struct xfs_buf_map *map = *mapp;
2484+
xfs_fileoff_t off = bno;
2485+
int error = 0, nirecs, i;
25572486

2558-
if (nfsb != 1)
2487+
if (nfsb > 1)
25592488
irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_NOFS);
2489+
25602490
nirecs = nfsb;
2561-
error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs,
2562-
&nirecs, xfs_bmapi_aflag(whichfork));
2491+
error = xfs_bmapi_read(dp, bno, nfsb, irecs, &nirecs,
2492+
xfs_bmapi_aflag(whichfork));
25632493
if (error)
2564-
goto out;
2494+
goto out_free_irecs;
25652495

2566-
if (!xfs_da_map_covers_blocks(nirecs, irecs, bno, nfsb)) {
2567-
/* Caller ok with no mapping. */
2568-
if (!XFS_IS_CORRUPT(mp, mappedbno != -2)) {
2569-
error = -1;
2570-
goto out;
2571-
}
2496+
/*
2497+
* Use the caller provided map for the single map case, else allocate a
2498+
* larger one that needs to be free by the caller.
2499+
*/
2500+
if (nirecs > 1) {
2501+
map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_NOFS);
2502+
if (!map)
2503+
goto out_free_irecs;
2504+
*mapp = map;
2505+
}
25722506

2573-
/* Caller expected a mapping, so abort. */
2507+
for (i = 0; i < nirecs; i++) {
2508+
if (irecs[i].br_startblock == HOLESTARTBLOCK ||
2509+
irecs[i].br_startblock == DELAYSTARTBLOCK)
2510+
goto invalid_mapping;
2511+
if (off != irecs[i].br_startoff)
2512+
goto invalid_mapping;
2513+
2514+
map[i].bm_bn = XFS_FSB_TO_DADDR(mp, irecs[i].br_startblock);
2515+
map[i].bm_len = XFS_FSB_TO_BB(mp, irecs[i].br_blockcount);
2516+
off += irecs[i].br_blockcount;
2517+
}
2518+
2519+
if (off != bno + nfsb)
2520+
goto invalid_mapping;
2521+
2522+
*nmaps = nirecs;
2523+
out_free_irecs:
2524+
if (irecs != &irec)
2525+
kmem_free(irecs);
2526+
return error;
2527+
2528+
invalid_mapping:
2529+
/* Caller ok with no mapping. */
2530+
if (XFS_IS_CORRUPT(mp, mappedbno != -2)) {
2531+
error = -EFSCORRUPTED;
25742532
if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
2575-
int i;
2533+
xfs_alert(mp, "%s: bno %u inode %llu",
2534+
__func__, bno, dp->i_ino);
25762535

2577-
xfs_alert(mp, "%s: bno %lld dir: inode %lld", __func__,
2578-
(long long)bno, (long long)dp->i_ino);
2579-
for (i = 0; i < *nmaps; i++) {
2536+
for (i = 0; i < nirecs; i++) {
25802537
xfs_alert(mp,
25812538
"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d",
2582-
i,
2583-
(long long)irecs[i].br_startoff,
2584-
(long long)irecs[i].br_startblock,
2585-
(long long)irecs[i].br_blockcount,
2539+
i, irecs[i].br_startoff,
2540+
irecs[i].br_startblock,
2541+
irecs[i].br_blockcount,
25862542
irecs[i].br_state);
25872543
}
25882544
}
2589-
error = -EFSCORRUPTED;
2590-
goto out;
2545+
} else {
2546+
*nmaps = 0;
25912547
}
2592-
error = xfs_buf_map_from_irec(mp, map, nmaps, irecs, nirecs);
2593-
out:
2594-
if (irecs != &irec)
2595-
kmem_free(irecs);
2596-
return error;
2548+
goto out_free_irecs;
25972549
}
25982550

25992551
/*

0 commit comments

Comments
 (0)