add drop snapshot/subvol ioctl
PATCH 4/4 add drop snapshot/subvol ioctl
This patch adds drop snapshot/subvol ioctl that allows dropping non-empty snapshot/subvols. The ioctl code is based on Aaron Straus's patch.
Another change in this patch is add code that finds orphan fs trees.
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/ctree.h +1 -0
@@ -2125,6 +2125,7 @@ int btrfs_find_last_root(struct btrfs_roint btrfs_search_root (struct btrfs_root *root,u64 search_start,u64 *found_objectid);int btrfs_find_dead_roots (struct btrfs_root *root,u64 objectid); +int btrfs_find_orphan_roots (struct btrfs_root *tree_root);int btrfs_set_root_node (struct btrfs_root_item *item,struct extent_buffer *node);/* dir-item.c */
fs/btrfs/disk-io.c +26 -12
@@ -950,13 +950,14 @@ static int find_and_setup_root(struct bt ret =btrfs_find_last_root (tree_root, objectid, &root->root_item, &root->root_key);BUG_ON (ret); +BUG_ON (btrfs_root_refs (&root->root_item) ==0 ); generation =btrfs_root_generation (&root->root_item); blocksize =btrfs_level_size (root,btrfs_root_level (&root->root_item)); root->node =read_tree_block (root,btrfs_root_bytenr (&root->root_item), blocksize, generation); - root->commit_root =btrfs_root_node (root);BUG_ON (!root->node); + root->commit_root =btrfs_root_node (root);return 0 ; }
@@ -1194,12 +1195,13 @@ struct btrfs_root *btrfs_read_fs_root_nokfree (root);return ERR_PTR (ret); } -if (!(fs_info->sb->s_flags &MS_RDONLY )) { - ret =btrfs_find_dead_roots (fs_info->tree_root, - root->root_key.objectid); -BUG_ON (ret); + ret =btrfs_find_dead_roots (fs_info->tree_root, + root->root_key.objectid); +BUG_ON (ret); + +if (!(fs_info->sb->s_flags &MS_RDONLY ))btrfs_orphan_cleanup (root); - } +return root; }
@@ -1424,9 +1426,12 @@ static int cleaner_kthread(void *arg)break ;vfs_check_frozen (root->fs_info->sb,SB_FREEZE_WRITE ); -mutex_lock (&root->fs_info->cleaner_mutex); -btrfs_clean_old_snapshots (root); -mutex_unlock (&root->fs_info->cleaner_mutex); + +if (!(root->fs_info->sb->s_flags &MS_RDONLY )) { +mutex_lock (&root->fs_info->cleaner_mutex); +btrfs_clean_old_snapshots (root); +mutex_unlock (&root->fs_info->cleaner_mutex); + }if (freezing (current)) {refrigerator ();
@@ -1889,6 +1894,9 @@ struct btrfs_root *open_ctree(struct sup } } + ret =btrfs_find_orphan_roots (tree_root); +BUG_ON (ret); +if (!(sb->s_flags &MS_RDONLY )) { ret =btrfs_recover_relocation (tree_root);BUG_ON (ret);
@@ -2229,6 +2237,15 @@ static int del_fs_roots(struct btrfs_fs_struct btrfs_root *gang[8 ];int i; +while (!list_empty (&fs_info->dead_roots)) { + gang[0 ] =list_entry (fs_info->dead_roots.next, + struct btrfs_root, root_list); +list_del (&gang[0 ]->root_list); +free_extent_buffer (gang[0 ]->node); +free_extent_buffer (gang[0 ]->commit_root); +kfree (gang[0 ]); + } +while (1 ) { ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, (void **)gang, 0,
@@ -2258,9 +2275,6 @@ int btrfs_cleanup_fs_roots(struct btrfs_ root_objectid = gang[ret -1 ]->root_key.objectid +1 ;for (i =0 ; i < ret; i++) { root_objectid = gang[i]->root_key.objectid; - ret =btrfs_find_dead_roots (fs_info->tree_root, - root_objectid); -BUG_ON (ret);btrfs_orphan_cleanup (gang[i]); } root_objectid++;
fs/btrfs/extent-tree.c +11 -0
@@ -5356,6 +5356,17 @@ int btrfs_drop_snapshot(struct btrfs_roo ret =btrfs_del_root (trans, tree_root, &root->root_key);BUG_ON (ret); +if (root->root_key.objectid !=BTRFS_TREE_RELOC_OBJECTID ) { + ret =btrfs_find_last_root (tree_root, root->root_key.objectid, +NULL ,NULL ); +BUG_ON (ret <0 ); +if (ret >0 ) { + ret =btrfs_del_orphan_item (trans, tree_root, + root->root_key.objectid); +BUG_ON (ret); + } + } +free_extent_buffer (root->node);free_extent_buffer (root->commit_root);kfree (root);
fs/btrfs/inode-map.c +2 -2
@@ -44,9 +44,9 @@ int btrfs_find_highest_inode(struct btrf l = path->nodes[0 ];btrfs_item_key_to_cpu (l, &found_key, slot); *objectid =max_t (u64, found_key.objectid, -BTRFS_FIRST_FREE_OBJECTID -1 ); +BTRFS_FIRST_FREE_OBJECTID ); }else { - *objectid =BTRFS_FIRST_FREE_OBJECTID -1 ; + *objectid =BTRFS_FIRST_FREE_OBJECTID ; } ret =0 ; error:
fs/btrfs/ioctl.c +88 -3
115 lines not on this page · raw message
fs/btrfs/ioctl.h +2 -1
@@ -65,5 +65,6 @@ struct btrfs_ioctl_clone_range_args {#define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ struct btrfs_ioctl_vol_args) - +#define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ + struct btrfs_ioctl_vol_args)#endif
fs/btrfs/root-tree.c +62 -4
85 lines not on this page · raw message
fs/btrfs/transaction.c +6 -2
@@ -1087,8 +1087,12 @@ int btrfs_clean_old_snapshots(struct btrwhile (!list_empty (&list)) { root = list_entry(list.next, struct btrfs_root, root_list); -list_del_init (&root->root_list); -btrfs_drop_snapshot (root,0 ); +list_del (&root->root_list); +if (btrfs_header_backref_rev (root->node) < +BTRFS_MIXED_BACKREF_REV ) +btrfs_drop_snapshot (root,0 ); +else +btrfs_drop_snapshot (root,1 ); }return 0 ; }