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/ctree.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/ctree.h')
-rw-r--r-- | fs/btrfs/ctree.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9b025960bbd..62499dd761b 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -518,6 +518,7 @@ struct btrfs_fs_info { | |||
518 | 518 | ||
519 | u64 generation; | 519 | u64 generation; |
520 | u64 last_trans_committed; | 520 | u64 last_trans_committed; |
521 | u64 open_ioctl_trans; | ||
521 | unsigned long mount_opt; | 522 | unsigned long mount_opt; |
522 | u64 max_extent; | 523 | u64 max_extent; |
523 | u64 max_inline; | 524 | u64 max_inline; |