With strange workloads which do a lot of quick truncation on small filesystems it is possible to get into a situation where there are free blocks on the disk, but they are not allocatable at this time due to their having been freed up in the current JBD transaction. Applications get unexpected ENOSPC errors. We can fix that with this patch, originally by Andreas Dilger which forces a single commit+retry when an ENOSPC is encountered. --- 25-akpm/fs/ext3/inode.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-) diff -puN fs/ext3/inode.c~ext3-bogus-enospc-fix fs/ext3/inode.c --- 25/fs/ext3/inode.c~ext3-bogus-enospc-fix 2004-04-27 01:34:56.729060456 -0700 +++ 25-akpm/fs/ext3/inode.c 2004-04-27 01:34:56.733059848 -0700 @@ -986,15 +986,28 @@ static int ext3_prepare_write(struct fil struct inode *inode = page->mapping->host; int ret, needed_blocks = ext3_writepage_trans_blocks(inode); handle_t *handle; + int tried_commit = 0; +retry: handle = ext3_journal_start(inode, needed_blocks); if (IS_ERR(handle)) { ret = PTR_ERR(handle); goto out; } ret = block_prepare_write(page, from, to, ext3_get_block); - if (ret != 0) - goto prepare_write_failed; + if (ret) { + if (ret != -ENOSPC || tried_commit) + goto prepare_write_failed; + /* + * It could be that there _is_ free space, but it's all tied up + * in uncommitted bitmaps. So force a commit here, which makes + * those blocks allocatable and try again. + */ + tried_commit = 1; + handle->h_sync = 1; + ext3_journal_stop(handle); + goto retry; + } if (ext3_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), _