Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 139462
b: refs/heads/master
c: b7ec40d
h: refs/heads/master
v: v3
  • Loading branch information
Chris Mason committed Mar 24, 2009
1 parent e08eddb commit 8d4d8ac
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 9 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: c3e69d58e86c3917ae4e9e31b4acf490a7cafe60
refs/heads/master: b7ec40d7845bffca8bb3af2ea3f192d6257bbe21
3 changes: 2 additions & 1 deletion trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3797,7 +3797,8 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
break;
if (wret < 0)
ret = wret;
if (trans->transaction->in_commit) {
if (trans->transaction->in_commit ||
trans->transaction->delayed_refs.flushing) {
ret = -EAGAIN;
break;
}
Expand Down
18 changes: 18 additions & 0 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1502,13 +1502,31 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
struct btrfs_trans_handle *trans;
struct btrfs_ordered_extent *ordered_extent;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
struct btrfs_path *path;
int compressed = 0;
int ret;

ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1);
if (!ret)
return 0;

/*
* before we join the transaction, try to do some of our IO.
* This will limit the amount of IO that we have to do with
* the transaction running. We're unlikely to need to do any
* IO if the file extents are new, the disk_i_size checks
* covers the most common case.
*/
if (start < BTRFS_I(inode)->disk_i_size) {
path = btrfs_alloc_path();
if (path) {
ret = btrfs_lookup_file_extent(NULL, root, path,
inode->i_ino,
start, 0);
btrfs_free_path(path);
}
}

trans = btrfs_join_transaction(root, 1);

ordered_extent = btrfs_lookup_ordered_extent(inode, start);
Expand Down
62 changes: 55 additions & 7 deletions trunk/fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
h->alloc_exclude_nr = 0;
h->alloc_exclude_start = 0;
h->delayed_ref_updates = 0;

root->fs_info->running_transaction->use_count++;
mutex_unlock(&root->fs_info->trans_mutex);
return h;
Expand Down Expand Up @@ -281,7 +282,6 @@ void btrfs_throttle(struct btrfs_root *root)
if (!root->fs_info->open_ioctl_trans)
wait_current_trans(root);
mutex_unlock(&root->fs_info->trans_mutex);

throttle_on_drops(root);
}

Expand All @@ -298,6 +298,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
if (cur &&
trans->transaction->delayed_refs.num_heads_ready > 64) {
trans->delayed_ref_updates = 0;

/*
* do a full flush if the transaction is trying
* to close
*/
if (trans->transaction->delayed_refs.flushing)
cur = 0;
btrfs_run_delayed_refs(trans, root, cur);
} else {
break;
Expand Down Expand Up @@ -665,6 +672,31 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
return 0;
}

/*
* when dropping snapshots, we generate a ton of delayed refs, and it makes
* sense not to join the transaction while it is trying to flush the current
* queue of delayed refs out.
*
* This is used by the drop snapshot code only
*/
static noinline int wait_transaction_pre_flush(struct btrfs_fs_info *info)
{
DEFINE_WAIT(wait);

mutex_lock(&info->trans_mutex);
while (info->running_transaction &&
info->running_transaction->delayed_refs.flushing) {
prepare_to_wait(&info->transaction_wait, &wait,
TASK_UNINTERRUPTIBLE);
mutex_unlock(&info->trans_mutex);
schedule();
mutex_lock(&info->trans_mutex);
finish_wait(&info->transaction_wait, &wait);
}
mutex_unlock(&info->trans_mutex);
return 0;
}

/*
* Given a list of roots that need to be deleted, call btrfs_drop_snapshot on
* all of them
Expand Down Expand Up @@ -692,7 +724,22 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
atomic_inc(&root->fs_info->throttles);

while (1) {
/*
* we don't want to jump in and create a bunch of
* delayed refs if the transaction is starting to close
*/
wait_transaction_pre_flush(tree_root->fs_info);
trans = btrfs_start_transaction(tree_root, 1);

/*
* we've joined a transaction, make sure it isn't
* closing right now
*/
if (trans->transaction->delayed_refs.flushing) {
btrfs_end_transaction(trans, tree_root);
continue;
}

mutex_lock(&root->fs_info->drop_mutex);
ret = btrfs_drop_snapshot(trans, dirty->root);
if (ret != -EAGAIN)
Expand Down Expand Up @@ -932,20 +979,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
ret = btrfs_run_delayed_refs(trans, root, 0);
BUG_ON(ret);

cur_trans = trans->transaction;
/*
* set the flushing flag so procs in this transaction have to
* start sending their work down.
*/
trans->transaction->delayed_refs.flushing = 1;
cur_trans->delayed_refs.flushing = 1;

ret = btrfs_run_delayed_refs(trans, root, 0);
BUG_ON(ret);

INIT_LIST_HEAD(&dirty_fs_roots);
mutex_lock(&root->fs_info->trans_mutex);
if (trans->transaction->in_commit) {
cur_trans = trans->transaction;
trans->transaction->use_count++;
INIT_LIST_HEAD(&dirty_fs_roots);
if (cur_trans->in_commit) {
cur_trans->use_count++;
mutex_unlock(&root->fs_info->trans_mutex);
btrfs_end_transaction(trans, root);

Expand All @@ -968,7 +1015,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,

trans->transaction->in_commit = 1;
trans->transaction->blocked = 1;
cur_trans = trans->transaction;
if (cur_trans->list.prev != &root->fs_info->trans_list) {
prev_trans = list_entry(cur_trans->list.prev,
struct btrfs_transaction, list);
Expand Down Expand Up @@ -1081,6 +1127,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
btrfs_copy_pinned(root, pinned_copy);

trans->transaction->blocked = 0;

wake_up(&root->fs_info->transaction_throttle);
wake_up(&root->fs_info->transaction_wait);

Expand All @@ -1107,6 +1154,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_lock(&root->fs_info->trans_mutex);

cur_trans->commit_done = 1;

root->fs_info->last_trans_committed = cur_trans->transid;
wake_up(&cur_trans->commit_wait);

Expand Down
5 changes: 5 additions & 0 deletions trunk/fs/btrfs/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@

struct btrfs_transaction {
u64 transid;
/*
* total writers in this transaction, it must be zero before the
* transaction can end
*/
unsigned long num_writers;

unsigned long num_joined;
int in_commit;
int use_count;
Expand Down

0 comments on commit 8d4d8ac

Please sign in to comment.