patch-2.4.0-test6 linux/fs/ext2/balloc.c

Next file: linux/fs/ext2/file.c
Previous file: linux/fs/exec.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test5/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
@@ -16,7 +16,6 @@
 #include <linux/locks.h>
 #include <linux/quotaops.h>
 
-
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
@@ -379,10 +378,8 @@
 	    ((sb->u.ext2_sb.s_resuid != current->fsuid) &&
 	     (sb->u.ext2_sb.s_resgid == 0 ||
 	      !in_group_p (sb->u.ext2_sb.s_resgid)) && 
-	     !capable(CAP_SYS_RESOURCE))) {
-		unlock_super (sb);
-		return 0;
-	}
+	     !capable(CAP_SYS_RESOURCE)))
+		goto out;
 
 	ext2_debug ("goal=%lu.\n", goal);
 
@@ -475,16 +472,13 @@
 		gdp = ext2_get_group_desc (sb, i, &bh2);
 		if (!gdp) {
 			*err = -EIO;
-			unlock_super (sb);
-			return 0;
+			goto out;
 		}
 		if (le16_to_cpu(gdp->bg_free_blocks_count) > 0)
 			break;
 	}
-	if (k >= sb->u.ext2_sb.s_groups_count) {
-		unlock_super (sb);
-		return 0;
-	}
+	if (k >= sb->u.ext2_sb.s_groups_count)
+		goto out;
 	bitmap_nr = load_block_bitmap (sb, i);
 	if (bitmap_nr < 0)
 		goto io_error;
@@ -500,8 +494,7 @@
 	if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
 		ext2_error (sb, "ext2_new_block",
 			    "Free blocks count corrupted for block group %d", i);
-		unlock_super (sb);
-		return 0;
+		goto out;
 	}
 
 search_back:
@@ -520,9 +513,8 @@
 	 * Check quota for allocation of this block.
 	 */
 	if(DQUOT_ALLOC_BLOCK(sb, inode, 1)) {
-		unlock_super(sb);
 		*err = -EDQUOT;
-		return 0;
+		goto out;
 	}
 
 	tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + le32_to_cpu(es->s_first_data_block);
@@ -548,33 +540,43 @@
 	 * Do block preallocation now if required.
 	 */
 #ifdef EXT2_PREALLOCATE
-	if (prealloc_block) {
+	/* Writer: ->i_prealloc* */
+	if (prealloc_count && !*prealloc_count) {
 		int	prealloc_goal;
+		unsigned long next_block = tmp + 1;
 
 		prealloc_goal = es->s_prealloc_blocks ?
 			es->s_prealloc_blocks : EXT2_DEFAULT_PREALLOC_BLOCKS;
 
-		*prealloc_count = 0;
-		*prealloc_block = tmp + 1;
+		*prealloc_block = next_block;
+		/* Writer: end */
 		for (k = 1;
 		     k < prealloc_goal && (j + k) < EXT2_BLOCKS_PER_GROUP(sb);
-		     k++) {
+		     k++, next_block++) {
 			if (DQUOT_PREALLOC_BLOCK(sb, inode, 1))
 				break;
-			if (ext2_set_bit (j + k, bh->b_data)) {
+			/* Writer: ->i_prealloc* */
+			if (*prealloc_block + *prealloc_count != next_block ||
+			    ext2_set_bit (j + k, bh->b_data)) {
+				/* Writer: end */
 				DQUOT_FREE_BLOCK(sb, inode, 1);
  				break;
 			}
 			(*prealloc_count)++;
+			/* Writer: end */
 		}	
+		/*
+		 * As soon as we go for per-group spinlocks we'll need these
+		 * done inside the loop above.
+		 */
 		gdp->bg_free_blocks_count =
 			cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) -
-			       *prealloc_count);
+			       (k - 1));
 		es->s_free_blocks_count =
 			cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) -
-			       *prealloc_count);
+			       (k - 1));
 		ext2_debug ("Preallocated a further %lu bits.\n",
-			    *prealloc_count);
+			       (k - 1));
 	}
 #endif
 
@@ -591,8 +593,7 @@
 			    "block(%d) >= blocks count(%d) - "
 			    "block_group = %d, es == %p ",j,
 			le32_to_cpu(es->s_blocks_count), i, es);
-		unlock_super (sb);
-		return 0;
+		goto out;
 	}
 
 	ext2_debug ("allocating block %d. "
@@ -609,6 +610,7 @@
 	
 io_error:
 	*err = -EIO;
+out:
 	unlock_super (sb);
 	return 0;
 	

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)