]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ext4/balloc.c
[PATCH] ext4: fix reservation extension
[karo-tx-linux.git] / fs / ext4 / balloc.c
index 3e85886a6382b734f1a9b20af4aadf96ef1ebd8b..6bd0bd5bbdc894f142c2a6b20df8e9460d750715 100644 (file)
  * balloc.c contains the blocks allocation and deallocation routines
  */
 
+/*
+ * Calculate the block group number and offset, given a block number
+ */
+void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
+               unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
+{
+        struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+       ext4_grpblk_t offset;
+
+        blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
+       offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
+       if (offsetp)
+               *offsetp = offset;
+       if (blockgrpp)
+               *blockgrpp = blocknr;
+
+}
+
 /*
  * The free blocks are managed by bitmaps.  A file system contains several
  * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
@@ -1306,10 +1324,14 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
                        if (!goal_in_my_reservation(&my_rsv->rsv_window,
                                                        grp_goal, group, sb))
                                grp_goal = -1;
-               } else if (grp_goal > 0 &&
-                         (my_rsv->rsv_end-grp_goal+1) < *count)
-                       try_to_extend_reservation(my_rsv, sb,
-                                       *count-my_rsv->rsv_end + grp_goal - 1);
+               } else if (grp_goal > 0) {
+                       int curr = my_rsv->rsv_end -
+                                       (grp_goal + group_first_block) + 1;
+
+                       if (curr < *count)
+                               try_to_extend_reservation(my_rsv, sb,
+                                                       *count - curr);
+               }
 
                if ((my_rsv->rsv_start > group_last_block) ||
                                (my_rsv->rsv_end < group_first_block)) {