diff options
| author | Boaz Harrosh <bharrosh@panasas.com> | 2010-01-12 15:13:47 +0200 | 
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-03-03 13:00:16 -0500 | 
| commit | ad2a722f196d2b014f49e6c37e072df71eb3695f (patch) | |
| tree | 5f643dc85181e1f2a63a906de316c3091c93c360 /fs/libfs.c | |
| parent | 4b1ae27a96d9860e6c4348673e8fb6a0322511fe (diff) | |
libfs: Open code simple_commit_write into only user
* simple_commit_write was only called by simple_write_end.
  Open coding it makes it tiny bit less heavy on the arithmetic and
  much more readable.
* While at it use zero_user() for clearing a partial page.
* While at it add a docbook comment for simple_write_end.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/libfs.c')
| -rw-r--r-- | fs/libfs.c | 59 | 
1 files changed, 35 insertions, 24 deletions
| diff --git a/fs/libfs.c b/fs/libfs.c index 6e8d17e1dc4c..cd88abdcb436 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -370,40 +370,51 @@ int simple_write_begin(struct file *file, struct address_space *mapping,  	return simple_prepare_write(file, page, from, from+len);  } -static int simple_commit_write(struct file *file, struct page *page, -			       unsigned from, unsigned to) -{ -	struct inode *inode = page->mapping->host; -	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - -	if (!PageUptodate(page)) -		SetPageUptodate(page); -	/* -	 * No need to use i_size_read() here, the i_size -	 * cannot change under us because we hold the i_mutex. -	 */ -	if (pos > inode->i_size) -		i_size_write(inode, pos); -	set_page_dirty(page); -	return 0; -} - +/** + * simple_write_end - .write_end helper for non-block-device FSes + * @available: See .write_end of address_space_operations + * @file: 		" + * @mapping: 		" + * @pos: 		" + * @len: 		" + * @copied: 		" + * @page: 		" + * @fsdata: 		" + * + * simple_write_end does the minimum needed for updating a page after writing is + * done. It has the same API signature as the .write_end of + * address_space_operations vector. So it can just be set onto .write_end for + * FSes that don't need any other processing. i_mutex is assumed to be held. + * Block based filesystems should use generic_write_end(). + * NOTE: Even though i_size might get updated by this function, mark_inode_dirty + * is not called, so a filesystem that actually does store data in .write_inode + * should extend on what's done here with a call to mark_inode_dirty() in the + * case that i_size has changed. + */  int simple_write_end(struct file *file, struct address_space *mapping,  			loff_t pos, unsigned len, unsigned copied,  			struct page *page, void *fsdata)  { -	unsigned from = pos & (PAGE_CACHE_SIZE - 1); +	struct inode *inode = page->mapping->host; +	loff_t last_pos = pos + copied;  	/* zero the stale part of the page if we did a short copy */  	if (copied < len) { -		void *kaddr = kmap_atomic(page, KM_USER0); -		memset(kaddr + from + copied, 0, len - copied); -		flush_dcache_page(page); -		kunmap_atomic(kaddr, KM_USER0); +		unsigned from = pos & (PAGE_CACHE_SIZE - 1); + +		zero_user(page, from + copied, len - copied);  	} -	simple_commit_write(file, page, from, from+copied); +	if (!PageUptodate(page)) +		SetPageUptodate(page); +	/* +	 * No need to use i_size_read() here, the i_size +	 * cannot change under us because we hold the i_mutex. +	 */ +	if (last_pos > inode->i_size) +		i_size_write(inode, last_pos); +	set_page_dirty(page);  	unlock_page(page);  	page_cache_release(page); | 
