Loading fs/ocfs2/aops.c +4 −3 Original line number Diff line number Diff line Loading @@ -1642,7 +1642,8 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh, return ret; } int ocfs2_write_begin_nolock(struct address_space *mapping, int ocfs2_write_begin_nolock(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata, struct buffer_head *di_bh, struct page *mmap_page) Loading Loading @@ -1692,7 +1693,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, mlog_errno(ret); goto out; } else if (ret == 1) { ret = ocfs2_refcount_cow(inode, di_bh, ret = ocfs2_refcount_cow(inode, filp, di_bh, wc->w_cpos, wc->w_clen, UINT_MAX); if (ret) { mlog_errno(ret); Loading Loading @@ -1854,7 +1855,7 @@ static int ocfs2_write_begin(struct file *file, struct address_space *mapping, */ down_write(&OCFS2_I(inode)->ip_alloc_sem); ret = ocfs2_write_begin_nolock(mapping, pos, len, flags, pagep, ret = ocfs2_write_begin_nolock(file, mapping, pos, len, flags, pagep, fsdata, di_bh, NULL); if (ret) { mlog_errno(ret); Loading fs/ocfs2/aops.h +2 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,8 @@ int ocfs2_write_end_nolock(struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata); int ocfs2_write_begin_nolock(struct address_space *mapping, int ocfs2_write_begin_nolock(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata, struct buffer_head *di_bh, struct page *mmap_page); Loading fs/ocfs2/file.c +10 −7 Original line number Diff line number Diff line Loading @@ -360,7 +360,7 @@ static int ocfs2_cow_file_pos(struct inode *inode, if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) goto out; return ocfs2_refcount_cow(inode, fe_bh, cpos, 1, cpos+1); return ocfs2_refcount_cow(inode, NULL, fe_bh, cpos, 1, cpos+1); out: return status; Loading Loading @@ -903,8 +903,8 @@ static int ocfs2_zero_extend_get_range(struct inode *inode, zero_clusters = last_cpos - zero_cpos; if (needs_cow) { rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters, UINT_MAX); rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos, zero_clusters, UINT_MAX); if (rc) { mlog_errno(rc); goto out; Loading Loading @@ -2052,6 +2052,7 @@ int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, } static int ocfs2_prepare_inode_for_refcount(struct inode *inode, struct file *file, loff_t pos, size_t count, int *meta_level) { Loading @@ -2069,7 +2070,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode, *meta_level = 1; ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX); ret = ocfs2_refcount_cow(inode, file, di_bh, cpos, clusters, UINT_MAX); if (ret) mlog_errno(ret); out: Loading @@ -2077,7 +2078,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode, return ret; } static int ocfs2_prepare_inode_for_write(struct dentry *dentry, static int ocfs2_prepare_inode_for_write(struct file *file, loff_t *ppos, size_t count, int appending, Loading @@ -2085,6 +2086,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, int *has_refcount) { int ret = 0, meta_level = 0; struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; loff_t saved_pos, end; Loading Loading @@ -2140,6 +2142,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, meta_level = -1; ret = ocfs2_prepare_inode_for_refcount(inode, file, saved_pos, count, &meta_level); Loading Loading @@ -2254,7 +2257,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, } can_do_direct = direct_io; ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos, ret = ocfs2_prepare_inode_for_write(file, ppos, iocb->ki_left, appending, &can_do_direct, &has_refcount); if (ret < 0) { Loading Loading @@ -2373,7 +2376,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, { int ret; ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, ret = ocfs2_prepare_inode_for_write(out, &sd->pos, sd->total_len, 0, NULL, NULL); if (ret < 0) { mlog_errno(ret); Loading fs/ocfs2/mmap.c +4 −3 Original line number Diff line number Diff line Loading @@ -59,10 +59,11 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) return ret; } static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh, struct page *page) { int ret; struct inode *inode = file->f_path.dentry->d_inode; struct address_space *mapping = inode->i_mapping; loff_t pos = page_offset(page); unsigned int len = PAGE_CACHE_SIZE; Loading Loading @@ -111,7 +112,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, if (page->index == last_index) len = ((size - 1) & ~PAGE_CACHE_MASK) + 1; ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, ret = ocfs2_write_begin_nolock(file, mapping, pos, len, 0, &locked_page, &fsdata, di_bh, page); if (ret) { if (ret != -ENOSPC) Loading Loading @@ -159,7 +160,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) */ down_write(&OCFS2_I(inode)->ip_alloc_sem); ret = __ocfs2_page_mkwrite(inode, di_bh, page); ret = __ocfs2_page_mkwrite(vma->vm_file, di_bh, page); up_write(&OCFS2_I(inode)->ip_alloc_sem); Loading fs/ocfs2/refcounttree.c +41 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct ocfs2_cow_context { struct inode *inode; struct file *file; u32 cow_start; u32 cow_len; struct ocfs2_extent_tree data_et; Loading Loading @@ -2932,13 +2933,16 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); struct page *page; pgoff_t page_index; unsigned int from, to; unsigned int from, to, readahead_pages; loff_t offset, end, map_end; struct address_space *mapping = context->inode->i_mapping; mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster, new_cluster, new_len, cpos); readahead_pages = (ocfs2_cow_contig_clusters(sb) << OCFS2_SB(sb)->s_clustersize_bits) >> PAGE_CACHE_SHIFT; offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); /* Loading Loading @@ -2969,6 +2973,14 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) BUG_ON(PageDirty(page)); if (PageReadahead(page) && context->file) { page_cache_async_readahead(mapping, &context->file->f_ra, context->file, page, page_index, readahead_pages); } if (!PageUptodate(page)) { ret = block_read_full_page(page, ocfs2_get_block); if (ret) { Loading Loading @@ -3409,12 +3421,35 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context) return ret; } static void ocfs2_readahead_for_cow(struct inode *inode, struct file *file, u32 start, u32 len) { struct address_space *mapping; pgoff_t index; unsigned long num_pages; int cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits; if (!file) return; mapping = file->f_mapping; num_pages = (len << cs_bits) >> PAGE_CACHE_SHIFT; if (!num_pages) num_pages = 1; index = ((loff_t)start << cs_bits) >> PAGE_CACHE_SHIFT; page_cache_sync_readahead(mapping, &file->f_ra, file, index, num_pages); } /* * Starting at cpos, try to CoW write_len clusters. Don't CoW * past max_cpos. This will stop when it runs into a hole or an * unrefcounted extent. */ static int ocfs2_refcount_cow_hunk(struct inode *inode, struct file *file, struct buffer_head *di_bh, u32 cpos, u32 write_len, u32 max_cpos) { Loading Loading @@ -3443,6 +3478,8 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, BUG_ON(cow_len == 0); ocfs2_readahead_for_cow(inode, file, cow_start, cow_len); context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); if (!context) { ret = -ENOMEM; Loading @@ -3464,6 +3501,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, context->ref_root_bh = ref_root_bh; context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page; context->get_clusters = ocfs2_di_get_clusters; context->file = file; ocfs2_init_dinode_extent_tree(&context->data_et, INODE_CACHE(inode), di_bh); Loading Loading @@ -3492,6 +3530,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, * clusters between cpos and cpos+write_len are safe to modify. */ int ocfs2_refcount_cow(struct inode *inode, struct file *file, struct buffer_head *di_bh, u32 cpos, u32 write_len, u32 max_cpos) { Loading @@ -3511,7 +3550,7 @@ int ocfs2_refcount_cow(struct inode *inode, num_clusters = write_len; if (ext_flags & OCFS2_EXT_REFCOUNTED) { ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos, ret = ocfs2_refcount_cow_hunk(inode, file, di_bh, cpos, num_clusters, max_cpos); if (ret) { mlog_errno(ret); Loading Loading
fs/ocfs2/aops.c +4 −3 Original line number Diff line number Diff line Loading @@ -1642,7 +1642,8 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh, return ret; } int ocfs2_write_begin_nolock(struct address_space *mapping, int ocfs2_write_begin_nolock(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata, struct buffer_head *di_bh, struct page *mmap_page) Loading Loading @@ -1692,7 +1693,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, mlog_errno(ret); goto out; } else if (ret == 1) { ret = ocfs2_refcount_cow(inode, di_bh, ret = ocfs2_refcount_cow(inode, filp, di_bh, wc->w_cpos, wc->w_clen, UINT_MAX); if (ret) { mlog_errno(ret); Loading Loading @@ -1854,7 +1855,7 @@ static int ocfs2_write_begin(struct file *file, struct address_space *mapping, */ down_write(&OCFS2_I(inode)->ip_alloc_sem); ret = ocfs2_write_begin_nolock(mapping, pos, len, flags, pagep, ret = ocfs2_write_begin_nolock(file, mapping, pos, len, flags, pagep, fsdata, di_bh, NULL); if (ret) { mlog_errno(ret); Loading
fs/ocfs2/aops.h +2 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,8 @@ int ocfs2_write_end_nolock(struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata); int ocfs2_write_begin_nolock(struct address_space *mapping, int ocfs2_write_begin_nolock(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata, struct buffer_head *di_bh, struct page *mmap_page); Loading
fs/ocfs2/file.c +10 −7 Original line number Diff line number Diff line Loading @@ -360,7 +360,7 @@ static int ocfs2_cow_file_pos(struct inode *inode, if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) goto out; return ocfs2_refcount_cow(inode, fe_bh, cpos, 1, cpos+1); return ocfs2_refcount_cow(inode, NULL, fe_bh, cpos, 1, cpos+1); out: return status; Loading Loading @@ -903,8 +903,8 @@ static int ocfs2_zero_extend_get_range(struct inode *inode, zero_clusters = last_cpos - zero_cpos; if (needs_cow) { rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters, UINT_MAX); rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos, zero_clusters, UINT_MAX); if (rc) { mlog_errno(rc); goto out; Loading Loading @@ -2052,6 +2052,7 @@ int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, } static int ocfs2_prepare_inode_for_refcount(struct inode *inode, struct file *file, loff_t pos, size_t count, int *meta_level) { Loading @@ -2069,7 +2070,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode, *meta_level = 1; ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX); ret = ocfs2_refcount_cow(inode, file, di_bh, cpos, clusters, UINT_MAX); if (ret) mlog_errno(ret); out: Loading @@ -2077,7 +2078,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode, return ret; } static int ocfs2_prepare_inode_for_write(struct dentry *dentry, static int ocfs2_prepare_inode_for_write(struct file *file, loff_t *ppos, size_t count, int appending, Loading @@ -2085,6 +2086,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, int *has_refcount) { int ret = 0, meta_level = 0; struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; loff_t saved_pos, end; Loading Loading @@ -2140,6 +2142,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry, meta_level = -1; ret = ocfs2_prepare_inode_for_refcount(inode, file, saved_pos, count, &meta_level); Loading Loading @@ -2254,7 +2257,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, } can_do_direct = direct_io; ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos, ret = ocfs2_prepare_inode_for_write(file, ppos, iocb->ki_left, appending, &can_do_direct, &has_refcount); if (ret < 0) { Loading Loading @@ -2373,7 +2376,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, { int ret; ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, ret = ocfs2_prepare_inode_for_write(out, &sd->pos, sd->total_len, 0, NULL, NULL); if (ret < 0) { mlog_errno(ret); Loading
fs/ocfs2/mmap.c +4 −3 Original line number Diff line number Diff line Loading @@ -59,10 +59,11 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) return ret; } static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh, struct page *page) { int ret; struct inode *inode = file->f_path.dentry->d_inode; struct address_space *mapping = inode->i_mapping; loff_t pos = page_offset(page); unsigned int len = PAGE_CACHE_SIZE; Loading Loading @@ -111,7 +112,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, if (page->index == last_index) len = ((size - 1) & ~PAGE_CACHE_MASK) + 1; ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, ret = ocfs2_write_begin_nolock(file, mapping, pos, len, 0, &locked_page, &fsdata, di_bh, page); if (ret) { if (ret != -ENOSPC) Loading Loading @@ -159,7 +160,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) */ down_write(&OCFS2_I(inode)->ip_alloc_sem); ret = __ocfs2_page_mkwrite(inode, di_bh, page); ret = __ocfs2_page_mkwrite(vma->vm_file, di_bh, page); up_write(&OCFS2_I(inode)->ip_alloc_sem); Loading
fs/ocfs2/refcounttree.c +41 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct ocfs2_cow_context { struct inode *inode; struct file *file; u32 cow_start; u32 cow_len; struct ocfs2_extent_tree data_et; Loading Loading @@ -2932,13 +2933,16 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); struct page *page; pgoff_t page_index; unsigned int from, to; unsigned int from, to, readahead_pages; loff_t offset, end, map_end; struct address_space *mapping = context->inode->i_mapping; mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster, new_cluster, new_len, cpos); readahead_pages = (ocfs2_cow_contig_clusters(sb) << OCFS2_SB(sb)->s_clustersize_bits) >> PAGE_CACHE_SHIFT; offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); /* Loading Loading @@ -2969,6 +2973,14 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) BUG_ON(PageDirty(page)); if (PageReadahead(page) && context->file) { page_cache_async_readahead(mapping, &context->file->f_ra, context->file, page, page_index, readahead_pages); } if (!PageUptodate(page)) { ret = block_read_full_page(page, ocfs2_get_block); if (ret) { Loading Loading @@ -3409,12 +3421,35 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context) return ret; } static void ocfs2_readahead_for_cow(struct inode *inode, struct file *file, u32 start, u32 len) { struct address_space *mapping; pgoff_t index; unsigned long num_pages; int cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits; if (!file) return; mapping = file->f_mapping; num_pages = (len << cs_bits) >> PAGE_CACHE_SHIFT; if (!num_pages) num_pages = 1; index = ((loff_t)start << cs_bits) >> PAGE_CACHE_SHIFT; page_cache_sync_readahead(mapping, &file->f_ra, file, index, num_pages); } /* * Starting at cpos, try to CoW write_len clusters. Don't CoW * past max_cpos. This will stop when it runs into a hole or an * unrefcounted extent. */ static int ocfs2_refcount_cow_hunk(struct inode *inode, struct file *file, struct buffer_head *di_bh, u32 cpos, u32 write_len, u32 max_cpos) { Loading Loading @@ -3443,6 +3478,8 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, BUG_ON(cow_len == 0); ocfs2_readahead_for_cow(inode, file, cow_start, cow_len); context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); if (!context) { ret = -ENOMEM; Loading @@ -3464,6 +3501,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, context->ref_root_bh = ref_root_bh; context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page; context->get_clusters = ocfs2_di_get_clusters; context->file = file; ocfs2_init_dinode_extent_tree(&context->data_et, INODE_CACHE(inode), di_bh); Loading Loading @@ -3492,6 +3530,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, * clusters between cpos and cpos+write_len are safe to modify. */ int ocfs2_refcount_cow(struct inode *inode, struct file *file, struct buffer_head *di_bh, u32 cpos, u32 write_len, u32 max_cpos) { Loading @@ -3511,7 +3550,7 @@ int ocfs2_refcount_cow(struct inode *inode, num_clusters = write_len; if (ext_flags & OCFS2_EXT_REFCOUNTED) { ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos, ret = ocfs2_refcount_cow_hunk(inode, file, di_bh, cpos, num_clusters, max_cpos); if (ret) { mlog_errno(ret); Loading