@@ -2460,74 +2460,6 @@ xfs_da_shrink_inode(
2460
2460
return error ;
2461
2461
}
2462
2462
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
-
2531
2463
/*
2532
2464
* Map the block we are given ready for reading. There are three possible return
2533
2465
* values:
@@ -2542,58 +2474,78 @@ xfs_dabuf_map(
2542
2474
xfs_dablk_t bno ,
2543
2475
xfs_daddr_t mappedbno ,
2544
2476
int whichfork ,
2545
- struct xfs_buf_map * * map ,
2477
+ struct xfs_buf_map * * mapp ,
2546
2478
int * nmaps )
2547
2479
{
2548
2480
struct xfs_mount * mp = dp -> i_mount ;
2549
2481
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 ;
2557
2486
2558
- if (nfsb != 1 )
2487
+ if (nfsb > 1 )
2559
2488
irecs = kmem_zalloc (sizeof (irec ) * nfsb , KM_NOFS );
2489
+
2560
2490
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 ));
2563
2493
if (error )
2564
- goto out ;
2494
+ goto out_free_irecs ;
2565
2495
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
+ }
2572
2506
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 ;
2574
2532
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 );
2576
2535
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 ++ ) {
2580
2537
xfs_alert (mp ,
2581
2538
"[%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 ,
2586
2542
irecs [i ].br_state );
2587
2543
}
2588
2544
}
2589
- error = - EFSCORRUPTED ;
2590
- goto out ;
2545
+ } else {
2546
+ * nmaps = 0 ;
2591
2547
}
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 ;
2597
2549
}
2598
2550
2599
2551
/*
0 commit comments