-/*
- * This writes the data from the source page to the specified page offset in
- * the nominated file
- * - the source page does not need to have any association with the file or the
- * page offset
- */
-int
-generic_file_buffered_write_one_kernel_page(struct address_space *mapping,
- pgoff_t index,
- struct page *src)
-{
- const struct address_space_operations *a_ops = mapping->a_ops;
- struct pagevec lru_pvec;
- struct page *page, *cached_page = NULL;
- long status = 0;
-
- pagevec_init(&lru_pvec, 0);
-
-#if 0
- if (mapping->tree_lock.magic != RWLOCK_MAGIC)
- printk("RWLOCK magic incorrect: %x != %x\n",
- mapping->tree_lock.magic, RWLOCK_MAGIC);
-#endif
-
- page = __grab_cache_page(mapping, index, &cached_page, &lru_pvec);
- if (!page) {
- BUG_ON(cached_page);
- return -ENOMEM;
- }
-
- status = a_ops->prepare_write(NULL, page, 0, PAGE_CACHE_SIZE);
- if (unlikely(status)) {
- loff_t isize = i_size_read(mapping->host);
-
- if (status != AOP_TRUNCATED_PAGE)
- unlock_page(page);
- page_cache_release(page);
- if (status == AOP_TRUNCATED_PAGE)
- goto sync;
-
- /* prepare_write() may have instantiated a few blocks outside
- * i_size. Trim these off again.
- */
- if ((1ULL << (index + 1)) > isize)
- vmtruncate(mapping->host, isize);
- goto sync;
- }
-
- copy_highpage(page, src);
- flush_dcache_page(page);
-
- status = a_ops->commit_write(NULL, page, 0, PAGE_CACHE_SIZE);
- if (status == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- goto sync;
- }
-
- if (status > 0)
- status = 0;
-
- unlock_page(page);
- mark_page_accessed(page);
- page_cache_release(page);
- if (status < 0)
- return status;
-
- balance_dirty_pages_ratelimited(mapping);
- cond_resched();
-
-sync:
- if (cached_page)
- page_cache_release(cached_page);
-
- /* the caller must handle O_SYNC themselves, but we handle S_SYNC and
- * MS_SYNCHRONOUS here */
- if (unlikely(IS_SYNC(mapping->host)) && !a_ops->writepage)
- status = generic_osync_inode(mapping->host, mapping,
- OSYNC_METADATA | OSYNC_DATA);
-
- /* the caller must handle O_DIRECT for themselves */
-
- pagevec_lru_add(&lru_pvec);
- return status;
-}
-EXPORT_SYMBOL(generic_file_buffered_write_one_kernel_page);
-