aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/delayed-inode.c9
-rw-r--r--fs/btrfs/delayed-inode.h3
-rw-r--r--fs/btrfs/disk-io.c10
-rw-r--r--fs/btrfs/inode.c52
-rw-r--r--fs/btrfs/relocation.c9
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 */
1684int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, 1684int 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);
140int btrfs_should_delete_dir_index(struct list_head *del_list, 140int btrfs_should_delete_dir_index(struct list_head *del_list,
141 u64 index); 141 u64 index);
142int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent, 142int 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);
2861fail_trans_kthread: 2861fail_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);
2865fail_cleaner: 2865fail_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
5140static int btrfs_real_readdir(struct file *filp, void *dirent, 5140static 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
5281skip: 5265skip:
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++;
5314nopos: 5297nopos:
5315 ret = 0; 5298 ret = 0;
5316err: 5299err:
@@ -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 = {
8729static const struct file_operations btrfs_dir_file_operations = { 8715static 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
4085static struct reloc_control *alloc_reloc_control(void) 4085static 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;