Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 189473
b: refs/heads/master
c: 6bdb72d
h: refs/heads/master
i:
  189471: ab240d5
v: v3
  • Loading branch information
Sage Weil authored and Chris Mason committed Apr 5, 2010
1 parent d59f5ce commit 994df88
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b5cb160084fad438c513d0952849e597ffe9e3d9
refs/heads/master: 6bdb72ded1e281cd8844918c39d00cdd0e59f655
97 changes: 31 additions & 66 deletions trunk/fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,10 +755,17 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
struct btrfs_root_item *new_root_item;
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_root *root = pending->root;
struct btrfs_root *parent_root;
struct inode *parent_inode;
struct extent_buffer *tmp;
struct extent_buffer *old;
int ret;
u64 objectid;
int namelen;
u64 index = 0;

parent_inode = pending->dentry->d_parent->d_inode;
parent_root = BTRFS_I(parent_inode)->root;

new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
if (!new_root_item) {
Expand All @@ -769,79 +776,59 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
if (ret)
goto fail;

record_root_in_trans(trans, root);
btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));

key.objectid = objectid;
/* record when the snapshot was created in key.offset */
key.offset = trans->transid;
btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);

old = btrfs_lock_root_node(root);
btrfs_cow_block(trans, root, old, NULL, 0, &old);
btrfs_set_lock_blocking(old);

btrfs_copy_root(trans, root, old, &tmp, objectid);
btrfs_tree_unlock(old);
free_extent_buffer(old);

btrfs_set_root_node(new_root_item, tmp);
ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
new_root_item);
btrfs_tree_unlock(tmp);
free_extent_buffer(tmp);
if (ret)
goto fail;

key.offset = (u64)-1;
memcpy(&pending->root_key, &key, sizeof(key));
fail:
kfree(new_root_item);
return ret;
}

static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
struct btrfs_pending_snapshot *pending)
{
int ret;
int namelen;
u64 index = 0;
struct btrfs_trans_handle *trans;
struct inode *parent_inode;
struct btrfs_root *parent_root;

parent_inode = pending->dentry->d_parent->d_inode;
parent_root = BTRFS_I(parent_inode)->root;
trans = btrfs_join_transaction(parent_root, 1);
pending->root_key.offset = (u64)-1;

record_root_in_trans(trans, parent_root);
/*
* insert the directory item
*/
namelen = strlen(pending->name);
ret = btrfs_set_inode_index(parent_inode, &index);
BUG_ON(ret);
ret = btrfs_insert_dir_item(trans, parent_root,
pending->name, namelen,
parent_inode->i_ino,
&pending->root_key, BTRFS_FT_DIR, index);

if (ret)
goto fail;
BUG_ON(ret);

btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2);
ret = btrfs_update_inode(trans, parent_root, parent_inode);
BUG_ON(ret);

record_root_in_trans(trans, root);
btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));

old = btrfs_lock_root_node(root);
btrfs_cow_block(trans, root, old, NULL, 0, &old);
btrfs_set_lock_blocking(old);

btrfs_copy_root(trans, root, old, &tmp, objectid);
btrfs_tree_unlock(old);
free_extent_buffer(old);

btrfs_set_root_node(new_root_item, tmp);
ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
new_root_item);
BUG_ON(ret);
btrfs_tree_unlock(tmp);
free_extent_buffer(tmp);

ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root,
pending->root_key.objectid,
parent_root->root_key.objectid,
parent_inode->i_ino, index, pending->name,
namelen);

BUG_ON(ret);

fail:
btrfs_end_transaction(trans, fs_info->fs_root);
kfree(new_root_item);
return ret;
}

Expand All @@ -862,25 +849,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
return 0;
}

static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info)
{
struct btrfs_pending_snapshot *pending;
struct list_head *head = &trans->transaction->pending_snapshots;
int ret;

while (!list_empty(head)) {
pending = list_entry(head->next,
struct btrfs_pending_snapshot, list);
ret = finish_pending_snapshot(fs_info, pending);
BUG_ON(ret);
list_del(&pending->list);
kfree(pending->name);
kfree(pending);
}
return 0;
}

static void update_super_roots(struct btrfs_root *root)
{
struct btrfs_root_item *root_item;
Expand Down Expand Up @@ -1092,9 +1060,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,

btrfs_finish_extent_commit(trans, root);

/* do the directory inserts of any pending snapshot creations */
finish_pending_snapshots(trans, root->fs_info);

mutex_lock(&root->fs_info->trans_mutex);

cur_trans->commit_done = 1;
Expand Down

0 comments on commit 994df88

Please sign in to comment.