Loading fs/btrfs/acl.c +13 −10 Original line number Original line Diff line number Diff line Loading @@ -94,7 +94,8 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, /* /* * Needs to be called with fs_mutex held * Needs to be called with fs_mutex held */ */ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) static int btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct posix_acl *acl, int type) { { int ret, size = 0; int ret, size = 0; const char *name; const char *name; Loading Loading @@ -140,8 +141,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) goto out; goto out; } } ret = __btrfs_setxattr(inode, name, value, size, 0); ret = __btrfs_setxattr(trans, inode, name, value, size, 0); out: out: kfree(value); kfree(value); Loading @@ -154,7 +154,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) const void *value, size_t size, int flags, int type) { { int ret = 0; int ret; struct posix_acl *acl = NULL; struct posix_acl *acl = NULL; if (value) { if (value) { Loading @@ -167,7 +167,7 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, } } } } ret = btrfs_set_acl(dentry->d_inode, acl, type); ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); posix_acl_release(acl); posix_acl_release(acl); Loading Loading @@ -196,7 +196,8 @@ int btrfs_check_acl(struct inode *inode, int mask) * stuff has been fixed to work with that. If the locking stuff changes, we * stuff has been fixed to work with that. If the locking stuff changes, we * need to re-evaluate the acl locking stuff. * need to re-evaluate the acl locking stuff. */ */ int btrfs_init_acl(struct inode *inode, struct inode *dir) int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir) { { struct posix_acl *acl = NULL; struct posix_acl *acl = NULL; int ret = 0; int ret = 0; Loading @@ -221,7 +222,8 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) mode_t mode; mode_t mode; if (S_ISDIR(inode->i_mode)) { if (S_ISDIR(inode->i_mode)) { ret = btrfs_set_acl(inode, acl, ACL_TYPE_DEFAULT); ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_DEFAULT); if (ret) if (ret) goto failed; goto failed; } } Loading @@ -236,7 +238,7 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) inode->i_mode = mode; inode->i_mode = mode; if (ret > 0) { if (ret > 0) { /* we need an acl */ /* we need an acl */ ret = btrfs_set_acl(inode, clone, ret = btrfs_set_acl(trans, inode, clone, ACL_TYPE_ACCESS); ACL_TYPE_ACCESS); } } } } Loading Loading @@ -269,7 +271,7 @@ int btrfs_acl_chmod(struct inode *inode) ret = posix_acl_chmod_masq(clone, inode->i_mode); ret = posix_acl_chmod_masq(clone, inode->i_mode); if (!ret) if (!ret) ret = btrfs_set_acl(inode, clone, ACL_TYPE_ACCESS); ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); posix_acl_release(clone); posix_acl_release(clone); Loading Loading @@ -297,7 +299,8 @@ int btrfs_acl_chmod(struct inode *inode) return 0; return 0; } } int btrfs_init_acl(struct inode *inode, struct inode *dir) int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir) { { return 0; return 0; } } Loading fs/btrfs/btrfs_inode.h +1 −4 Original line number Original line Diff line number Diff line Loading @@ -44,9 +44,6 @@ struct btrfs_inode { */ */ struct extent_io_tree io_failure_tree; struct extent_io_tree io_failure_tree; /* held while inesrting or deleting extents from files */ struct mutex extent_mutex; /* held while logging the inode in tree-log.c */ /* held while logging the inode in tree-log.c */ struct mutex log_mutex; struct mutex log_mutex; Loading Loading @@ -166,7 +163,7 @@ static inline struct btrfs_inode *BTRFS_I(struct inode *inode) static inline void btrfs_i_size_write(struct inode *inode, u64 size) static inline void btrfs_i_size_write(struct inode *inode, u64 size) { { inode->i_size = size; i_size_write(inode, size); BTRFS_I(inode)->disk_i_size = size; BTRFS_I(inode)->disk_i_size = size; } } Loading fs/btrfs/ctree.c +153 −76 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,11 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct extent_buffer *src_buf); struct extent_buffer *src_buf); static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); struct btrfs_path *path, int level, int slot); static int setup_items_for_insert(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *cpu_key, u32 *data_size, u32 total_data, u32 total_size, int nr); struct btrfs_path *btrfs_alloc_path(void) struct btrfs_path *btrfs_alloc_path(void) { { Loading Loading @@ -451,9 +456,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, extent_buffer_get(cow); extent_buffer_get(cow); spin_unlock(&root->node_lock); spin_unlock(&root->node_lock); btrfs_free_extent(trans, root, buf->start, buf->len, btrfs_free_tree_block(trans, root, buf->start, buf->len, parent_start, root->root_key.objectid, parent_start, root->root_key.objectid, level); level, 0); free_extent_buffer(buf); free_extent_buffer(buf); add_root_to_dirty_list(root); add_root_to_dirty_list(root); } else { } else { Loading @@ -468,9 +472,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, btrfs_set_node_ptr_generation(parent, parent_slot, btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); trans->transid); btrfs_mark_buffer_dirty(parent); btrfs_mark_buffer_dirty(parent); btrfs_free_extent(trans, root, buf->start, buf->len, btrfs_free_tree_block(trans, root, buf->start, buf->len, parent_start, root->root_key.objectid, parent_start, root->root_key.objectid, level); level, 0); } } if (unlock_orig) if (unlock_orig) btrfs_tree_unlock(buf); btrfs_tree_unlock(buf); Loading Loading @@ -1030,8 +1033,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_tree_unlock(mid); btrfs_tree_unlock(mid); /* once for the path */ /* once for the path */ free_extent_buffer(mid); free_extent_buffer(mid); ret = btrfs_free_extent(trans, root, mid->start, mid->len, ret = btrfs_free_tree_block(trans, root, mid->start, mid->len, 0, root->root_key.objectid, level, 1); 0, root->root_key.objectid, level); /* once for the root ptr */ /* once for the root ptr */ free_extent_buffer(mid); free_extent_buffer(mid); return ret; return ret; Loading Loading @@ -1095,10 +1098,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, 1); 1); if (wret) if (wret) ret = wret; ret = wret; wret = btrfs_free_extent(trans, root, bytenr, wret = btrfs_free_tree_block(trans, root, blocksize, 0, bytenr, blocksize, 0, root->root_key.objectid, root->root_key.objectid, level, 0); level); if (wret) if (wret) ret = wret; ret = wret; } else { } else { Loading Loading @@ -1143,9 +1146,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, wret = del_ptr(trans, root, path, level + 1, pslot); wret = del_ptr(trans, root, path, level + 1, pslot); if (wret) if (wret) ret = wret; ret = wret; wret = btrfs_free_extent(trans, root, bytenr, blocksize, wret = btrfs_free_tree_block(trans, root, bytenr, blocksize, 0, root->root_key.objectid, 0, root->root_key.objectid, level); level, 0); if (wret) if (wret) ret = wret; ret = wret; } else { } else { Loading Loading @@ -2997,75 +2999,85 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, return ret; return ret; } } /* static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, * This function splits a single item into two items, * giving 'new_key' to the new item and splitting the * old one at split_offset (from the start of the item). * * The path may be released by this operation. After * the split, the path is pointing to the old item. The * new item is going to be in the same node as the old one. * * Note, the item being split must be smaller enough to live alone on * a tree block with room for one extra struct btrfs_item * * This allows us to split the item in place, keeping a lock on the * leaf the entire time. */ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_path *path, int ins_len) struct btrfs_key *new_key, unsigned long split_offset) { { u32 item_size; struct btrfs_key key; struct extent_buffer *leaf; struct extent_buffer *leaf; struct btrfs_key orig_key; struct btrfs_file_extent_item *fi; struct btrfs_item *item; u64 extent_len = 0; struct btrfs_item *new_item; u32 item_size; int ret = 0; int ret; int slot; u32 nritems; u32 orig_offset; struct btrfs_disk_key disk_key; char *buf; leaf = path->nodes[0]; leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); if (btrfs_leaf_free_space(root, leaf) >= sizeof(struct btrfs_item)) goto split; BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && key.type != BTRFS_EXTENT_CSUM_KEY); if (btrfs_leaf_free_space(root, leaf) >= ins_len) return 0; item_size = btrfs_item_size_nr(leaf, path->slots[0]); item_size = btrfs_item_size_nr(leaf, path->slots[0]); if (key.type == BTRFS_EXTENT_DATA_KEY) { fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); extent_len = btrfs_file_extent_num_bytes(leaf, fi); } btrfs_release_path(root, path); btrfs_release_path(root, path); path->search_for_split = 1; path->keep_locks = 1; path->keep_locks = 1; path->search_for_split = 1; ret = btrfs_search_slot(trans, root, &orig_key, path, 0, 1); ret = btrfs_search_slot(trans, root, &key, path, 0, 1); path->search_for_split = 0; path->search_for_split = 0; if (ret < 0) goto err; ret = -EAGAIN; leaf = path->nodes[0]; /* if our item isn't there or got smaller, return now */ /* if our item isn't there or got smaller, return now */ if (ret != 0 || item_size != btrfs_item_size_nr(path->nodes[0], if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) path->slots[0])) { goto err; path->keep_locks = 0; return -EAGAIN; if (key.type == BTRFS_EXTENT_DATA_KEY) { fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); if (extent_len != btrfs_file_extent_num_bytes(leaf, fi)) goto err; } } btrfs_set_path_blocking(path); btrfs_set_path_blocking(path); ret = split_leaf(trans, root, &orig_key, path, ret = split_leaf(trans, root, &key, path, ins_len, 1); sizeof(struct btrfs_item), 1); path->keep_locks = 0; BUG_ON(ret); BUG_ON(ret); path->keep_locks = 0; btrfs_unlock_up_safe(path, 1); btrfs_unlock_up_safe(path, 1); return 0; err: path->keep_locks = 0; return ret; } static noinline int split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key, unsigned long split_offset) { struct extent_buffer *leaf; struct btrfs_item *item; struct btrfs_item *new_item; int slot; char *buf; u32 nritems; u32 item_size; u32 orig_offset; struct btrfs_disk_key disk_key; leaf = path->nodes[0]; leaf = path->nodes[0]; BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); split: /* * make sure any changes to the path from split_leaf leave it * in a blocking state */ btrfs_set_path_blocking(path); btrfs_set_path_blocking(path); item = btrfs_item_nr(leaf, path->slots[0]); item = btrfs_item_nr(leaf, path->slots[0]); Loading @@ -3073,19 +3085,19 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, item_size = btrfs_item_size(leaf, item); item_size = btrfs_item_size(leaf, item); buf = kmalloc(item_size, GFP_NOFS); buf = kmalloc(item_size, GFP_NOFS); if (!buf) return -ENOMEM; read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, path->slots[0]), item_size); path->slots[0]), item_size); slot = path->slots[0] + 1; leaf = path->nodes[0]; slot = path->slots[0] + 1; nritems = btrfs_header_nritems(leaf); nritems = btrfs_header_nritems(leaf); if (slot != nritems) { if (slot != nritems) { /* shift the items */ /* shift the items */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), btrfs_item_nr_offset(slot), btrfs_item_nr_offset(slot), (nritems - slot) * sizeof(struct btrfs_item)); (nritems - slot) * sizeof(struct btrfs_item)); } } btrfs_cpu_key_to_disk(&disk_key, new_key); btrfs_cpu_key_to_disk(&disk_key, new_key); Loading Loading @@ -3113,15 +3125,80 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, item_size - split_offset); item_size - split_offset); btrfs_mark_buffer_dirty(leaf); btrfs_mark_buffer_dirty(leaf); ret = 0; BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); if (btrfs_leaf_free_space(root, leaf) < 0) { btrfs_print_leaf(root, leaf); BUG(); } kfree(buf); kfree(buf); return 0; } /* * This function splits a single item into two items, * giving 'new_key' to the new item and splitting the * old one at split_offset (from the start of the item). * * The path may be released by this operation. After * the split, the path is pointing to the old item. The * new item is going to be in the same node as the old one. * * Note, the item being split must be smaller enough to live alone on * a tree block with room for one extra struct btrfs_item * * This allows us to split the item in place, keeping a lock on the * leaf the entire time. */ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key, unsigned long split_offset) { int ret; ret = setup_leaf_for_split(trans, root, path, sizeof(struct btrfs_item)); if (ret) return ret; ret = split_item(trans, root, path, new_key, split_offset); return ret; return ret; } } /* * This function duplicate a item, giving 'new_key' to the new item. * It guarantees both items live in the same tree leaf and the new item * is contiguous with the original item. * * This allows us to split file extent in place, keeping a lock on the * leaf the entire time. */ int btrfs_duplicate_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key) { struct extent_buffer *leaf; int ret; u32 item_size; leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); ret = setup_leaf_for_split(trans, root, path, item_size + sizeof(struct btrfs_item)); if (ret) return ret; path->slots[0]++; ret = setup_items_for_insert(trans, root, path, new_key, &item_size, item_size, item_size + sizeof(struct btrfs_item), 1); BUG_ON(ret); leaf = path->nodes[0]; memcpy_extent_buffer(leaf, btrfs_item_ptr_offset(leaf, path->slots[0]), btrfs_item_ptr_offset(leaf, path->slots[0] - 1), item_size); return 0; } /* /* * make the item pointed to by the path smaller. new_size indicates * make the item pointed to by the path smaller. new_size indicates * how small to make it, and from_end tells us if we just chop bytes * how small to make it, and from_end tells us if we just chop bytes Loading Loading @@ -3714,8 +3791,8 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, */ */ btrfs_unlock_up_safe(path, 0); btrfs_unlock_up_safe(path, 0); ret = btrfs_free_extent(trans, root, leaf->start, leaf->len, ret = btrfs_free_tree_block(trans, root, leaf->start, leaf->len, 0, root->root_key.objectid, 0, 0); 0, root->root_key.objectid, 0); return ret; return ret; } } /* /* Loading fs/btrfs/ctree.h +28 −12 Original line number Original line Diff line number Diff line Loading @@ -310,6 +310,9 @@ struct btrfs_header { #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) - \ sizeof(struct btrfs_item) - \ sizeof(struct btrfs_file_extent_item)) sizeof(struct btrfs_file_extent_item)) #define BTRFS_MAX_XATTR_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) -\ sizeof(struct btrfs_dir_item)) /* /* Loading Loading @@ -859,8 +862,9 @@ struct btrfs_fs_info { struct mutex ordered_operations_mutex; struct mutex ordered_operations_mutex; struct rw_semaphore extent_commit_sem; struct rw_semaphore extent_commit_sem; struct rw_semaphore subvol_sem; struct rw_semaphore cleanup_work_sem; struct rw_semaphore subvol_sem; struct srcu_struct subvol_srcu; struct srcu_struct subvol_srcu; struct list_head trans_list; struct list_head trans_list; Loading @@ -868,6 +872,9 @@ struct btrfs_fs_info { struct list_head dead_roots; struct list_head dead_roots; struct list_head caching_block_groups; struct list_head caching_block_groups; spinlock_t delayed_iput_lock; struct list_head delayed_iputs; atomic_t nr_async_submits; atomic_t nr_async_submits; atomic_t async_submit_draining; atomic_t async_submit_draining; atomic_t nr_async_bios; atomic_t nr_async_bios; Loading Loading @@ -1034,12 +1041,12 @@ struct btrfs_root { int ref_cows; int ref_cows; int track_dirty; int track_dirty; int in_radix; int in_radix; int clean_orphans; u64 defrag_trans_start; u64 defrag_trans_start; struct btrfs_key defrag_progress; struct btrfs_key defrag_progress; struct btrfs_key defrag_max; struct btrfs_key defrag_max; int defrag_running; int defrag_running; int defrag_level; char *name; char *name; int in_sysfs; int in_sysfs; Loading Loading @@ -1975,6 +1982,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u64 parent, u64 root_objectid, u64 parent, u64 root_objectid, struct btrfs_disk_key *key, int level, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); u64 hint, u64 empty_size); int btrfs_free_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 parent, u64 root_objectid, int level); struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 bytenr, u32 blocksize, Loading Loading @@ -2089,6 +2100,10 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_path *path, struct btrfs_key *new_key, struct btrfs_key *new_key, unsigned long split_offset); unsigned long split_offset); int btrfs_duplicate_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key); int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_path *p, int *root, struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow); ins_len, int cow); Loading Loading @@ -2196,9 +2211,10 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_path *path, struct btrfs_dir_item *di); struct btrfs_dir_item *di); int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, struct btrfs_root *root, u16 name_len, const void *data, u16 data_len, struct btrfs_path *path, u64 objectid, u64 dir); const char *name, u16 name_len, const void *data, u16 data_len); struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_root *root, struct btrfs_path *path, u64 dir, struct btrfs_path *path, u64 dir, Loading Loading @@ -2292,7 +2308,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct inode *inode, u64 new_size, struct inode *inode, u64 new_size, u32 min_type); u32 min_type); int btrfs_start_delalloc_inodes(struct btrfs_root *root); int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); int btrfs_writepages(struct address_space *mapping, int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc); struct writeback_control *wbc); Loading Loading @@ -2332,6 +2348,8 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); void btrfs_orphan_cleanup(struct btrfs_root *root); void btrfs_orphan_cleanup(struct btrfs_root *root); int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_invalidate_inodes(struct btrfs_root *root); int btrfs_invalidate_inodes(struct btrfs_root *root); void btrfs_add_delayed_iput(struct inode *inode); void btrfs_run_delayed_iputs(struct btrfs_root *root); extern const struct dentry_operations btrfs_dentry_operations; extern const struct dentry_operations btrfs_dentry_operations; /* ioctl.c */ /* ioctl.c */ Loading @@ -2345,12 +2363,9 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, int skip_pinned); int skip_pinned); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); extern const struct file_operations btrfs_file_operations; extern const struct file_operations btrfs_file_operations; int btrfs_drop_extents(struct btrfs_trans_handle *trans, int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, struct btrfs_root *root, struct inode *inode, u64 start, u64 end, u64 *hint_byte, int drop_cache); u64 start, u64 end, u64 locked_end, u64 inline_limit, u64 *hint_block, int drop_cache); int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode, u64 start, u64 end); struct inode *inode, u64 start, u64 end); int btrfs_release_file(struct inode *inode, struct file *file); int btrfs_release_file(struct inode *inode, struct file *file); Loading Loading @@ -2380,7 +2395,8 @@ int btrfs_check_acl(struct inode *inode, int mask); #else #else #define btrfs_check_acl NULL #define btrfs_check_acl NULL #endif #endif int btrfs_init_acl(struct inode *inode, struct inode *dir); int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir); int btrfs_acl_chmod(struct inode *inode); int btrfs_acl_chmod(struct inode *inode); /* relocation.c */ /* relocation.c */ Loading fs/btrfs/dir-item.c +7 −12 Original line number Original line Diff line number Diff line Loading @@ -68,12 +68,12 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle * into the tree * into the tree */ */ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, struct btrfs_root *root, u16 name_len, const void *data, u16 data_len, struct btrfs_path *path, u64 objectid, u64 dir) const char *name, u16 name_len, const void *data, u16 data_len) { { int ret = 0; int ret = 0; struct btrfs_path *path; struct btrfs_dir_item *dir_item; struct btrfs_dir_item *dir_item; unsigned long name_ptr, data_ptr; unsigned long name_ptr, data_ptr; struct btrfs_key key, location; struct btrfs_key key, location; Loading @@ -81,15 +81,11 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; struct extent_buffer *leaf; u32 data_size; u32 data_size; key.objectid = dir; BUG_ON(name_len + data_len > BTRFS_MAX_XATTR_SIZE(root)); key.objectid = objectid; btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); key.offset = btrfs_name_hash(name, name_len); key.offset = btrfs_name_hash(name, name_len); path = btrfs_alloc_path(); if (!path) return -ENOMEM; if (name_len + data_len + sizeof(struct btrfs_dir_item) > BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) return -ENOSPC; data_size = sizeof(*dir_item) + name_len + data_len; data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, dir_item = insert_with_overflow(trans, root, path, &key, data_size, Loading Loading @@ -117,7 +113,6 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, write_extent_buffer(leaf, data, data_ptr, data_len); write_extent_buffer(leaf, data, data_ptr, data_len); btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_free_path(path); return ret; return ret; } } Loading Loading
fs/btrfs/acl.c +13 −10 Original line number Original line Diff line number Diff line Loading @@ -94,7 +94,8 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, /* /* * Needs to be called with fs_mutex held * Needs to be called with fs_mutex held */ */ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) static int btrfs_set_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct posix_acl *acl, int type) { { int ret, size = 0; int ret, size = 0; const char *name; const char *name; Loading Loading @@ -140,8 +141,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) goto out; goto out; } } ret = __btrfs_setxattr(inode, name, value, size, 0); ret = __btrfs_setxattr(trans, inode, name, value, size, 0); out: out: kfree(value); kfree(value); Loading @@ -154,7 +154,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) const void *value, size_t size, int flags, int type) { { int ret = 0; int ret; struct posix_acl *acl = NULL; struct posix_acl *acl = NULL; if (value) { if (value) { Loading @@ -167,7 +167,7 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, } } } } ret = btrfs_set_acl(dentry->d_inode, acl, type); ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); posix_acl_release(acl); posix_acl_release(acl); Loading Loading @@ -196,7 +196,8 @@ int btrfs_check_acl(struct inode *inode, int mask) * stuff has been fixed to work with that. If the locking stuff changes, we * stuff has been fixed to work with that. If the locking stuff changes, we * need to re-evaluate the acl locking stuff. * need to re-evaluate the acl locking stuff. */ */ int btrfs_init_acl(struct inode *inode, struct inode *dir) int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir) { { struct posix_acl *acl = NULL; struct posix_acl *acl = NULL; int ret = 0; int ret = 0; Loading @@ -221,7 +222,8 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) mode_t mode; mode_t mode; if (S_ISDIR(inode->i_mode)) { if (S_ISDIR(inode->i_mode)) { ret = btrfs_set_acl(inode, acl, ACL_TYPE_DEFAULT); ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_DEFAULT); if (ret) if (ret) goto failed; goto failed; } } Loading @@ -236,7 +238,7 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) inode->i_mode = mode; inode->i_mode = mode; if (ret > 0) { if (ret > 0) { /* we need an acl */ /* we need an acl */ ret = btrfs_set_acl(inode, clone, ret = btrfs_set_acl(trans, inode, clone, ACL_TYPE_ACCESS); ACL_TYPE_ACCESS); } } } } Loading Loading @@ -269,7 +271,7 @@ int btrfs_acl_chmod(struct inode *inode) ret = posix_acl_chmod_masq(clone, inode->i_mode); ret = posix_acl_chmod_masq(clone, inode->i_mode); if (!ret) if (!ret) ret = btrfs_set_acl(inode, clone, ACL_TYPE_ACCESS); ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); posix_acl_release(clone); posix_acl_release(clone); Loading Loading @@ -297,7 +299,8 @@ int btrfs_acl_chmod(struct inode *inode) return 0; return 0; } } int btrfs_init_acl(struct inode *inode, struct inode *dir) int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir) { { return 0; return 0; } } Loading
fs/btrfs/btrfs_inode.h +1 −4 Original line number Original line Diff line number Diff line Loading @@ -44,9 +44,6 @@ struct btrfs_inode { */ */ struct extent_io_tree io_failure_tree; struct extent_io_tree io_failure_tree; /* held while inesrting or deleting extents from files */ struct mutex extent_mutex; /* held while logging the inode in tree-log.c */ /* held while logging the inode in tree-log.c */ struct mutex log_mutex; struct mutex log_mutex; Loading Loading @@ -166,7 +163,7 @@ static inline struct btrfs_inode *BTRFS_I(struct inode *inode) static inline void btrfs_i_size_write(struct inode *inode, u64 size) static inline void btrfs_i_size_write(struct inode *inode, u64 size) { { inode->i_size = size; i_size_write(inode, size); BTRFS_I(inode)->disk_i_size = size; BTRFS_I(inode)->disk_i_size = size; } } Loading
fs/btrfs/ctree.c +153 −76 Original line number Original line Diff line number Diff line Loading @@ -37,6 +37,11 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct extent_buffer *src_buf); struct extent_buffer *src_buf); static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); struct btrfs_path *path, int level, int slot); static int setup_items_for_insert(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *cpu_key, u32 *data_size, u32 total_data, u32 total_size, int nr); struct btrfs_path *btrfs_alloc_path(void) struct btrfs_path *btrfs_alloc_path(void) { { Loading Loading @@ -451,9 +456,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, extent_buffer_get(cow); extent_buffer_get(cow); spin_unlock(&root->node_lock); spin_unlock(&root->node_lock); btrfs_free_extent(trans, root, buf->start, buf->len, btrfs_free_tree_block(trans, root, buf->start, buf->len, parent_start, root->root_key.objectid, parent_start, root->root_key.objectid, level); level, 0); free_extent_buffer(buf); free_extent_buffer(buf); add_root_to_dirty_list(root); add_root_to_dirty_list(root); } else { } else { Loading @@ -468,9 +472,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, btrfs_set_node_ptr_generation(parent, parent_slot, btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); trans->transid); btrfs_mark_buffer_dirty(parent); btrfs_mark_buffer_dirty(parent); btrfs_free_extent(trans, root, buf->start, buf->len, btrfs_free_tree_block(trans, root, buf->start, buf->len, parent_start, root->root_key.objectid, parent_start, root->root_key.objectid, level); level, 0); } } if (unlock_orig) if (unlock_orig) btrfs_tree_unlock(buf); btrfs_tree_unlock(buf); Loading Loading @@ -1030,8 +1033,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_tree_unlock(mid); btrfs_tree_unlock(mid); /* once for the path */ /* once for the path */ free_extent_buffer(mid); free_extent_buffer(mid); ret = btrfs_free_extent(trans, root, mid->start, mid->len, ret = btrfs_free_tree_block(trans, root, mid->start, mid->len, 0, root->root_key.objectid, level, 1); 0, root->root_key.objectid, level); /* once for the root ptr */ /* once for the root ptr */ free_extent_buffer(mid); free_extent_buffer(mid); return ret; return ret; Loading Loading @@ -1095,10 +1098,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, 1); 1); if (wret) if (wret) ret = wret; ret = wret; wret = btrfs_free_extent(trans, root, bytenr, wret = btrfs_free_tree_block(trans, root, blocksize, 0, bytenr, blocksize, 0, root->root_key.objectid, root->root_key.objectid, level, 0); level); if (wret) if (wret) ret = wret; ret = wret; } else { } else { Loading Loading @@ -1143,9 +1146,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, wret = del_ptr(trans, root, path, level + 1, pslot); wret = del_ptr(trans, root, path, level + 1, pslot); if (wret) if (wret) ret = wret; ret = wret; wret = btrfs_free_extent(trans, root, bytenr, blocksize, wret = btrfs_free_tree_block(trans, root, bytenr, blocksize, 0, root->root_key.objectid, 0, root->root_key.objectid, level); level, 0); if (wret) if (wret) ret = wret; ret = wret; } else { } else { Loading Loading @@ -2997,75 +2999,85 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, return ret; return ret; } } /* static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, * This function splits a single item into two items, * giving 'new_key' to the new item and splitting the * old one at split_offset (from the start of the item). * * The path may be released by this operation. After * the split, the path is pointing to the old item. The * new item is going to be in the same node as the old one. * * Note, the item being split must be smaller enough to live alone on * a tree block with room for one extra struct btrfs_item * * This allows us to split the item in place, keeping a lock on the * leaf the entire time. */ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_path *path, int ins_len) struct btrfs_key *new_key, unsigned long split_offset) { { u32 item_size; struct btrfs_key key; struct extent_buffer *leaf; struct extent_buffer *leaf; struct btrfs_key orig_key; struct btrfs_file_extent_item *fi; struct btrfs_item *item; u64 extent_len = 0; struct btrfs_item *new_item; u32 item_size; int ret = 0; int ret; int slot; u32 nritems; u32 orig_offset; struct btrfs_disk_key disk_key; char *buf; leaf = path->nodes[0]; leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); if (btrfs_leaf_free_space(root, leaf) >= sizeof(struct btrfs_item)) goto split; BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && key.type != BTRFS_EXTENT_CSUM_KEY); if (btrfs_leaf_free_space(root, leaf) >= ins_len) return 0; item_size = btrfs_item_size_nr(leaf, path->slots[0]); item_size = btrfs_item_size_nr(leaf, path->slots[0]); if (key.type == BTRFS_EXTENT_DATA_KEY) { fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); extent_len = btrfs_file_extent_num_bytes(leaf, fi); } btrfs_release_path(root, path); btrfs_release_path(root, path); path->search_for_split = 1; path->keep_locks = 1; path->keep_locks = 1; path->search_for_split = 1; ret = btrfs_search_slot(trans, root, &orig_key, path, 0, 1); ret = btrfs_search_slot(trans, root, &key, path, 0, 1); path->search_for_split = 0; path->search_for_split = 0; if (ret < 0) goto err; ret = -EAGAIN; leaf = path->nodes[0]; /* if our item isn't there or got smaller, return now */ /* if our item isn't there or got smaller, return now */ if (ret != 0 || item_size != btrfs_item_size_nr(path->nodes[0], if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) path->slots[0])) { goto err; path->keep_locks = 0; return -EAGAIN; if (key.type == BTRFS_EXTENT_DATA_KEY) { fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); if (extent_len != btrfs_file_extent_num_bytes(leaf, fi)) goto err; } } btrfs_set_path_blocking(path); btrfs_set_path_blocking(path); ret = split_leaf(trans, root, &orig_key, path, ret = split_leaf(trans, root, &key, path, ins_len, 1); sizeof(struct btrfs_item), 1); path->keep_locks = 0; BUG_ON(ret); BUG_ON(ret); path->keep_locks = 0; btrfs_unlock_up_safe(path, 1); btrfs_unlock_up_safe(path, 1); return 0; err: path->keep_locks = 0; return ret; } static noinline int split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key, unsigned long split_offset) { struct extent_buffer *leaf; struct btrfs_item *item; struct btrfs_item *new_item; int slot; char *buf; u32 nritems; u32 item_size; u32 orig_offset; struct btrfs_disk_key disk_key; leaf = path->nodes[0]; leaf = path->nodes[0]; BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); split: /* * make sure any changes to the path from split_leaf leave it * in a blocking state */ btrfs_set_path_blocking(path); btrfs_set_path_blocking(path); item = btrfs_item_nr(leaf, path->slots[0]); item = btrfs_item_nr(leaf, path->slots[0]); Loading @@ -3073,19 +3085,19 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, item_size = btrfs_item_size(leaf, item); item_size = btrfs_item_size(leaf, item); buf = kmalloc(item_size, GFP_NOFS); buf = kmalloc(item_size, GFP_NOFS); if (!buf) return -ENOMEM; read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, path->slots[0]), item_size); path->slots[0]), item_size); slot = path->slots[0] + 1; leaf = path->nodes[0]; slot = path->slots[0] + 1; nritems = btrfs_header_nritems(leaf); nritems = btrfs_header_nritems(leaf); if (slot != nritems) { if (slot != nritems) { /* shift the items */ /* shift the items */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), btrfs_item_nr_offset(slot), btrfs_item_nr_offset(slot), (nritems - slot) * sizeof(struct btrfs_item)); (nritems - slot) * sizeof(struct btrfs_item)); } } btrfs_cpu_key_to_disk(&disk_key, new_key); btrfs_cpu_key_to_disk(&disk_key, new_key); Loading Loading @@ -3113,15 +3125,80 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, item_size - split_offset); item_size - split_offset); btrfs_mark_buffer_dirty(leaf); btrfs_mark_buffer_dirty(leaf); ret = 0; BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); if (btrfs_leaf_free_space(root, leaf) < 0) { btrfs_print_leaf(root, leaf); BUG(); } kfree(buf); kfree(buf); return 0; } /* * This function splits a single item into two items, * giving 'new_key' to the new item and splitting the * old one at split_offset (from the start of the item). * * The path may be released by this operation. After * the split, the path is pointing to the old item. The * new item is going to be in the same node as the old one. * * Note, the item being split must be smaller enough to live alone on * a tree block with room for one extra struct btrfs_item * * This allows us to split the item in place, keeping a lock on the * leaf the entire time. */ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key, unsigned long split_offset) { int ret; ret = setup_leaf_for_split(trans, root, path, sizeof(struct btrfs_item)); if (ret) return ret; ret = split_item(trans, root, path, new_key, split_offset); return ret; return ret; } } /* * This function duplicate a item, giving 'new_key' to the new item. * It guarantees both items live in the same tree leaf and the new item * is contiguous with the original item. * * This allows us to split file extent in place, keeping a lock on the * leaf the entire time. */ int btrfs_duplicate_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key) { struct extent_buffer *leaf; int ret; u32 item_size; leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); ret = setup_leaf_for_split(trans, root, path, item_size + sizeof(struct btrfs_item)); if (ret) return ret; path->slots[0]++; ret = setup_items_for_insert(trans, root, path, new_key, &item_size, item_size, item_size + sizeof(struct btrfs_item), 1); BUG_ON(ret); leaf = path->nodes[0]; memcpy_extent_buffer(leaf, btrfs_item_ptr_offset(leaf, path->slots[0]), btrfs_item_ptr_offset(leaf, path->slots[0] - 1), item_size); return 0; } /* /* * make the item pointed to by the path smaller. new_size indicates * make the item pointed to by the path smaller. new_size indicates * how small to make it, and from_end tells us if we just chop bytes * how small to make it, and from_end tells us if we just chop bytes Loading Loading @@ -3714,8 +3791,8 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, */ */ btrfs_unlock_up_safe(path, 0); btrfs_unlock_up_safe(path, 0); ret = btrfs_free_extent(trans, root, leaf->start, leaf->len, ret = btrfs_free_tree_block(trans, root, leaf->start, leaf->len, 0, root->root_key.objectid, 0, 0); 0, root->root_key.objectid, 0); return ret; return ret; } } /* /* Loading
fs/btrfs/ctree.h +28 −12 Original line number Original line Diff line number Diff line Loading @@ -310,6 +310,9 @@ struct btrfs_header { #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) - \ sizeof(struct btrfs_item) - \ sizeof(struct btrfs_file_extent_item)) sizeof(struct btrfs_file_extent_item)) #define BTRFS_MAX_XATTR_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) -\ sizeof(struct btrfs_dir_item)) /* /* Loading Loading @@ -859,8 +862,9 @@ struct btrfs_fs_info { struct mutex ordered_operations_mutex; struct mutex ordered_operations_mutex; struct rw_semaphore extent_commit_sem; struct rw_semaphore extent_commit_sem; struct rw_semaphore subvol_sem; struct rw_semaphore cleanup_work_sem; struct rw_semaphore subvol_sem; struct srcu_struct subvol_srcu; struct srcu_struct subvol_srcu; struct list_head trans_list; struct list_head trans_list; Loading @@ -868,6 +872,9 @@ struct btrfs_fs_info { struct list_head dead_roots; struct list_head dead_roots; struct list_head caching_block_groups; struct list_head caching_block_groups; spinlock_t delayed_iput_lock; struct list_head delayed_iputs; atomic_t nr_async_submits; atomic_t nr_async_submits; atomic_t async_submit_draining; atomic_t async_submit_draining; atomic_t nr_async_bios; atomic_t nr_async_bios; Loading Loading @@ -1034,12 +1041,12 @@ struct btrfs_root { int ref_cows; int ref_cows; int track_dirty; int track_dirty; int in_radix; int in_radix; int clean_orphans; u64 defrag_trans_start; u64 defrag_trans_start; struct btrfs_key defrag_progress; struct btrfs_key defrag_progress; struct btrfs_key defrag_max; struct btrfs_key defrag_max; int defrag_running; int defrag_running; int defrag_level; char *name; char *name; int in_sysfs; int in_sysfs; Loading Loading @@ -1975,6 +1982,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u64 parent, u64 root_objectid, u64 parent, u64 root_objectid, struct btrfs_disk_key *key, int level, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); u64 hint, u64 empty_size); int btrfs_free_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 parent, u64 root_objectid, int level); struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 bytenr, u32 blocksize, Loading Loading @@ -2089,6 +2100,10 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_path *path, struct btrfs_key *new_key, struct btrfs_key *new_key, unsigned long split_offset); unsigned long split_offset); int btrfs_duplicate_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, struct btrfs_key *new_key); int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_path *p, int *root, struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow); ins_len, int cow); Loading Loading @@ -2196,9 +2211,10 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_path *path, struct btrfs_dir_item *di); struct btrfs_dir_item *di); int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, struct btrfs_root *root, u16 name_len, const void *data, u16 data_len, struct btrfs_path *path, u64 objectid, u64 dir); const char *name, u16 name_len, const void *data, u16 data_len); struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_root *root, struct btrfs_path *path, u64 dir, struct btrfs_path *path, u64 dir, Loading Loading @@ -2292,7 +2308,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct inode *inode, u64 new_size, struct inode *inode, u64 new_size, u32 min_type); u32 min_type); int btrfs_start_delalloc_inodes(struct btrfs_root *root); int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); int btrfs_writepages(struct address_space *mapping, int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc); struct writeback_control *wbc); Loading Loading @@ -2332,6 +2348,8 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); void btrfs_orphan_cleanup(struct btrfs_root *root); void btrfs_orphan_cleanup(struct btrfs_root *root); int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_invalidate_inodes(struct btrfs_root *root); int btrfs_invalidate_inodes(struct btrfs_root *root); void btrfs_add_delayed_iput(struct inode *inode); void btrfs_run_delayed_iputs(struct btrfs_root *root); extern const struct dentry_operations btrfs_dentry_operations; extern const struct dentry_operations btrfs_dentry_operations; /* ioctl.c */ /* ioctl.c */ Loading @@ -2345,12 +2363,9 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, int skip_pinned); int skip_pinned); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); extern const struct file_operations btrfs_file_operations; extern const struct file_operations btrfs_file_operations; int btrfs_drop_extents(struct btrfs_trans_handle *trans, int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, struct btrfs_root *root, struct inode *inode, u64 start, u64 end, u64 *hint_byte, int drop_cache); u64 start, u64 end, u64 locked_end, u64 inline_limit, u64 *hint_block, int drop_cache); int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode, u64 start, u64 end); struct inode *inode, u64 start, u64 end); int btrfs_release_file(struct inode *inode, struct file *file); int btrfs_release_file(struct inode *inode, struct file *file); Loading Loading @@ -2380,7 +2395,8 @@ int btrfs_check_acl(struct inode *inode, int mask); #else #else #define btrfs_check_acl NULL #define btrfs_check_acl NULL #endif #endif int btrfs_init_acl(struct inode *inode, struct inode *dir); int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir); int btrfs_acl_chmod(struct inode *inode); int btrfs_acl_chmod(struct inode *inode); /* relocation.c */ /* relocation.c */ Loading
fs/btrfs/dir-item.c +7 −12 Original line number Original line Diff line number Diff line Loading @@ -68,12 +68,12 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle * into the tree * into the tree */ */ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, struct btrfs_root *root, u16 name_len, const void *data, u16 data_len, struct btrfs_path *path, u64 objectid, u64 dir) const char *name, u16 name_len, const void *data, u16 data_len) { { int ret = 0; int ret = 0; struct btrfs_path *path; struct btrfs_dir_item *dir_item; struct btrfs_dir_item *dir_item; unsigned long name_ptr, data_ptr; unsigned long name_ptr, data_ptr; struct btrfs_key key, location; struct btrfs_key key, location; Loading @@ -81,15 +81,11 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; struct extent_buffer *leaf; u32 data_size; u32 data_size; key.objectid = dir; BUG_ON(name_len + data_len > BTRFS_MAX_XATTR_SIZE(root)); key.objectid = objectid; btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); key.offset = btrfs_name_hash(name, name_len); key.offset = btrfs_name_hash(name, name_len); path = btrfs_alloc_path(); if (!path) return -ENOMEM; if (name_len + data_len + sizeof(struct btrfs_dir_item) > BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) return -ENOSPC; data_size = sizeof(*dir_item) + name_len + data_len; data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, dir_item = insert_with_overflow(trans, root, path, &key, data_size, Loading Loading @@ -117,7 +113,6 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, write_extent_buffer(leaf, data, data_ptr, data_len); write_extent_buffer(leaf, data, data_ptr, data_len); btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_mark_buffer_dirty(path->nodes[0]); btrfs_free_path(path); return ret; return ret; } } Loading