diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 12 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 81 | ||||
| -rw-r--r-- | fs/btrfs/export.c | 133 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 21 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 134 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 320 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/relocation.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/root-tree.c | 69 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 10 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 13 |
12 files changed, 605 insertions, 233 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 6ade48b227e9..bc57e236ac64 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -839,9 +839,7 @@ struct btrfs_fs_info { | |||
| 839 | struct mutex transaction_kthread_mutex; | 839 | struct mutex transaction_kthread_mutex; |
| 840 | struct mutex cleaner_mutex; | 840 | struct mutex cleaner_mutex; |
| 841 | struct mutex chunk_mutex; | 841 | struct mutex chunk_mutex; |
| 842 | struct mutex drop_mutex; | ||
| 843 | struct mutex volume_mutex; | 842 | struct mutex volume_mutex; |
| 844 | struct mutex tree_reloc_mutex; | ||
| 845 | /* | 843 | /* |
| 846 | * this protects the ordered operations list only while we are | 844 | * this protects the ordered operations list only while we are |
| 847 | * processing all of the entries on it. This way we make | 845 | * processing all of the entries on it. This way we make |
| @@ -852,6 +850,10 @@ struct btrfs_fs_info { | |||
| 852 | struct mutex ordered_operations_mutex; | 850 | struct mutex ordered_operations_mutex; |
| 853 | struct rw_semaphore extent_commit_sem; | 851 | struct rw_semaphore extent_commit_sem; |
| 854 | 852 | ||
| 853 | struct rw_semaphore subvol_sem; | ||
| 854 | |||
| 855 | struct srcu_struct subvol_srcu; | ||
| 856 | |||
| 855 | struct list_head trans_list; | 857 | struct list_head trans_list; |
| 856 | struct list_head hashers; | 858 | struct list_head hashers; |
| 857 | struct list_head dead_roots; | 859 | struct list_head dead_roots; |
| @@ -2142,6 +2144,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct | |||
| 2142 | int btrfs_search_root(struct btrfs_root *root, u64 search_start, | 2144 | int btrfs_search_root(struct btrfs_root *root, u64 search_start, |
| 2143 | u64 *found_objectid); | 2145 | u64 *found_objectid); |
| 2144 | int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); | 2146 | int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); |
| 2147 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root); | ||
| 2145 | int btrfs_set_root_node(struct btrfs_root_item *item, | 2148 | int btrfs_set_root_node(struct btrfs_root_item *item, |
| 2146 | struct extent_buffer *node); | 2149 | struct extent_buffer *node); |
| 2147 | /* dir-item.c */ | 2150 | /* dir-item.c */ |
| @@ -2273,7 +2276,7 @@ int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); | |||
| 2273 | int btrfs_writepages(struct address_space *mapping, | 2276 | int btrfs_writepages(struct address_space *mapping, |
| 2274 | struct writeback_control *wbc); | 2277 | struct writeback_control *wbc); |
| 2275 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 2278 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
| 2276 | struct btrfs_root *new_root, struct dentry *dentry, | 2279 | struct btrfs_root *new_root, |
| 2277 | u64 new_dirid, u64 alloc_hint); | 2280 | u64 new_dirid, u64 alloc_hint); |
| 2278 | int btrfs_merge_bio_hook(struct page *page, unsigned long offset, | 2281 | int btrfs_merge_bio_hook(struct page *page, unsigned long offset, |
| 2279 | size_t size, struct bio *bio, unsigned long bio_flags); | 2282 | size_t size, struct bio *bio, unsigned long bio_flags); |
| @@ -2289,6 +2292,7 @@ int btrfs_write_inode(struct inode *inode, int wait); | |||
| 2289 | void btrfs_dirty_inode(struct inode *inode); | 2292 | void btrfs_dirty_inode(struct inode *inode); |
| 2290 | struct inode *btrfs_alloc_inode(struct super_block *sb); | 2293 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
| 2291 | void btrfs_destroy_inode(struct inode *inode); | 2294 | void btrfs_destroy_inode(struct inode *inode); |
| 2295 | void btrfs_drop_inode(struct inode *inode); | ||
| 2292 | int btrfs_init_cachep(void); | 2296 | int btrfs_init_cachep(void); |
| 2293 | void btrfs_destroy_cachep(void); | 2297 | void btrfs_destroy_cachep(void); |
| 2294 | long btrfs_ioctl_trans_end(struct file *file); | 2298 | long btrfs_ioctl_trans_end(struct file *file); |
| @@ -2306,6 +2310,8 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode); | |||
| 2306 | int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); | 2310 | int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); |
| 2307 | void btrfs_orphan_cleanup(struct btrfs_root *root); | 2311 | void btrfs_orphan_cleanup(struct btrfs_root *root); |
| 2308 | int btrfs_cont_expand(struct inode *inode, loff_t size); | 2312 | int btrfs_cont_expand(struct inode *inode, loff_t size); |
| 2313 | int btrfs_invalidate_inodes(struct btrfs_root *root); | ||
| 2314 | extern struct dentry_operations btrfs_dentry_operations; | ||
| 2309 | 2315 | ||
| 2310 | /* ioctl.c */ | 2316 | /* ioctl.c */ |
| 2311 | long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 2317 | long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a4f531047c4a..a0d41e713f3c 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); |
| 2001 | fail_bdi: | 2026 | fail_bdi: |
| 2002 | bdi_destroy(&fs_info->bdi); | 2027 | bdi_destroy(&fs_info->bdi); |
| 2028 | fail_srcu: | ||
| 2029 | cleanup_srcu_struct(&fs_info->subvol_srcu); | ||
| 2003 | fail: | 2030 | fail: |
| 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); |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 9596b40caa4e..ba5c3fd5ab8c 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -28,7 +28,7 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
| 28 | len = BTRFS_FID_SIZE_NON_CONNECTABLE; | 28 | len = BTRFS_FID_SIZE_NON_CONNECTABLE; |
| 29 | type = FILEID_BTRFS_WITHOUT_PARENT; | 29 | type = FILEID_BTRFS_WITHOUT_PARENT; |
| 30 | 30 | ||
| 31 | fid->objectid = BTRFS_I(inode)->location.objectid; | 31 | fid->objectid = inode->i_ino; |
| 32 | fid->root_objectid = BTRFS_I(inode)->root->objectid; | 32 | fid->root_objectid = BTRFS_I(inode)->root->objectid; |
| 33 | fid->gen = inode->i_generation; | 33 | fid->gen = inode->i_generation; |
| 34 | 34 | ||
| @@ -60,34 +60,61 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, | |||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, | 62 | static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, |
| 63 | u64 root_objectid, u32 generation) | 63 | u64 root_objectid, u32 generation, |
| 64 | int check_generation) | ||
| 64 | { | 65 | { |
| 66 | struct btrfs_fs_info *fs_info = btrfs_sb(sb)->fs_info; | ||
| 65 | struct btrfs_root *root; | 67 | struct btrfs_root *root; |
| 68 | struct dentry *dentry; | ||
| 66 | struct inode *inode; | 69 | struct inode *inode; |
| 67 | struct btrfs_key key; | 70 | struct btrfs_key key; |
| 71 | int index; | ||
| 72 | int err = 0; | ||
| 73 | |||
| 74 | if (objectid < BTRFS_FIRST_FREE_OBJECTID) | ||
| 75 | return ERR_PTR(-ESTALE); | ||
| 68 | 76 | ||
| 69 | key.objectid = root_objectid; | 77 | key.objectid = root_objectid; |
| 70 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | 78 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); |
| 71 | key.offset = (u64)-1; | 79 | key.offset = (u64)-1; |
| 72 | 80 | ||
| 73 | root = btrfs_read_fs_root_no_name(btrfs_sb(sb)->fs_info, &key); | 81 | index = srcu_read_lock(&fs_info->subvol_srcu); |
| 74 | if (IS_ERR(root)) | 82 | |
| 75 | return ERR_CAST(root); | 83 | root = btrfs_read_fs_root_no_name(fs_info, &key); |
| 84 | if (IS_ERR(root)) { | ||
| 85 | err = PTR_ERR(root); | ||
| 86 | goto fail; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (btrfs_root_refs(&root->root_item) == 0) { | ||
| 90 | err = -ENOENT; | ||
| 91 | goto fail; | ||
| 92 | } | ||
| 76 | 93 | ||
| 77 | key.objectid = objectid; | 94 | key.objectid = objectid; |
| 78 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 95 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
| 79 | key.offset = 0; | 96 | key.offset = 0; |
| 80 | 97 | ||
| 81 | inode = btrfs_iget(sb, &key, root); | 98 | inode = btrfs_iget(sb, &key, root); |
| 82 | if (IS_ERR(inode)) | 99 | if (IS_ERR(inode)) { |
| 83 | return (void *)inode; | 100 | err = PTR_ERR(inode); |
| 101 | goto fail; | ||
| 102 | } | ||
| 103 | |||
| 104 | srcu_read_unlock(&fs_info->subvol_srcu, index); | ||
| 84 | 105 | ||
| 85 | if (generation != inode->i_generation) { | 106 | if (check_generation && generation != inode->i_generation) { |
| 86 | iput(inode); | 107 | iput(inode); |
| 87 | return ERR_PTR(-ESTALE); | 108 | return ERR_PTR(-ESTALE); |
| 88 | } | 109 | } |
| 89 | 110 | ||
| 90 | return d_obtain_alias(inode); | 111 | dentry = d_obtain_alias(inode); |
| 112 | if (!IS_ERR(dentry)) | ||
| 113 | dentry->d_op = &btrfs_dentry_operations; | ||
| 114 | return dentry; | ||
| 115 | fail: | ||
| 116 | srcu_read_unlock(&fs_info->subvol_srcu, index); | ||
| 117 | return ERR_PTR(err); | ||
| 91 | } | 118 | } |
| 92 | 119 | ||
| 93 | static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh, | 120 | static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh, |
| @@ -111,7 +138,7 @@ static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh, | |||
| 111 | objectid = fid->parent_objectid; | 138 | objectid = fid->parent_objectid; |
| 112 | generation = fid->parent_gen; | 139 | generation = fid->parent_gen; |
| 113 | 140 | ||
| 114 | return btrfs_get_dentry(sb, objectid, root_objectid, generation); | 141 | return btrfs_get_dentry(sb, objectid, root_objectid, generation, 1); |
| 115 | } | 142 | } |
| 116 | 143 | ||
| 117 | static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | 144 | static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, |
| @@ -133,66 +160,76 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | |||
| 133 | root_objectid = fid->root_objectid; | 160 | root_objectid = fid->root_objectid; |
| 134 | generation = fid->gen; | 161 | generation = fid->gen; |
| 135 | 162 | ||
| 136 | return btrfs_get_dentry(sb, objectid, root_objectid, generation); | 163 | return btrfs_get_dentry(sb, objectid, root_objectid, generation, 1); |
| 137 | } | 164 | } |
| 138 | 165 | ||
| 139 | static struct dentry *btrfs_get_parent(struct dentry *child) | 166 | static struct dentry *btrfs_get_parent(struct dentry *child) |
| 140 | { | 167 | { |
| 141 | struct inode *dir = child->d_inode; | 168 | struct inode *dir = child->d_inode; |
| 169 | static struct dentry *dentry; | ||
| 142 | struct btrfs_root *root = BTRFS_I(dir)->root; | 170 | struct btrfs_root *root = BTRFS_I(dir)->root; |
| 143 | struct btrfs_key key; | ||
| 144 | struct btrfs_path *path; | 171 | struct btrfs_path *path; |
| 145 | struct extent_buffer *leaf; | 172 | struct extent_buffer *leaf; |
| 146 | int slot; | 173 | struct btrfs_root_ref *ref; |
| 147 | u64 objectid; | 174 | struct btrfs_key key; |
| 175 | struct btrfs_key found_key; | ||
| 148 | int ret; | 176 | int ret; |
| 149 | 177 | ||
| 150 | path = btrfs_alloc_path(); | 178 | path = btrfs_alloc_path(); |
| 151 | 179 | ||
| 152 | key.objectid = dir->i_ino; | 180 | if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) { |
| 153 | btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); | 181 | key.objectid = root->root_key.objectid; |
| 154 | key.offset = (u64)-1; | 182 | key.type = BTRFS_ROOT_BACKREF_KEY; |
| 183 | key.offset = (u64)-1; | ||
| 184 | root = root->fs_info->tree_root; | ||
| 185 | } else { | ||
| 186 | key.objectid = dir->i_ino; | ||
| 187 | key.type = BTRFS_INODE_REF_KEY; | ||
| 188 | key.offset = (u64)-1; | ||
| 189 | } | ||
| 155 | 190 | ||
| 156 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 191 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 157 | if (ret < 0) { | 192 | if (ret < 0) |
| 158 | /* Error */ | 193 | goto fail; |
| 159 | btrfs_free_path(path); | 194 | |
| 160 | return ERR_PTR(ret); | 195 | BUG_ON(ret == 0); |
| 196 | if (path->slots[0] == 0) { | ||
| 197 | ret = -ENOENT; | ||
| 198 | goto fail; | ||
| 161 | } | 199 | } |
| 200 | |||
| 201 | path->slots[0]--; | ||
| 162 | leaf = path->nodes[0]; | 202 | leaf = path->nodes[0]; |
| 163 | slot = path->slots[0]; | 203 | |
| 164 | if (ret) { | 204 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
| 165 | /* btrfs_search_slot() returns the slot where we'd want to | 205 | if (found_key.objectid != key.objectid || found_key.type != key.type) { |
| 166 | insert a backref for parent inode #0xFFFFFFFFFFFFFFFF. | 206 | ret = -ENOENT; |
| 167 | The _real_ backref, telling us what the parent inode | 207 | goto fail; |
| 168 | _actually_ is, will be in the slot _before_ the one | ||
| 169 | that btrfs_search_slot() returns. */ | ||
| 170 | if (!slot) { | ||
| 171 | /* Unless there is _no_ key in the tree before... */ | ||
| 172 | btrfs_free_path(path); | ||
| 173 | return ERR_PTR(-EIO); | ||
| 174 | } | ||
| 175 | slot--; | ||
| 176 | } | 208 | } |
| 177 | 209 | ||
| 178 | btrfs_item_key_to_cpu(leaf, &key, slot); | 210 | if (found_key.type == BTRFS_ROOT_BACKREF_KEY) { |
| 211 | ref = btrfs_item_ptr(leaf, path->slots[0], | ||
| 212 | struct btrfs_root_ref); | ||
| 213 | key.objectid = btrfs_root_ref_dirid(leaf, ref); | ||
| 214 | } else { | ||
| 215 | key.objectid = found_key.offset; | ||
| 216 | } | ||
| 179 | btrfs_free_path(path); | 217 | btrfs_free_path(path); |
| 180 | 218 | ||
| 181 | if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY) | 219 | if (found_key.type == BTRFS_ROOT_BACKREF_KEY) { |
| 182 | return ERR_PTR(-EINVAL); | 220 | return btrfs_get_dentry(root->fs_info->sb, key.objectid, |
| 183 | 221 | found_key.offset, 0, 0); | |
| 184 | objectid = key.offset; | 222 | } |
| 185 | |||
| 186 | /* If we are already at the root of a subvol, return the real root */ | ||
| 187 | if (objectid == dir->i_ino) | ||
| 188 | return dget(dir->i_sb->s_root); | ||
| 189 | 223 | ||
| 190 | /* Build a new key for the inode item */ | 224 | key.type = BTRFS_INODE_ITEM_KEY; |
| 191 | key.objectid = objectid; | ||
| 192 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | ||
| 193 | key.offset = 0; | 225 | key.offset = 0; |
| 194 | 226 | dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); | |
| 195 | return d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); | 227 | if (!IS_ERR(dentry)) |
| 228 | dentry->d_op = &btrfs_dentry_operations; | ||
| 229 | return dentry; | ||
| 230 | fail: | ||
| 231 | btrfs_free_path(path); | ||
| 232 | return ERR_PTR(ret); | ||
| 196 | } | 233 | } |
| 197 | 234 | ||
| 198 | const struct export_operations btrfs_export_ops = { | 235 | const struct export_operations btrfs_export_ops = { |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 8fc922982183..4bd04f3fa8bb 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -5463,9 +5463,24 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref) | |||
| 5463 | ret = btrfs_del_root(trans, tree_root, &root->root_key); | 5463 | ret = btrfs_del_root(trans, tree_root, &root->root_key); |
| 5464 | BUG_ON(ret); | 5464 | BUG_ON(ret); |
| 5465 | 5465 | ||
| 5466 | free_extent_buffer(root->node); | 5466 | if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { |
| 5467 | free_extent_buffer(root->commit_root); | 5467 | ret = btrfs_find_last_root(tree_root, root->root_key.objectid, |
| 5468 | kfree(root); | 5468 | NULL, NULL); |
| 5469 | BUG_ON(ret < 0); | ||
| 5470 | if (ret > 0) { | ||
| 5471 | ret = btrfs_del_orphan_item(trans, tree_root, | ||
| 5472 | root->root_key.objectid); | ||
| 5473 | BUG_ON(ret); | ||
| 5474 | } | ||
| 5475 | } | ||
| 5476 | |||
| 5477 | if (root->in_radix) { | ||
| 5478 | btrfs_free_fs_root(tree_root->fs_info, root); | ||
| 5479 | } else { | ||
| 5480 | free_extent_buffer(root->node); | ||
| 5481 | free_extent_buffer(root->commit_root); | ||
| 5482 | kfree(root); | ||
| 5483 | } | ||
| 5469 | out: | 5484 | out: |
| 5470 | btrfs_end_transaction(trans, tree_root); | 5485 | btrfs_end_transaction(trans, tree_root); |
| 5471 | kfree(wc); | 5486 | kfree(wc); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6036b36789cc..db9cbd91eb4c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -3089,6 +3089,11 @@ void btrfs_delete_inode(struct inode *inode) | |||
| 3089 | } | 3089 | } |
| 3090 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 3090 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
| 3091 | 3091 | ||
| 3092 | if (inode->i_nlink > 0) { | ||
| 3093 | BUG_ON(btrfs_root_refs(&root->root_item) != 0); | ||
| 3094 | goto no_delete; | ||
| 3095 | } | ||
| 3096 | |||
| 3092 | btrfs_i_size_write(inode, 0); | 3097 | btrfs_i_size_write(inode, 0); |
| 3093 | trans = btrfs_join_transaction(root, 1); | 3098 | trans = btrfs_join_transaction(root, 1); |
| 3094 | 3099 | ||
| @@ -3225,11 +3230,13 @@ static void inode_tree_add(struct inode *inode) | |||
| 3225 | struct btrfs_inode *entry; | 3230 | struct btrfs_inode *entry; |
| 3226 | struct rb_node **p; | 3231 | struct rb_node **p; |
| 3227 | struct rb_node *parent; | 3232 | struct rb_node *parent; |
| 3228 | |||
| 3229 | again: | 3233 | again: |
| 3230 | p = &root->inode_tree.rb_node; | 3234 | p = &root->inode_tree.rb_node; |
| 3231 | parent = NULL; | 3235 | parent = NULL; |
| 3232 | 3236 | ||
| 3237 | if (hlist_unhashed(&inode->i_hash)) | ||
| 3238 | return; | ||
| 3239 | |||
| 3233 | spin_lock(&root->inode_lock); | 3240 | spin_lock(&root->inode_lock); |
| 3234 | while (*p) { | 3241 | while (*p) { |
| 3235 | parent = *p; | 3242 | parent = *p; |
| @@ -3256,13 +3263,87 @@ again: | |||
| 3256 | static void inode_tree_del(struct inode *inode) | 3263 | static void inode_tree_del(struct inode *inode) |
| 3257 | { | 3264 | { |
| 3258 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3265 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 3266 | int empty = 0; | ||
| 3259 | 3267 | ||
| 3260 | spin_lock(&root->inode_lock); | 3268 | spin_lock(&root->inode_lock); |
| 3261 | if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { | 3269 | if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { |
| 3262 | rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); | 3270 | rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); |
| 3263 | RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); | 3271 | RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); |
| 3272 | empty = RB_EMPTY_ROOT(&root->inode_tree); | ||
| 3264 | } | 3273 | } |
| 3265 | spin_unlock(&root->inode_lock); | 3274 | spin_unlock(&root->inode_lock); |
| 3275 | |||
| 3276 | if (empty && btrfs_root_refs(&root->root_item) == 0) { | ||
| 3277 | synchronize_srcu(&root->fs_info->subvol_srcu); | ||
| 3278 | spin_lock(&root->inode_lock); | ||
| 3279 | empty = RB_EMPTY_ROOT(&root->inode_tree); | ||
| 3280 | spin_unlock(&root->inode_lock); | ||
| 3281 | if (empty) | ||
| 3282 | btrfs_add_dead_root(root); | ||
| 3283 | } | ||
| 3284 | } | ||
| 3285 | |||
| 3286 | int btrfs_invalidate_inodes(struct btrfs_root *root) | ||
| 3287 | { | ||
| 3288 | struct rb_node *node; | ||
| 3289 | struct rb_node *prev; | ||
| 3290 | struct btrfs_inode *entry; | ||
| 3291 | struct inode *inode; | ||
| 3292 | u64 objectid = 0; | ||
| 3293 | |||
| 3294 | WARN_ON(btrfs_root_refs(&root->root_item) != 0); | ||
| 3295 | |||
| 3296 | spin_lock(&root->inode_lock); | ||
| 3297 | again: | ||
| 3298 | node = root->inode_tree.rb_node; | ||
| 3299 | prev = NULL; | ||
| 3300 | while (node) { | ||
| 3301 | prev = node; | ||
| 3302 | entry = rb_entry(node, struct btrfs_inode, rb_node); | ||
| 3303 | |||
| 3304 | if (objectid < entry->vfs_inode.i_ino) | ||
| 3305 | node = node->rb_left; | ||
| 3306 | else if (objectid > entry->vfs_inode.i_ino) | ||
| 3307 | node = node->rb_right; | ||
| 3308 | else | ||
| 3309 | break; | ||
| 3310 | } | ||
| 3311 | if (!node) { | ||
| 3312 | while (prev) { | ||
| 3313 | entry = rb_entry(prev, struct btrfs_inode, rb_node); | ||
| 3314 | if (objectid <= entry->vfs_inode.i_ino) { | ||
| 3315 | node = prev; | ||
| 3316 | break; | ||
| 3317 | } | ||
| 3318 | prev = rb_next(prev); | ||
| 3319 | } | ||
| 3320 | } | ||
| 3321 | while (node) { | ||
| 3322 | entry = rb_entry(node, struct btrfs_inode, rb_node); | ||
| 3323 | objectid = entry->vfs_inode.i_ino + 1; | ||
| 3324 | inode = igrab(&entry->vfs_inode); | ||
| 3325 | if (inode) { | ||
| 3326 | spin_unlock(&root->inode_lock); | ||
| 3327 | if (atomic_read(&inode->i_count) > 1) | ||
| 3328 | d_prune_aliases(inode); | ||
| 3329 | /* | ||
| 3330 | * btrfs_drop_inode will remove it from | ||
| 3331 | * the inode cache when its usage count | ||
| 3332 | * hits zero. | ||
| 3333 | */ | ||
| 3334 | iput(inode); | ||
| 3335 | cond_resched(); | ||
| 3336 | spin_lock(&root->inode_lock); | ||
| 3337 | goto again; | ||
| 3338 | } | ||
| 3339 | |||
| 3340 | if (cond_resched_lock(&root->inode_lock)) | ||
| 3341 | goto again; | ||
| 3342 | |||
| 3343 | node = rb_next(node); | ||
| 3344 | } | ||
| 3345 | spin_unlock(&root->inode_lock); | ||
| 3346 | return 0; | ||
| 3266 | } | 3347 | } |
| 3267 | 3348 | ||
| 3268 | static noinline void init_btrfs_i(struct inode *inode) | 3349 | static noinline void init_btrfs_i(struct inode *inode) |
| @@ -3379,8 +3460,11 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 3379 | struct btrfs_root *root = BTRFS_I(dir)->root; | 3460 | struct btrfs_root *root = BTRFS_I(dir)->root; |
| 3380 | struct btrfs_root *sub_root = root; | 3461 | struct btrfs_root *sub_root = root; |
| 3381 | struct btrfs_key location; | 3462 | struct btrfs_key location; |
| 3463 | int index; | ||
| 3382 | int ret; | 3464 | int ret; |
| 3383 | 3465 | ||
| 3466 | dentry->d_op = &btrfs_dentry_operations; | ||
| 3467 | |||
| 3384 | if (dentry->d_name.len > BTRFS_NAME_LEN) | 3468 | if (dentry->d_name.len > BTRFS_NAME_LEN) |
| 3385 | return ERR_PTR(-ENAMETOOLONG); | 3469 | return ERR_PTR(-ENAMETOOLONG); |
| 3386 | 3470 | ||
| @@ -3399,6 +3483,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 3399 | 3483 | ||
| 3400 | BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); | 3484 | BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); |
| 3401 | 3485 | ||
| 3486 | index = srcu_read_lock(&root->fs_info->subvol_srcu); | ||
| 3402 | ret = fixup_tree_root_location(root, dir, dentry, | 3487 | ret = fixup_tree_root_location(root, dir, dentry, |
| 3403 | &location, &sub_root); | 3488 | &location, &sub_root); |
| 3404 | if (ret < 0) { | 3489 | if (ret < 0) { |
| @@ -3409,9 +3494,24 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
| 3409 | } else { | 3494 | } else { |
| 3410 | inode = btrfs_iget(dir->i_sb, &location, sub_root); | 3495 | inode = btrfs_iget(dir->i_sb, &location, sub_root); |
| 3411 | } | 3496 | } |
| 3497 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); | ||
| 3498 | |||
| 3412 | return inode; | 3499 | return inode; |
| 3413 | } | 3500 | } |
| 3414 | 3501 | ||
| 3502 | static int btrfs_dentry_delete(struct dentry *dentry) | ||
| 3503 | { | ||
| 3504 | struct btrfs_root *root; | ||
| 3505 | |||
| 3506 | if (!dentry->d_inode) | ||
| 3507 | return 0; | ||
| 3508 | |||
| 3509 | root = BTRFS_I(dentry->d_inode)->root; | ||
| 3510 | if (btrfs_root_refs(&root->root_item) == 0) | ||
| 3511 | return 1; | ||
| 3512 | return 0; | ||
| 3513 | } | ||
| 3514 | |||
| 3415 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | 3515 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, |
| 3416 | struct nameidata *nd) | 3516 | struct nameidata *nd) |
| 3417 | { | 3517 | { |
| @@ -4773,11 +4873,11 @@ out: | |||
| 4773 | * create a new subvolume directory/inode (helper for the ioctl). | 4873 | * create a new subvolume directory/inode (helper for the ioctl). |
| 4774 | */ | 4874 | */ |
| 4775 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 4875 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
| 4776 | struct btrfs_root *new_root, struct dentry *dentry, | 4876 | struct btrfs_root *new_root, |
| 4777 | u64 new_dirid, u64 alloc_hint) | 4877 | u64 new_dirid, u64 alloc_hint) |
| 4778 | { | 4878 | { |
| 4779 | struct inode *inode; | 4879 | struct inode *inode; |
| 4780 | int error; | 4880 | int err; |
| 4781 | u64 index = 0; | 4881 | u64 index = 0; |
| 4782 | 4882 | ||
| 4783 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, | 4883 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, |
| @@ -4790,11 +4890,10 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | |||
| 4790 | inode->i_nlink = 1; | 4890 | inode->i_nlink = 1; |
| 4791 | btrfs_i_size_write(inode, 0); | 4891 | btrfs_i_size_write(inode, 0); |
| 4792 | 4892 | ||
| 4793 | error = btrfs_update_inode(trans, new_root, inode); | 4893 | err = btrfs_update_inode(trans, new_root, inode); |
| 4794 | if (error) | 4894 | BUG_ON(err); |
| 4795 | return error; | ||
| 4796 | 4895 | ||
| 4797 | d_instantiate(dentry, inode); | 4896 | iput(inode); |
| 4798 | return 0; | 4897 | return 0; |
| 4799 | } | 4898 | } |
| 4800 | 4899 | ||
| @@ -4872,6 +4971,16 @@ void btrfs_destroy_inode(struct inode *inode) | |||
| 4872 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); | 4971 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); |
| 4873 | } | 4972 | } |
| 4874 | 4973 | ||
| 4974 | void btrfs_drop_inode(struct inode *inode) | ||
| 4975 | { | ||
| 4976 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 4977 | |||
| 4978 | if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) | ||
| 4979 | generic_delete_inode(inode); | ||
| 4980 | else | ||
| 4981 | generic_drop_inode(inode); | ||
| 4982 | } | ||
| 4983 | |||
| 4875 | static void init_once(void *foo) | 4984 | static void init_once(void *foo) |
| 4876 | { | 4985 | { |
| 4877 | struct btrfs_inode *ei = (struct btrfs_inode *) foo; | 4986 | struct btrfs_inode *ei = (struct btrfs_inode *) foo; |
| @@ -4973,6 +5082,10 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 4973 | old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) | 5082 | old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) |
| 4974 | filemap_flush(old_inode->i_mapping); | 5083 | filemap_flush(old_inode->i_mapping); |
| 4975 | 5084 | ||
| 5085 | /* close the racy window with snapshot create/destroy ioctl */ | ||
| 5086 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
| 5087 | down_read(&root->fs_info->subvol_sem); | ||
| 5088 | |||
| 4976 | trans = btrfs_start_transaction(root, 1); | 5089 | trans = btrfs_start_transaction(root, 1); |
| 4977 | 5090 | ||
| 4978 | if (dest != root) | 5091 | if (dest != root) |
| @@ -5062,6 +5175,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 5062 | 5175 | ||
| 5063 | btrfs_end_transaction_throttle(trans, root); | 5176 | btrfs_end_transaction_throttle(trans, root); |
| 5064 | 5177 | ||
| 5178 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
| 5179 | up_read(&root->fs_info->subvol_sem); | ||
| 5065 | return ret; | 5180 | return ret; |
| 5066 | } | 5181 | } |
| 5067 | 5182 | ||
| @@ -5420,6 +5535,7 @@ static struct inode_operations btrfs_dir_ro_inode_operations = { | |||
| 5420 | .lookup = btrfs_lookup, | 5535 | .lookup = btrfs_lookup, |
| 5421 | .permission = btrfs_permission, | 5536 | .permission = btrfs_permission, |
| 5422 | }; | 5537 | }; |
| 5538 | |||
| 5423 | static struct file_operations btrfs_dir_file_operations = { | 5539 | static struct file_operations btrfs_dir_file_operations = { |
| 5424 | .llseek = generic_file_llseek, | 5540 | .llseek = generic_file_llseek, |
| 5425 | .read = generic_read_dir, | 5541 | .read = generic_read_dir, |
| @@ -5506,3 +5622,7 @@ static struct inode_operations btrfs_symlink_inode_operations = { | |||
| 5506 | .listxattr = btrfs_listxattr, | 5622 | .listxattr = btrfs_listxattr, |
| 5507 | .removexattr = btrfs_removexattr, | 5623 | .removexattr = btrfs_removexattr, |
| 5508 | }; | 5624 | }; |
| 5625 | |||
| 5626 | struct dentry_operations btrfs_dentry_operations = { | ||
| 5627 | .d_delete = btrfs_dentry_delete, | ||
| 5628 | }; | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9b3a88755e51..a13fd556db74 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; |
| @@ -241,7 +241,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 241 | 241 | ||
| 242 | ret = btrfs_check_metadata_free_space(root); | 242 | ret = btrfs_check_metadata_free_space(root); |
| 243 | if (ret) | 243 | if (ret) |
| 244 | goto fail_commit; | 244 | return ret; |
| 245 | 245 | ||
| 246 | trans = btrfs_start_transaction(root, 1); | 246 | trans = btrfs_start_transaction(root, 1); |
| 247 | BUG_ON(!trans); | 247 | BUG_ON(!trans); |
| @@ -304,11 +304,17 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 304 | if (ret) | 304 | if (ret) |
| 305 | goto fail; | 305 | goto fail; |
| 306 | 306 | ||
| 307 | key.offset = (u64)-1; | ||
| 308 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &key); | ||
| 309 | BUG_ON(IS_ERR(new_root)); | ||
| 310 | |||
| 311 | btrfs_record_root_in_trans(trans, new_root); | ||
| 312 | |||
| 313 | ret = btrfs_create_subvol_root(trans, new_root, new_dirid, | ||
| 314 | BTRFS_I(dir)->block_group); | ||
| 307 | /* | 315 | /* |
| 308 | * insert the directory item | 316 | * insert the directory item |
| 309 | */ | 317 | */ |
| 310 | key.offset = (u64)-1; | ||
| 311 | dir = dentry->d_parent->d_inode; | ||
| 312 | ret = btrfs_set_inode_index(dir, &index); | 318 | ret = btrfs_set_inode_index(dir, &index); |
| 313 | BUG_ON(ret); | 319 | BUG_ON(ret); |
| 314 | 320 | ||
| @@ -325,30 +331,15 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 325 | ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, | 331 | ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, |
| 326 | objectid, root->root_key.objectid, | 332 | objectid, root->root_key.objectid, |
| 327 | dir->i_ino, index, name, namelen); | 333 | dir->i_ino, index, name, namelen); |
| 328 | BUG_ON(ret); | ||
| 329 | 334 | ||
| 330 | ret = btrfs_commit_transaction(trans, root); | 335 | BUG_ON(ret); |
| 331 | if (ret) | ||
| 332 | goto fail_commit; | ||
| 333 | |||
| 334 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &key); | ||
| 335 | BUG_ON(!new_root); | ||
| 336 | |||
| 337 | trans = btrfs_start_transaction(new_root, 1); | ||
| 338 | BUG_ON(!trans); | ||
| 339 | |||
| 340 | ret = btrfs_create_subvol_root(trans, new_root, dentry, new_dirid, | ||
| 341 | BTRFS_I(dir)->block_group); | ||
| 342 | if (ret) | ||
| 343 | goto fail; | ||
| 344 | 336 | ||
| 337 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | ||
| 345 | fail: | 338 | fail: |
| 346 | nr = trans->blocks_used; | 339 | nr = trans->blocks_used; |
| 347 | err = btrfs_commit_transaction(trans, new_root); | 340 | err = btrfs_commit_transaction(trans, root); |
| 348 | if (err && !ret) | 341 | if (err && !ret) |
| 349 | ret = err; | 342 | ret = err; |
| 350 | fail_commit: | ||
| 351 | btrfs_btree_balance_dirty(root, nr); | ||
| 352 | return ret; | 343 | return ret; |
| 353 | } | 344 | } |
| 354 | 345 | ||
| @@ -409,14 +400,15 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child) | |||
| 409 | * sys_mkdirat and vfs_mkdir, but we only do a single component lookup | 400 | * sys_mkdirat and vfs_mkdir, but we only do a single component lookup |
| 410 | * inside this filesystem so it's quite a bit simpler. | 401 | * inside this filesystem so it's quite a bit simpler. |
| 411 | */ | 402 | */ |
| 412 | static noinline int btrfs_mksubvol(struct path *parent, char *name, | 403 | static noinline int btrfs_mksubvol(struct path *parent, |
| 413 | int mode, int namelen, | 404 | char *name, int namelen, |
| 414 | struct btrfs_root *snap_src) | 405 | struct btrfs_root *snap_src) |
| 415 | { | 406 | { |
| 407 | struct inode *dir = parent->dentry->d_inode; | ||
| 416 | struct dentry *dentry; | 408 | struct dentry *dentry; |
| 417 | int error; | 409 | int error; |
| 418 | 410 | ||
| 419 | mutex_lock_nested(&parent->dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 411 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
| 420 | 412 | ||
| 421 | dentry = lookup_one_len(name, parent->dentry, namelen); | 413 | dentry = lookup_one_len(name, parent->dentry, namelen); |
| 422 | error = PTR_ERR(dentry); | 414 | error = PTR_ERR(dentry); |
| @@ -427,99 +419,39 @@ static noinline int btrfs_mksubvol(struct path *parent, char *name, | |||
| 427 | if (dentry->d_inode) | 419 | if (dentry->d_inode) |
| 428 | goto out_dput; | 420 | goto out_dput; |
| 429 | 421 | ||
| 430 | if (!IS_POSIXACL(parent->dentry->d_inode)) | ||
| 431 | mode &= ~current_umask(); | ||
| 432 | |||
| 433 | error = mnt_want_write(parent->mnt); | 422 | error = mnt_want_write(parent->mnt); |
| 434 | if (error) | 423 | if (error) |
| 435 | goto out_dput; | 424 | goto out_dput; |
| 436 | 425 | ||
| 437 | error = btrfs_may_create(parent->dentry->d_inode, dentry); | 426 | error = btrfs_may_create(dir, dentry); |
| 438 | if (error) | 427 | if (error) |
| 439 | goto out_drop_write; | 428 | goto out_drop_write; |
| 440 | 429 | ||
| 441 | /* | 430 | down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); |
| 442 | * Actually perform the low-level subvolume creation after all | 431 | |
| 443 | * this VFS fuzz. | 432 | if (btrfs_root_refs(&BTRFS_I(dir)->root->root_item) == 0) |
| 444 | * | 433 | goto out_up_read; |
| 445 | * Eventually we want to pass in an inode under which we create this | 434 | |
| 446 | * subvolume, but for now all are under the filesystem root. | ||
| 447 | * | ||
| 448 | * Also we should pass on the mode eventually to allow creating new | ||
| 449 | * subvolume with specific mode bits. | ||
| 450 | */ | ||
| 451 | if (snap_src) { | 435 | if (snap_src) { |
| 452 | struct dentry *dir = dentry->d_parent; | 436 | error = create_snapshot(snap_src, dentry, |
| 453 | struct dentry *test = dir->d_parent; | 437 | name, namelen); |
| 454 | struct btrfs_path *path = btrfs_alloc_path(); | ||
| 455 | int ret; | ||
| 456 | u64 test_oid; | ||
| 457 | u64 parent_oid = BTRFS_I(dir->d_inode)->root->root_key.objectid; | ||
| 458 | |||
| 459 | test_oid = snap_src->root_key.objectid; | ||
| 460 | |||
| 461 | ret = btrfs_find_root_ref(snap_src->fs_info->tree_root, | ||
| 462 | path, parent_oid, test_oid); | ||
| 463 | if (ret == 0) | ||
| 464 | goto create; | ||
| 465 | btrfs_release_path(snap_src->fs_info->tree_root, path); | ||
| 466 | |||
| 467 | /* we need to make sure we aren't creating a directory loop | ||
| 468 | * by taking a snapshot of something that has our current | ||
| 469 | * subvol in its directory tree. So, this loops through | ||
| 470 | * the dentries and checks the forward refs for each subvolume | ||
| 471 | * to see if is references the subvolume where we are | ||
| 472 | * placing this new snapshot. | ||
| 473 | */ | ||
| 474 | while (1) { | ||
| 475 | if (!test || | ||
| 476 | dir == snap_src->fs_info->sb->s_root || | ||
| 477 | test == snap_src->fs_info->sb->s_root || | ||
| 478 | test->d_inode->i_sb != snap_src->fs_info->sb) { | ||
| 479 | break; | ||
| 480 | } | ||
| 481 | if (S_ISLNK(test->d_inode->i_mode)) { | ||
| 482 | printk(KERN_INFO "Btrfs symlink in snapshot " | ||
| 483 | "path, failed\n"); | ||
| 484 | error = -EMLINK; | ||
| 485 | btrfs_free_path(path); | ||
| 486 | goto out_drop_write; | ||
| 487 | } | ||
| 488 | test_oid = | ||
| 489 | BTRFS_I(test->d_inode)->root->root_key.objectid; | ||
| 490 | ret = btrfs_find_root_ref(snap_src->fs_info->tree_root, | ||
| 491 | path, test_oid, parent_oid); | ||
| 492 | if (ret == 0) { | ||
| 493 | printk(KERN_INFO "Btrfs snapshot creation " | ||
| 494 | "failed, looping\n"); | ||
| 495 | error = -EMLINK; | ||
| 496 | btrfs_free_path(path); | ||
| 497 | goto out_drop_write; | ||
| 498 | } | ||
| 499 | btrfs_release_path(snap_src->fs_info->tree_root, path); | ||
| 500 | test = test->d_parent; | ||
| 501 | } | ||
| 502 | create: | ||
| 503 | btrfs_free_path(path); | ||
| 504 | error = create_snapshot(snap_src, dentry, name, namelen); | ||
| 505 | } else { | 438 | } else { |
| 506 | error = create_subvol(BTRFS_I(parent->dentry->d_inode)->root, | 439 | error = create_subvol(BTRFS_I(dir)->root, dentry, |
| 507 | dentry, name, namelen); | 440 | name, namelen); |
| 508 | } | 441 | } |
| 509 | if (error) | 442 | if (!error) |
| 510 | goto out_drop_write; | 443 | fsnotify_mkdir(dir, dentry); |
| 511 | 444 | out_up_read: | |
| 512 | fsnotify_mkdir(parent->dentry->d_inode, dentry); | 445 | up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); |
| 513 | out_drop_write: | 446 | out_drop_write: |
| 514 | mnt_drop_write(parent->mnt); | 447 | mnt_drop_write(parent->mnt); |
| 515 | out_dput: | 448 | out_dput: |
| 516 | dput(dentry); | 449 | dput(dentry); |
| 517 | out_unlock: | 450 | out_unlock: |
| 518 | mutex_unlock(&parent->dentry->d_inode->i_mutex); | 451 | mutex_unlock(&dir->i_mutex); |
| 519 | return error; | 452 | return error; |
| 520 | } | 453 | } |
| 521 | 454 | ||
| 522 | |||
| 523 | static int btrfs_defrag_file(struct file *file) | 455 | static int btrfs_defrag_file(struct file *file) |
| 524 | { | 456 | { |
| 525 | struct inode *inode = fdentry(file)->d_inode; | 457 | struct inode *inode = fdentry(file)->d_inode; |
| @@ -597,7 +529,8 @@ out_unlock: | |||
| 597 | return 0; | 529 | return 0; |
| 598 | } | 530 | } |
| 599 | 531 | ||
| 600 | static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | 532 | static noinline int btrfs_ioctl_resize(struct btrfs_root *root, |
| 533 | void __user *arg) | ||
| 601 | { | 534 | { |
| 602 | u64 new_size; | 535 | u64 new_size; |
| 603 | u64 old_size; | 536 | u64 old_size; |
| @@ -706,10 +639,7 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
| 706 | { | 639 | { |
| 707 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 640 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; |
| 708 | struct btrfs_ioctl_vol_args *vol_args; | 641 | struct btrfs_ioctl_vol_args *vol_args; |
| 709 | struct btrfs_dir_item *di; | ||
| 710 | struct btrfs_path *path; | ||
| 711 | struct file *src_file; | 642 | struct file *src_file; |
| 712 | u64 root_dirid; | ||
| 713 | int namelen; | 643 | int namelen; |
| 714 | int ret = 0; | 644 | int ret = 0; |
| 715 | 645 | ||
| @@ -727,32 +657,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
| 727 | goto out; | 657 | goto out; |
| 728 | } | 658 | } |
| 729 | 659 | ||
| 730 | path = btrfs_alloc_path(); | ||
| 731 | if (!path) { | ||
| 732 | ret = -ENOMEM; | ||
| 733 | goto out; | ||
| 734 | } | ||
| 735 | |||
| 736 | root_dirid = root->fs_info->sb->s_root->d_inode->i_ino, | ||
| 737 | di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, | ||
| 738 | path, root_dirid, | ||
| 739 | vol_args->name, namelen, 0); | ||
| 740 | btrfs_free_path(path); | ||
| 741 | |||
| 742 | if (di && !IS_ERR(di)) { | ||
| 743 | ret = -EEXIST; | ||
| 744 | goto out; | ||
| 745 | } | ||
| 746 | |||
| 747 | if (IS_ERR(di)) { | ||
| 748 | ret = PTR_ERR(di); | ||
| 749 | goto out; | ||
| 750 | } | ||
| 751 | |||
| 752 | if (subvol) { | 660 | if (subvol) { |
| 753 | ret = btrfs_mksubvol(&file->f_path, vol_args->name, | 661 | ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen, |
| 754 | file->f_path.dentry->d_inode->i_mode, | 662 | NULL); |
| 755 | namelen, NULL); | ||
| 756 | } else { | 663 | } else { |
| 757 | struct inode *src_inode; | 664 | struct inode *src_inode; |
| 758 | src_file = fget(vol_args->fd); | 665 | src_file = fget(vol_args->fd); |
| @@ -769,17 +676,156 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
| 769 | fput(src_file); | 676 | fput(src_file); |
| 770 | goto out; | 677 | goto out; |
| 771 | } | 678 | } |
| 772 | ret = btrfs_mksubvol(&file->f_path, vol_args->name, | 679 | ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen, |
| 773 | file->f_path.dentry->d_inode->i_mode, | 680 | BTRFS_I(src_inode)->root); |
| 774 | namelen, BTRFS_I(src_inode)->root); | ||
| 775 | fput(src_file); | 681 | fput(src_file); |
| 776 | } | 682 | } |
| 777 | |||
| 778 | out: | 683 | out: |
| 779 | kfree(vol_args); | 684 | kfree(vol_args); |
| 780 | return ret; | 685 | return ret; |
| 781 | } | 686 | } |
| 782 | 687 | ||
| 688 | /* | ||
| 689 | * helper to check if the subvolume references other subvolumes | ||
| 690 | */ | ||
| 691 | static noinline int may_destroy_subvol(struct btrfs_root *root) | ||
| 692 | { | ||
| 693 | struct btrfs_path *path; | ||
| 694 | struct btrfs_key key; | ||
| 695 | int ret; | ||
| 696 | |||
| 697 | path = btrfs_alloc_path(); | ||
| 698 | if (!path) | ||
| 699 | return -ENOMEM; | ||
| 700 | |||
| 701 | key.objectid = root->root_key.objectid; | ||
| 702 | key.type = BTRFS_ROOT_REF_KEY; | ||
| 703 | key.offset = (u64)-1; | ||
| 704 | |||
| 705 | ret = btrfs_search_slot(NULL, root->fs_info->tree_root, | ||
| 706 | &key, path, 0, 0); | ||
| 707 | if (ret < 0) | ||
| 708 | goto out; | ||
| 709 | BUG_ON(ret == 0); | ||
| 710 | |||
| 711 | ret = 0; | ||
| 712 | if (path->slots[0] > 0) { | ||
| 713 | path->slots[0]--; | ||
| 714 | btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); | ||
| 715 | if (key.objectid == root->root_key.objectid && | ||
| 716 | key.type == BTRFS_ROOT_REF_KEY) | ||
| 717 | ret = -ENOTEMPTY; | ||
| 718 | } | ||
| 719 | out: | ||
| 720 | btrfs_free_path(path); | ||
| 721 | return ret; | ||
| 722 | } | ||
| 723 | |||
| 724 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, | ||
| 725 | void __user *arg) | ||
| 726 | { | ||
| 727 | struct dentry *parent = fdentry(file); | ||
| 728 | struct dentry *dentry; | ||
| 729 | struct inode *dir = parent->d_inode; | ||
| 730 | struct inode *inode; | ||
| 731 | struct btrfs_root *root = BTRFS_I(dir)->root; | ||
| 732 | struct btrfs_root *dest = NULL; | ||
| 733 | struct btrfs_ioctl_vol_args *vol_args; | ||
| 734 | struct btrfs_trans_handle *trans; | ||
| 735 | int namelen; | ||
| 736 | int ret; | ||
| 737 | int err = 0; | ||
| 738 | |||
| 739 | if (!capable(CAP_SYS_ADMIN)) | ||
| 740 | return -EPERM; | ||
| 741 | |||
| 742 | vol_args = memdup_user(arg, sizeof(*vol_args)); | ||
| 743 | if (IS_ERR(vol_args)) | ||
| 744 | return PTR_ERR(vol_args); | ||
| 745 | |||
| 746 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | ||
| 747 | namelen = strlen(vol_args->name); | ||
| 748 | if (strchr(vol_args->name, '/') || | ||
| 749 | strncmp(vol_args->name, "..", namelen) == 0) { | ||
| 750 | err = -EINVAL; | ||
| 751 | goto out; | ||
| 752 | } | ||
| 753 | |||
| 754 | err = mnt_want_write(file->f_path.mnt); | ||
| 755 | if (err) | ||
| 756 | goto out; | ||
| 757 | |||
| 758 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | ||
| 759 | dentry = lookup_one_len(vol_args->name, parent, namelen); | ||
| 760 | if (IS_ERR(dentry)) { | ||
| 761 | err = PTR_ERR(dentry); | ||
| 762 | goto out_unlock_dir; | ||
| 763 | } | ||
| 764 | |||
| 765 | if (!dentry->d_inode) { | ||
| 766 | err = -ENOENT; | ||
| 767 | goto out_dput; | ||
| 768 | } | ||
| 769 | |||
| 770 | inode = dentry->d_inode; | ||
| 771 | if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { | ||
| 772 | err = -EINVAL; | ||
| 773 | goto out_dput; | ||
| 774 | } | ||
| 775 | |||
| 776 | dest = BTRFS_I(inode)->root; | ||
| 777 | |||
| 778 | mutex_lock(&inode->i_mutex); | ||
| 779 | err = d_invalidate(dentry); | ||
| 780 | if (err) | ||
| 781 | goto out_unlock; | ||
| 782 | |||
| 783 | down_write(&root->fs_info->subvol_sem); | ||
| 784 | |||
| 785 | err = may_destroy_subvol(dest); | ||
| 786 | if (err) | ||
| 787 | goto out_up_write; | ||
| 788 | |||
| 789 | trans = btrfs_start_transaction(root, 1); | ||
| 790 | ret = btrfs_unlink_subvol(trans, root, dir, | ||
| 791 | dest->root_key.objectid, | ||
| 792 | dentry->d_name.name, | ||
| 793 | dentry->d_name.len); | ||
| 794 | BUG_ON(ret); | ||
| 795 | |||
| 796 | btrfs_record_root_in_trans(trans, dest); | ||
| 797 | |||
| 798 | memset(&dest->root_item.drop_progress, 0, | ||
| 799 | sizeof(dest->root_item.drop_progress)); | ||
| 800 | dest->root_item.drop_level = 0; | ||
| 801 | btrfs_set_root_refs(&dest->root_item, 0); | ||
| 802 | |||
| 803 | ret = btrfs_insert_orphan_item(trans, | ||
| 804 | root->fs_info->tree_root, | ||
| 805 | dest->root_key.objectid); | ||
| 806 | BUG_ON(ret); | ||
| 807 | |||
| 808 | ret = btrfs_commit_transaction(trans, root); | ||
| 809 | BUG_ON(ret); | ||
| 810 | inode->i_flags |= S_DEAD; | ||
| 811 | out_up_write: | ||
| 812 | up_write(&root->fs_info->subvol_sem); | ||
| 813 | out_unlock: | ||
| 814 | mutex_unlock(&inode->i_mutex); | ||
| 815 | if (!err) { | ||
| 816 | btrfs_invalidate_inodes(dest); | ||
| 817 | d_delete(dentry); | ||
| 818 | } | ||
| 819 | out_dput: | ||
| 820 | dput(dentry); | ||
| 821 | out_unlock_dir: | ||
| 822 | mutex_unlock(&dir->i_mutex); | ||
| 823 | mnt_drop_write(file->f_path.mnt); | ||
| 824 | out: | ||
| 825 | kfree(vol_args); | ||
| 826 | return err; | ||
| 827 | } | ||
| 828 | |||
| 783 | static int btrfs_ioctl_defrag(struct file *file) | 829 | static int btrfs_ioctl_defrag(struct file *file) |
| 784 | { | 830 | { |
| 785 | struct inode *inode = fdentry(file)->d_inode; | 831 | struct inode *inode = fdentry(file)->d_inode; |
| @@ -853,8 +899,8 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) | |||
| 853 | return ret; | 899 | return ret; |
| 854 | } | 900 | } |
| 855 | 901 | ||
| 856 | static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | 902 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, |
| 857 | u64 off, u64 olen, u64 destoff) | 903 | u64 off, u64 olen, u64 destoff) |
| 858 | { | 904 | { |
| 859 | struct inode *inode = fdentry(file)->d_inode; | 905 | struct inode *inode = fdentry(file)->d_inode; |
| 860 | struct btrfs_root *root = BTRFS_I(inode)->root; | 906 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| @@ -1246,6 +1292,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
| 1246 | return btrfs_ioctl_snap_create(file, argp, 0); | 1292 | return btrfs_ioctl_snap_create(file, argp, 0); |
| 1247 | case BTRFS_IOC_SUBVOL_CREATE: | 1293 | case BTRFS_IOC_SUBVOL_CREATE: |
| 1248 | return btrfs_ioctl_snap_create(file, argp, 1); | 1294 | return btrfs_ioctl_snap_create(file, argp, 1); |
| 1295 | case BTRFS_IOC_SNAP_DESTROY: | ||
| 1296 | return btrfs_ioctl_snap_destroy(file, argp); | ||
| 1249 | case BTRFS_IOC_DEFRAG: | 1297 | case BTRFS_IOC_DEFRAG: |
| 1250 | return btrfs_ioctl_defrag(file); | 1298 | return btrfs_ioctl_defrag(file); |
| 1251 | case BTRFS_IOC_RESIZE: | 1299 | case BTRFS_IOC_RESIZE: |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index b320b103fa13..bc49914475eb 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
| @@ -65,5 +65,6 @@ struct btrfs_ioctl_clone_range_args { | |||
| 65 | 65 | ||
| 66 | #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ | 66 | #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ |
| 67 | struct btrfs_ioctl_vol_args) | 67 | struct btrfs_ioctl_vol_args) |
| 68 | 68 | #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ | |
| 69 | struct btrfs_ioctl_vol_args) | ||
| 69 | #endif | 70 | #endif |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 3be16ccc7eea..48a504260635 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -3203,6 +3203,7 @@ static int check_extent_flags(u64 flags) | |||
| 3203 | return 0; | 3203 | return 0; |
| 3204 | } | 3204 | } |
| 3205 | 3205 | ||
| 3206 | |||
| 3206 | static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | 3207 | static noinline_for_stack int relocate_block_group(struct reloc_control *rc) |
| 3207 | { | 3208 | { |
| 3208 | struct rb_root blocks = RB_ROOT; | 3209 | struct rb_root blocks = RB_ROOT; |
| @@ -3220,6 +3221,9 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
| 3220 | if (!path) | 3221 | if (!path) |
| 3221 | return -ENOMEM; | 3222 | return -ENOMEM; |
| 3222 | 3223 | ||
| 3224 | rc->extents_found = 0; | ||
| 3225 | rc->extents_skipped = 0; | ||
| 3226 | |||
| 3223 | rc->search_start = rc->block_group->key.objectid; | 3227 | rc->search_start = rc->block_group->key.objectid; |
| 3224 | clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, | 3228 | clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, |
| 3225 | GFP_NOFS); | 3229 | GFP_NOFS); |
| @@ -3475,14 +3479,15 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) | |||
| 3475 | btrfs_wait_ordered_extents(fs_info->tree_root, 0); | 3479 | btrfs_wait_ordered_extents(fs_info->tree_root, 0); |
| 3476 | 3480 | ||
| 3477 | while (1) { | 3481 | while (1) { |
| 3478 | mutex_lock(&fs_info->cleaner_mutex); | ||
| 3479 | btrfs_clean_old_snapshots(fs_info->tree_root); | ||
| 3480 | mutex_unlock(&fs_info->cleaner_mutex); | ||
| 3481 | |||
| 3482 | rc->extents_found = 0; | 3482 | rc->extents_found = 0; |
| 3483 | rc->extents_skipped = 0; | 3483 | rc->extents_skipped = 0; |
| 3484 | 3484 | ||
| 3485 | mutex_lock(&fs_info->cleaner_mutex); | ||
| 3486 | |||
| 3487 | btrfs_clean_old_snapshots(fs_info->tree_root); | ||
| 3485 | ret = relocate_block_group(rc); | 3488 | ret = relocate_block_group(rc); |
| 3489 | |||
| 3490 | mutex_unlock(&fs_info->cleaner_mutex); | ||
| 3486 | if (ret < 0) { | 3491 | if (ret < 0) { |
| 3487 | err = ret; | 3492 | err = ret; |
| 3488 | break; | 3493 | break; |
| @@ -3530,6 +3535,26 @@ out: | |||
| 3530 | return err; | 3535 | return err; |
| 3531 | } | 3536 | } |
| 3532 | 3537 | ||
| 3538 | static noinline_for_stack int mark_garbage_root(struct btrfs_root *root) | ||
| 3539 | { | ||
| 3540 | struct btrfs_trans_handle *trans; | ||
| 3541 | int ret; | ||
| 3542 | |||
| 3543 | trans = btrfs_start_transaction(root->fs_info->tree_root, 1); | ||
| 3544 | |||
| 3545 | memset(&root->root_item.drop_progress, 0, | ||
| 3546 | sizeof(root->root_item.drop_progress)); | ||
| 3547 | root->root_item.drop_level = 0; | ||
| 3548 | btrfs_set_root_refs(&root->root_item, 0); | ||
| 3549 | ret = btrfs_update_root(trans, root->fs_info->tree_root, | ||
| 3550 | &root->root_key, &root->root_item); | ||
| 3551 | BUG_ON(ret); | ||
| 3552 | |||
| 3553 | ret = btrfs_end_transaction(trans, root->fs_info->tree_root); | ||
| 3554 | BUG_ON(ret); | ||
| 3555 | return 0; | ||
| 3556 | } | ||
| 3557 | |||
| 3533 | /* | 3558 | /* |
| 3534 | * recover relocation interrupted by system crash. | 3559 | * recover relocation interrupted by system crash. |
| 3535 | * | 3560 | * |
| @@ -3589,8 +3614,12 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
| 3589 | fs_root = read_fs_root(root->fs_info, | 3614 | fs_root = read_fs_root(root->fs_info, |
| 3590 | reloc_root->root_key.offset); | 3615 | reloc_root->root_key.offset); |
| 3591 | if (IS_ERR(fs_root)) { | 3616 | if (IS_ERR(fs_root)) { |
| 3592 | err = PTR_ERR(fs_root); | 3617 | ret = PTR_ERR(fs_root); |
| 3593 | goto out; | 3618 | if (ret != -ENOENT) { |
| 3619 | err = ret; | ||
| 3620 | goto out; | ||
| 3621 | } | ||
| 3622 | mark_garbage_root(reloc_root); | ||
| 3594 | } | 3623 | } |
| 3595 | } | 3624 | } |
| 3596 | 3625 | ||
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 5ef72599a581..9351428f30e2 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
| @@ -94,17 +94,23 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |||
| 94 | goto out; | 94 | goto out; |
| 95 | 95 | ||
| 96 | BUG_ON(ret == 0); | 96 | BUG_ON(ret == 0); |
| 97 | if (path->slots[0] == 0) { | ||
| 98 | ret = 1; | ||
| 99 | goto out; | ||
| 100 | } | ||
| 97 | l = path->nodes[0]; | 101 | l = path->nodes[0]; |
| 98 | BUG_ON(path->slots[0] == 0); | ||
| 99 | slot = path->slots[0] - 1; | 102 | slot = path->slots[0] - 1; |
| 100 | btrfs_item_key_to_cpu(l, &found_key, slot); | 103 | btrfs_item_key_to_cpu(l, &found_key, slot); |
| 101 | if (found_key.objectid != objectid) { | 104 | if (found_key.objectid != objectid || |
| 105 | found_key.type != BTRFS_ROOT_ITEM_KEY) { | ||
| 102 | ret = 1; | 106 | ret = 1; |
| 103 | goto out; | 107 | goto out; |
| 104 | } | 108 | } |
| 105 | read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), | 109 | if (item) |
| 106 | sizeof(*item)); | 110 | read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), |
| 107 | memcpy(key, &found_key, sizeof(found_key)); | 111 | sizeof(*item)); |
| 112 | if (key) | ||
| 113 | memcpy(key, &found_key, sizeof(found_key)); | ||
| 108 | ret = 0; | 114 | ret = 0; |
| 109 | out: | 115 | out: |
| 110 | btrfs_free_path(path); | 116 | btrfs_free_path(path); |
| @@ -249,6 +255,59 @@ err: | |||
| 249 | return ret; | 255 | return ret; |
| 250 | } | 256 | } |
| 251 | 257 | ||
| 258 | int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | ||
| 259 | { | ||
| 260 | struct extent_buffer *leaf; | ||
| 261 | struct btrfs_path *path; | ||
| 262 | struct btrfs_key key; | ||
| 263 | int err = 0; | ||
| 264 | int ret; | ||
| 265 | |||
| 266 | path = btrfs_alloc_path(); | ||
| 267 | if (!path) | ||
| 268 | return -ENOMEM; | ||
| 269 | |||
| 270 | key.objectid = BTRFS_ORPHAN_OBJECTID; | ||
| 271 | key.type = BTRFS_ORPHAN_ITEM_KEY; | ||
| 272 | key.offset = 0; | ||
| 273 | |||
| 274 | while (1) { | ||
| 275 | ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); | ||
| 276 | if (ret < 0) { | ||
| 277 | err = ret; | ||
| 278 | break; | ||
| 279 | } | ||
| 280 | |||
| 281 | leaf = path->nodes[0]; | ||
| 282 | if (path->slots[0] >= btrfs_header_nritems(leaf)) { | ||
| 283 | ret = btrfs_next_leaf(tree_root, path); | ||
| 284 | if (ret < 0) | ||
| 285 | err = ret; | ||
| 286 | if (ret != 0) | ||
| 287 | break; | ||
| 288 | leaf = path->nodes[0]; | ||
| 289 | } | ||
| 290 | |||
| 291 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
| 292 | btrfs_release_path(tree_root, path); | ||
| 293 | |||
| 294 | if (key.objectid != BTRFS_ORPHAN_OBJECTID || | ||
| 295 | key.type != BTRFS_ORPHAN_ITEM_KEY) | ||
| 296 | break; | ||
| 297 | |||
| 298 | ret = btrfs_find_dead_roots(tree_root, key.offset); | ||
| 299 | if (ret) { | ||
| 300 | err = ret; | ||
| 301 | break; | ||
| 302 | } | ||
| 303 | |||
| 304 | key.offset++; | ||
| 305 | } | ||
| 306 | |||
| 307 | btrfs_free_path(path); | ||
| 308 | return err; | ||
| 309 | } | ||
| 310 | |||
| 252 | /* drop the root item for 'key' from 'root' */ | 311 | /* drop the root item for 'key' from 'root' */ |
| 253 | int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 312 | int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| 254 | struct btrfs_key *key) | 313 | struct btrfs_key *key) |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 6d6d06cb6dfc..0242c8babae9 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -676,6 +676,7 @@ static int btrfs_unfreeze(struct super_block *sb) | |||
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | static struct super_operations btrfs_super_ops = { | 678 | static struct super_operations btrfs_super_ops = { |
| 679 | .drop_inode = btrfs_drop_inode, | ||
| 679 | .delete_inode = btrfs_delete_inode, | 680 | .delete_inode = btrfs_delete_inode, |
| 680 | .put_super = btrfs_put_super, | 681 | .put_super = btrfs_put_super, |
| 681 | .sync_fs = btrfs_sync_fs, | 682 | .sync_fs = btrfs_sync_fs, |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 915077725fea..88f866f85e7a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -104,7 +104,6 @@ static noinline int record_root_in_trans(struct btrfs_trans_handle *trans, | |||
| 104 | { | 104 | { |
| 105 | if (root->ref_cows && root->last_trans < trans->transid) { | 105 | if (root->ref_cows && root->last_trans < trans->transid) { |
| 106 | WARN_ON(root == root->fs_info->extent_root); | 106 | WARN_ON(root == root->fs_info->extent_root); |
| 107 | WARN_ON(root->root_item.refs == 0); | ||
| 108 | WARN_ON(root->commit_root != root->node); | 107 | WARN_ON(root->commit_root != root->node); |
| 109 | 108 | ||
| 110 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | 109 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, |
| @@ -1078,8 +1077,13 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
| 1078 | 1077 | ||
| 1079 | while (!list_empty(&list)) { | 1078 | while (!list_empty(&list)) { |
| 1080 | root = list_entry(list.next, struct btrfs_root, root_list); | 1079 | root = list_entry(list.next, struct btrfs_root, root_list); |
| 1081 | list_del_init(&root->root_list); | 1080 | list_del(&root->root_list); |
| 1082 | btrfs_drop_snapshot(root, 0); | 1081 | |
| 1082 | if (btrfs_header_backref_rev(root->node) < | ||
| 1083 | BTRFS_MIXED_BACKREF_REV) | ||
| 1084 | btrfs_drop_snapshot(root, 0); | ||
| 1085 | else | ||
| 1086 | btrfs_drop_snapshot(root, 1); | ||
| 1083 | } | 1087 | } |
| 1084 | return 0; | 1088 | return 0; |
| 1085 | } | 1089 | } |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 6e674d76186d..4d7d9abef42f 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -2841,7 +2841,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 2841 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) | 2841 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) |
| 2842 | break; | 2842 | break; |
| 2843 | 2843 | ||
| 2844 | if (parent == sb->s_root) | 2844 | if (IS_ROOT(parent)) |
| 2845 | break; | 2845 | break; |
| 2846 | 2846 | ||
| 2847 | parent = parent->d_parent; | 2847 | parent = parent->d_parent; |
| @@ -2880,6 +2880,12 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2880 | goto end_no_trans; | 2880 | goto end_no_trans; |
| 2881 | } | 2881 | } |
| 2882 | 2882 | ||
| 2883 | if (root != BTRFS_I(inode)->root || | ||
| 2884 | btrfs_root_refs(&root->root_item) == 0) { | ||
| 2885 | ret = 1; | ||
| 2886 | goto end_no_trans; | ||
| 2887 | } | ||
| 2888 | |||
| 2883 | ret = check_parent_dirs_for_sync(trans, inode, parent, | 2889 | ret = check_parent_dirs_for_sync(trans, inode, parent, |
| 2884 | sb, last_committed); | 2890 | sb, last_committed); |
| 2885 | if (ret) | 2891 | if (ret) |
| @@ -2907,12 +2913,15 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2907 | break; | 2913 | break; |
| 2908 | 2914 | ||
| 2909 | inode = parent->d_inode; | 2915 | inode = parent->d_inode; |
| 2916 | if (root != BTRFS_I(inode)->root) | ||
| 2917 | break; | ||
| 2918 | |||
| 2910 | if (BTRFS_I(inode)->generation > | 2919 | if (BTRFS_I(inode)->generation > |
| 2911 | root->fs_info->last_trans_committed) { | 2920 | root->fs_info->last_trans_committed) { |
| 2912 | ret = btrfs_log_inode(trans, root, inode, inode_only); | 2921 | ret = btrfs_log_inode(trans, root, inode, inode_only); |
| 2913 | BUG_ON(ret); | 2922 | BUG_ON(ret); |
| 2914 | } | 2923 | } |
| 2915 | if (parent == sb->s_root) | 2924 | if (IS_ROOT(parent)) |
| 2916 | break; | 2925 | break; |
| 2917 | 2926 | ||
| 2918 | parent = parent->d_parent; | 2927 | parent = parent->d_parent; |
