btrfs: Remove fs_info argument from update_free_space_extent_count
[sfrench/cifs-2.6.git] / fs / btrfs / free-space-tree.c
index 32a0f6cb55948aac654bc30e986adbeeaf5b451b..4f36016b2476ec9ecffc07d4acaf3b31077c63a0 100644 (file)
@@ -12,7 +12,6 @@
 #include "transaction.h"
 
 static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
-                                       struct btrfs_fs_info *fs_info,
                                        struct btrfs_block_group_cache *block_group,
                                        struct btrfs_path *path);
 
@@ -45,11 +44,10 @@ void set_free_space_tree_thresholds(struct btrfs_block_group_cache *cache)
 }
 
 static int add_new_free_space_info(struct btrfs_trans_handle *trans,
-                                  struct btrfs_fs_info *fs_info,
                                   struct btrfs_block_group_cache *block_group,
                                   struct btrfs_path *path)
 {
-       struct btrfs_root *root = fs_info->free_space_root;
+       struct btrfs_root *root = trans->fs_info->free_space_root;
        struct btrfs_free_space_info *info;
        struct btrfs_key key;
        struct extent_buffer *leaf;
@@ -138,10 +136,11 @@ static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize)
        return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE);
 }
 
-static u8 *alloc_bitmap(u32 bitmap_size)
+static unsigned long *alloc_bitmap(u32 bitmap_size)
 {
-       u8 *ret;
+       unsigned long *ret;
        unsigned int nofs_flag;
+       u32 bitmap_rounded_size = round_up(bitmap_size, sizeof(unsigned long));
 
        /*
         * GFP_NOFS doesn't work with kvmalloc(), but we really can't recurse
@@ -152,21 +151,42 @@ static u8 *alloc_bitmap(u32 bitmap_size)
         * know that recursion is unsafe.
         */
        nofs_flag = memalloc_nofs_save();
-       ret = kvzalloc(bitmap_size, GFP_KERNEL);
+       ret = kvzalloc(bitmap_rounded_size, GFP_KERNEL);
        memalloc_nofs_restore(nofs_flag);
        return ret;
 }
 
+static void le_bitmap_set(unsigned long *map, unsigned int start, int len)
+{
+       u8 *p = ((u8 *)map) + BIT_BYTE(start);
+       const unsigned int size = start + len;
+       int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
+       u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
+
+       while (len - bits_to_set >= 0) {
+               *p |= mask_to_set;
+               len -= bits_to_set;
+               bits_to_set = BITS_PER_BYTE;
+               mask_to_set = ~0;
+               p++;
+       }
+       if (len) {
+               mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
+               *p |= mask_to_set;
+       }
+}
+
 int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
-                                 struct btrfs_fs_info *fs_info,
                                  struct btrfs_block_group_cache *block_group,
                                  struct btrfs_path *path)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_root *root = fs_info->free_space_root;
        struct btrfs_free_space_info *info;
        struct btrfs_key key, found_key;
        struct extent_buffer *leaf;
-       u8 *bitmap, *bitmap_cursor;
+       unsigned long *bitmap;
+       char *bitmap_cursor;
        u64 start, end;
        u64 bitmap_range, i;
        u32 bitmap_size, flags, expected_extent_count;
@@ -255,7 +275,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       bitmap_cursor = bitmap;
+       bitmap_cursor = (char *)bitmap;
        bitmap_range = fs_info->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
        i = start;
        while (i < end) {
@@ -296,21 +316,18 @@ out:
 }
 
 int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
-                                 struct btrfs_fs_info *fs_info,
                                  struct btrfs_block_group_cache *block_group,
                                  struct btrfs_path *path)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_root *root = fs_info->free_space_root;
        struct btrfs_free_space_info *info;
        struct btrfs_key key, found_key;
        struct extent_buffer *leaf;
-       u8 *bitmap;
+       unsigned long *bitmap;
        u64 start, end;
-       /* Initialize to silence GCC. */
-       u64 extent_start = 0;
-       u64 offset;
        u32 bitmap_size, flags, expected_extent_count;
-       int prev_bit = 0, bit, bitnr;
+       unsigned long nrbits, start_bit, end_bit;
        u32 extent_count = 0;
        int done = 0, nr;
        int ret;
@@ -348,7 +365,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
                                break;
                        } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
                                unsigned long ptr;
-                               u8 *bitmap_cursor;
+                               char *bitmap_cursor;
                                u32 bitmap_pos, data_size;
 
                                ASSERT(found_key.objectid >= start);
@@ -358,7 +375,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
                                bitmap_pos = div_u64(found_key.objectid - start,
                                                     fs_info->sectorsize *
                                                     BITS_PER_BYTE);
-                               bitmap_cursor = bitmap + bitmap_pos;
+                               bitmap_cursor = ((char *)bitmap) + bitmap_pos;
                                data_size = free_space_bitmap_size(found_key.offset,
                                                                   fs_info->sectorsize);
 
@@ -392,32 +409,16 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
        btrfs_mark_buffer_dirty(leaf);
        btrfs_release_path(path);
 
-       offset = start;
-       bitnr = 0;
-       while (offset < end) {
-               bit = !!le_test_bit(bitnr, bitmap);
-               if (prev_bit == 0 && bit == 1) {
-                       extent_start = offset;
-               } else if (prev_bit == 1 && bit == 0) {
-                       key.objectid = extent_start;
-                       key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
-                       key.offset = offset - extent_start;
-
-                       ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
-                       if (ret)
-                               goto out;
-                       btrfs_release_path(path);
+       nrbits = div_u64(block_group->key.offset, block_group->fs_info->sectorsize);
+       start_bit = find_next_bit_le(bitmap, nrbits, 0);
 
-                       extent_count++;
-               }
-               prev_bit = bit;
-               offset += fs_info->sectorsize;
-               bitnr++;
-       }
-       if (prev_bit == 1) {
-               key.objectid = extent_start;
+       while (start_bit < nrbits) {
+               end_bit = find_next_zero_bit_le(bitmap, nrbits, start_bit);
+               ASSERT(start_bit < end_bit);
+
+               key.objectid = start + start_bit * block_group->fs_info->sectorsize;
                key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
-               key.offset = end - extent_start;
+               key.offset = (end_bit - start_bit) * block_group->fs_info->sectorsize;
 
                ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
                if (ret)
@@ -425,6 +426,8 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
                btrfs_release_path(path);
 
                extent_count++;
+
+               start_bit = find_next_bit_le(bitmap, nrbits, end_bit);
        }
 
        if (extent_count != expected_extent_count) {
@@ -446,7 +449,6 @@ out:
 }
 
 static int update_free_space_extent_count(struct btrfs_trans_handle *trans,
-                                         struct btrfs_fs_info *fs_info,
                                          struct btrfs_block_group_cache *block_group,
                                          struct btrfs_path *path,
                                          int new_extents)
@@ -459,7 +461,8 @@ static int update_free_space_extent_count(struct btrfs_trans_handle *trans,
        if (new_extents == 0)
                return 0;
 
-       info = search_free_space_info(trans, fs_info, block_group, path, 1);
+       info = search_free_space_info(trans, trans->fs_info, block_group, path,
+                                     1);
        if (IS_ERR(info)) {
                ret = PTR_ERR(info);
                goto out;
@@ -474,12 +477,10 @@ static int update_free_space_extent_count(struct btrfs_trans_handle *trans,
 
        if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
            extent_count > block_group->bitmap_high_thresh) {
-               ret = convert_free_space_to_bitmaps(trans, fs_info, block_group,
-                                                   path);
+               ret = convert_free_space_to_bitmaps(trans, block_group, path);
        } else if ((flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
                   extent_count < block_group->bitmap_low_thresh) {
-               ret = convert_free_space_to_extents(trans, fs_info, block_group,
-                                                   path);
+               ret = convert_free_space_to_extents(trans, block_group, path);
        }
 
 out:
@@ -682,7 +683,7 @@ static int modify_free_space_bitmap(struct btrfs_trans_handle *trans,
        }
 
        btrfs_release_path(path);
-       ret = update_free_space_extent_count(trans, fs_info, block_group, path,
+       ret = update_free_space_extent_count(trans, block_group, path,
                                             new_extents);
 
 out:
@@ -769,7 +770,7 @@ static int remove_free_space_extent(struct btrfs_trans_handle *trans,
        }
 
        btrfs_release_path(path);
-       ret = update_free_space_extent_count(trans, fs_info, block_group, path,
+       ret = update_free_space_extent_count(trans, block_group, path,
                                             new_extents);
 
 out:
@@ -786,8 +787,7 @@ int __remove_from_free_space_tree(struct btrfs_trans_handle *trans,
        int ret;
 
        if (block_group->needs_free_space) {
-               ret = __add_block_group_free_space(trans, fs_info, block_group,
-                                                  path);
+               ret = __add_block_group_free_space(trans, block_group, path);
                if (ret)
                        return ret;
        }
@@ -965,7 +965,7 @@ insert:
                goto out;
 
        btrfs_release_path(path);
-       ret = update_free_space_extent_count(trans, fs_info, block_group, path,
+       ret = update_free_space_extent_count(trans, block_group, path,
                                             new_extents);
 
 out:
@@ -973,17 +973,16 @@ out:
 }
 
 int __add_to_free_space_tree(struct btrfs_trans_handle *trans,
-                            struct btrfs_fs_info *fs_info,
                             struct btrfs_block_group_cache *block_group,
                             struct btrfs_path *path, u64 start, u64 size)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_free_space_info *info;
        u32 flags;
        int ret;
 
        if (block_group->needs_free_space) {
-               ret = __add_block_group_free_space(trans, fs_info, block_group,
-                                                  path);
+               ret = __add_block_group_free_space(trans, block_group, path);
                if (ret)
                        return ret;
        }
@@ -1028,8 +1027,7 @@ int add_to_free_space_tree(struct btrfs_trans_handle *trans,
        }
 
        mutex_lock(&block_group->free_space_lock);
-       ret = __add_to_free_space_tree(trans, fs_info, block_group, path, start,
-                                      size);
+       ret = __add_to_free_space_tree(trans, block_group, path, start, size);
        mutex_unlock(&block_group->free_space_lock);
 
        btrfs_put_block_group(block_group);
@@ -1066,7 +1064,7 @@ static int populate_free_space_tree(struct btrfs_trans_handle *trans,
                return -ENOMEM;
        }
 
-       ret = add_new_free_space_info(trans, fs_info, block_group, path2);
+       ret = add_new_free_space_info(trans, block_group, path2);
        if (ret)
                goto out;
 
@@ -1099,7 +1097,7 @@ static int populate_free_space_tree(struct btrfs_trans_handle *trans,
                                break;
 
                        if (start < key.objectid) {
-                               ret = __add_to_free_space_tree(trans, fs_info,
+                               ret = __add_to_free_space_tree(trans,
                                                               block_group,
                                                               path2, start,
                                                               key.objectid -
@@ -1124,8 +1122,8 @@ static int populate_free_space_tree(struct btrfs_trans_handle *trans,
                        break;
        }
        if (start < end) {
-               ret = __add_to_free_space_tree(trans, fs_info, block_group,
-                                              path2, start, end - start);
+               ret = __add_to_free_space_tree(trans, block_group, path2,
+                                              start, end - start);
                if (ret)
                        goto out_locked;
        }
@@ -1269,7 +1267,6 @@ abort:
 }
 
 static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
-                                       struct btrfs_fs_info *fs_info,
                                        struct btrfs_block_group_cache *block_group,
                                        struct btrfs_path *path)
 {
@@ -1277,19 +1274,19 @@ static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
 
        block_group->needs_free_space = 0;
 
-       ret = add_new_free_space_info(trans, fs_info, block_group, path);
+       ret = add_new_free_space_info(trans, block_group, path);
        if (ret)
                return ret;
 
-       return __add_to_free_space_tree(trans, fs_info, block_group, path,
+       return __add_to_free_space_tree(trans, block_group, path,
                                        block_group->key.objectid,
                                        block_group->key.offset);
 }
 
 int add_block_group_free_space(struct btrfs_trans_handle *trans,
-                              struct btrfs_fs_info *fs_info,
                               struct btrfs_block_group_cache *block_group)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_path *path = NULL;
        int ret = 0;
 
@@ -1306,7 +1303,7 @@ int add_block_group_free_space(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       ret = __add_block_group_free_space(trans, fs_info, block_group, path);
+       ret = __add_block_group_free_space(trans, block_group, path);
 
 out:
        btrfs_free_path(path);
@@ -1317,10 +1314,9 @@ out:
 }
 
 int remove_block_group_free_space(struct btrfs_trans_handle *trans,
-                                 struct btrfs_fs_info *fs_info,
                                  struct btrfs_block_group_cache *block_group)
 {
-       struct btrfs_root *root = fs_info->free_space_root;
+       struct btrfs_root *root = trans->fs_info->free_space_root;
        struct btrfs_path *path;
        struct btrfs_key key, found_key;
        struct extent_buffer *leaf;
@@ -1328,7 +1324,7 @@ int remove_block_group_free_space(struct btrfs_trans_handle *trans,
        int done = 0, nr;
        int ret;
 
-       if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
+       if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
                return 0;
 
        if (block_group->needs_free_space) {
@@ -1439,7 +1435,6 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
                                extent_start = offset;
                        } else if (prev_bit == 1 && bit == 0) {
                                total_found += add_new_free_space(block_group,
-                                                                 fs_info,
                                                                  extent_start,
                                                                  offset);
                                if (total_found > CACHING_CTL_WAKE_UP) {
@@ -1453,8 +1448,8 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
                }
        }
        if (prev_bit == 1) {
-               total_found += add_new_free_space(block_group, fs_info,
-                                                 extent_start, end);
+               total_found += add_new_free_space(block_group, extent_start,
+                                                 end);
                extent_count++;
        }
 
@@ -1511,8 +1506,7 @@ static int load_free_space_extents(struct btrfs_caching_control *caching_ctl,
 
                caching_ctl->progress = key.objectid;
 
-               total_found += add_new_free_space(block_group, fs_info,
-                                                 key.objectid,
+               total_found += add_new_free_space(block_group, key.objectid,
                                                  key.objectid + key.offset);
                if (total_found > CACHING_CTL_WAKE_UP) {
                        total_found = 0;