aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-11-17 20:37:39 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-17 20:37:39 -0500
commit0660b5af3f7ac0fac69de975914e1f4a3a586fb3 (patch)
tree5e911dfad23df29f1815fbbc76d38ffff7fe36d8 /fs/btrfs/transaction.c
parent3394e1607eaf870ebba37d303fbd590a4c569908 (diff)
Btrfs: Add backrefs and forward refs for subvols and snapshots
Subvols and snapshots can now be referenced from any point in the directory tree. We need to maintain back refs for them so we can find lost subvols. Forward refs are added so that we know all of the subvols and snapshots referenced anywhere in the directory tree of a single subvol. This can be used to do recursive snapshotting (but they aren't yet) and it is also used to detect and prevent directory loops when creating new snapshots. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 93f23a456a36..e9c8ebeedd7e 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -831,28 +831,43 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
831 struct btrfs_trans_handle *trans; 831 struct btrfs_trans_handle *trans;
832 struct inode *parent_inode; 832 struct inode *parent_inode;
833 struct inode *inode; 833 struct inode *inode;
834 struct btrfs_root *parent_root;
834 835
835 parent_inode = pending->dentry->d_parent->d_inode; 836 parent_inode = pending->dentry->d_parent->d_inode;
836 trans = btrfs_start_transaction(BTRFS_I(parent_inode)->root, 1); 837 parent_root = BTRFS_I(parent_inode)->root;
838 trans = btrfs_start_transaction(parent_root, 1);
837 839
838 /* 840 /*
839 * insert the directory item 841 * insert the directory item
840 */ 842 */
841 namelen = strlen(pending->name); 843 namelen = strlen(pending->name);
842 ret = btrfs_set_inode_index(parent_inode, &index); 844 ret = btrfs_set_inode_index(parent_inode, &index);
843 ret = btrfs_insert_dir_item(trans, 845 ret = btrfs_insert_dir_item(trans, parent_root,
844 BTRFS_I(parent_inode)->root,
845 pending->name, namelen, 846 pending->name, namelen,
846 parent_inode->i_ino, 847 parent_inode->i_ino,
847 &pending->root_key, BTRFS_FT_DIR, index); 848 &pending->root_key, BTRFS_FT_DIR, index);
848 849
849 if (ret) 850 if (ret)
850 goto fail; 851 goto fail;
851#if 0 852
852 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root, 853 /* add the backref first */
853 pending->name, strlen(pending->name), objectid, 854 ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
854 root->fs_info->sb->s_root->d_inode->i_ino, 0); 855 pending->root_key.objectid,
855#endif 856 BTRFS_ROOT_BACKREF_KEY,
857 parent_root->root_key.objectid,
858 parent_inode->i_ino, index, pending->name,
859 namelen);
860
861 BUG_ON(ret);
862
863 /* now add the forward ref */
864 ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
865 parent_root->root_key.objectid,
866 BTRFS_ROOT_REF_KEY,
867 pending->root_key.objectid,
868 parent_inode->i_ino, index, pending->name,
869 namelen);
870
856 inode = btrfs_lookup_dentry(parent_inode, pending->dentry); 871 inode = btrfs_lookup_dentry(parent_inode, pending->dentry);
857 d_instantiate(pending->dentry, inode); 872 d_instantiate(pending->dentry, inode);
858fail: 873fail: