Commit 375f73f9 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ext3: direct-io transaction extending fix

ext3_direct_io_get_blocks() is misinterpreting the return value from
ext3_journal_extend(), and is consequently running out of buffer credits and
going BUG on tremendously large direct-io writes.  Fix that up.

Also, I note that the really large direct-io writes can hold a transaction
open for the entire duration, which can be minutes.  This violates ext3's
attempt to commit data at regular intervals.  Fix that up by looking at the
transaction state: if it's T_LOCKED, shut off the current handle so the
pending commit can complete.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 924cfe97
......@@ -881,26 +881,42 @@ ext3_direct_io_get_blocks(struct inode *inode, sector_t iblock,
handle_t *handle = journal_current_handle();
int ret = 0;
if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
if (!handle)
goto get_block; /* A read */
if (handle->h_transaction->t_state == T_LOCKED) {
/*
* Huge direct-io writes can hold off commits for long
* periods of time. Let this commit run.
*/
ext3_journal_stop(handle);
handle = ext3_journal_start(inode, DIO_CREDITS);
if (IS_ERR(handle))
ret = PTR_ERR(handle);
goto get_block;
}
if (handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
/*
* Getting low on buffer credits...
*/
if (!ext3_journal_extend(handle, DIO_CREDITS)) {
ret = ext3_journal_extend(handle, DIO_CREDITS);
if (ret > 0) {
/*
* Couldn't extend the transaction. Start a new one
* Couldn't extend the transaction. Start a new one.
*/
ret = ext3_journal_restart(handle, DIO_CREDITS);
}
}
get_block:
if (ret == 0)
ret = ext3_get_block_handle(handle, inode, iblock,
bh_result, create, 0);
if (ret == 0)
bh_result->b_size = (1 << inode->i_blkbits);
bh_result->b_size = (1 << inode->i_blkbits);
return ret;
}
/*
* `handle' can be NULL if create is zero
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment