Commit b1a5f642 authored by Andrew Morton's avatar Andrew Morton Committed by Jeff Garzik

This fixes the "i_blocks went wrong when the disk filled up"

problem.

In ext3_new_block() we increment i_blocks early, so the
quota operation can be performed outside lock_super().
But if the block allocation ends up failing, we forget to
undo the allocation.  

This is not a serious bug, and probably does not warrant
an upgrade for production machines.  Its effects are:

1) errors are generated from e2fsck and

2) users could appear to be over quota when they really aren't.

The patch undoes the accounting operation if the allocation
ends up failing.
parent 5e4b5079
...@@ -542,6 +542,7 @@ int ext3_new_block (handle_t *handle, struct inode * inode, ...@@ -542,6 +542,7 @@ int ext3_new_block (handle_t *handle, struct inode * inode,
int i, j, k, tmp, alloctmp; int i, j, k, tmp, alloctmp;
int bitmap_nr; int bitmap_nr;
int fatal = 0, err; int fatal = 0, err;
int performed_allocation = 0;
struct super_block * sb; struct super_block * sb;
struct ext3_group_desc * gdp; struct ext3_group_desc * gdp;
struct ext3_super_block * es; struct ext3_super_block * es;
...@@ -644,8 +645,7 @@ int ext3_new_block (handle_t *handle, struct inode * inode, ...@@ -644,8 +645,7 @@ int ext3_new_block (handle_t *handle, struct inode * inode,
} }
/* No space left on the device */ /* No space left on the device */
unlock_super (sb); goto out;
return 0;
search_back: search_back:
/* /*
...@@ -694,6 +694,7 @@ int ext3_new_block (handle_t *handle, struct inode * inode, ...@@ -694,6 +694,7 @@ int ext3_new_block (handle_t *handle, struct inode * inode,
J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data)); J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data));
BUFFER_TRACE(bh, "setting bitmap bit"); BUFFER_TRACE(bh, "setting bitmap bit");
ext3_set_bit(j, bh->b_data); ext3_set_bit(j, bh->b_data);
performed_allocation = 1;
#ifdef CONFIG_JBD_DEBUG #ifdef CONFIG_JBD_DEBUG
{ {
...@@ -815,6 +816,11 @@ int ext3_new_block (handle_t *handle, struct inode * inode, ...@@ -815,6 +816,11 @@ int ext3_new_block (handle_t *handle, struct inode * inode,
ext3_std_error(sb, fatal); ext3_std_error(sb, fatal);
} }
unlock_super (sb); unlock_super (sb);
/*
* Undo the block allocation
*/
if (!performed_allocation)
DQUOT_FREE_BLOCK(inode, 1);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment