Loading fs/btrfs/ctree.h +4 −6 Original line number Diff line number Diff line Loading @@ -1415,17 +1415,15 @@ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ static inline u##bits btrfs_##name(struct extent_buffer *eb) \ { \ type *p = kmap_atomic(eb->first_page, KM_USER0); \ type *p = page_address(eb->first_page); \ u##bits res = le##bits##_to_cpu(p->member); \ kunmap_atomic(p, KM_USER0); \ return res; \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ u##bits val) \ { \ type *p = kmap_atomic(eb->first_page, KM_USER0); \ type *p = page_address(eb->first_page); \ p->member = cpu_to_le##bits(val); \ kunmap_atomic(p, KM_USER0); \ } #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ Loading Loading @@ -2367,7 +2365,7 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); int btrfs_drop_snapshot(struct btrfs_root *root, void btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, int update_ref); int btrfs_drop_subtree(struct btrfs_trans_handle *trans, struct btrfs_root *root, Loading fs/btrfs/extent-tree.c +59 −16 Original line number Diff line number Diff line Loading @@ -1782,6 +1782,9 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, for (i = 0; i < multi->num_stripes; i++, stripe++) { if (!stripe->dev->can_discard) continue; ret = btrfs_issue_discard(stripe->dev->bdev, stripe->physical, stripe->length); Loading @@ -1789,11 +1792,16 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, discarded_bytes += stripe->length; else if (ret != -EOPNOTSUPP) break; /* * Just in case we get back EOPNOTSUPP for some reason, * just ignore the return value so we don't screw up * people calling discard_extent. */ ret = 0; } kfree(multi); } if (discarded_bytes && ret == -EOPNOTSUPP) ret = 0; if (actual_bytes) *actual_bytes = discarded_bytes; Loading Loading @@ -6269,7 +6277,7 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, * also make sure backrefs for the shared block and all lower level * blocks are properly updated. */ int btrfs_drop_snapshot(struct btrfs_root *root, void btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, int update_ref) { struct btrfs_path *path; Loading @@ -6283,13 +6291,16 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int level; path = btrfs_alloc_path(); if (!path) return -ENOMEM; if (!path) { err = -ENOMEM; goto out; } wc = kzalloc(sizeof(*wc), GFP_NOFS); if (!wc) { btrfs_free_path(path); return -ENOMEM; err = -ENOMEM; goto out; } trans = btrfs_start_transaction(tree_root, 0); Loading Loading @@ -6318,7 +6329,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, path->lowest_level = 0; if (ret < 0) { err = ret; goto out; goto out_free; } WARN_ON(ret > 0); Loading Loading @@ -6425,11 +6436,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root, free_extent_buffer(root->commit_root); kfree(root); } out: out_free: btrfs_end_transaction_throttle(trans, tree_root); kfree(wc); btrfs_free_path(path); return err; out: if (err) btrfs_std_error(root->fs_info, err); return; } /* Loading Loading @@ -6720,6 +6734,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) struct btrfs_space_info *space_info; struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; struct btrfs_device *device; u64 min_free; int index; int dev_nr = 0; int dev_min = 1; int full = 0; int ret = 0; Loading @@ -6729,8 +6747,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if (!block_group) return -1; min_free = btrfs_block_group_used(&block_group->item); /* no bytes used, we're good */ if (!btrfs_block_group_used(&block_group->item)) if (!min_free) goto out; space_info = block_group->space_info; Loading @@ -6748,8 +6768,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if ((space_info->total_bytes != block_group->key.offset) && (space_info->bytes_used + space_info->bytes_reserved + space_info->bytes_pinned + space_info->bytes_readonly + btrfs_block_group_used(&block_group->item) < space_info->total_bytes)) { min_free < space_info->total_bytes)) { spin_unlock(&space_info->lock); goto out; } Loading @@ -6766,9 +6785,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if (full) goto out; /* * index: * 0: raid10 * 1: raid1 * 2: dup * 3: raid0 * 4: single */ index = get_block_group_index(block_group); if (index == 0) { dev_min = 4; min_free /= 2; } else if (index == 1) { dev_min = 2; } else if (index == 2) { min_free *= 2; } else if (index == 3) { dev_min = fs_devices->rw_devices; min_free /= dev_min; } mutex_lock(&root->fs_info->chunk_mutex); list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { u64 min_free = btrfs_block_group_used(&block_group->item); u64 dev_offset; /* Loading @@ -6779,7 +6818,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) ret = find_free_dev_extent(NULL, device, min_free, &dev_offset, NULL); if (!ret) dev_nr++; if (dev_nr >= dev_min) break; ret = -1; } } Loading fs/btrfs/file.c +16 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,8 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, spin_lock(&root->fs_info->defrag_inodes_lock); if (!BTRFS_I(inode)->in_defrag) __btrfs_add_inode_defrag(inode, defrag); else kfree(defrag); spin_unlock(&root->fs_info->defrag_inodes_lock); return 0; } Loading Loading @@ -1638,11 +1640,15 @@ static long btrfs_fallocate(struct file *file, int mode, cur_offset = alloc_start; while (1) { u64 actual_end; em = btrfs_get_extent(inode, NULL, 0, cur_offset, alloc_end - cur_offset, 0); BUG_ON(IS_ERR_OR_NULL(em)); last_byte = min(extent_map_end(em), alloc_end); actual_end = min_t(u64, extent_map_end(em), offset + len); last_byte = (last_byte + mask) & ~mask; if (em->block_start == EXTENT_MAP_HOLE || (cur_offset >= inode->i_size && !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { Loading @@ -1655,6 +1661,16 @@ static long btrfs_fallocate(struct file *file, int mode, free_extent_map(em); break; } } else if (actual_end > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE)) { /* * We didn't need to allocate any more space, but we * still extended the size of the file so we need to * update i_size. */ inode->i_ctime = CURRENT_TIME; i_size_write(inode, actual_end); btrfs_ordered_update_i_size(inode, actual_end, NULL); } free_extent_map(em); Loading fs/btrfs/free-space-cache.c +11 −5 Original line number Diff line number Diff line Loading @@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); } static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info, u64 offset, u64 bytes) static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info, u64 offset, u64 bytes) { unsigned long start, count; Loading @@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, bitmap_clear(info->bitmap, start, count); info->bytes -= bytes; } static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info, u64 offset, u64 bytes) { __bitmap_clear_bits(ctl, info, offset, bytes); ctl->free_space -= bytes; } Loading Loading @@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, return 0; ret = search_start; bitmap_clear_bits(ctl, entry, ret, bytes); __bitmap_clear_bits(ctl, entry, ret, bytes); return ret; } Loading Loading @@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, continue; } } else { ret = entry->offset; entry->offset += bytes; Loading fs/btrfs/ioctl.c +4 −0 Original line number Diff line number Diff line Loading @@ -2236,6 +2236,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, btrfs_wait_ordered_range(src, off, len); } /* truncate page cache pages from target inode range */ truncate_inode_pages_range(&inode->i_data, off, ALIGN(off + len, PAGE_CACHE_SIZE) - 1); /* clone data */ key.objectid = btrfs_ino(src); key.type = BTRFS_EXTENT_DATA_KEY; Loading Loading
fs/btrfs/ctree.h +4 −6 Original line number Diff line number Diff line Loading @@ -1415,17 +1415,15 @@ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ static inline u##bits btrfs_##name(struct extent_buffer *eb) \ { \ type *p = kmap_atomic(eb->first_page, KM_USER0); \ type *p = page_address(eb->first_page); \ u##bits res = le##bits##_to_cpu(p->member); \ kunmap_atomic(p, KM_USER0); \ return res; \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ u##bits val) \ { \ type *p = kmap_atomic(eb->first_page, KM_USER0); \ type *p = page_address(eb->first_page); \ p->member = cpu_to_le##bits(val); \ kunmap_atomic(p, KM_USER0); \ } #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ Loading Loading @@ -2367,7 +2365,7 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); int btrfs_drop_snapshot(struct btrfs_root *root, void btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, int update_ref); int btrfs_drop_subtree(struct btrfs_trans_handle *trans, struct btrfs_root *root, Loading
fs/btrfs/extent-tree.c +59 −16 Original line number Diff line number Diff line Loading @@ -1782,6 +1782,9 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, for (i = 0; i < multi->num_stripes; i++, stripe++) { if (!stripe->dev->can_discard) continue; ret = btrfs_issue_discard(stripe->dev->bdev, stripe->physical, stripe->length); Loading @@ -1789,11 +1792,16 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, discarded_bytes += stripe->length; else if (ret != -EOPNOTSUPP) break; /* * Just in case we get back EOPNOTSUPP for some reason, * just ignore the return value so we don't screw up * people calling discard_extent. */ ret = 0; } kfree(multi); } if (discarded_bytes && ret == -EOPNOTSUPP) ret = 0; if (actual_bytes) *actual_bytes = discarded_bytes; Loading Loading @@ -6269,7 +6277,7 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, * also make sure backrefs for the shared block and all lower level * blocks are properly updated. */ int btrfs_drop_snapshot(struct btrfs_root *root, void btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, int update_ref) { struct btrfs_path *path; Loading @@ -6283,13 +6291,16 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int level; path = btrfs_alloc_path(); if (!path) return -ENOMEM; if (!path) { err = -ENOMEM; goto out; } wc = kzalloc(sizeof(*wc), GFP_NOFS); if (!wc) { btrfs_free_path(path); return -ENOMEM; err = -ENOMEM; goto out; } trans = btrfs_start_transaction(tree_root, 0); Loading Loading @@ -6318,7 +6329,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, path->lowest_level = 0; if (ret < 0) { err = ret; goto out; goto out_free; } WARN_ON(ret > 0); Loading Loading @@ -6425,11 +6436,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root, free_extent_buffer(root->commit_root); kfree(root); } out: out_free: btrfs_end_transaction_throttle(trans, tree_root); kfree(wc); btrfs_free_path(path); return err; out: if (err) btrfs_std_error(root->fs_info, err); return; } /* Loading Loading @@ -6720,6 +6734,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) struct btrfs_space_info *space_info; struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; struct btrfs_device *device; u64 min_free; int index; int dev_nr = 0; int dev_min = 1; int full = 0; int ret = 0; Loading @@ -6729,8 +6747,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if (!block_group) return -1; min_free = btrfs_block_group_used(&block_group->item); /* no bytes used, we're good */ if (!btrfs_block_group_used(&block_group->item)) if (!min_free) goto out; space_info = block_group->space_info; Loading @@ -6748,8 +6768,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if ((space_info->total_bytes != block_group->key.offset) && (space_info->bytes_used + space_info->bytes_reserved + space_info->bytes_pinned + space_info->bytes_readonly + btrfs_block_group_used(&block_group->item) < space_info->total_bytes)) { min_free < space_info->total_bytes)) { spin_unlock(&space_info->lock); goto out; } Loading @@ -6766,9 +6785,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) if (full) goto out; /* * index: * 0: raid10 * 1: raid1 * 2: dup * 3: raid0 * 4: single */ index = get_block_group_index(block_group); if (index == 0) { dev_min = 4; min_free /= 2; } else if (index == 1) { dev_min = 2; } else if (index == 2) { min_free *= 2; } else if (index == 3) { dev_min = fs_devices->rw_devices; min_free /= dev_min; } mutex_lock(&root->fs_info->chunk_mutex); list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { u64 min_free = btrfs_block_group_used(&block_group->item); u64 dev_offset; /* Loading @@ -6779,7 +6818,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) ret = find_free_dev_extent(NULL, device, min_free, &dev_offset, NULL); if (!ret) dev_nr++; if (dev_nr >= dev_min) break; ret = -1; } } Loading
fs/btrfs/file.c +16 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,8 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, spin_lock(&root->fs_info->defrag_inodes_lock); if (!BTRFS_I(inode)->in_defrag) __btrfs_add_inode_defrag(inode, defrag); else kfree(defrag); spin_unlock(&root->fs_info->defrag_inodes_lock); return 0; } Loading Loading @@ -1638,11 +1640,15 @@ static long btrfs_fallocate(struct file *file, int mode, cur_offset = alloc_start; while (1) { u64 actual_end; em = btrfs_get_extent(inode, NULL, 0, cur_offset, alloc_end - cur_offset, 0); BUG_ON(IS_ERR_OR_NULL(em)); last_byte = min(extent_map_end(em), alloc_end); actual_end = min_t(u64, extent_map_end(em), offset + len); last_byte = (last_byte + mask) & ~mask; if (em->block_start == EXTENT_MAP_HOLE || (cur_offset >= inode->i_size && !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { Loading @@ -1655,6 +1661,16 @@ static long btrfs_fallocate(struct file *file, int mode, free_extent_map(em); break; } } else if (actual_end > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE)) { /* * We didn't need to allocate any more space, but we * still extended the size of the file so we need to * update i_size. */ inode->i_ctime = CURRENT_TIME; i_size_write(inode, actual_end); btrfs_ordered_update_i_size(inode, actual_end, NULL); } free_extent_map(em); Loading
fs/btrfs/free-space-cache.c +11 −5 Original line number Diff line number Diff line Loading @@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); } static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info, u64 offset, u64 bytes) static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info, u64 offset, u64 bytes) { unsigned long start, count; Loading @@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, bitmap_clear(info->bitmap, start, count); info->bytes -= bytes; } static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, struct btrfs_free_space *info, u64 offset, u64 bytes) { __bitmap_clear_bits(ctl, info, offset, bytes); ctl->free_space -= bytes; } Loading Loading @@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, return 0; ret = search_start; bitmap_clear_bits(ctl, entry, ret, bytes); __bitmap_clear_bits(ctl, entry, ret, bytes); return ret; } Loading Loading @@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, continue; } } else { ret = entry->offset; entry->offset += bytes; Loading
fs/btrfs/ioctl.c +4 −0 Original line number Diff line number Diff line Loading @@ -2236,6 +2236,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, btrfs_wait_ordered_range(src, off, len); } /* truncate page cache pages from target inode range */ truncate_inode_pages_range(&inode->i_data, off, ALIGN(off + len, PAGE_CACHE_SIZE) - 1); /* clone data */ key.objectid = btrfs_ino(src); key.type = BTRFS_EXTENT_DATA_KEY; Loading