diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/delayed-inode.c | 9 | ||||
-rw-r--r-- | fs/btrfs/delayed-inode.h | 3 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 10 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 52 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 9 |
5 files changed, 34 insertions, 49 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index f26f38ccd194..eb34438ddedb 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -1681,8 +1681,7 @@ int btrfs_should_delete_dir_index(struct list_head *del_list, | |||
1681 | * btrfs_readdir_delayed_dir_index - read dir info stored in the delayed tree | 1681 | * btrfs_readdir_delayed_dir_index - read dir info stored in the delayed tree |
1682 | * | 1682 | * |
1683 | */ | 1683 | */ |
1684 | int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, | 1684 | int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, |
1685 | filldir_t filldir, | ||
1686 | struct list_head *ins_list) | 1685 | struct list_head *ins_list) |
1687 | { | 1686 | { |
1688 | struct btrfs_dir_item *di; | 1687 | struct btrfs_dir_item *di; |
@@ -1704,13 +1703,13 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, | |||
1704 | list_for_each_entry_safe(curr, next, ins_list, readdir_list) { | 1703 | list_for_each_entry_safe(curr, next, ins_list, readdir_list) { |
1705 | list_del(&curr->readdir_list); | 1704 | list_del(&curr->readdir_list); |
1706 | 1705 | ||
1707 | if (curr->key.offset < filp->f_pos) { | 1706 | if (curr->key.offset < ctx->pos) { |
1708 | if (atomic_dec_and_test(&curr->refs)) | 1707 | if (atomic_dec_and_test(&curr->refs)) |
1709 | kfree(curr); | 1708 | kfree(curr); |
1710 | continue; | 1709 | continue; |
1711 | } | 1710 | } |
1712 | 1711 | ||
1713 | filp->f_pos = curr->key.offset; | 1712 | ctx->pos = curr->key.offset; |
1714 | 1713 | ||
1715 | di = (struct btrfs_dir_item *)curr->data; | 1714 | di = (struct btrfs_dir_item *)curr->data; |
1716 | name = (char *)(di + 1); | 1715 | name = (char *)(di + 1); |
@@ -1719,7 +1718,7 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, | |||
1719 | d_type = btrfs_filetype_table[di->type]; | 1718 | d_type = btrfs_filetype_table[di->type]; |
1720 | btrfs_disk_key_to_cpu(&location, &di->location); | 1719 | btrfs_disk_key_to_cpu(&location, &di->location); |
1721 | 1720 | ||
1722 | over = filldir(dirent, name, name_len, curr->key.offset, | 1721 | over = !dir_emit(ctx, name, name_len, |
1723 | location.objectid, d_type); | 1722 | location.objectid, d_type); |
1724 | 1723 | ||
1725 | if (atomic_dec_and_test(&curr->refs)) | 1724 | if (atomic_dec_and_test(&curr->refs)) |
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h index 1d5c5f7abe3e..a4b38f934d14 100644 --- a/fs/btrfs/delayed-inode.h +++ b/fs/btrfs/delayed-inode.h | |||
@@ -139,8 +139,7 @@ void btrfs_put_delayed_items(struct list_head *ins_list, | |||
139 | struct list_head *del_list); | 139 | struct list_head *del_list); |
140 | int btrfs_should_delete_dir_index(struct list_head *del_list, | 140 | int btrfs_should_delete_dir_index(struct list_head *del_list, |
141 | u64 index); | 141 | u64 index); |
142 | int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, | 142 | int btrfs_readdir_delayed_dir_index(struct dir_context *ctx, |
143 | filldir_t filldir, | ||
144 | struct list_head *ins_list); | 143 | struct list_head *ins_list); |
145 | 144 | ||
146 | /* for init */ | 145 | /* for init */ |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 40c7bc300075..b0292b3ead54 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2860,8 +2860,8 @@ fail_qgroup: | |||
2860 | btrfs_free_qgroup_config(fs_info); | 2860 | btrfs_free_qgroup_config(fs_info); |
2861 | fail_trans_kthread: | 2861 | fail_trans_kthread: |
2862 | kthread_stop(fs_info->transaction_kthread); | 2862 | kthread_stop(fs_info->transaction_kthread); |
2863 | del_fs_roots(fs_info); | ||
2864 | btrfs_cleanup_transaction(fs_info->tree_root); | 2863 | btrfs_cleanup_transaction(fs_info->tree_root); |
2864 | del_fs_roots(fs_info); | ||
2865 | fail_cleaner: | 2865 | fail_cleaner: |
2866 | kthread_stop(fs_info->cleaner_kthread); | 2866 | kthread_stop(fs_info->cleaner_kthread); |
2867 | 2867 | ||
@@ -3513,15 +3513,15 @@ int close_ctree(struct btrfs_root *root) | |||
3513 | percpu_counter_sum(&fs_info->delalloc_bytes)); | 3513 | percpu_counter_sum(&fs_info->delalloc_bytes)); |
3514 | } | 3514 | } |
3515 | 3515 | ||
3516 | free_root_pointers(fs_info, 1); | ||
3517 | |||
3518 | btrfs_free_block_groups(fs_info); | 3516 | btrfs_free_block_groups(fs_info); |
3519 | 3517 | ||
3518 | btrfs_stop_all_workers(fs_info); | ||
3519 | |||
3520 | del_fs_roots(fs_info); | 3520 | del_fs_roots(fs_info); |
3521 | 3521 | ||
3522 | iput(fs_info->btree_inode); | 3522 | free_root_pointers(fs_info, 1); |
3523 | 3523 | ||
3524 | btrfs_stop_all_workers(fs_info); | 3524 | iput(fs_info->btree_inode); |
3525 | 3525 | ||
3526 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY | 3526 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
3527 | if (btrfs_test_opt(root, CHECK_INTEGRITY)) | 3527 | if (btrfs_test_opt(root, CHECK_INTEGRITY)) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index db57e6384fbb..4f9d16b70d3d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -5137,10 +5137,9 @@ unsigned char btrfs_filetype_table[] = { | |||
5137 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK | 5137 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK |
5138 | }; | 5138 | }; |
5139 | 5139 | ||
5140 | static int btrfs_real_readdir(struct file *filp, void *dirent, | 5140 | static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) |
5141 | filldir_t filldir) | ||
5142 | { | 5141 | { |
5143 | struct inode *inode = file_inode(filp); | 5142 | struct inode *inode = file_inode(file); |
5144 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5143 | struct btrfs_root *root = BTRFS_I(inode)->root; |
5145 | struct btrfs_item *item; | 5144 | struct btrfs_item *item; |
5146 | struct btrfs_dir_item *di; | 5145 | struct btrfs_dir_item *di; |
@@ -5161,29 +5160,15 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
5161 | char tmp_name[32]; | 5160 | char tmp_name[32]; |
5162 | char *name_ptr; | 5161 | char *name_ptr; |
5163 | int name_len; | 5162 | int name_len; |
5164 | int is_curr = 0; /* filp->f_pos points to the current index? */ | 5163 | int is_curr = 0; /* ctx->pos points to the current index? */ |
5165 | 5164 | ||
5166 | /* FIXME, use a real flag for deciding about the key type */ | 5165 | /* FIXME, use a real flag for deciding about the key type */ |
5167 | if (root->fs_info->tree_root == root) | 5166 | if (root->fs_info->tree_root == root) |
5168 | key_type = BTRFS_DIR_ITEM_KEY; | 5167 | key_type = BTRFS_DIR_ITEM_KEY; |
5169 | 5168 | ||
5170 | /* special case for "." */ | 5169 | if (!dir_emit_dots(file, ctx)) |
5171 | if (filp->f_pos == 0) { | 5170 | return 0; |
5172 | over = filldir(dirent, ".", 1, | 5171 | |
5173 | filp->f_pos, btrfs_ino(inode), DT_DIR); | ||
5174 | if (over) | ||
5175 | return 0; | ||
5176 | filp->f_pos = 1; | ||
5177 | } | ||
5178 | /* special case for .., just use the back ref */ | ||
5179 | if (filp->f_pos == 1) { | ||
5180 | u64 pino = parent_ino(filp->f_path.dentry); | ||
5181 | over = filldir(dirent, "..", 2, | ||
5182 | filp->f_pos, pino, DT_DIR); | ||
5183 | if (over) | ||
5184 | return 0; | ||
5185 | filp->f_pos = 2; | ||
5186 | } | ||
5187 | path = btrfs_alloc_path(); | 5172 | path = btrfs_alloc_path(); |
5188 | if (!path) | 5173 | if (!path) |
5189 | return -ENOMEM; | 5174 | return -ENOMEM; |
@@ -5197,7 +5182,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
5197 | } | 5182 | } |
5198 | 5183 | ||
5199 | btrfs_set_key_type(&key, key_type); | 5184 | btrfs_set_key_type(&key, key_type); |
5200 | key.offset = filp->f_pos; | 5185 | key.offset = ctx->pos; |
5201 | key.objectid = btrfs_ino(inode); | 5186 | key.objectid = btrfs_ino(inode); |
5202 | 5187 | ||
5203 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 5188 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
@@ -5223,14 +5208,14 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
5223 | break; | 5208 | break; |
5224 | if (btrfs_key_type(&found_key) != key_type) | 5209 | if (btrfs_key_type(&found_key) != key_type) |
5225 | break; | 5210 | break; |
5226 | if (found_key.offset < filp->f_pos) | 5211 | if (found_key.offset < ctx->pos) |
5227 | goto next; | 5212 | goto next; |
5228 | if (key_type == BTRFS_DIR_INDEX_KEY && | 5213 | if (key_type == BTRFS_DIR_INDEX_KEY && |
5229 | btrfs_should_delete_dir_index(&del_list, | 5214 | btrfs_should_delete_dir_index(&del_list, |
5230 | found_key.offset)) | 5215 | found_key.offset)) |
5231 | goto next; | 5216 | goto next; |
5232 | 5217 | ||
5233 | filp->f_pos = found_key.offset; | 5218 | ctx->pos = found_key.offset; |
5234 | is_curr = 1; | 5219 | is_curr = 1; |
5235 | 5220 | ||
5236 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); | 5221 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); |
@@ -5274,9 +5259,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
5274 | over = 0; | 5259 | over = 0; |
5275 | goto skip; | 5260 | goto skip; |
5276 | } | 5261 | } |
5277 | over = filldir(dirent, name_ptr, name_len, | 5262 | over = !dir_emit(ctx, name_ptr, name_len, |
5278 | found_key.offset, location.objectid, | 5263 | location.objectid, d_type); |
5279 | d_type); | ||
5280 | 5264 | ||
5281 | skip: | 5265 | skip: |
5282 | if (name_ptr != tmp_name) | 5266 | if (name_ptr != tmp_name) |
@@ -5295,9 +5279,8 @@ next: | |||
5295 | 5279 | ||
5296 | if (key_type == BTRFS_DIR_INDEX_KEY) { | 5280 | if (key_type == BTRFS_DIR_INDEX_KEY) { |
5297 | if (is_curr) | 5281 | if (is_curr) |
5298 | filp->f_pos++; | 5282 | ctx->pos++; |
5299 | ret = btrfs_readdir_delayed_dir_index(filp, dirent, filldir, | 5283 | ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list); |
5300 | &ins_list); | ||
5301 | if (ret) | 5284 | if (ret) |
5302 | goto nopos; | 5285 | goto nopos; |
5303 | } | 5286 | } |
@@ -5308,9 +5291,9 @@ next: | |||
5308 | * 32-bit glibc will use getdents64, but then strtol - | 5291 | * 32-bit glibc will use getdents64, but then strtol - |
5309 | * so the last number we can serve is this. | 5292 | * so the last number we can serve is this. |
5310 | */ | 5293 | */ |
5311 | filp->f_pos = 0x7fffffff; | 5294 | ctx->pos = 0x7fffffff; |
5312 | else | 5295 | else |
5313 | filp->f_pos++; | 5296 | ctx->pos++; |
5314 | nopos: | 5297 | nopos: |
5315 | ret = 0; | 5298 | ret = 0; |
5316 | err: | 5299 | err: |
@@ -8013,6 +7996,9 @@ int btrfs_drop_inode(struct inode *inode) | |||
8013 | { | 7996 | { |
8014 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7997 | struct btrfs_root *root = BTRFS_I(inode)->root; |
8015 | 7998 | ||
7999 | if (root == NULL) | ||
8000 | return 1; | ||
8001 | |||
8016 | /* the snap/subvol tree is on deleting */ | 8002 | /* the snap/subvol tree is on deleting */ |
8017 | if (btrfs_root_refs(&root->root_item) == 0 && | 8003 | if (btrfs_root_refs(&root->root_item) == 0 && |
8018 | root != root->fs_info->tree_root) | 8004 | root != root->fs_info->tree_root) |
@@ -8729,7 +8715,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = { | |||
8729 | static const struct file_operations btrfs_dir_file_operations = { | 8715 | static const struct file_operations btrfs_dir_file_operations = { |
8730 | .llseek = generic_file_llseek, | 8716 | .llseek = generic_file_llseek, |
8731 | .read = generic_read_dir, | 8717 | .read = generic_read_dir, |
8732 | .readdir = btrfs_real_readdir, | 8718 | .iterate = btrfs_real_readdir, |
8733 | .unlocked_ioctl = btrfs_ioctl, | 8719 | .unlocked_ioctl = btrfs_ioctl, |
8734 | #ifdef CONFIG_COMPAT | 8720 | #ifdef CONFIG_COMPAT |
8735 | .compat_ioctl = btrfs_ioctl, | 8721 | .compat_ioctl = btrfs_ioctl, |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 395b82031a42..4febca4fc2de 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -4082,7 +4082,7 @@ out: | |||
4082 | return inode; | 4082 | return inode; |
4083 | } | 4083 | } |
4084 | 4084 | ||
4085 | static struct reloc_control *alloc_reloc_control(void) | 4085 | static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info) |
4086 | { | 4086 | { |
4087 | struct reloc_control *rc; | 4087 | struct reloc_control *rc; |
4088 | 4088 | ||
@@ -4093,7 +4093,8 @@ static struct reloc_control *alloc_reloc_control(void) | |||
4093 | INIT_LIST_HEAD(&rc->reloc_roots); | 4093 | INIT_LIST_HEAD(&rc->reloc_roots); |
4094 | backref_cache_init(&rc->backref_cache); | 4094 | backref_cache_init(&rc->backref_cache); |
4095 | mapping_tree_init(&rc->reloc_root_tree); | 4095 | mapping_tree_init(&rc->reloc_root_tree); |
4096 | extent_io_tree_init(&rc->processed_blocks, NULL); | 4096 | extent_io_tree_init(&rc->processed_blocks, |
4097 | fs_info->btree_inode->i_mapping); | ||
4097 | return rc; | 4098 | return rc; |
4098 | } | 4099 | } |
4099 | 4100 | ||
@@ -4110,7 +4111,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) | |||
4110 | int rw = 0; | 4111 | int rw = 0; |
4111 | int err = 0; | 4112 | int err = 0; |
4112 | 4113 | ||
4113 | rc = alloc_reloc_control(); | 4114 | rc = alloc_reloc_control(fs_info); |
4114 | if (!rc) | 4115 | if (!rc) |
4115 | return -ENOMEM; | 4116 | return -ENOMEM; |
4116 | 4117 | ||
@@ -4311,7 +4312,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4311 | if (list_empty(&reloc_roots)) | 4312 | if (list_empty(&reloc_roots)) |
4312 | goto out; | 4313 | goto out; |
4313 | 4314 | ||
4314 | rc = alloc_reloc_control(); | 4315 | rc = alloc_reloc_control(root->fs_info); |
4315 | if (!rc) { | 4316 | if (!rc) { |
4316 | err = -ENOMEM; | 4317 | err = -ENOMEM; |
4317 | goto out; | 4318 | goto out; |