Hi,

a few minor comments, I haven't reviewed the changes in depth.

On Tue, Sep 29, 2015 at 08:50:35PM -0700, Omar Sandoval wrote:
> From: Omar Sandoval <osan...@fb.com>
> +static int btrfs_search_prev_slot(struct btrfs_trans_handle *trans,
> +                               struct btrfs_root *root,
> +                               struct btrfs_key *key, struct btrfs_path *p,

Please don't use single letter variables, eg. 'path' is commonly used
elsewere.

> +                               int ins_len, int cow)
> +{
> +     int ret;
> +
> +     ret = btrfs_search_slot(trans, root, key, p, ins_len, cow);
> +     if (ret < 0)
> +             return ret;
> +
> +     if (ret == 0) {
> +             ASSERT(0);
> +             return -EIO;
> +     }
> +
> +     if (p->slots[0] == 0) {
> +             ASSERT(0);
> +             return -EIO;
> +     }
> +     p->slots[0]--;
> +
> +     return 0;
> +}
> +
> +static unsigned long *alloc_bitmap(u32 bitmap_size)
> +{
> +     return __vmalloc(bitmap_size, GFP_NOFS | __GFP_HIGHMEM | __GFP_ZERO,

Why is GFP_HIGHMEM here?

> +                      PAGE_KERNEL);
> +}
> +
> +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_root *root = fs_info->free_space_root;
> +     struct btrfs_free_space_info *info;
> +     struct btrfs_key key, found_key;
> +     struct extent_buffer *leaf;
> +     unsigned long *bitmap;
> +     char *bitmap_cursor;
> +     u64 start, end;
> +     u64 bitmap_range, i;
> +     u32 bitmap_size, flags, expected_extent_count;
> +     u32 extent_count = 0;
> +     int done = 0, nr;
> +     int ret;
> +
> +     bitmap_size = free_space_bitmap_size(block_group->key.offset,
> +                                          block_group->sectorsize);
> +     bitmap = alloc_bitmap(bitmap_size);
> +     if (!bitmap) {
> +             ret = -ENOMEM;
> +             goto out;
> +     }

Can we get rid of this potential allocation failure site? You free the
buffer in the same function, no recursion, so it should be ok to
preallocate the buffer at the mount time and just reuse here. Converting
to bitmap is not a frequent operation but IMO is critical enough to make
it more robust.

> +
> +     start = block_group->key.objectid;
> +     end = block_group->key.objectid + block_group->key.offset;
> +
> +     key.objectid = end - 1;
> +     key.type = (u8)-1;
> +     key.offset = (u64)-1;
> +
> +     while (!done) {
> +             ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
> +             if (ret)
> +                     goto out;
> +
> +             leaf = path->nodes[0];
> +             nr = 0;
> +             path->slots[0]++;
> +             while (path->slots[0] > 0) {
> +                     btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] 
> - 1);
> +
> +                     if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
> +                             ASSERT(found_key.objectid == 
> block_group->key.objectid);
> +                             ASSERT(found_key.offset == 
> block_group->key.offset);
> +                             done = 1;
> +                             break;
> +                     } else if (found_key.type == 
> BTRFS_FREE_SPACE_EXTENT_KEY) {
> +                             u64 first, last;
> +
> +                             ASSERT(found_key.objectid >= start);
> +                             ASSERT(found_key.objectid < end);
> +                             ASSERT(found_key.objectid + found_key.offset <= 
> end);
> +
> +                             first = div_u64(found_key.objectid - start,
> +                                             block_group->sectorsize);
> +                             last = div_u64(found_key.objectid + 
> found_key.offset - start,
> +                                            block_group->sectorsize);
> +                             bitmap_set(bitmap, first, last - first);
> +
> +                             extent_count++;
> +                             nr++;
> +                             path->slots[0]--;
> +                     } else {
> +                             ASSERT(0);
> +                     }
> +             }
> +
> +             ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
> +             if (ret)
> +                     goto out;
> +             btrfs_release_path(path);
> +     }
> +
> +     info = search_free_space_info(trans, fs_info, block_group, path, 1);
> +     if (IS_ERR(info)) {
> +             ret = PTR_ERR(info);
> +             goto out;
> +     }
> +     leaf = path->nodes[0];
> +     flags = btrfs_free_space_flags(leaf, info);
> +     flags |= BTRFS_FREE_SPACE_USING_BITMAPS;
> +     btrfs_set_free_space_flags(leaf, info, flags);
> +     expected_extent_count = btrfs_free_space_extent_count(leaf, info);
> +     btrfs_mark_buffer_dirty(leaf);
> +     btrfs_release_path(path);
> +
> +     if (extent_count != expected_extent_count) {
> +             btrfs_err(fs_info, "incorrect extent count for %llu; counted 
> %u, expected %u",
> +                       block_group->key.objectid, extent_count,
> +                       expected_extent_count);
> +             ASSERT(0);
> +             ret = -EIO;
> +             goto out;
> +     }
> +
> +     bitmap_cursor = (char *)bitmap;
> +     bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
> +     i = start;
> +     while (i < end) {
> +             unsigned long ptr;
> +             u64 extent_size;
> +             u32 data_size;
> +
> +             extent_size = min(end - i, bitmap_range);
> +             data_size = free_space_bitmap_size(extent_size,
> +                                                block_group->sectorsize);
> +
> +             key.objectid = i;
> +             key.type = BTRFS_FREE_SPACE_BITMAP_KEY;
> +             key.offset = extent_size;
> +
> +             ret = btrfs_insert_empty_item(trans, root, path, &key,
> +                                           data_size);
> +             if (ret)
> +                     goto out;
> +
> +             leaf = path->nodes[0];
> +             ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
> +             write_extent_buffer(leaf, bitmap_cursor, ptr,
> +                                 data_size);
> +             btrfs_mark_buffer_dirty(leaf);
> +             btrfs_release_path(path);
> +
> +             i += extent_size;
> +             bitmap_cursor += data_size;
> +     }
> +
> +     ret = 0;
> +out:
> +     vfree(bitmap);
> +     if (ret)
> +             btrfs_abort_transaction(trans, root, ret);

A general comment to the transaction aborts: the call should happen at
the location of the error and not in the common exit block. Otherwise we
lose the information what caused the failure.

This applies to the remaining functions as well, I won't point it out
specifically.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to