diff options
| author | Alex Tomas <alex@clusterfs.com> | 2008-07-11 19:27:31 -0400 | 
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2008-07-11 19:27:31 -0400 | 
| commit | 29a814d2ee0e43c2980f33f91c1311ec06c0aa35 (patch) | |
| tree | dfc9d45fc3194237192b6cde1069faa70fe4c260 | |
| parent | 87c89c232c8f7b3820c33c3b9bc803e9358027da (diff) | |
| download | olio-linux-3.10-29a814d2ee0e43c2980f33f91c1311ec06c0aa35.tar.xz olio-linux-3.10-29a814d2ee0e43c2980f33f91c1311ec06c0aa35.zip  | |
vfs: add hooks for ext4's delayed allocation support
Export mpage_bio_submit() and __mpage_writepage() for the benefit of
ext4's delayed allocation support.   Also change __block_write_full_page
so that if buffers that have the BH_Delay flag set it will call
get_block() to get the physical block allocated, just as in the
!BH_Mapped case.
Signed-off-by: Alex Tomas <alex@clusterfs.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
| -rw-r--r-- | fs/buffer.c | 7 | ||||
| -rw-r--r-- | fs/mpage.c | 14 | ||||
| -rw-r--r-- | include/linux/mpage.h | 10 | 
3 files changed, 20 insertions, 11 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index f4b033237a0..5fa1512cd9a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1691,11 +1691,13 @@ static int __block_write_full_page(struct inode *inode, struct page *page,  			 */  			clear_buffer_dirty(bh);  			set_buffer_uptodate(bh); -		} else if (!buffer_mapped(bh) && buffer_dirty(bh)) { +		} else if ((!buffer_mapped(bh) || buffer_delay(bh)) && +			   buffer_dirty(bh)) {  			WARN_ON(bh->b_size != blocksize);  			err = get_block(inode, block, bh, 1);  			if (err)  				goto recover; +			clear_buffer_delay(bh);  			if (buffer_new(bh)) {  				/* blockdev mappings never come here */  				clear_buffer_new(bh); @@ -1774,7 +1776,8 @@ recover:  	bh = head;  	/* Recovery: lock and submit the mapped buffers */  	do { -		if (buffer_mapped(bh) && buffer_dirty(bh)) { +		if (buffer_mapped(bh) && buffer_dirty(bh) && +		    !buffer_delay(bh)) {  			lock_buffer(bh);  			mark_buffer_async_write(bh);  		} else { diff --git a/fs/mpage.c b/fs/mpage.c index 235e4d3873a..dbcc7af76a1 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -82,7 +82,7 @@ static void mpage_end_io_write(struct bio *bio, int err)  	bio_put(bio);  } -static struct bio *mpage_bio_submit(int rw, struct bio *bio) +struct bio *mpage_bio_submit(int rw, struct bio *bio)  {  	bio->bi_end_io = mpage_end_io_read;  	if (rw == WRITE) @@ -90,6 +90,7 @@ static struct bio *mpage_bio_submit(int rw, struct bio *bio)  	submit_bio(rw, bio);  	return NULL;  } +EXPORT_SYMBOL(mpage_bio_submit);  static struct bio *  mpage_alloc(struct block_device *bdev, @@ -435,15 +436,9 @@ EXPORT_SYMBOL(mpage_readpage);   * written, so it can intelligently allocate a suitably-sized BIO.  For now,   * just allocate full-size (16-page) BIOs.   */ -struct mpage_data { -	struct bio *bio; -	sector_t last_block_in_bio; -	get_block_t *get_block; -	unsigned use_writepage; -}; -static int __mpage_writepage(struct page *page, struct writeback_control *wbc, -			     void *data) +int __mpage_writepage(struct page *page, struct writeback_control *wbc, +		      void *data)  {  	struct mpage_data *mpd = data;  	struct bio *bio = mpd->bio; @@ -651,6 +646,7 @@ out:  	mpd->bio = bio;  	return ret;  } +EXPORT_SYMBOL(__mpage_writepage);  /**   * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them diff --git a/include/linux/mpage.h b/include/linux/mpage.h index 068a0c9946a..5c42821da2d 100644 --- a/include/linux/mpage.h +++ b/include/linux/mpage.h @@ -11,11 +11,21 @@   */  #ifdef CONFIG_BLOCK +struct mpage_data { +	struct bio *bio; +	sector_t last_block_in_bio; +	get_block_t *get_block; +	unsigned use_writepage; +}; +  struct writeback_control; +struct bio *mpage_bio_submit(int rw, struct bio *bio);  int mpage_readpages(struct address_space *mapping, struct list_head *pages,  				unsigned nr_pages, get_block_t get_block);  int mpage_readpage(struct page *page, get_block_t get_block); +int __mpage_writepage(struct page *page, struct writeback_control *wbc, +		      void *data);  int mpage_writepages(struct address_space *mapping,  		struct writeback_control *wbc, get_block_t get_block);  int mpage_writepage(struct page *page, get_block_t *get_block,  |