aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c404
1 files changed, 231 insertions, 173 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index bd88f25889f7..cdbb054102b9 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -230,8 +230,8 @@ static noinline int create_subvol(struct btrfs_root *root,
230 struct btrfs_root_item root_item; 230 struct btrfs_root_item root_item;
231 struct btrfs_inode_item *inode_item; 231 struct btrfs_inode_item *inode_item;
232 struct extent_buffer *leaf; 232 struct extent_buffer *leaf;
233 struct btrfs_root *new_root = root; 233 struct btrfs_root *new_root;
234 struct inode *dir; 234 struct inode *dir = dentry->d_parent->d_inode;
235 int ret; 235 int ret;
236 int err; 236 int err;
237 u64 objectid; 237 u64 objectid;
@@ -239,9 +239,15 @@ static noinline int create_subvol(struct btrfs_root *root,
239 u64 index = 0; 239 u64 index = 0;
240 unsigned long nr = 1; 240 unsigned long nr = 1;
241 241
242 ret = btrfs_check_metadata_free_space(root); 242 /*
243 * 1 - inode item
244 * 2 - refs
245 * 1 - root item
246 * 2 - dir items
247 */
248 ret = btrfs_reserve_metadata_space(root, 6);
243 if (ret) 249 if (ret)
244 goto fail_commit; 250 return ret;
245 251
246 trans = btrfs_start_transaction(root, 1); 252 trans = btrfs_start_transaction(root, 1);
247 BUG_ON(!trans); 253 BUG_ON(!trans);
@@ -304,11 +310,17 @@ static noinline int create_subvol(struct btrfs_root *root,
304 if (ret) 310 if (ret)
305 goto fail; 311 goto fail;
306 312
313 key.offset = (u64)-1;
314 new_root = btrfs_read_fs_root_no_name(root->fs_info, &key);
315 BUG_ON(IS_ERR(new_root));
316
317 btrfs_record_root_in_trans(trans, new_root);
318
319 ret = btrfs_create_subvol_root(trans, new_root, new_dirid,
320 BTRFS_I(dir)->block_group);
307 /* 321 /*
308 * insert the directory item 322 * insert the directory item
309 */ 323 */
310 key.offset = (u64)-1;
311 dir = dentry->d_parent->d_inode;
312 ret = btrfs_set_inode_index(dir, &index); 324 ret = btrfs_set_inode_index(dir, &index);
313 BUG_ON(ret); 325 BUG_ON(ret);
314 326
@@ -322,43 +334,20 @@ static noinline int create_subvol(struct btrfs_root *root,
322 ret = btrfs_update_inode(trans, root, dir); 334 ret = btrfs_update_inode(trans, root, dir);
323 BUG_ON(ret); 335 BUG_ON(ret);
324 336
325 /* add the backref first */
326 ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, 337 ret = btrfs_add_root_ref(trans, root->fs_info->tree_root,
327 objectid, BTRFS_ROOT_BACKREF_KEY, 338 objectid, root->root_key.objectid,
328 root->root_key.objectid,
329 dir->i_ino, index, name, namelen); 339 dir->i_ino, index, name, namelen);
330 340
331 BUG_ON(ret); 341 BUG_ON(ret);
332 342
333 /* now add the forward ref */ 343 d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
334 ret = btrfs_add_root_ref(trans, root->fs_info->tree_root,
335 root->root_key.objectid, BTRFS_ROOT_REF_KEY,
336 objectid,
337 dir->i_ino, index, name, namelen);
338
339 BUG_ON(ret);
340
341 ret = btrfs_commit_transaction(trans, root);
342 if (ret)
343 goto fail_commit;
344
345 new_root = btrfs_read_fs_root_no_name(root->fs_info, &key);
346 BUG_ON(!new_root);
347
348 trans = btrfs_start_transaction(new_root, 1);
349 BUG_ON(!trans);
350
351 ret = btrfs_create_subvol_root(trans, new_root, dentry, new_dirid,
352 BTRFS_I(dir)->block_group);
353 if (ret)
354 goto fail;
355
356fail: 344fail:
357 nr = trans->blocks_used; 345 nr = trans->blocks_used;
358 err = btrfs_commit_transaction(trans, new_root); 346 err = btrfs_commit_transaction(trans, root);
359 if (err && !ret) 347 if (err && !ret)
360 ret = err; 348 ret = err;
361fail_commit: 349
350 btrfs_unreserve_metadata_space(root, 6);
362 btrfs_btree_balance_dirty(root, nr); 351 btrfs_btree_balance_dirty(root, nr);
363 return ret; 352 return ret;
364} 353}
@@ -375,19 +364,27 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
375 if (!root->ref_cows) 364 if (!root->ref_cows)
376 return -EINVAL; 365 return -EINVAL;
377 366
378 ret = btrfs_check_metadata_free_space(root); 367 /*
368 * 1 - inode item
369 * 2 - refs
370 * 1 - root item
371 * 2 - dir items
372 */
373 ret = btrfs_reserve_metadata_space(root, 6);
379 if (ret) 374 if (ret)
380 goto fail_unlock; 375 goto fail_unlock;
381 376
382 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); 377 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
383 if (!pending_snapshot) { 378 if (!pending_snapshot) {
384 ret = -ENOMEM; 379 ret = -ENOMEM;
380 btrfs_unreserve_metadata_space(root, 6);
385 goto fail_unlock; 381 goto fail_unlock;
386 } 382 }
387 pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS); 383 pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS);
388 if (!pending_snapshot->name) { 384 if (!pending_snapshot->name) {
389 ret = -ENOMEM; 385 ret = -ENOMEM;
390 kfree(pending_snapshot); 386 kfree(pending_snapshot);
387 btrfs_unreserve_metadata_space(root, 6);
391 goto fail_unlock; 388 goto fail_unlock;
392 } 389 }
393 memcpy(pending_snapshot->name, name, namelen); 390 memcpy(pending_snapshot->name, name, namelen);
@@ -420,14 +417,15 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child)
420 * sys_mkdirat and vfs_mkdir, but we only do a single component lookup 417 * sys_mkdirat and vfs_mkdir, but we only do a single component lookup
421 * inside this filesystem so it's quite a bit simpler. 418 * inside this filesystem so it's quite a bit simpler.
422 */ 419 */
423static noinline int btrfs_mksubvol(struct path *parent, char *name, 420static noinline int btrfs_mksubvol(struct path *parent,
424 int mode, int namelen, 421 char *name, int namelen,
425 struct btrfs_root *snap_src) 422 struct btrfs_root *snap_src)
426{ 423{
424 struct inode *dir = parent->dentry->d_inode;
427 struct dentry *dentry; 425 struct dentry *dentry;
428 int error; 426 int error;
429 427
430 mutex_lock_nested(&parent->dentry->d_inode->i_mutex, I_MUTEX_PARENT); 428 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
431 429
432 dentry = lookup_one_len(name, parent->dentry, namelen); 430 dentry = lookup_one_len(name, parent->dentry, namelen);
433 error = PTR_ERR(dentry); 431 error = PTR_ERR(dentry);
@@ -438,99 +436,39 @@ static noinline int btrfs_mksubvol(struct path *parent, char *name,
438 if (dentry->d_inode) 436 if (dentry->d_inode)
439 goto out_dput; 437 goto out_dput;
440 438
441 if (!IS_POSIXACL(parent->dentry->d_inode))
442 mode &= ~current_umask();
443
444 error = mnt_want_write(parent->mnt); 439 error = mnt_want_write(parent->mnt);
445 if (error) 440 if (error)
446 goto out_dput; 441 goto out_dput;
447 442
448 error = btrfs_may_create(parent->dentry->d_inode, dentry); 443 error = btrfs_may_create(dir, dentry);
449 if (error) 444 if (error)
450 goto out_drop_write; 445 goto out_drop_write;
451 446
452 /* 447 down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
453 * Actually perform the low-level subvolume creation after all 448
454 * this VFS fuzz. 449 if (btrfs_root_refs(&BTRFS_I(dir)->root->root_item) == 0)
455 * 450 goto out_up_read;
456 * Eventually we want to pass in an inode under which we create this 451
457 * subvolume, but for now all are under the filesystem root.
458 *
459 * Also we should pass on the mode eventually to allow creating new
460 * subvolume with specific mode bits.
461 */
462 if (snap_src) { 452 if (snap_src) {
463 struct dentry *dir = dentry->d_parent; 453 error = create_snapshot(snap_src, dentry,
464 struct dentry *test = dir->d_parent; 454 name, namelen);
465 struct btrfs_path *path = btrfs_alloc_path();
466 int ret;
467 u64 test_oid;
468 u64 parent_oid = BTRFS_I(dir->d_inode)->root->root_key.objectid;
469
470 test_oid = snap_src->root_key.objectid;
471
472 ret = btrfs_find_root_ref(snap_src->fs_info->tree_root,
473 path, parent_oid, test_oid);
474 if (ret == 0)
475 goto create;
476 btrfs_release_path(snap_src->fs_info->tree_root, path);
477
478 /* we need to make sure we aren't creating a directory loop
479 * by taking a snapshot of something that has our current
480 * subvol in its directory tree. So, this loops through
481 * the dentries and checks the forward refs for each subvolume
482 * to see if is references the subvolume where we are
483 * placing this new snapshot.
484 */
485 while (1) {
486 if (!test ||
487 dir == snap_src->fs_info->sb->s_root ||
488 test == snap_src->fs_info->sb->s_root ||
489 test->d_inode->i_sb != snap_src->fs_info->sb) {
490 break;
491 }
492 if (S_ISLNK(test->d_inode->i_mode)) {
493 printk(KERN_INFO "Btrfs symlink in snapshot "
494 "path, failed\n");
495 error = -EMLINK;
496 btrfs_free_path(path);
497 goto out_drop_write;
498 }
499 test_oid =
500 BTRFS_I(test->d_inode)->root->root_key.objectid;
501 ret = btrfs_find_root_ref(snap_src->fs_info->tree_root,
502 path, test_oid, parent_oid);
503 if (ret == 0) {
504 printk(KERN_INFO "Btrfs snapshot creation "
505 "failed, looping\n");
506 error = -EMLINK;
507 btrfs_free_path(path);
508 goto out_drop_write;
509 }
510 btrfs_release_path(snap_src->fs_info->tree_root, path);
511 test = test->d_parent;
512 }
513create:
514 btrfs_free_path(path);
515 error = create_snapshot(snap_src, dentry, name, namelen);
516 } else { 455 } else {
517 error = create_subvol(BTRFS_I(parent->dentry->d_inode)->root, 456 error = create_subvol(BTRFS_I(dir)->root, dentry,
518 dentry, name, namelen); 457 name, namelen);
519 } 458 }
520 if (error) 459 if (!error)
521 goto out_drop_write; 460 fsnotify_mkdir(dir, dentry);
522 461out_up_read:
523 fsnotify_mkdir(parent->dentry->d_inode, dentry); 462 up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem);
524out_drop_write: 463out_drop_write:
525 mnt_drop_write(parent->mnt); 464 mnt_drop_write(parent->mnt);
526out_dput: 465out_dput:
527 dput(dentry); 466 dput(dentry);
528out_unlock: 467out_unlock:
529 mutex_unlock(&parent->dentry->d_inode->i_mutex); 468 mutex_unlock(&dir->i_mutex);
530 return error; 469 return error;
531} 470}
532 471
533
534static int btrfs_defrag_file(struct file *file) 472static int btrfs_defrag_file(struct file *file)
535{ 473{
536 struct inode *inode = fdentry(file)->d_inode; 474 struct inode *inode = fdentry(file)->d_inode;
@@ -596,9 +534,8 @@ again:
596 clear_page_dirty_for_io(page); 534 clear_page_dirty_for_io(page);
597 535
598 btrfs_set_extent_delalloc(inode, page_start, page_end); 536 btrfs_set_extent_delalloc(inode, page_start, page_end);
599
600 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
601 set_page_dirty(page); 537 set_page_dirty(page);
538 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
602 unlock_page(page); 539 unlock_page(page);
603 page_cache_release(page); 540 page_cache_release(page);
604 balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); 541 balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1);
@@ -609,7 +546,8 @@ out_unlock:
609 return 0; 546 return 0;
610} 547}
611 548
612static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) 549static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
550 void __user *arg)
613{ 551{
614 u64 new_size; 552 u64 new_size;
615 u64 old_size; 553 u64 old_size;
@@ -718,10 +656,7 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
718{ 656{
719 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; 657 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root;
720 struct btrfs_ioctl_vol_args *vol_args; 658 struct btrfs_ioctl_vol_args *vol_args;
721 struct btrfs_dir_item *di;
722 struct btrfs_path *path;
723 struct file *src_file; 659 struct file *src_file;
724 u64 root_dirid;
725 int namelen; 660 int namelen;
726 int ret = 0; 661 int ret = 0;
727 662
@@ -739,32 +674,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
739 goto out; 674 goto out;
740 } 675 }
741 676
742 path = btrfs_alloc_path();
743 if (!path) {
744 ret = -ENOMEM;
745 goto out;
746 }
747
748 root_dirid = root->fs_info->sb->s_root->d_inode->i_ino,
749 di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root,
750 path, root_dirid,
751 vol_args->name, namelen, 0);
752 btrfs_free_path(path);
753
754 if (di && !IS_ERR(di)) {
755 ret = -EEXIST;
756 goto out;
757 }
758
759 if (IS_ERR(di)) {
760 ret = PTR_ERR(di);
761 goto out;
762 }
763
764 if (subvol) { 677 if (subvol) {
765 ret = btrfs_mksubvol(&file->f_path, vol_args->name, 678 ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen,
766 file->f_path.dentry->d_inode->i_mode, 679 NULL);
767 namelen, NULL);
768 } else { 680 } else {
769 struct inode *src_inode; 681 struct inode *src_inode;
770 src_file = fget(vol_args->fd); 682 src_file = fget(vol_args->fd);
@@ -781,17 +693,157 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
781 fput(src_file); 693 fput(src_file);
782 goto out; 694 goto out;
783 } 695 }
784 ret = btrfs_mksubvol(&file->f_path, vol_args->name, 696 ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen,
785 file->f_path.dentry->d_inode->i_mode, 697 BTRFS_I(src_inode)->root);
786 namelen, BTRFS_I(src_inode)->root);
787 fput(src_file); 698 fput(src_file);
788 } 699 }
789
790out: 700out:
791 kfree(vol_args); 701 kfree(vol_args);
792 return ret; 702 return ret;
793} 703}
794 704
705/*
706 * helper to check if the subvolume references other subvolumes
707 */
708static noinline int may_destroy_subvol(struct btrfs_root *root)
709{
710 struct btrfs_path *path;
711 struct btrfs_key key;
712 int ret;
713
714 path = btrfs_alloc_path();
715 if (!path)
716 return -ENOMEM;
717
718 key.objectid = root->root_key.objectid;
719 key.type = BTRFS_ROOT_REF_KEY;
720 key.offset = (u64)-1;
721
722 ret = btrfs_search_slot(NULL, root->fs_info->tree_root,
723 &key, path, 0, 0);
724 if (ret < 0)
725 goto out;
726 BUG_ON(ret == 0);
727
728 ret = 0;
729 if (path->slots[0] > 0) {
730 path->slots[0]--;
731 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
732 if (key.objectid == root->root_key.objectid &&
733 key.type == BTRFS_ROOT_REF_KEY)
734 ret = -ENOTEMPTY;
735 }
736out:
737 btrfs_free_path(path);
738 return ret;
739}
740
741static noinline int btrfs_ioctl_snap_destroy(struct file *file,
742 void __user *arg)
743{
744 struct dentry *parent = fdentry(file);
745 struct dentry *dentry;
746 struct inode *dir = parent->d_inode;
747 struct inode *inode;
748 struct btrfs_root *root = BTRFS_I(dir)->root;
749 struct btrfs_root *dest = NULL;
750 struct btrfs_ioctl_vol_args *vol_args;
751 struct btrfs_trans_handle *trans;
752 int namelen;
753 int ret;
754 int err = 0;
755
756 if (!capable(CAP_SYS_ADMIN))
757 return -EPERM;
758
759 vol_args = memdup_user(arg, sizeof(*vol_args));
760 if (IS_ERR(vol_args))
761 return PTR_ERR(vol_args);
762
763 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
764 namelen = strlen(vol_args->name);
765 if (strchr(vol_args->name, '/') ||
766 strncmp(vol_args->name, "..", namelen) == 0) {
767 err = -EINVAL;
768 goto out;
769 }
770
771 err = mnt_want_write(file->f_path.mnt);
772 if (err)
773 goto out;
774
775 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
776 dentry = lookup_one_len(vol_args->name, parent, namelen);
777 if (IS_ERR(dentry)) {
778 err = PTR_ERR(dentry);
779 goto out_unlock_dir;
780 }
781
782 if (!dentry->d_inode) {
783 err = -ENOENT;
784 goto out_dput;
785 }
786
787 inode = dentry->d_inode;
788 if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) {
789 err = -EINVAL;
790 goto out_dput;
791 }
792
793 dest = BTRFS_I(inode)->root;
794
795 mutex_lock(&inode->i_mutex);
796 err = d_invalidate(dentry);
797 if (err)
798 goto out_unlock;
799
800 down_write(&root->fs_info->subvol_sem);
801
802 err = may_destroy_subvol(dest);
803 if (err)
804 goto out_up_write;
805
806 trans = btrfs_start_transaction(root, 1);
807 ret = btrfs_unlink_subvol(trans, root, dir,
808 dest->root_key.objectid,
809 dentry->d_name.name,
810 dentry->d_name.len);
811 BUG_ON(ret);
812
813 btrfs_record_root_in_trans(trans, dest);
814
815 memset(&dest->root_item.drop_progress, 0,
816 sizeof(dest->root_item.drop_progress));
817 dest->root_item.drop_level = 0;
818 btrfs_set_root_refs(&dest->root_item, 0);
819
820 ret = btrfs_insert_orphan_item(trans,
821 root->fs_info->tree_root,
822 dest->root_key.objectid);
823 BUG_ON(ret);
824
825 ret = btrfs_commit_transaction(trans, root);
826 BUG_ON(ret);
827 inode->i_flags |= S_DEAD;
828out_up_write:
829 up_write(&root->fs_info->subvol_sem);
830out_unlock:
831 mutex_unlock(&inode->i_mutex);
832 if (!err) {
833 shrink_dcache_sb(root->fs_info->sb);
834 btrfs_invalidate_inodes(dest);
835 d_delete(dentry);
836 }
837out_dput:
838 dput(dentry);
839out_unlock_dir:
840 mutex_unlock(&dir->i_mutex);
841 mnt_drop_write(file->f_path.mnt);
842out:
843 kfree(vol_args);
844 return err;
845}
846
795static int btrfs_ioctl_defrag(struct file *file) 847static int btrfs_ioctl_defrag(struct file *file)
796{ 848{
797 struct inode *inode = fdentry(file)->d_inode; 849 struct inode *inode = fdentry(file)->d_inode;
@@ -865,8 +917,8 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
865 return ret; 917 return ret;
866} 918}
867 919
868static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, 920static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
869 u64 off, u64 olen, u64 destoff) 921 u64 off, u64 olen, u64 destoff)
870{ 922{
871 struct inode *inode = fdentry(file)->d_inode; 923 struct inode *inode = fdentry(file)->d_inode;
872 struct btrfs_root *root = BTRFS_I(inode)->root; 924 struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -976,7 +1028,7 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
976 1028
977 /* punch hole in destination first */ 1029 /* punch hole in destination first */
978 btrfs_drop_extents(trans, root, inode, off, off + len, 1030 btrfs_drop_extents(trans, root, inode, off, off + len,
979 off + len, 0, &hint_byte); 1031 off + len, 0, &hint_byte, 1);
980 1032
981 /* clone data */ 1033 /* clone data */
982 key.objectid = src->i_ino; 1034 key.objectid = src->i_ino;
@@ -1071,9 +1123,10 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
1071 datao += off - key.offset; 1123 datao += off - key.offset;
1072 datal -= off - key.offset; 1124 datal -= off - key.offset;
1073 } 1125 }
1074 if (key.offset + datao + datal + key.offset > 1126
1075 off + len) 1127 if (key.offset + datal > off + len)
1076 datal = off + len - key.offset - datao; 1128 datal = off + len - key.offset;
1129
1077 /* disko == 0 means it's a hole */ 1130 /* disko == 0 means it's a hole */
1078 if (!disko) 1131 if (!disko)
1079 datao = 0; 1132 datao = 0;
@@ -1182,15 +1235,15 @@ static long btrfs_ioctl_trans_start(struct file *file)
1182 struct inode *inode = fdentry(file)->d_inode; 1235 struct inode *inode = fdentry(file)->d_inode;
1183 struct btrfs_root *root = BTRFS_I(inode)->root; 1236 struct btrfs_root *root = BTRFS_I(inode)->root;
1184 struct btrfs_trans_handle *trans; 1237 struct btrfs_trans_handle *trans;
1185 int ret = 0; 1238 int ret;
1186 1239
1240 ret = -EPERM;
1187 if (!capable(CAP_SYS_ADMIN)) 1241 if (!capable(CAP_SYS_ADMIN))
1188 return -EPERM; 1242 goto out;
1189 1243
1190 if (file->private_data) { 1244 ret = -EINPROGRESS;
1191 ret = -EINPROGRESS; 1245 if (file->private_data)
1192 goto out; 1246 goto out;
1193 }
1194 1247
1195 ret = mnt_want_write(file->f_path.mnt); 1248 ret = mnt_want_write(file->f_path.mnt);
1196 if (ret) 1249 if (ret)
@@ -1200,12 +1253,19 @@ static long btrfs_ioctl_trans_start(struct file *file)
1200 root->fs_info->open_ioctl_trans++; 1253 root->fs_info->open_ioctl_trans++;
1201 mutex_unlock(&root->fs_info->trans_mutex); 1254 mutex_unlock(&root->fs_info->trans_mutex);
1202 1255
1256 ret = -ENOMEM;
1203 trans = btrfs_start_ioctl_transaction(root, 0); 1257 trans = btrfs_start_ioctl_transaction(root, 0);
1204 if (trans) 1258 if (!trans)
1205 file->private_data = trans; 1259 goto out_drop;
1206 else 1260
1207 ret = -ENOMEM; 1261 file->private_data = trans;
1208 /*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/ 1262 return 0;
1263
1264out_drop:
1265 mutex_lock(&root->fs_info->trans_mutex);
1266 root->fs_info->open_ioctl_trans--;
1267 mutex_unlock(&root->fs_info->trans_mutex);
1268 mnt_drop_write(file->f_path.mnt);
1209out: 1269out:
1210 return ret; 1270 return ret;
1211} 1271}
@@ -1221,24 +1281,20 @@ long btrfs_ioctl_trans_end(struct file *file)
1221 struct inode *inode = fdentry(file)->d_inode; 1281 struct inode *inode = fdentry(file)->d_inode;
1222 struct btrfs_root *root = BTRFS_I(inode)->root; 1282 struct btrfs_root *root = BTRFS_I(inode)->root;
1223 struct btrfs_trans_handle *trans; 1283 struct btrfs_trans_handle *trans;
1224 int ret = 0;
1225 1284
1226 trans = file->private_data; 1285 trans = file->private_data;
1227 if (!trans) { 1286 if (!trans)
1228 ret = -EINVAL; 1287 return -EINVAL;
1229 goto out;
1230 }
1231 btrfs_end_transaction(trans, root);
1232 file->private_data = NULL; 1288 file->private_data = NULL;
1233 1289
1290 btrfs_end_transaction(trans, root);
1291
1234 mutex_lock(&root->fs_info->trans_mutex); 1292 mutex_lock(&root->fs_info->trans_mutex);
1235 root->fs_info->open_ioctl_trans--; 1293 root->fs_info->open_ioctl_trans--;
1236 mutex_unlock(&root->fs_info->trans_mutex); 1294 mutex_unlock(&root->fs_info->trans_mutex);
1237 1295
1238 mnt_drop_write(file->f_path.mnt); 1296 mnt_drop_write(file->f_path.mnt);
1239 1297 return 0;
1240out:
1241 return ret;
1242} 1298}
1243 1299
1244long btrfs_ioctl(struct file *file, unsigned int 1300long btrfs_ioctl(struct file *file, unsigned int
@@ -1258,6 +1314,8 @@ long btrfs_ioctl(struct file *file, unsigned int
1258 return btrfs_ioctl_snap_create(file, argp, 0); 1314 return btrfs_ioctl_snap_create(file, argp, 0);
1259 case BTRFS_IOC_SUBVOL_CREATE: 1315 case BTRFS_IOC_SUBVOL_CREATE:
1260 return btrfs_ioctl_snap_create(file, argp, 1); 1316 return btrfs_ioctl_snap_create(file, argp, 1);
1317 case BTRFS_IOC_SNAP_DESTROY:
1318 return btrfs_ioctl_snap_destroy(file, argp);
1261 case BTRFS_IOC_DEFRAG: 1319 case BTRFS_IOC_DEFRAG:
1262 return btrfs_ioctl_defrag(file); 1320 return btrfs_ioctl_defrag(file);
1263 case BTRFS_IOC_RESIZE: 1321 case BTRFS_IOC_RESIZE: