diff options
| author | Wim Van Sebroeck <wim@iguana.be> | 2007-05-11 19:03:13 +0000 | 
|---|---|---|
| committer | Wim Van Sebroeck <wim@iguana.be> | 2007-05-11 19:03:13 +0000 | 
| commit | 5c34202b8bf942da411b6599668a76b07449bbfd (patch) | |
| tree | 5719c361321eaddc8e4f1b0c8a7994f0e9a6fdd3 /fs/buffer.c | |
| parent | 0d4804b31f91cfbcff6d62af0bc09a893a1c8ae0 (diff) | |
| parent | 1f8a6b658a943b4f04a1fc7b3a420360202c86cd (diff) | |
Merge /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/buffer.c')
| -rw-r--r-- | fs/buffer.c | 84 | 
1 files changed, 18 insertions, 66 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 1d0852fa728..aecd057cd0e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -24,7 +24,6 @@  #include <linux/mm.h>  #include <linux/percpu.h>  #include <linux/slab.h> -#include <linux/smp_lock.h>  #include <linux/capability.h>  #include <linux/blkdev.h>  #include <linux/file.h> @@ -44,7 +43,6 @@  #include <linux/bit_spinlock.h>  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); -static void invalidate_bh_lrus(void);  #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers) @@ -333,7 +331,7 @@ out:     we think the disk contains more recent information than the buffercache.     The update == 1 pass marks the buffers we need to update, the update == 2     pass does the actual I/O. */ -void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) +void invalidate_bdev(struct block_device *bdev)  {  	struct address_space *mapping = bdev->bd_inode->i_mapping; @@ -341,11 +339,6 @@ void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)  		return;  	invalidate_bh_lrus(); -	/* -	 * FIXME: what about destroy_dirty_buffers? -	 * We really want to use invalidate_inode_pages2() for -	 * that, but not until that's cleaned up. -	 */  	invalidate_mapping_pages(mapping, 0, -1);  } @@ -1408,7 +1401,7 @@ static void invalidate_bh_lru(void *arg)  	put_cpu_var(bh_lrus);  } -static void invalidate_bh_lrus(void) +void invalidate_bh_lrus(void)  {  	on_each_cpu(invalidate_bh_lru, NULL, 1, 1);  } @@ -1700,17 +1693,8 @@ done:  		 * clean.  Someone wrote them back by hand with  		 * ll_rw_block/submit_bh.  A rare case.  		 */ -		int uptodate = 1; -		do { -			if (!buffer_uptodate(bh)) { -				uptodate = 0; -				break; -			} -			bh = bh->b_this_page; -		} while (bh != head); -		if (uptodate) -			SetPageUptodate(page);  		end_page_writeback(page); +  		/*  		 * The page and buffer_heads can be released at any time from  		 * here on. @@ -1742,6 +1726,7 @@ recover:  	} while ((bh = bh->b_this_page) != head);  	SetPageError(page);  	BUG_ON(PageWriteback(page)); +	mapping_set_error(page->mapping, err);  	set_page_writeback(page);  	do {  		struct buffer_head *next = bh->b_this_page; @@ -1861,13 +1846,8 @@ static int __block_prepare_write(struct inode *inode, struct page *page,  		if (block_start >= to)  			break;  		if (buffer_new(bh)) { -			void *kaddr; -  			clear_buffer_new(bh); -			kaddr = kmap_atomic(page, KM_USER0); -			memset(kaddr+block_start, 0, bh->b_size); -			flush_dcache_page(page); -			kunmap_atomic(kaddr, KM_USER0); +			zero_user_page(page, block_start, bh->b_size, KM_USER0);  			set_buffer_uptodate(bh);  			mark_buffer_dirty(bh);  		} @@ -1955,10 +1935,8 @@ int block_read_full_page(struct page *page, get_block_t *get_block)  					SetPageError(page);  			}  			if (!buffer_mapped(bh)) { -				void *kaddr = kmap_atomic(page, KM_USER0); -				memset(kaddr + i * blocksize, 0, blocksize); -				flush_dcache_page(page); -				kunmap_atomic(kaddr, KM_USER0); +				zero_user_page(page, i * blocksize, blocksize, +						KM_USER0);  				if (!err)  					set_buffer_uptodate(bh);  				continue; @@ -2101,7 +2079,6 @@ int cont_prepare_write(struct page *page, unsigned offset,  	long status;  	unsigned zerofrom;  	unsigned blocksize = 1 << inode->i_blkbits; -	void *kaddr;  	while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) {  		status = -ENOMEM; @@ -2123,10 +2100,8 @@ int cont_prepare_write(struct page *page, unsigned offset,  						PAGE_CACHE_SIZE, get_block);  		if (status)  			goto out_unmap; -		kaddr = kmap_atomic(new_page, KM_USER0); -		memset(kaddr+zerofrom, 0, PAGE_CACHE_SIZE-zerofrom); -		flush_dcache_page(new_page); -		kunmap_atomic(kaddr, KM_USER0); +		zero_user_page(page, zerofrom, PAGE_CACHE_SIZE - zerofrom, +				KM_USER0);  		generic_commit_write(NULL, new_page, zerofrom, PAGE_CACHE_SIZE);  		unlock_page(new_page);  		page_cache_release(new_page); @@ -2153,10 +2128,7 @@ int cont_prepare_write(struct page *page, unsigned offset,  	if (status)  		goto out1;  	if (zerofrom < offset) { -		kaddr = kmap_atomic(page, KM_USER0); -		memset(kaddr+zerofrom, 0, offset-zerofrom); -		flush_dcache_page(page); -		kunmap_atomic(kaddr, KM_USER0); +		zero_user_page(page, zerofrom, offset - zerofrom, KM_USER0);  		__block_commit_write(inode, page, zerofrom, offset);  	}  	return 0; @@ -2355,10 +2327,7 @@ failed:  	 * Error recovery is pretty slack.  Clear the page and mark it dirty  	 * so we'll later zero out any blocks which _were_ allocated.  	 */ -	kaddr = kmap_atomic(page, KM_USER0); -	memset(kaddr, 0, PAGE_CACHE_SIZE); -	flush_dcache_page(page); -	kunmap_atomic(kaddr, KM_USER0); +	zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);  	SetPageUptodate(page);  	set_page_dirty(page);  	return ret; @@ -2397,7 +2366,6 @@ int nobh_writepage(struct page *page, get_block_t *get_block,  	loff_t i_size = i_size_read(inode);  	const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;  	unsigned offset; -	void *kaddr;  	int ret;  	/* Is the page fully inside i_size? */ @@ -2428,10 +2396,7 @@ int nobh_writepage(struct page *page, get_block_t *get_block,  	 * the  page size, the remaining memory is zeroed when mapped, and  	 * writes to that region are not written out to the file."  	 */ -	kaddr = kmap_atomic(page, KM_USER0); -	memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); -	flush_dcache_page(page); -	kunmap_atomic(kaddr, KM_USER0); +	zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0);  out:  	ret = mpage_writepage(page, get_block, wbc);  	if (ret == -EAGAIN) @@ -2452,7 +2417,6 @@ int nobh_truncate_page(struct address_space *mapping, loff_t from)  	unsigned to;  	struct page *page;  	const struct address_space_operations *a_ops = mapping->a_ops; -	char *kaddr;  	int ret = 0;  	if ((offset & (blocksize - 1)) == 0) @@ -2466,10 +2430,8 @@ int nobh_truncate_page(struct address_space *mapping, loff_t from)  	to = (offset + blocksize) & ~(blocksize - 1);  	ret = a_ops->prepare_write(NULL, page, offset, to);  	if (ret == 0) { -		kaddr = kmap_atomic(page, KM_USER0); -		memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); -		flush_dcache_page(page); -		kunmap_atomic(kaddr, KM_USER0); +		zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, +				KM_USER0);  		/*  		 * It would be more correct to call aops->commit_write()  		 * here, but this is more efficient. @@ -2495,7 +2457,6 @@ int block_truncate_page(struct address_space *mapping,  	struct inode *inode = mapping->host;  	struct page *page;  	struct buffer_head *bh; -	void *kaddr;  	int err;  	blocksize = 1 << inode->i_blkbits; @@ -2549,11 +2510,7 @@ int block_truncate_page(struct address_space *mapping,  			goto unlock;  	} -	kaddr = kmap_atomic(page, KM_USER0); -	memset(kaddr + offset, 0, length); -	flush_dcache_page(page); -	kunmap_atomic(kaddr, KM_USER0); - +	zero_user_page(page, offset, length, KM_USER0);  	mark_buffer_dirty(bh);  	err = 0; @@ -2574,7 +2531,6 @@ int block_write_full_page(struct page *page, get_block_t *get_block,  	loff_t i_size = i_size_read(inode);  	const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;  	unsigned offset; -	void *kaddr;  	/* Is the page fully inside i_size? */  	if (page->index < end_index) @@ -2600,10 +2556,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block,  	 * the  page size, the remaining memory is zeroed when mapped, and  	 * writes to that region are not written out to the file."  	 */ -	kaddr = kmap_atomic(page, KM_USER0); -	memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); -	flush_dcache_page(page); -	kunmap_atomic(kaddr, KM_USER0); +	zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, KM_USER0);  	return __block_write_full_page(inode, page, get_block, wbc);  } @@ -2968,8 +2921,7 @@ EXPORT_SYMBOL(free_buffer_head);  static void  init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags)  { -	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == -			    SLAB_CTOR_CONSTRUCTOR) { +	if (flags & SLAB_CTOR_CONSTRUCTOR) {  		struct buffer_head * bh = (struct buffer_head *)data;  		memset(bh, 0, sizeof(*bh)); @@ -2994,7 +2946,7 @@ static void buffer_exit_cpu(int cpu)  static int buffer_cpu_notify(struct notifier_block *self,  			      unsigned long action, void *hcpu)  { -	if (action == CPU_DEAD) +	if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)  		buffer_exit_cpu((unsigned long)hcpu);  	return NOTIFY_OK;  }  | 
