|
@@ -370,40 +370,51 @@ int simple_write_begin(struct file *file, struct address_space *mapping,
|
|
return simple_prepare_write(file, page, from, from+len);
|
|
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,
|
|
int simple_write_end(struct file *file, struct address_space *mapping,
|
|
loff_t pos, unsigned len, unsigned copied,
|
|
loff_t pos, unsigned len, unsigned copied,
|
|
struct page *page, void *fsdata)
|
|
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 */
|
|
/* zero the stale part of the page if we did a short copy */
|
|
if (copied < len) {
|
|
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);
|
|
unlock_page(page);
|
|
page_cache_release(page);
|
|
page_cache_release(page);
|
|
|
|
|