aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/extent_io.c6
-rw-r--r--fs/btrfs/inode.c5
-rw-r--r--fs/btrfs/ioctl.c32
-rw-r--r--fs/btrfs/reada.c18
4 files changed, 33 insertions, 28 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 4c878476bb91..b08ea4717e9d 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -107,6 +107,12 @@ void extent_io_exit(void)
107 list_del(&eb->leak_list); 107 list_del(&eb->leak_list);
108 kmem_cache_free(extent_buffer_cache, eb); 108 kmem_cache_free(extent_buffer_cache, eb);
109 } 109 }
110
111 /*
112 * Make sure all delayed rcu free are flushed before we
113 * destroy caches.
114 */
115 rcu_barrier();
110 if (extent_state_cache) 116 if (extent_state_cache)
111 kmem_cache_destroy(extent_state_cache); 117 kmem_cache_destroy(extent_state_cache);
112 if (extent_buffer_cache) 118 if (extent_buffer_cache)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2a028a58619c..a6ed6944e50c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7076,6 +7076,11 @@ static void init_once(void *foo)
7076 7076
7077void btrfs_destroy_cachep(void) 7077void btrfs_destroy_cachep(void)
7078{ 7078{
7079 /*
7080 * Make sure all delayed rcu free inodes are flushed before we
7081 * destroy cache.
7082 */
7083 rcu_barrier();
7079 if (btrfs_inode_cachep) 7084 if (btrfs_inode_cachep)
7080 kmem_cache_destroy(btrfs_inode_cachep); 7085 kmem_cache_destroy(btrfs_inode_cachep);
7081 if (btrfs_trans_handle_cachep) 7086 if (btrfs_trans_handle_cachep)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 27bfce58da3b..47127c1bd290 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1397,7 +1397,6 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
1397 u64 *transid, bool readonly, 1397 u64 *transid, bool readonly,
1398 struct btrfs_qgroup_inherit **inherit) 1398 struct btrfs_qgroup_inherit **inherit)
1399{ 1399{
1400 struct file *src_file;
1401 int namelen; 1400 int namelen;
1402 int ret = 0; 1401 int ret = 0;
1403 1402
@@ -1421,25 +1420,24 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
1421 ret = btrfs_mksubvol(&file->f_path, name, namelen, 1420 ret = btrfs_mksubvol(&file->f_path, name, namelen,
1422 NULL, transid, readonly, inherit); 1421 NULL, transid, readonly, inherit);
1423 } else { 1422 } else {
1423 struct fd src = fdget(fd);
1424 struct inode *src_inode; 1424 struct inode *src_inode;
1425 src_file = fget(fd); 1425 if (!src.file) {
1426 if (!src_file) {
1427 ret = -EINVAL; 1426 ret = -EINVAL;
1428 goto out_drop_write; 1427 goto out_drop_write;
1429 } 1428 }
1430 1429
1431 src_inode = src_file->f_path.dentry->d_inode; 1430 src_inode = src.file->f_path.dentry->d_inode;
1432 if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) { 1431 if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) {
1433 printk(KERN_INFO "btrfs: Snapshot src from " 1432 printk(KERN_INFO "btrfs: Snapshot src from "
1434 "another FS\n"); 1433 "another FS\n");
1435 ret = -EINVAL; 1434 ret = -EINVAL;
1436 fput(src_file); 1435 } else {
1437 goto out_drop_write; 1436 ret = btrfs_mksubvol(&file->f_path, name, namelen,
1437 BTRFS_I(src_inode)->root,
1438 transid, readonly, inherit);
1438 } 1439 }
1439 ret = btrfs_mksubvol(&file->f_path, name, namelen, 1440 fdput(src);
1440 BTRFS_I(src_inode)->root,
1441 transid, readonly, inherit);
1442 fput(src_file);
1443 } 1441 }
1444out_drop_write: 1442out_drop_write:
1445 mnt_drop_write_file(file); 1443 mnt_drop_write_file(file);
@@ -2341,7 +2339,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2341{ 2339{
2342 struct inode *inode = fdentry(file)->d_inode; 2340 struct inode *inode = fdentry(file)->d_inode;
2343 struct btrfs_root *root = BTRFS_I(inode)->root; 2341 struct btrfs_root *root = BTRFS_I(inode)->root;
2344 struct file *src_file; 2342 struct fd src_file;
2345 struct inode *src; 2343 struct inode *src;
2346 struct btrfs_trans_handle *trans; 2344 struct btrfs_trans_handle *trans;
2347 struct btrfs_path *path; 2345 struct btrfs_path *path;
@@ -2376,24 +2374,24 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2376 if (ret) 2374 if (ret)
2377 return ret; 2375 return ret;
2378 2376
2379 src_file = fget(srcfd); 2377 src_file = fdget(srcfd);
2380 if (!src_file) { 2378 if (!src_file.file) {
2381 ret = -EBADF; 2379 ret = -EBADF;
2382 goto out_drop_write; 2380 goto out_drop_write;
2383 } 2381 }
2384 2382
2385 ret = -EXDEV; 2383 ret = -EXDEV;
2386 if (src_file->f_path.mnt != file->f_path.mnt) 2384 if (src_file.file->f_path.mnt != file->f_path.mnt)
2387 goto out_fput; 2385 goto out_fput;
2388 2386
2389 src = src_file->f_dentry->d_inode; 2387 src = src_file.file->f_dentry->d_inode;
2390 2388
2391 ret = -EINVAL; 2389 ret = -EINVAL;
2392 if (src == inode) 2390 if (src == inode)
2393 goto out_fput; 2391 goto out_fput;
2394 2392
2395 /* the src must be open for reading */ 2393 /* the src must be open for reading */
2396 if (!(src_file->f_mode & FMODE_READ)) 2394 if (!(src_file.file->f_mode & FMODE_READ))
2397 goto out_fput; 2395 goto out_fput;
2398 2396
2399 /* don't make the dst file partly checksummed */ 2397 /* don't make the dst file partly checksummed */
@@ -2724,7 +2722,7 @@ out_unlock:
2724 vfree(buf); 2722 vfree(buf);
2725 btrfs_free_path(path); 2723 btrfs_free_path(path);
2726out_fput: 2724out_fput:
2727 fput(src_file); 2725 fdput(src_file);
2728out_drop_write: 2726out_drop_write:
2729 mnt_drop_write_file(file); 2727 mnt_drop_write_file(file);
2730 return ret; 2728 return ret;
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index 48a4882d8ad5..a955669519a2 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -68,7 +68,7 @@ struct reada_extent {
68 u32 blocksize; 68 u32 blocksize;
69 int err; 69 int err;
70 struct list_head extctl; 70 struct list_head extctl;
71 struct kref refcnt; 71 int refcnt;
72 spinlock_t lock; 72 spinlock_t lock;
73 struct reada_zone *zones[BTRFS_MAX_MIRRORS]; 73 struct reada_zone *zones[BTRFS_MAX_MIRRORS];
74 int nzones; 74 int nzones;
@@ -126,7 +126,7 @@ static int __readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
126 spin_lock(&fs_info->reada_lock); 126 spin_lock(&fs_info->reada_lock);
127 re = radix_tree_lookup(&fs_info->reada_tree, index); 127 re = radix_tree_lookup(&fs_info->reada_tree, index);
128 if (re) 128 if (re)
129 kref_get(&re->refcnt); 129 re->refcnt++;
130 spin_unlock(&fs_info->reada_lock); 130 spin_unlock(&fs_info->reada_lock);
131 131
132 if (!re) 132 if (!re)
@@ -336,7 +336,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
336 spin_lock(&fs_info->reada_lock); 336 spin_lock(&fs_info->reada_lock);
337 re = radix_tree_lookup(&fs_info->reada_tree, index); 337 re = radix_tree_lookup(&fs_info->reada_tree, index);
338 if (re) 338 if (re)
339 kref_get(&re->refcnt); 339 re->refcnt++;
340 spin_unlock(&fs_info->reada_lock); 340 spin_unlock(&fs_info->reada_lock);
341 341
342 if (re) 342 if (re)
@@ -352,7 +352,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
352 re->top = *top; 352 re->top = *top;
353 INIT_LIST_HEAD(&re->extctl); 353 INIT_LIST_HEAD(&re->extctl);
354 spin_lock_init(&re->lock); 354 spin_lock_init(&re->lock);
355 kref_init(&re->refcnt); 355 re->refcnt = 1;
356 356
357 /* 357 /*
358 * map block 358 * map block
@@ -398,7 +398,7 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
398 if (ret == -EEXIST) { 398 if (ret == -EEXIST) {
399 re_exist = radix_tree_lookup(&fs_info->reada_tree, index); 399 re_exist = radix_tree_lookup(&fs_info->reada_tree, index);
400 BUG_ON(!re_exist); 400 BUG_ON(!re_exist);
401 kref_get(&re_exist->refcnt); 401 re_exist->refcnt++;
402 spin_unlock(&fs_info->reada_lock); 402 spin_unlock(&fs_info->reada_lock);
403 goto error; 403 goto error;
404 } 404 }
@@ -465,10 +465,6 @@ error:
465 return re_exist; 465 return re_exist;
466} 466}
467 467
468static void reada_kref_dummy(struct kref *kr)
469{
470}
471
472static void reada_extent_put(struct btrfs_fs_info *fs_info, 468static void reada_extent_put(struct btrfs_fs_info *fs_info,
473 struct reada_extent *re) 469 struct reada_extent *re)
474{ 470{
@@ -476,7 +472,7 @@ static void reada_extent_put(struct btrfs_fs_info *fs_info,
476 unsigned long index = re->logical >> PAGE_CACHE_SHIFT; 472 unsigned long index = re->logical >> PAGE_CACHE_SHIFT;
477 473
478 spin_lock(&fs_info->reada_lock); 474 spin_lock(&fs_info->reada_lock);
479 if (!kref_put(&re->refcnt, reada_kref_dummy)) { 475 if (--re->refcnt) {
480 spin_unlock(&fs_info->reada_lock); 476 spin_unlock(&fs_info->reada_lock);
481 return; 477 return;
482 } 478 }
@@ -671,7 +667,7 @@ static int reada_start_machine_dev(struct btrfs_fs_info *fs_info,
671 return 0; 667 return 0;
672 } 668 }
673 dev->reada_next = re->logical + re->blocksize; 669 dev->reada_next = re->logical + re->blocksize;
674 kref_get(&re->refcnt); 670 re->refcnt++;
675 671
676 spin_unlock(&fs_info->reada_lock); 672 spin_unlock(&fs_info->reada_lock);
677 673