@ -4427,18 +4427,24 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
return 0 ;
}
/*
* Main entry point into mballoc to free blocks
/**
* ext4_free_blocks ( ) - - Free given blocks and update quota
* @ handle : handle for this transaction
* @ inode : inode
* @ block : start physical block to free
* @ count : number of blocks to count
* @ metadata : Are these metadata blocks
*/
void ext4_mb_free_blocks ( handle_t * handle , struct inode * inode ,
ext4_fsblk_t block , unsigned long count ,
int metadata , unsigned long * freed )
void ext4_free_blocks ( handle_t * handle , struct inode * inode ,
ext4_fsblk_t block , unsigned long count ,
int metadata )
{
struct buffer_head * bitmap_bh = NULL ;
struct super_block * sb = inode - > i_sb ;
struct ext4_allocation_context * ac = NULL ;
struct ext4_group_desc * gdp ;
struct ext4_super_block * es ;
unsigned long freed = 0 ;
unsigned int overflow ;
ext4_grpblk_t bit ;
struct buffer_head * gd_bh ;
@ -4448,7 +4454,15 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
int err = 0 ;
int ret ;
* freed = 0 ;
/*
* We need to make sure we don ' t reuse the freed block until
* after the transaction is committed , which we can do by
* treating the block as metadata , below . We make an
* exception if the inode is to be written in writeback mode
* since writeback mode has weak data consistency guarantees .
*/
if ( ! ext4_should_writeback_data ( inode ) )
metadata = 1 ;
sbi = EXT4_SB ( sb ) ;
es = EXT4_SB ( sb ) - > s_es ;
@ -4577,7 +4591,7 @@ do_more:
ext4_mb_release_desc ( & e4b ) ;
* freed + = count ;
freed + = count ;
/* We dirtied the bitmap block */
BUFFER_TRACE ( bitmap_bh , " dirtied bitmap block " ) ;
@ -4597,6 +4611,8 @@ do_more:
}
sb - > s_dirt = 1 ;
error_return :
if ( freed )
vfs_dq_free_block ( inode , freed ) ;
brelse ( bitmap_bh ) ;
ext4_std_error ( sb , err ) ;
if ( ac )