@@ -853,7 +853,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
853
853
for (i = 0 ; i < depth ; i ++ ) {
854
854
if (!ablocks [i ])
855
855
continue ;
856
- ext4_free_blocks (handle , inode , ablocks [i ], 1 );
856
+ ext4_free_blocks (handle , inode , ablocks [i ], 1 , 1 );
857
857
}
858
858
}
859
859
kfree (ablocks );
@@ -1698,7 +1698,7 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
1698
1698
ext_debug ("index is empty, remove it, free block %llu\n" , leaf );
1699
1699
bh = sb_find_get_block (inode -> i_sb , leaf );
1700
1700
ext4_forget (handle , 1 , inode , bh , leaf );
1701
- ext4_free_blocks (handle , inode , leaf , 1 );
1701
+ ext4_free_blocks (handle , inode , leaf , 1 , 1 );
1702
1702
return err ;
1703
1703
}
1704
1704
@@ -1759,8 +1759,10 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
1759
1759
{
1760
1760
struct buffer_head * bh ;
1761
1761
unsigned short ee_len = ext4_ext_get_actual_len (ex );
1762
- int i ;
1762
+ int i , metadata = 0 ;
1763
1763
1764
+ if (S_ISDIR (inode -> i_mode ) || S_ISLNK (inode -> i_mode ))
1765
+ metadata = 1 ;
1764
1766
#ifdef EXTENTS_STATS
1765
1767
{
1766
1768
struct ext4_sb_info * sbi = EXT4_SB (inode -> i_sb );
@@ -1789,7 +1791,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
1789
1791
bh = sb_find_get_block (inode -> i_sb , start + i );
1790
1792
ext4_forget (handle , 0 , inode , bh , start + i );
1791
1793
}
1792
- ext4_free_blocks (handle , inode , start , num );
1794
+ ext4_free_blocks (handle , inode , start , num , metadata );
1793
1795
} else if (from == le32_to_cpu (ex -> ee_block )
1794
1796
&& to <= le32_to_cpu (ex -> ee_block ) + ee_len - 1 ) {
1795
1797
printk (KERN_INFO "strange request: removal %u-%u from %u:%u\n" ,
@@ -2287,6 +2289,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2287
2289
ext4_fsblk_t goal , newblock ;
2288
2290
int err = 0 , depth , ret ;
2289
2291
unsigned long allocated = 0 ;
2292
+ struct ext4_allocation_request ar ;
2290
2293
2291
2294
__clear_bit (BH_New , & bh_result -> b_state );
2292
2295
ext_debug ("blocks %u/%lu requested for inode %u\n" ,
@@ -2397,8 +2400,15 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2397
2400
if (S_ISREG (inode -> i_mode ) && (!EXT4_I (inode )-> i_block_alloc_info ))
2398
2401
ext4_init_block_alloc_info (inode );
2399
2402
2400
- /* allocate new block */
2401
- goal = ext4_ext_find_goal (inode , path , iblock );
2403
+ /* find neighbour allocated blocks */
2404
+ ar .lleft = iblock ;
2405
+ err = ext4_ext_search_left (inode , path , & ar .lleft , & ar .pleft );
2406
+ if (err )
2407
+ goto out2 ;
2408
+ ar .lright = iblock ;
2409
+ err = ext4_ext_search_right (inode , path , & ar .lright , & ar .pright );
2410
+ if (err )
2411
+ goto out2 ;
2402
2412
2403
2413
/*
2404
2414
* See if request is beyond maximum number of blocks we can have in
@@ -2421,22 +2431,36 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2421
2431
allocated = le16_to_cpu (newex .ee_len );
2422
2432
else
2423
2433
allocated = max_blocks ;
2424
- newblock = ext4_new_blocks (handle , inode , goal , & allocated , & err );
2434
+
2435
+ /* allocate new block */
2436
+ ar .inode = inode ;
2437
+ ar .goal = ext4_ext_find_goal (inode , path , iblock );
2438
+ ar .logical = iblock ;
2439
+ ar .len = allocated ;
2440
+ if (S_ISREG (inode -> i_mode ))
2441
+ ar .flags = EXT4_MB_HINT_DATA ;
2442
+ else
2443
+ /* disable in-core preallocation for non-regular files */
2444
+ ar .flags = 0 ;
2445
+ newblock = ext4_mb_new_blocks (handle , & ar , & err );
2425
2446
if (!newblock )
2426
2447
goto out2 ;
2427
2448
ext_debug ("allocate new block: goal %llu, found %llu/%lu\n" ,
2428
2449
goal , newblock , allocated );
2429
2450
2430
2451
/* try to insert new extent into found leaf and return */
2431
2452
ext4_ext_store_pblock (& newex , newblock );
2432
- newex .ee_len = cpu_to_le16 (allocated );
2453
+ newex .ee_len = cpu_to_le16 (ar . len );
2433
2454
if (create == EXT4_CREATE_UNINITIALIZED_EXT ) /* Mark uninitialized */
2434
2455
ext4_ext_mark_uninitialized (& newex );
2435
2456
err = ext4_ext_insert_extent (handle , inode , path , & newex );
2436
2457
if (err ) {
2437
2458
/* free data blocks we just allocated */
2459
+ /* not a good idea to call discard here directly,
2460
+ * but otherwise we'd need to call it every free() */
2461
+ ext4_mb_discard_inode_preallocations (inode );
2438
2462
ext4_free_blocks (handle , inode , ext_pblock (& newex ),
2439
- le16_to_cpu (newex .ee_len ));
2463
+ le16_to_cpu (newex .ee_len ), 0 );
2440
2464
goto out2 ;
2441
2465
}
2442
2466
@@ -2445,6 +2469,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2445
2469
2446
2470
/* previous routine could use block we allocated */
2447
2471
newblock = ext_pblock (& newex );
2472
+ allocated = le16_to_cpu (newex .ee_len );
2448
2473
outnew :
2449
2474
__set_bit (BH_New , & bh_result -> b_state );
2450
2475
@@ -2496,6 +2521,8 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
2496
2521
down_write (& EXT4_I (inode )-> i_data_sem );
2497
2522
ext4_ext_invalidate_cache (inode );
2498
2523
2524
+ ext4_mb_discard_inode_preallocations (inode );
2525
+
2499
2526
/*
2500
2527
* TODO: optimization is possible here.
2501
2528
* Probably we need not scan at all,
0 commit comments