diff options
| author | Jan Kara <jack@suse.cz> | 2012-03-12 16:05:50 +0100 | 
|---|---|---|
| committer | David Sterba <dsterba@suse.cz> | 2012-03-22 11:53:11 +0100 | 
| commit | 914b20070b413ca10f832c45a58b2894990f065f (patch) | |
| tree | 1c1f6af7f0f1243e9585a4b726065d579eebc3e9 | |
| parent | 79787eaab46121d4713ed03c8fc63b9ec3eaec76 (diff) | |
btrfs: Fix busyloop in transaction_kthread()
When a filesystem got aborted due do error, transaction_kthread() will
busyloop.  Fix it by going to sleep in that case as well. Maybe we should
just stop transaction_kthread() when filesystem is aborted but that would be
more complex.
Signed-off-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/btrfs/disk-io.c | 9 | 
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 16a0cada26c2..438993e3d832 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1640,8 +1640,10 @@ static int transaction_kthread(void *arg)  	u64 transid;  	unsigned long now;  	unsigned long delay; +	bool cannot_commit;  	do { +		cannot_commit = false;  		delay = HZ * 30;  		vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);  		mutex_lock(&root->fs_info->transaction_kthread_mutex); @@ -1665,8 +1667,10 @@ static int transaction_kthread(void *arg)  		/* If the file system is aborted, this will always fail. */  		trans = btrfs_join_transaction(root); -		if (IS_ERR(trans)) +		if (IS_ERR(trans)) { +			cannot_commit = true;  			goto sleep; +		}  		if (transid == trans->transid) {  			btrfs_commit_transaction(trans, root);  		} else { @@ -1679,7 +1683,8 @@ sleep:  		if (!try_to_freeze()) {  			set_current_state(TASK_INTERRUPTIBLE);  			if (!kthread_should_stop() && -			    !btrfs_transaction_blocked(root->fs_info)) +			    (!btrfs_transaction_blocked(root->fs_info) || +			     cannot_commit))  				schedule_timeout(delay);  			__set_current_state(TASK_RUNNING);  		}  | 
