On Thu, Feb 03, 2005 at 07:51:37AM -0800, Badari Pulavarty wrote: > On Wed, 2005-02-02 at 12:19, Sonny Rao wrote: > > On Wed, Feb 02, 2005 at 07:32:04AM -0800, Badari Pulavarty wrote: > > > Hi, > > > > > > I forgot the reason why we don't have ext3_writepages() ? > > > I can dig through to find out, but it would be easy to ask > > > people. > > > > > > Please let me know. > > > > Badari, I seem to have successfully hacked the writeback mode to use > > writepages on a User-Mode Linux instance. I'm going to try it on a > > real box soon. The only issue is that pdflush is passing the create > > parameter as 1 to writepages, which doesn't exactly make sense. I > > suppose it might be needed for a filesystem like XFS which does > > delayed block allocation ? In ext3 however, the blocks should have > > been allocated beforehand. > > Funny, I am also hacking writepages for writeback mode. You are a step > ahead of me :) Please let me know, how it goes.
Well it seems to work, here's my (rather ugly) patch. I'm doing some performance comparisons now. Sonny
diff -Naurp linux-2.6.10-original/fs/ext3/inode.c linux-2.6.10-working/fs/ext3/inode.c --- linux-2.6.10-original/fs/ext3/inode.c 2004-12-24 15:35:01.000000000 -0600 +++ linux-2.6.10-working/fs/ext3/inode.c 2005-01-29 10:45:09.599837136 -0600 @@ -810,6 +810,18 @@ static int ext3_get_block(struct inode * return ret; } +static int ext3_get_block_wpages(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + /* ugly hack, just pass 0 tfor create to get_block_handle */ + /* the blocks shouldd have already been allocated ifwe're in */ + /* writepages writeback */ + return ext3_get_block_handle(NULL, inode, iblock, + bh_result, 0, 0); +} + + + #define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32) static int @@ -1025,6 +1037,32 @@ out: return ret; } +static int ext3_nobh_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + struct inode *inode = page->mapping->host; + int ret; + int needed_blocks = ext3_writepage_trans_blocks(inode); + handle_t *handle; + int retries = 0; + +retry: + handle = ext3_journal_start(inode, needed_blocks); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + goto out; + } + ret = nobh_prepare_write(page, from, to, ext3_get_block); + if (ret) + ext3_journal_stop(handle); + if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) + goto retry; +out: + + return ret; +} + + static int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh) { @@ -1092,7 +1130,7 @@ static int ext3_writeback_commit_write(s new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; if (new_i_size > EXT3_I(inode)->i_disksize) EXT3_I(inode)->i_disksize = new_i_size; - ret = generic_commit_write(file, page, from, to); + ret = nobh_commit_write(file, page, from, to); ret2 = ext3_journal_stop(handle); if (!ret) ret = ret2; @@ -1321,6 +1359,14 @@ out_fail: return ret; } +static int +ext3_writeback_writepages(struct address_space *mapping, + struct writeback_control *wbc) +{ + return mpage_writepages(mapping, wbc, ext3_get_block_wpages); +} + + static int ext3_writeback_writepage(struct page *page, struct writeback_control *wbc) { @@ -1552,8 +1598,9 @@ static struct address_space_operations e .readpage = ext3_readpage, .readpages = ext3_readpages, .writepage = ext3_writeback_writepage, + .writepages = ext3_writeback_writepages, .sync_page = block_sync_page, - .prepare_write = ext3_prepare_write, + .prepare_write = ext3_nobh_prepare_write, .commit_write = ext3_writeback_commit_write, .bmap = ext3_bmap, .invalidatepage = ext3_invalidatepage,