aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2010-09-10 11:41:04 -0400
committerJoel Becker <joel.becker@oracle.com>2010-09-10 11:41:04 -0400
commit729963a1ff8d069d05dab6a024bfd59805ac622c (patch)
tree5489aae570960d1908d738913ea581cc1689fbbb /fs
parent17ae521158d6fe89cfdd00a9990aa40d02e81391 (diff)
parent6ea4843f53282465f2bdbe5eedde7d8c3081dfdf (diff)
Merge branch 'cow_readahead' of git://oss.oracle.com/git/tma/linux-2.6 into merge-2
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/aops.c7
-rw-r--r--fs/ocfs2/aops.h3
-rw-r--r--fs/ocfs2/file.c17
-rw-r--r--fs/ocfs2/mmap.c7
-rw-r--r--fs/ocfs2/refcounttree.c43
-rw-r--r--fs/ocfs2/refcounttree.h3
6 files changed, 63 insertions, 17 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index f477f18b35d5..5cfeee118158 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1642,7 +1642,8 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
1642 return ret; 1642 return ret;
1643} 1643}
1644 1644
1645int ocfs2_write_begin_nolock(struct address_space *mapping, 1645int ocfs2_write_begin_nolock(struct file *filp,
1646 struct address_space *mapping,
1646 loff_t pos, unsigned len, unsigned flags, 1647 loff_t pos, unsigned len, unsigned flags,
1647 struct page **pagep, void **fsdata, 1648 struct page **pagep, void **fsdata,
1648 struct buffer_head *di_bh, struct page *mmap_page) 1649 struct buffer_head *di_bh, struct page *mmap_page)
@@ -1692,7 +1693,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
1692 mlog_errno(ret); 1693 mlog_errno(ret);
1693 goto out; 1694 goto out;
1694 } else if (ret == 1) { 1695 } else if (ret == 1) {
1695 ret = ocfs2_refcount_cow(inode, di_bh, 1696 ret = ocfs2_refcount_cow(inode, filp, di_bh,
1696 wc->w_cpos, wc->w_clen, UINT_MAX); 1697 wc->w_cpos, wc->w_clen, UINT_MAX);
1697 if (ret) { 1698 if (ret) {
1698 mlog_errno(ret); 1699 mlog_errno(ret);
@@ -1854,7 +1855,7 @@ static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1854 */ 1855 */
1855 down_write(&OCFS2_I(inode)->ip_alloc_sem); 1856 down_write(&OCFS2_I(inode)->ip_alloc_sem);
1856 1857
1857 ret = ocfs2_write_begin_nolock(mapping, pos, len, flags, pagep, 1858 ret = ocfs2_write_begin_nolock(file, mapping, pos, len, flags, pagep,
1858 fsdata, di_bh, NULL); 1859 fsdata, di_bh, NULL);
1859 if (ret) { 1860 if (ret) {
1860 mlog_errno(ret); 1861 mlog_errno(ret);
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index c48e93ffc513..7606f663da6d 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -48,7 +48,8 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
48 loff_t pos, unsigned len, unsigned copied, 48 loff_t pos, unsigned len, unsigned copied,
49 struct page *page, void *fsdata); 49 struct page *page, void *fsdata);
50 50
51int ocfs2_write_begin_nolock(struct address_space *mapping, 51int ocfs2_write_begin_nolock(struct file *filp,
52 struct address_space *mapping,
52 loff_t pos, unsigned len, unsigned flags, 53 loff_t pos, unsigned len, unsigned flags,
53 struct page **pagep, void **fsdata, 54 struct page **pagep, void **fsdata,
54 struct buffer_head *di_bh, struct page *mmap_page); 55 struct buffer_head *di_bh, struct page *mmap_page);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index b03f6601fd71..9a74542e1a05 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -360,7 +360,7 @@ static int ocfs2_cow_file_pos(struct inode *inode,
360 if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) 360 if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
361 goto out; 361 goto out;
362 362
363 return ocfs2_refcount_cow(inode, fe_bh, cpos, 1, cpos+1); 363 return ocfs2_refcount_cow(inode, NULL, fe_bh, cpos, 1, cpos+1);
364 364
365out: 365out:
366 return status; 366 return status;
@@ -903,8 +903,8 @@ static int ocfs2_zero_extend_get_range(struct inode *inode,
903 zero_clusters = last_cpos - zero_cpos; 903 zero_clusters = last_cpos - zero_cpos;
904 904
905 if (needs_cow) { 905 if (needs_cow) {
906 rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters, 906 rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos,
907 UINT_MAX); 907 zero_clusters, UINT_MAX);
908 if (rc) { 908 if (rc) {
909 mlog_errno(rc); 909 mlog_errno(rc);
910 goto out; 910 goto out;
@@ -2052,6 +2052,7 @@ out:
2052} 2052}
2053 2053
2054static int ocfs2_prepare_inode_for_refcount(struct inode *inode, 2054static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
2055 struct file *file,
2055 loff_t pos, size_t count, 2056 loff_t pos, size_t count,
2056 int *meta_level) 2057 int *meta_level)
2057{ 2058{
@@ -2069,7 +2070,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
2069 2070
2070 *meta_level = 1; 2071 *meta_level = 1;
2071 2072
2072 ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX); 2073 ret = ocfs2_refcount_cow(inode, file, di_bh, cpos, clusters, UINT_MAX);
2073 if (ret) 2074 if (ret)
2074 mlog_errno(ret); 2075 mlog_errno(ret);
2075out: 2076out:
@@ -2077,7 +2078,7 @@ out:
2077 return ret; 2078 return ret;
2078} 2079}
2079 2080
2080static int ocfs2_prepare_inode_for_write(struct dentry *dentry, 2081static int ocfs2_prepare_inode_for_write(struct file *file,
2081 loff_t *ppos, 2082 loff_t *ppos,
2082 size_t count, 2083 size_t count,
2083 int appending, 2084 int appending,
@@ -2085,6 +2086,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
2085 int *has_refcount) 2086 int *has_refcount)
2086{ 2087{
2087 int ret = 0, meta_level = 0; 2088 int ret = 0, meta_level = 0;
2089 struct dentry *dentry = file->f_path.dentry;
2088 struct inode *inode = dentry->d_inode; 2090 struct inode *inode = dentry->d_inode;
2089 loff_t saved_pos, end; 2091 loff_t saved_pos, end;
2090 2092
@@ -2140,6 +2142,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
2140 meta_level = -1; 2142 meta_level = -1;
2141 2143
2142 ret = ocfs2_prepare_inode_for_refcount(inode, 2144 ret = ocfs2_prepare_inode_for_refcount(inode,
2145 file,
2143 saved_pos, 2146 saved_pos,
2144 count, 2147 count,
2145 &meta_level); 2148 &meta_level);
@@ -2254,7 +2257,7 @@ relock:
2254 } 2257 }
2255 2258
2256 can_do_direct = direct_io; 2259 can_do_direct = direct_io;
2257 ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos, 2260 ret = ocfs2_prepare_inode_for_write(file, ppos,
2258 iocb->ki_left, appending, 2261 iocb->ki_left, appending,
2259 &can_do_direct, &has_refcount); 2262 &can_do_direct, &has_refcount);
2260 if (ret < 0) { 2263 if (ret < 0) {
@@ -2373,7 +2376,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe,
2373{ 2376{
2374 int ret; 2377 int ret;
2375 2378
2376 ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, 2379 ret = ocfs2_prepare_inode_for_write(out, &sd->pos,
2377 sd->total_len, 0, NULL, NULL); 2380 sd->total_len, 0, NULL, NULL);
2378 if (ret < 0) { 2381 if (ret < 0) {
2379 mlog_errno(ret); 2382 mlog_errno(ret);
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 4c18f4ad93b4..7e32db9c2c99 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -59,10 +59,11 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
59 return ret; 59 return ret;
60} 60}
61 61
62static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, 62static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
63 struct page *page) 63 struct page *page)
64{ 64{
65 int ret; 65 int ret;
66 struct inode *inode = file->f_path.dentry->d_inode;
66 struct address_space *mapping = inode->i_mapping; 67 struct address_space *mapping = inode->i_mapping;
67 loff_t pos = page_offset(page); 68 loff_t pos = page_offset(page);
68 unsigned int len = PAGE_CACHE_SIZE; 69 unsigned int len = PAGE_CACHE_SIZE;
@@ -111,7 +112,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh,
111 if (page->index == last_index) 112 if (page->index == last_index)
112 len = ((size - 1) & ~PAGE_CACHE_MASK) + 1; 113 len = ((size - 1) & ~PAGE_CACHE_MASK) + 1;
113 114
114 ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, 115 ret = ocfs2_write_begin_nolock(file, mapping, pos, len, 0, &locked_page,
115 &fsdata, di_bh, page); 116 &fsdata, di_bh, page);
116 if (ret) { 117 if (ret) {
117 if (ret != -ENOSPC) 118 if (ret != -ENOSPC)
@@ -159,7 +160,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
159 */ 160 */
160 down_write(&OCFS2_I(inode)->ip_alloc_sem); 161 down_write(&OCFS2_I(inode)->ip_alloc_sem);
161 162
162 ret = __ocfs2_page_mkwrite(inode, di_bh, page); 163 ret = __ocfs2_page_mkwrite(vma->vm_file, di_bh, page);
163 164
164 up_write(&OCFS2_I(inode)->ip_alloc_sem); 165 up_write(&OCFS2_I(inode)->ip_alloc_sem);
165 166
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 0afeda83120f..a120cfcf69bf 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -49,6 +49,7 @@
49 49
50struct ocfs2_cow_context { 50struct ocfs2_cow_context {
51 struct inode *inode; 51 struct inode *inode;
52 struct file *file;
52 u32 cow_start; 53 u32 cow_start;
53 u32 cow_len; 54 u32 cow_len;
54 struct ocfs2_extent_tree data_et; 55 struct ocfs2_extent_tree data_et;
@@ -2932,13 +2933,16 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
2932 u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster); 2933 u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
2933 struct page *page; 2934 struct page *page;
2934 pgoff_t page_index; 2935 pgoff_t page_index;
2935 unsigned int from, to; 2936 unsigned int from, to, readahead_pages;
2936 loff_t offset, end, map_end; 2937 loff_t offset, end, map_end;
2937 struct address_space *mapping = context->inode->i_mapping; 2938 struct address_space *mapping = context->inode->i_mapping;
2938 2939
2939 mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster, 2940 mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster,
2940 new_cluster, new_len, cpos); 2941 new_cluster, new_len, cpos);
2941 2942
2943 readahead_pages =
2944 (ocfs2_cow_contig_clusters(sb) <<
2945 OCFS2_SB(sb)->s_clustersize_bits) >> PAGE_CACHE_SHIFT;
2942 offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; 2946 offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits;
2943 end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); 2947 end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits);
2944 /* 2948 /*
@@ -2969,6 +2973,14 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
2969 if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize) 2973 if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize)
2970 BUG_ON(PageDirty(page)); 2974 BUG_ON(PageDirty(page));
2971 2975
2976 if (PageReadahead(page) && context->file) {
2977 page_cache_async_readahead(mapping,
2978 &context->file->f_ra,
2979 context->file,
2980 page, page_index,
2981 readahead_pages);
2982 }
2983
2972 if (!PageUptodate(page)) { 2984 if (!PageUptodate(page)) {
2973 ret = block_read_full_page(page, ocfs2_get_block); 2985 ret = block_read_full_page(page, ocfs2_get_block);
2974 if (ret) { 2986 if (ret) {
@@ -3409,12 +3421,35 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context)
3409 return ret; 3421 return ret;
3410} 3422}
3411 3423
3424static void ocfs2_readahead_for_cow(struct inode *inode,
3425 struct file *file,
3426 u32 start, u32 len)
3427{
3428 struct address_space *mapping;
3429 pgoff_t index;
3430 unsigned long num_pages;
3431 int cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
3432
3433 if (!file)
3434 return;
3435
3436 mapping = file->f_mapping;
3437 num_pages = (len << cs_bits) >> PAGE_CACHE_SHIFT;
3438 if (!num_pages)
3439 num_pages = 1;
3440
3441 index = ((loff_t)start << cs_bits) >> PAGE_CACHE_SHIFT;
3442 page_cache_sync_readahead(mapping, &file->f_ra, file,
3443 index, num_pages);
3444}
3445
3412/* 3446/*
3413 * Starting at cpos, try to CoW write_len clusters. Don't CoW 3447 * Starting at cpos, try to CoW write_len clusters. Don't CoW
3414 * past max_cpos. This will stop when it runs into a hole or an 3448 * past max_cpos. This will stop when it runs into a hole or an
3415 * unrefcounted extent. 3449 * unrefcounted extent.
3416 */ 3450 */
3417static int ocfs2_refcount_cow_hunk(struct inode *inode, 3451static int ocfs2_refcount_cow_hunk(struct inode *inode,
3452 struct file *file,
3418 struct buffer_head *di_bh, 3453 struct buffer_head *di_bh,
3419 u32 cpos, u32 write_len, u32 max_cpos) 3454 u32 cpos, u32 write_len, u32 max_cpos)
3420{ 3455{
@@ -3443,6 +3478,8 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
3443 3478
3444 BUG_ON(cow_len == 0); 3479 BUG_ON(cow_len == 0);
3445 3480
3481 ocfs2_readahead_for_cow(inode, file, cow_start, cow_len);
3482
3446 context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); 3483 context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
3447 if (!context) { 3484 if (!context) {
3448 ret = -ENOMEM; 3485 ret = -ENOMEM;
@@ -3464,6 +3501,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
3464 context->ref_root_bh = ref_root_bh; 3501 context->ref_root_bh = ref_root_bh;
3465 context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page; 3502 context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page;
3466 context->get_clusters = ocfs2_di_get_clusters; 3503 context->get_clusters = ocfs2_di_get_clusters;
3504 context->file = file;
3467 3505
3468 ocfs2_init_dinode_extent_tree(&context->data_et, 3506 ocfs2_init_dinode_extent_tree(&context->data_et,
3469 INODE_CACHE(inode), di_bh); 3507 INODE_CACHE(inode), di_bh);
@@ -3492,6 +3530,7 @@ out:
3492 * clusters between cpos and cpos+write_len are safe to modify. 3530 * clusters between cpos and cpos+write_len are safe to modify.
3493 */ 3531 */
3494int ocfs2_refcount_cow(struct inode *inode, 3532int ocfs2_refcount_cow(struct inode *inode,
3533 struct file *file,
3495 struct buffer_head *di_bh, 3534 struct buffer_head *di_bh,
3496 u32 cpos, u32 write_len, u32 max_cpos) 3535 u32 cpos, u32 write_len, u32 max_cpos)
3497{ 3536{
@@ -3511,7 +3550,7 @@ int ocfs2_refcount_cow(struct inode *inode,
3511 num_clusters = write_len; 3550 num_clusters = write_len;
3512 3551
3513 if (ext_flags & OCFS2_EXT_REFCOUNTED) { 3552 if (ext_flags & OCFS2_EXT_REFCOUNTED) {
3514 ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos, 3553 ret = ocfs2_refcount_cow_hunk(inode, file, di_bh, cpos,
3515 num_clusters, max_cpos); 3554 num_clusters, max_cpos);
3516 if (ret) { 3555 if (ret) {
3517 mlog_errno(ret); 3556 mlog_errno(ret);
diff --git a/fs/ocfs2/refcounttree.h b/fs/ocfs2/refcounttree.h
index f04892d6175d..c8ce46f7d8e3 100644
--- a/fs/ocfs2/refcounttree.h
+++ b/fs/ocfs2/refcounttree.h
@@ -52,7 +52,8 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
52 u32 clusters, 52 u32 clusters,
53 int *credits, 53 int *credits,
54 int *ref_blocks); 54 int *ref_blocks);
55int ocfs2_refcount_cow(struct inode *inode, struct buffer_head *di_bh, 55int ocfs2_refcount_cow(struct inode *inode,
56 struct file *filep, struct buffer_head *di_bh,
56 u32 cpos, u32 write_len, u32 max_cpos); 57 u32 cpos, u32 write_len, u32 max_cpos);
57 58
58typedef int (ocfs2_post_refcount_func)(struct inode *inode, 59typedef int (ocfs2_post_refcount_func)(struct inode *inode,