Loading fs/btrfs/acl.c +6 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,9 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) char *value = NULL; struct posix_acl *acl; if (!IS_POSIXACL(inode)) return NULL; acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; Loading Loading @@ -84,6 +87,9 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, struct posix_acl *acl; int ret = 0; if (!IS_POSIXACL(dentry->d_inode)) return -EOPNOTSUPP; acl = btrfs_get_acl(dentry->d_inode, type); if (IS_ERR(acl)) Loading fs/btrfs/disk-io.c +2 −0 Original line number Diff line number Diff line Loading @@ -2565,6 +2565,8 @@ int close_ctree(struct btrfs_root *root) kfree(fs_info->chunk_root); kfree(fs_info->dev_root); kfree(fs_info->csum_root); kfree(fs_info); return 0; } Loading fs/btrfs/free-space-cache.c +99 −62 Original line number Diff line number Diff line Loading @@ -987,11 +987,18 @@ tree_search_offset(struct btrfs_block_group_cache *block_group, return entry; } static void unlink_free_space(struct btrfs_block_group_cache *block_group, static inline void __unlink_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info) { rb_erase(&info->offset_index, &block_group->free_space_offset); block_group->free_extents--; } static void unlink_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info) { __unlink_free_space(block_group, info); block_group->free_space -= info->bytes; } Loading @@ -1016,14 +1023,18 @@ static void recalculate_thresholds(struct btrfs_block_group_cache *block_group) u64 max_bytes; u64 bitmap_bytes; u64 extent_bytes; u64 size = block_group->key.offset; /* * The goal is to keep the total amount of memory used per 1gb of space * at or below 32k, so we need to adjust how much memory we allow to be * used by extent based free space tracking */ if (size < 1024 * 1024 * 1024) max_bytes = MAX_CACHE_BYTES_PER_GIG; else max_bytes = MAX_CACHE_BYTES_PER_GIG * (div64_u64(block_group->key.offset, 1024 * 1024 * 1024)); div64_u64(size, 1024 * 1024 * 1024); /* * we want to account for 1 more bitmap than what we have so we can make Loading Loading @@ -1171,6 +1182,16 @@ static void add_new_bitmap(struct btrfs_block_group_cache *block_group, recalculate_thresholds(block_group); } static void free_bitmap(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *bitmap_info) { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *bitmap_info, u64 *offset, u64 *bytes) Loading Loading @@ -1211,13 +1232,8 @@ static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_gro if (*bytes) { struct rb_node *next = rb_next(&bitmap_info->offset_index); if (!bitmap_info->bytes) { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } if (!bitmap_info->bytes) free_bitmap(block_group, bitmap_info); /* * no entry after this bitmap, but we still have bytes to Loading Loading @@ -1250,13 +1266,8 @@ static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_gro return -EAGAIN; goto again; } else if (!bitmap_info->bytes) { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } } else if (!bitmap_info->bytes) free_bitmap(block_group, bitmap_info); return 0; } Loading Loading @@ -1359,22 +1370,14 @@ static int insert_into_bitmap(struct btrfs_block_group_cache *block_group, return ret; } int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, u64 offset, u64 bytes) bool try_merge_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info, bool update_stat) { struct btrfs_free_space *right_info = NULL; struct btrfs_free_space *left_info = NULL; struct btrfs_free_space *info = NULL; int ret = 0; info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); if (!info) return -ENOMEM; info->offset = offset; info->bytes = bytes; spin_lock(&block_group->tree_lock); struct btrfs_free_space *left_info; struct btrfs_free_space *right_info; bool merged = false; u64 offset = info->offset; u64 bytes = info->bytes; /* * first we want to see if there is free space adjacent to the range we Loading @@ -1388,37 +1391,62 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, else left_info = tree_search_offset(block_group, offset - 1, 0, 0); /* * If there was no extent directly to the left or right of this new * extent then we know we're going to have to allocate a new extent, so * before we do that see if we need to drop this into a bitmap */ if ((!left_info || left_info->bitmap) && (!right_info || right_info->bitmap)) { ret = insert_into_bitmap(block_group, info); if (ret < 0) { goto out; } else if (ret) { ret = 0; goto out; } } if (right_info && !right_info->bitmap) { if (update_stat) unlink_free_space(block_group, right_info); else __unlink_free_space(block_group, right_info); info->bytes += right_info->bytes; kfree(right_info); merged = true; } if (left_info && !left_info->bitmap && left_info->offset + left_info->bytes == offset) { if (update_stat) unlink_free_space(block_group, left_info); else __unlink_free_space(block_group, left_info); info->offset = left_info->offset; info->bytes += left_info->bytes; kfree(left_info); merged = true; } return merged; } int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, u64 offset, u64 bytes) { struct btrfs_free_space *info; int ret = 0; info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); if (!info) return -ENOMEM; info->offset = offset; info->bytes = bytes; spin_lock(&block_group->tree_lock); if (try_merge_free_space(block_group, info, true)) goto link; /* * There was no extent directly to the left or right of this new * extent then we know we're going to have to allocate a new extent, so * before we do that see if we need to drop this into a bitmap */ ret = insert_into_bitmap(block_group, info); if (ret < 0) { goto out; } else if (ret) { ret = 0; goto out; } link: ret = link_free_space(block_group, info); if (ret) kfree(info); Loading Loading @@ -1621,6 +1649,7 @@ __btrfs_return_cluster_to_free_space( node = rb_next(&entry->offset_index); rb_erase(&entry->offset_index, &cluster->root); BUG_ON(entry->bitmap); try_merge_free_space(block_group, entry, false); tree_insert_offset(&block_group->free_space_offset, entry->offset, &entry->offset_index, 0); } Loading Loading @@ -1685,13 +1714,8 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, ret = offset; if (entry->bitmap) { bitmap_clear_bits(block_group, entry, offset, bytes); if (!entry->bytes) { unlink_free_space(block_group, entry); kfree(entry->bitmap); kfree(entry); block_group->total_bitmaps--; recalculate_thresholds(block_group); } if (!entry->bytes) free_bitmap(block_group, entry); } else { unlink_free_space(block_group, entry); entry->offset += bytes; Loading Loading @@ -1789,6 +1813,8 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, ret = search_start; bitmap_clear_bits(block_group, entry, ret, bytes); if (entry->bytes == 0) free_bitmap(block_group, entry); out: spin_unlock(&cluster->lock); spin_unlock(&block_group->tree_lock); Loading Loading @@ -1842,15 +1868,26 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, entry->offset += bytes; entry->bytes -= bytes; if (entry->bytes == 0) { if (entry->bytes == 0) rb_erase(&entry->offset_index, &cluster->root); kfree(entry); } break; } out: spin_unlock(&cluster->lock); if (!ret) return 0; spin_lock(&block_group->tree_lock); block_group->free_space -= bytes; if (entry->bytes == 0) { block_group->free_extents--; kfree(entry); } spin_unlock(&block_group->tree_lock); return ret; } Loading fs/btrfs/inode.c +1 −0 Original line number Diff line number Diff line Loading @@ -1557,6 +1557,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) out_page: unlock_page(page); page_cache_release(page); kfree(fixup); } /* Loading fs/btrfs/ioctl.c +4 −1 Original line number Diff line number Diff line Loading @@ -1898,7 +1898,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, memcpy(&new_key, &key, sizeof(new_key)); new_key.objectid = inode->i_ino; if (off <= key.offset) new_key.offset = key.offset + destoff - off; else new_key.offset = destoff; trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { Loading Loading
fs/btrfs/acl.c +6 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,9 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) char *value = NULL; struct posix_acl *acl; if (!IS_POSIXACL(inode)) return NULL; acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; Loading Loading @@ -84,6 +87,9 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, struct posix_acl *acl; int ret = 0; if (!IS_POSIXACL(dentry->d_inode)) return -EOPNOTSUPP; acl = btrfs_get_acl(dentry->d_inode, type); if (IS_ERR(acl)) Loading
fs/btrfs/disk-io.c +2 −0 Original line number Diff line number Diff line Loading @@ -2565,6 +2565,8 @@ int close_ctree(struct btrfs_root *root) kfree(fs_info->chunk_root); kfree(fs_info->dev_root); kfree(fs_info->csum_root); kfree(fs_info); return 0; } Loading
fs/btrfs/free-space-cache.c +99 −62 Original line number Diff line number Diff line Loading @@ -987,11 +987,18 @@ tree_search_offset(struct btrfs_block_group_cache *block_group, return entry; } static void unlink_free_space(struct btrfs_block_group_cache *block_group, static inline void __unlink_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info) { rb_erase(&info->offset_index, &block_group->free_space_offset); block_group->free_extents--; } static void unlink_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info) { __unlink_free_space(block_group, info); block_group->free_space -= info->bytes; } Loading @@ -1016,14 +1023,18 @@ static void recalculate_thresholds(struct btrfs_block_group_cache *block_group) u64 max_bytes; u64 bitmap_bytes; u64 extent_bytes; u64 size = block_group->key.offset; /* * The goal is to keep the total amount of memory used per 1gb of space * at or below 32k, so we need to adjust how much memory we allow to be * used by extent based free space tracking */ if (size < 1024 * 1024 * 1024) max_bytes = MAX_CACHE_BYTES_PER_GIG; else max_bytes = MAX_CACHE_BYTES_PER_GIG * (div64_u64(block_group->key.offset, 1024 * 1024 * 1024)); div64_u64(size, 1024 * 1024 * 1024); /* * we want to account for 1 more bitmap than what we have so we can make Loading Loading @@ -1171,6 +1182,16 @@ static void add_new_bitmap(struct btrfs_block_group_cache *block_group, recalculate_thresholds(block_group); } static void free_bitmap(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *bitmap_info) { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *bitmap_info, u64 *offset, u64 *bytes) Loading Loading @@ -1211,13 +1232,8 @@ static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_gro if (*bytes) { struct rb_node *next = rb_next(&bitmap_info->offset_index); if (!bitmap_info->bytes) { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } if (!bitmap_info->bytes) free_bitmap(block_group, bitmap_info); /* * no entry after this bitmap, but we still have bytes to Loading Loading @@ -1250,13 +1266,8 @@ static noinline int remove_from_bitmap(struct btrfs_block_group_cache *block_gro return -EAGAIN; goto again; } else if (!bitmap_info->bytes) { unlink_free_space(block_group, bitmap_info); kfree(bitmap_info->bitmap); kfree(bitmap_info); block_group->total_bitmaps--; recalculate_thresholds(block_group); } } else if (!bitmap_info->bytes) free_bitmap(block_group, bitmap_info); return 0; } Loading Loading @@ -1359,22 +1370,14 @@ static int insert_into_bitmap(struct btrfs_block_group_cache *block_group, return ret; } int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, u64 offset, u64 bytes) bool try_merge_free_space(struct btrfs_block_group_cache *block_group, struct btrfs_free_space *info, bool update_stat) { struct btrfs_free_space *right_info = NULL; struct btrfs_free_space *left_info = NULL; struct btrfs_free_space *info = NULL; int ret = 0; info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); if (!info) return -ENOMEM; info->offset = offset; info->bytes = bytes; spin_lock(&block_group->tree_lock); struct btrfs_free_space *left_info; struct btrfs_free_space *right_info; bool merged = false; u64 offset = info->offset; u64 bytes = info->bytes; /* * first we want to see if there is free space adjacent to the range we Loading @@ -1388,37 +1391,62 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, else left_info = tree_search_offset(block_group, offset - 1, 0, 0); /* * If there was no extent directly to the left or right of this new * extent then we know we're going to have to allocate a new extent, so * before we do that see if we need to drop this into a bitmap */ if ((!left_info || left_info->bitmap) && (!right_info || right_info->bitmap)) { ret = insert_into_bitmap(block_group, info); if (ret < 0) { goto out; } else if (ret) { ret = 0; goto out; } } if (right_info && !right_info->bitmap) { if (update_stat) unlink_free_space(block_group, right_info); else __unlink_free_space(block_group, right_info); info->bytes += right_info->bytes; kfree(right_info); merged = true; } if (left_info && !left_info->bitmap && left_info->offset + left_info->bytes == offset) { if (update_stat) unlink_free_space(block_group, left_info); else __unlink_free_space(block_group, left_info); info->offset = left_info->offset; info->bytes += left_info->bytes; kfree(left_info); merged = true; } return merged; } int btrfs_add_free_space(struct btrfs_block_group_cache *block_group, u64 offset, u64 bytes) { struct btrfs_free_space *info; int ret = 0; info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS); if (!info) return -ENOMEM; info->offset = offset; info->bytes = bytes; spin_lock(&block_group->tree_lock); if (try_merge_free_space(block_group, info, true)) goto link; /* * There was no extent directly to the left or right of this new * extent then we know we're going to have to allocate a new extent, so * before we do that see if we need to drop this into a bitmap */ ret = insert_into_bitmap(block_group, info); if (ret < 0) { goto out; } else if (ret) { ret = 0; goto out; } link: ret = link_free_space(block_group, info); if (ret) kfree(info); Loading Loading @@ -1621,6 +1649,7 @@ __btrfs_return_cluster_to_free_space( node = rb_next(&entry->offset_index); rb_erase(&entry->offset_index, &cluster->root); BUG_ON(entry->bitmap); try_merge_free_space(block_group, entry, false); tree_insert_offset(&block_group->free_space_offset, entry->offset, &entry->offset_index, 0); } Loading Loading @@ -1685,13 +1714,8 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group, ret = offset; if (entry->bitmap) { bitmap_clear_bits(block_group, entry, offset, bytes); if (!entry->bytes) { unlink_free_space(block_group, entry); kfree(entry->bitmap); kfree(entry); block_group->total_bitmaps--; recalculate_thresholds(block_group); } if (!entry->bytes) free_bitmap(block_group, entry); } else { unlink_free_space(block_group, entry); entry->offset += bytes; Loading Loading @@ -1789,6 +1813,8 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, ret = search_start; bitmap_clear_bits(block_group, entry, ret, bytes); if (entry->bytes == 0) free_bitmap(block_group, entry); out: spin_unlock(&cluster->lock); spin_unlock(&block_group->tree_lock); Loading Loading @@ -1842,15 +1868,26 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, entry->offset += bytes; entry->bytes -= bytes; if (entry->bytes == 0) { if (entry->bytes == 0) rb_erase(&entry->offset_index, &cluster->root); kfree(entry); } break; } out: spin_unlock(&cluster->lock); if (!ret) return 0; spin_lock(&block_group->tree_lock); block_group->free_space -= bytes; if (entry->bytes == 0) { block_group->free_extents--; kfree(entry); } spin_unlock(&block_group->tree_lock); return ret; } Loading
fs/btrfs/inode.c +1 −0 Original line number Diff line number Diff line Loading @@ -1557,6 +1557,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) out_page: unlock_page(page); page_cache_release(page); kfree(fixup); } /* Loading
fs/btrfs/ioctl.c +4 −1 Original line number Diff line number Diff line Loading @@ -1898,7 +1898,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, memcpy(&new_key, &key, sizeof(new_key)); new_key.objectid = inode->i_ino; if (off <= key.offset) new_key.offset = key.offset + destoff - off; else new_key.offset = destoff; trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { Loading