diff options
author | Sage Weil <sage@newdream.net> | 2008-08-04 10:41:27 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:06 -0400 |
commit | 9ca9ee09c176a814189063c8b88f75c8f8e4ad19 (patch) | |
tree | 3092ed3f5dd472e66a61da9306dfa6839604c42c /fs/btrfs/transaction.h | |
parent | 3117a77370b6cb902191568e4e647cdcba083d0a (diff) |
Btrfs: fix ioctl-initiated transactions vs wait_current_trans()
Commit 597:466b27332893 (btrfs_start_transaction: wait for commits in
progress) breaks the transaction start/stop ioctls by making
btrfs_start_transaction conditionally wait for the next transaction to
start. If an application artificially is holding a transaction open,
things deadlock.
This workaround maintains a count of open ioctl-initiated transactions in
fs_info, and avoids wait_current_trans() if any are currently open (in
start_transaction() and btrfs_throttle()). The start transaction ioctl
uses a new btrfs_start_ioctl_transaction() that _does_ call
wait_current_trans(), effectively pushing the join/wait decision to the
outer ioctl-initiated transaction.
This more or less neuters btrfs_throttle() when ioctl-initiated
transactions are in use, but that seems like a pretty fundamental
consequence of wrapping lots of write()'s in a transaction. Btrfs has no
way to tell if the application considers a given operation as part of it's
transaction.
Obviously, if the transaction start/stop ioctls aren't being used, there
is no effect on current behavior.
Signed-off-by: Sage Weil <sage@newdream.net>
---
ctree.h | 1 +
ioctl.c | 12 +++++++++++-
transaction.c | 18 +++++++++++++-----
transaction.h | 2 ++
4 files changed, 27 insertions(+), 6 deletions(-)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.h')
-rw-r--r-- | fs/btrfs/transaction.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index f5adb23151fb..2c73caeebb2c 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -83,6 +83,8 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | |||
83 | int num_blocks); | 83 | int num_blocks); |
84 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, | 84 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, |
85 | int num_blocks); | 85 | int num_blocks); |
86 | struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, | ||
87 | int num_blocks); | ||
86 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 88 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
87 | struct btrfs_root *root); | 89 | struct btrfs_root *root); |
88 | int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, | 90 | int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, |