aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2009-09-21 16:00:26 -0400
committerChris Mason <chris.mason@oracle.com>2009-09-21 16:00:26 -0400
commit76dda93c6ae2c1dc3e6cde34569d6aca26b0c918 (patch)
treef5ca46ec89d4ae2c762952d5f35e2c6f95ac046a /fs/btrfs/disk-io.c
parent4df27c4d5cc1dda54ed7d0a8389347f2df359cf9 (diff)
Btrfs: add snapshot/subvolume destroy ioctl
This patch adds snapshot/subvolume destroy ioctl. A subvolume that isn't being used and doesn't contains links to other subvolumes can be destroyed. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c81
1 files changed, 62 insertions, 19 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a4f531047c4..a0d41e713f3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1378,8 +1378,10 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
1378 1378
1379 err = bdi_register(bdi, NULL, "btrfs-%d", 1379 err = bdi_register(bdi, NULL, "btrfs-%d",
1380 atomic_inc_return(&btrfs_bdi_num)); 1380 atomic_inc_return(&btrfs_bdi_num));
1381 if (err) 1381 if (err) {
1382 bdi_destroy(bdi);
1382 return err; 1383 return err;
1384 }
1383 1385
1384 bdi->ra_pages = default_backing_dev_info.ra_pages; 1386 bdi->ra_pages = default_backing_dev_info.ra_pages;
1385 bdi->unplug_io_fn = btrfs_unplug_io_fn; 1387 bdi->unplug_io_fn = btrfs_unplug_io_fn;
@@ -1469,9 +1471,12 @@ static int cleaner_kthread(void *arg)
1469 break; 1471 break;
1470 1472
1471 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); 1473 vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
1472 mutex_lock(&root->fs_info->cleaner_mutex); 1474
1473 btrfs_clean_old_snapshots(root); 1475 if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
1474 mutex_unlock(&root->fs_info->cleaner_mutex); 1476 mutex_trylock(&root->fs_info->cleaner_mutex)) {
1477 btrfs_clean_old_snapshots(root);
1478 mutex_unlock(&root->fs_info->cleaner_mutex);
1479 }
1475 1480
1476 if (freezing(current)) { 1481 if (freezing(current)) {
1477 refrigerator(); 1482 refrigerator();
@@ -1576,7 +1581,26 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1576 err = -ENOMEM; 1581 err = -ENOMEM;
1577 goto fail; 1582 goto fail;
1578 } 1583 }
1579 INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS); 1584
1585 ret = init_srcu_struct(&fs_info->subvol_srcu);
1586 if (ret) {
1587 err = ret;
1588 goto fail;
1589 }
1590
1591 ret = setup_bdi(fs_info, &fs_info->bdi);
1592 if (ret) {
1593 err = ret;
1594 goto fail_srcu;
1595 }
1596
1597 fs_info->btree_inode = new_inode(sb);
1598 if (!fs_info->btree_inode) {
1599 err = -ENOMEM;
1600 goto fail_bdi;
1601 }
1602
1603 INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
1580 INIT_LIST_HEAD(&fs_info->trans_list); 1604 INIT_LIST_HEAD(&fs_info->trans_list);
1581 INIT_LIST_HEAD(&fs_info->dead_roots); 1605 INIT_LIST_HEAD(&fs_info->dead_roots);
1582 INIT_LIST_HEAD(&fs_info->hashers); 1606 INIT_LIST_HEAD(&fs_info->hashers);
@@ -1586,6 +1610,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1586 spin_lock_init(&fs_info->delalloc_lock); 1610 spin_lock_init(&fs_info->delalloc_lock);
1587 spin_lock_init(&fs_info->new_trans_lock); 1611 spin_lock_init(&fs_info->new_trans_lock);
1588 spin_lock_init(&fs_info->ref_cache_lock); 1612 spin_lock_init(&fs_info->ref_cache_lock);
1613 spin_lock_init(&fs_info->fs_roots_radix_lock);
1589 1614
1590 init_completion(&fs_info->kobj_unregister); 1615 init_completion(&fs_info->kobj_unregister);
1591 fs_info->tree_root = tree_root; 1616 fs_info->tree_root = tree_root;
@@ -1604,11 +1629,6 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1604 fs_info->sb = sb; 1629 fs_info->sb = sb;
1605 fs_info->max_extent = (u64)-1; 1630 fs_info->max_extent = (u64)-1;
1606 fs_info->max_inline = 8192 * 1024; 1631 fs_info->max_inline = 8192 * 1024;
1607 if (setup_bdi(fs_info, &fs_info->bdi))
1608 goto fail_bdi;
1609 fs_info->btree_inode = new_inode(sb);
1610 fs_info->btree_inode->i_ino = 1;
1611 fs_info->btree_inode->i_nlink = 1;
1612 fs_info->metadata_ratio = 8; 1632 fs_info->metadata_ratio = 8;
1613 1633
1614 fs_info->thread_pool_size = min_t(unsigned long, 1634 fs_info->thread_pool_size = min_t(unsigned long,
@@ -1620,6 +1640,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1620 sb->s_blocksize = 4096; 1640 sb->s_blocksize = 4096;
1621 sb->s_blocksize_bits = blksize_bits(4096); 1641 sb->s_blocksize_bits = blksize_bits(4096);
1622 1642
1643 fs_info->btree_inode->i_ino = BTRFS_BTREE_INODE_OBJECTID;
1644 fs_info->btree_inode->i_nlink = 1;
1623 /* 1645 /*
1624 * we set the i_size on the btree inode to the max possible int. 1646 * we set the i_size on the btree inode to the max possible int.
1625 * the real end of the address space is determined by all of 1647 * the real end of the address space is determined by all of
@@ -1638,6 +1660,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1638 1660
1639 BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; 1661 BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops;
1640 1662
1663 BTRFS_I(fs_info->btree_inode)->root = tree_root;
1664 memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
1665 sizeof(struct btrfs_key));
1666 BTRFS_I(fs_info->btree_inode)->dummy_inode = 1;
1667
1641 spin_lock_init(&fs_info->block_group_cache_lock); 1668 spin_lock_init(&fs_info->block_group_cache_lock);
1642 fs_info->block_group_cache_tree.rb_node = NULL; 1669 fs_info->block_group_cache_tree.rb_node = NULL;
1643 1670
@@ -1648,21 +1675,16 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1648 fs_info->pinned_extents = &fs_info->freed_extents[0]; 1675 fs_info->pinned_extents = &fs_info->freed_extents[0];
1649 fs_info->do_barriers = 1; 1676 fs_info->do_barriers = 1;
1650 1677
1651 BTRFS_I(fs_info->btree_inode)->root = tree_root;
1652 memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
1653 sizeof(struct btrfs_key));
1654 insert_inode_hash(fs_info->btree_inode);
1655 1678
1656 mutex_init(&fs_info->trans_mutex); 1679 mutex_init(&fs_info->trans_mutex);
1657 mutex_init(&fs_info->ordered_operations_mutex); 1680 mutex_init(&fs_info->ordered_operations_mutex);
1658 mutex_init(&fs_info->tree_log_mutex); 1681 mutex_init(&fs_info->tree_log_mutex);
1659 mutex_init(&fs_info->drop_mutex);
1660 mutex_init(&fs_info->chunk_mutex); 1682 mutex_init(&fs_info->chunk_mutex);
1661 mutex_init(&fs_info->transaction_kthread_mutex); 1683 mutex_init(&fs_info->transaction_kthread_mutex);
1662 mutex_init(&fs_info->cleaner_mutex); 1684 mutex_init(&fs_info->cleaner_mutex);
1663 mutex_init(&fs_info->volume_mutex); 1685 mutex_init(&fs_info->volume_mutex);
1664 mutex_init(&fs_info->tree_reloc_mutex);
1665 init_rwsem(&fs_info->extent_commit_sem); 1686 init_rwsem(&fs_info->extent_commit_sem);
1687 init_rwsem(&fs_info->subvol_sem);
1666 1688
1667 btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); 1689 btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
1668 btrfs_init_free_cluster(&fs_info->data_alloc_cluster); 1690 btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
@@ -1941,6 +1963,9 @@ printk("thread pool is %d\n", fs_info->thread_pool_size);
1941 } 1963 }
1942 } 1964 }
1943 1965
1966 ret = btrfs_find_orphan_roots(tree_root);
1967 BUG_ON(ret);
1968
1944 if (!(sb->s_flags & MS_RDONLY)) { 1969 if (!(sb->s_flags & MS_RDONLY)) {
1945 ret = btrfs_recover_relocation(tree_root); 1970 ret = btrfs_recover_relocation(tree_root);
1946 BUG_ON(ret); 1971 BUG_ON(ret);
@@ -2000,6 +2025,8 @@ fail_iput:
2000 btrfs_mapping_tree_free(&fs_info->mapping_tree); 2025 btrfs_mapping_tree_free(&fs_info->mapping_tree);
2001fail_bdi: 2026fail_bdi:
2002 bdi_destroy(&fs_info->bdi); 2027 bdi_destroy(&fs_info->bdi);
2028fail_srcu:
2029 cleanup_srcu_struct(&fs_info->subvol_srcu);
2003fail: 2030fail:
2004 kfree(extent_root); 2031 kfree(extent_root);
2005 kfree(tree_root); 2032 kfree(tree_root);
@@ -2263,6 +2290,10 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
2263 radix_tree_delete(&fs_info->fs_roots_radix, 2290 radix_tree_delete(&fs_info->fs_roots_radix,
2264 (unsigned long)root->root_key.objectid); 2291 (unsigned long)root->root_key.objectid);
2265 spin_unlock(&fs_info->fs_roots_radix_lock); 2292 spin_unlock(&fs_info->fs_roots_radix_lock);
2293
2294 if (btrfs_root_refs(&root->root_item) == 0)
2295 synchronize_srcu(&fs_info->subvol_srcu);
2296
2266 free_fs_root(root); 2297 free_fs_root(root);
2267 return 0; 2298 return 0;
2268} 2299}
@@ -2286,6 +2317,20 @@ static int del_fs_roots(struct btrfs_fs_info *fs_info)
2286 struct btrfs_root *gang[8]; 2317 struct btrfs_root *gang[8];
2287 int i; 2318 int i;
2288 2319
2320 while (!list_empty(&fs_info->dead_roots)) {
2321 gang[0] = list_entry(fs_info->dead_roots.next,
2322 struct btrfs_root, root_list);
2323 list_del(&gang[0]->root_list);
2324
2325 if (gang[0]->in_radix) {
2326 btrfs_free_fs_root(fs_info, gang[0]);
2327 } else {
2328 free_extent_buffer(gang[0]->node);
2329 free_extent_buffer(gang[0]->commit_root);
2330 kfree(gang[0]);
2331 }
2332 }
2333
2289 while (1) { 2334 while (1) {
2290 ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, 2335 ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
2291 (void **)gang, 0, 2336 (void **)gang, 0,
@@ -2315,9 +2360,6 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
2315 root_objectid = gang[ret - 1]->root_key.objectid + 1; 2360 root_objectid = gang[ret - 1]->root_key.objectid + 1;
2316 for (i = 0; i < ret; i++) { 2361 for (i = 0; i < ret; i++) {
2317 root_objectid = gang[i]->root_key.objectid; 2362 root_objectid = gang[i]->root_key.objectid;
2318 ret = btrfs_find_dead_roots(fs_info->tree_root,
2319 root_objectid);
2320 BUG_ON(ret);
2321 btrfs_orphan_cleanup(gang[i]); 2363 btrfs_orphan_cleanup(gang[i]);
2322 } 2364 }
2323 root_objectid++; 2365 root_objectid++;
@@ -2405,6 +2447,7 @@ int close_ctree(struct btrfs_root *root)
2405 btrfs_mapping_tree_free(&fs_info->mapping_tree); 2447 btrfs_mapping_tree_free(&fs_info->mapping_tree);
2406 2448
2407 bdi_destroy(&fs_info->bdi); 2449 bdi_destroy(&fs_info->bdi);
2450 cleanup_srcu_struct(&fs_info->subvol_srcu);
2408 2451
2409 kfree(fs_info->extent_root); 2452 kfree(fs_info->extent_root);
2410 kfree(fs_info->tree_root); 2453 kfree(fs_info->tree_root);