- 论坛徽章:
- 0
|
- static int ocfs2_write_data_page(struct inode *inode, handle_t *handle,
- u64 *p_blkno, struct page *page,
- struct ocfs2_write_ctxt *wc, int new)
- {
- int ret, copied = 0;
- unsigned int from = 0, to = 0;
- unsigned int cluster_start, cluster_end;
- unsigned int zero_from = 0, zero_to = 0;
- ocfs2_figure_cluster_boundaries(OCFS2_SB(inode->i_sb), wc->w_cpos,
- &cluster_start, &cluster_end);
- if ((wc->w_pos >> PAGE_CACHE_SHIFT) == page->index
- && !wc->w_finished_copy) {
- wc->w_this_page = page;
- wc->w_this_page_new = new;
-
- ret = wc->w_write_data_page(inode, wc, p_blkno, &from, &to);
- if (ret < 0) {
- mlog_errno(ret);
- goto out;
- }
- copied = ret;
- zero_from = from;
- zero_to = to;
- if (new) {
- from = cluster_start;
- to = cluster_end;
- }
- } else {
- /*
- * If we haven't allocated the new page yet, we
- * shouldn't be writing it out without copying user
- * data. This is likely a math error from the caller.
- */
- BUG_ON(!new);
- from = cluster_start;
- to = cluster_end;
- ret = ocfs2_map_page_blocks(page, p_blkno, inode,
- cluster_start, cluster_end, 1);
- if (ret) {
- mlog_errno(ret);
- goto out;
- }
- }
- /*
- * Parts of newly allocated pages need to be zero'd.
- *
- * Above, we have also rewritten 'to' and 'from' - as far as
- * the rest of the function is concerned, the entire cluster
- * range inside of a page needs to be written.
- *
- * We can skip this if the page is uptodate - it's already
- * been zero'd from being read in as a hole.
- */
- if (new && !PageUptodate(page))
- ocfs2_clear_page_regions(page, OCFS2_SB(inode->i_sb),
- wc->w_cpos, zero_from, zero_to);
- flush_dcache_page(page);
- if (ocfs2_should_order_data(inode)) {
- ret = walk_page_buffers(handle,
- page_buffers(page),
- from, to, NULL,
- ocfs2_journal_dirty_data);
- if (ret < 0)
- /*
- * linux-2.6.22.5/fs/ocfs2/aops.c
- *
- * how to & necessary to include this case on return?
- * how to re-check in mlog?
- */
- mlog_errno(ret);
- }
- /*
- * We don't use generic_commit_write() because we need to
- * handle our own i_size update.
- */
- ret = block_commit_write(page, from, to);
- if (ret)
- mlog_errno(ret);
- out:
- return copied ? copied : ret;
- }
复制代码 |
|