Skip to content

Commit

Permalink
libfs: Open code simple_commit_write into only user
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Boaz Harrosh authored and Al Viro committed Mar 3, 2010
1 parent 4b1ae27 commit ad2a722
Showing 1 changed file with 35 additions and 24 deletions.
59 changes: 35 additions & 24 deletions fs/libfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit ad2a722

Please sign in to comment.