Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 332591
b: refs/heads/master
c: 354aa0f
h: refs/heads/master
i:
  332589: 1ae1f1b
  332587: 717db96
  332583: 2c220fe
  332575: 4f9474a
v: v3
  • Loading branch information
Miao Xie authored and Chris Mason committed Oct 9, 2012
1 parent c0f76c3 commit dd4cb48
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 24 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: a698d0755adb6f27289d1e6610b2240595d27e8c
refs/heads/master: 354aa0fb6d5b97b262e056f7ad7bfc88d7ce0004
5 changes: 3 additions & 2 deletions trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1657,9 +1657,10 @@ static int transaction_kthread(void *arg)
spin_unlock(&root->fs_info->trans_lock);

/* If the file system is aborted, this will always fail. */
trans = btrfs_join_transaction(root);
trans = btrfs_attach_transaction(root);
if (IS_ERR(trans)) {
cannot_commit = true;
if (PTR_ERR(trans) != -ENOENT)
cannot_commit = true;
goto sleep;
}
if (transid == trans->transid) {
Expand Down
18 changes: 14 additions & 4 deletions trunk/fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,10 +854,10 @@ int btrfs_sync_fs(struct super_block *sb, int wait)

btrfs_wait_ordered_extents(root, 0);

trans = btrfs_join_transaction_freeze(root);
trans = btrfs_attach_transaction(root);
if (IS_ERR(trans)) {
/* Frozen, don't bother */
if (PTR_ERR(trans) == -EPERM)
/* no transaction, don't bother */
if (PTR_ERR(trans) == -ENOENT)
return 0;
return PTR_ERR(trans);
}
Expand Down Expand Up @@ -1511,7 +1511,17 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,

static int btrfs_freeze(struct super_block *sb)
{
return 0;
struct btrfs_trans_handle *trans;
struct btrfs_root *root = btrfs_sb(sb)->tree_root;

trans = btrfs_attach_transaction(root);
if (IS_ERR(trans)) {
/* no transaction, don't bother */
if (PTR_ERR(trans) == -ENOENT)
return 0;
return PTR_ERR(trans);
}
return btrfs_commit_transaction(trans, root);
}

static int btrfs_unfreeze(struct super_block *sb)
Expand Down
45 changes: 30 additions & 15 deletions trunk/fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static noinline void switch_commit_root(struct btrfs_root *root)
/*
* either allocate a new transaction or hop into the existing one
*/
static noinline int join_transaction(struct btrfs_root *root, int nofail)
static noinline int join_transaction(struct btrfs_root *root, int type)
{
struct btrfs_transaction *cur_trans;
struct btrfs_fs_info *fs_info = root->fs_info;
Expand All @@ -67,7 +67,13 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail)
}

if (fs_info->trans_no_join) {
if (!nofail) {
/*
* If we are JOIN_NOLOCK we're already committing a current
* transaction, we just need a handle to deal with something
* when committing the transaction, such as inode cache and
* space cache. It is a special case.
*/
if (type != TRANS_JOIN_NOLOCK) {
spin_unlock(&fs_info->trans_lock);
return -EBUSY;
}
Expand All @@ -87,6 +93,13 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail)
}
spin_unlock(&fs_info->trans_lock);

/*
* If we are ATTACH, we just want to catch the current transaction,
* and commit it. If there is no transaction, just return ENOENT.
*/
if (type == TRANS_ATTACH)
return -ENOENT;

cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS);
if (!cur_trans)
return -ENOMEM;
Expand Down Expand Up @@ -340,27 +353,28 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
* because we're already holding a ref. We need this because we could
* have raced in and did an fsync() on a file which can kick a commit
* and then we deadlock with somebody doing a freeze.
*
* If we are ATTACH, it means we just want to catch the current
* transaction and commit it, so we needn't do sb_start_intwrite().
*/
if (type != TRANS_JOIN_NOLOCK &&
!__sb_start_write(root->fs_info->sb, SB_FREEZE_FS, false)) {
if (type == TRANS_JOIN_FREEZE) {
kmem_cache_free(btrfs_trans_handle_cachep, h);
return ERR_PTR(-EPERM);
}
if (type < TRANS_JOIN_NOLOCK)
sb_start_intwrite(root->fs_info->sb);
}

if (may_wait_transaction(root, type))
wait_current_trans(root);

do {
ret = join_transaction(root, type == TRANS_JOIN_NOLOCK);
ret = join_transaction(root, type);
if (ret == -EBUSY)
wait_current_trans(root);
} while (ret == -EBUSY);

if (ret < 0) {
sb_end_intwrite(root->fs_info->sb);
/* We must get the transaction if we are JOIN_NOLOCK. */
BUG_ON(type == TRANS_JOIN_NOLOCK);

if (type < TRANS_JOIN_NOLOCK)
sb_end_intwrite(root->fs_info->sb);
kmem_cache_free(btrfs_trans_handle_cachep, h);
return ERR_PTR(ret);
}
Expand Down Expand Up @@ -432,9 +446,9 @@ struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root
return start_transaction(root, 0, TRANS_USERSPACE, 0);
}

struct btrfs_trans_handle *btrfs_join_transaction_freeze(struct btrfs_root *root)
struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root)
{
return start_transaction(root, 0, TRANS_JOIN_FREEZE, 0);
return start_transaction(root, 0, TRANS_ATTACH, 0);
}

/* wait for a transaction commit to be fully complete */
Expand Down Expand Up @@ -605,7 +619,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
}
}

if (lock)
if (trans->type < TRANS_JOIN_NOLOCK)
sb_end_intwrite(root->fs_info->sb);

WARN_ON(cur_trans != info->running_transaction);
Expand Down Expand Up @@ -1678,7 +1692,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
put_transaction(cur_trans);
put_transaction(cur_trans);

sb_end_intwrite(root->fs_info->sb);
if (trans->type < TRANS_JOIN_NOLOCK)
sb_end_intwrite(root->fs_info->sb);

trace_btrfs_transaction_commit(root);

Expand Down
4 changes: 2 additions & 2 deletions trunk/fs/btrfs/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ enum btrfs_trans_type {
TRANS_JOIN,
TRANS_USERSPACE,
TRANS_JOIN_NOLOCK,
TRANS_JOIN_FREEZE,
TRANS_ATTACH,
};

struct btrfs_trans_handle {
Expand Down Expand Up @@ -109,7 +109,7 @@ struct btrfs_trans_handle *btrfs_start_transaction_noflush(
struct btrfs_root *root, int num_items);
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_join_transaction_freeze(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root);
int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
Expand Down

0 comments on commit dd4cb48

Please sign in to comment.