aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-11-17 21:02:50 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-17 21:02:50 -0500
commit3de4586c5278a28107030c336956381f69ff7a9d (patch)
treed636e3806cd5ecff71927d0300e46526fa23de1a /fs/btrfs/transaction.c
parent4ce4cb526f67775c1cce3e3fa01c292672ba874e (diff)
Btrfs: Allow subvolumes and snapshots anywhere in the directory tree
Before, all snapshots and subvolumes lived in a single flat directory. This was awkward and confusing because the single flat directory was only writable with the ioctls. This commit changes the ioctls to create subvols and snapshots at any point in the directory tree. This requires making separate ioctls for snapshot and subvol creation instead of a combining them into one. The subvol ioctl does: btrfsctl -S subvol_name parent_dir After the ioctl is done subvol_name lives inside parent_dir. The snapshot ioctl does: btrfsctl -s path_for_snapshot root_to_snapshot path_for_snapshot can be an absolute or relative path. btrfsctl breaks it up into directory and basename components. root_to_snapshot can be any file or directory in the FS. The snapshot is taken of the entire root where that file lives. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c66
1 files changed, 53 insertions, 13 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 202c1b6df4a4..eec8b2465039 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -779,7 +779,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
779 struct extent_buffer *tmp; 779 struct extent_buffer *tmp;
780 struct extent_buffer *old; 780 struct extent_buffer *old;
781 int ret; 781 int ret;
782 int namelen;
783 u64 objectid; 782 u64 objectid;
784 783
785 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 784 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
@@ -816,28 +815,48 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
816 if (ret) 815 if (ret)
817 goto fail; 816 goto fail;
818 817
818 key.offset = (u64)-1;
819 memcpy(&pending->root_key, &key, sizeof(key));
820fail:
821 kfree(new_root_item);
822 return ret;
823}
824
825static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
826 struct btrfs_pending_snapshot *pending)
827{
828 int ret;
829 int namelen;
830 u64 index = 0;
831 struct btrfs_trans_handle *trans;
832 struct inode *parent_inode;
833 struct inode *inode;
834
835 trans = btrfs_start_transaction(fs_info->fs_root, 1);
836
819 /* 837 /*
820 * insert the directory item 838 * insert the directory item
821 */ 839 */
822 key.offset = (u64)-1;
823 namelen = strlen(pending->name); 840 namelen = strlen(pending->name);
824 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, 841 parent_inode = pending->dentry->d_parent->d_inode;
825 pending->name, namelen, 842 ret = btrfs_set_inode_index(parent_inode, &index);
826 root->fs_info->sb->s_root->d_inode->i_ino, 843 ret = btrfs_insert_dir_item(trans,
827 &key, BTRFS_FT_DIR, 0); 844 BTRFS_I(parent_inode)->root,
845 pending->name, namelen,
846 parent_inode->i_ino,
847 &pending->root_key, BTRFS_FT_DIR, index);
828 848
829 if (ret) 849 if (ret)
830 goto fail; 850 goto fail;
831 851#if 0
832 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root, 852 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root,
833 pending->name, strlen(pending->name), objectid, 853 pending->name, strlen(pending->name), objectid,
834 root->fs_info->sb->s_root->d_inode->i_ino, 0); 854 root->fs_info->sb->s_root->d_inode->i_ino, 0);
835 855#endif
836 /* Invalidate existing dcache entry for new snapshot. */ 856 inode = btrfs_lookup_dentry(parent_inode, pending->dentry);
837 btrfs_invalidate_dcache_root(root, pending->name, namelen); 857 d_instantiate(pending->dentry, inode);
838
839fail: 858fail:
840 kfree(new_root_item); 859 btrfs_end_transaction(trans, fs_info->fs_root);
841 return ret; 860 return ret;
842} 861}
843 862
@@ -849,12 +868,28 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
849{ 868{
850 struct btrfs_pending_snapshot *pending; 869 struct btrfs_pending_snapshot *pending;
851 struct list_head *head = &trans->transaction->pending_snapshots; 870 struct list_head *head = &trans->transaction->pending_snapshots;
871 struct list_head *cur;
872 int ret;
873
874 list_for_each(cur, head) {
875 pending = list_entry(cur, struct btrfs_pending_snapshot, list);
876 ret = create_pending_snapshot(trans, fs_info, pending);
877 BUG_ON(ret);
878 }
879 return 0;
880}
881
882static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
883 struct btrfs_fs_info *fs_info)
884{
885 struct btrfs_pending_snapshot *pending;
886 struct list_head *head = &trans->transaction->pending_snapshots;
852 int ret; 887 int ret;
853 888
854 while(!list_empty(head)) { 889 while(!list_empty(head)) {
855 pending = list_entry(head->next, 890 pending = list_entry(head->next,
856 struct btrfs_pending_snapshot, list); 891 struct btrfs_pending_snapshot, list);
857 ret = create_pending_snapshot(trans, fs_info, pending); 892 ret = finish_pending_snapshot(fs_info, pending);
858 BUG_ON(ret); 893 BUG_ON(ret);
859 list_del(&pending->list); 894 list_del(&pending->list);
860 kfree(pending->name); 895 kfree(pending->name);
@@ -1033,11 +1068,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1033 btrfs_drop_dead_reloc_roots(root); 1068 btrfs_drop_dead_reloc_roots(root);
1034 mutex_unlock(&root->fs_info->tree_reloc_mutex); 1069 mutex_unlock(&root->fs_info->tree_reloc_mutex);
1035 1070
1071 /* do the directory inserts of any pending snapshot creations */
1072 finish_pending_snapshots(trans, root->fs_info);
1073
1036 mutex_lock(&root->fs_info->trans_mutex); 1074 mutex_lock(&root->fs_info->trans_mutex);
1037 1075
1038 cur_trans->commit_done = 1; 1076 cur_trans->commit_done = 1;
1039 root->fs_info->last_trans_committed = cur_trans->transid; 1077 root->fs_info->last_trans_committed = cur_trans->transid;
1040 wake_up(&cur_trans->commit_wait); 1078 wake_up(&cur_trans->commit_wait);
1079
1041 put_transaction(cur_trans); 1080 put_transaction(cur_trans);
1042 put_transaction(cur_trans); 1081 put_transaction(cur_trans);
1043 1082
@@ -1046,6 +1085,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1046 list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots); 1085 list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots);
1047 1086
1048 mutex_unlock(&root->fs_info->trans_mutex); 1087 mutex_unlock(&root->fs_info->trans_mutex);
1088
1049 kmem_cache_free(btrfs_trans_handle_cachep, trans); 1089 kmem_cache_free(btrfs_trans_handle_cachep, trans);
1050 1090
1051 if (root->fs_info->closing) { 1091 if (root->fs_info->closing) {