|
@@ -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)
|