Skip to content

Commit 729963a

Browse files
author
Joel Becker
committed
Merge branch 'cow_readahead' of git://oss.oracle.com/git/tma/linux-2.6 into merge-2
2 parents 17ae521 + 6ea4843 commit 729963a

File tree

6 files changed

+63
-17
lines changed

6 files changed

+63
-17
lines changed

fs/ocfs2/aops.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,8 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
16421642
return ret;
16431643
}
16441644

1645-
int ocfs2_write_begin_nolock(struct address_space *mapping,
1645+
int ocfs2_write_begin_nolock(struct file *filp,
1646+
struct address_space *mapping,
16461647
loff_t pos, unsigned len, unsigned flags,
16471648
struct page **pagep, void **fsdata,
16481649
struct buffer_head *di_bh, struct page *mmap_page)
@@ -1692,7 +1693,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
16921693
mlog_errno(ret);
16931694
goto out;
16941695
} else if (ret == 1) {
1695-
ret = ocfs2_refcount_cow(inode, di_bh,
1696+
ret = ocfs2_refcount_cow(inode, filp, di_bh,
16961697
wc->w_cpos, wc->w_clen, UINT_MAX);
16971698
if (ret) {
16981699
mlog_errno(ret);
@@ -1854,7 +1855,7 @@ static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
18541855
*/
18551856
down_write(&OCFS2_I(inode)->ip_alloc_sem);
18561857

1857-
ret = ocfs2_write_begin_nolock(mapping, pos, len, flags, pagep,
1858+
ret = ocfs2_write_begin_nolock(file, mapping, pos, len, flags, pagep,
18581859
fsdata, di_bh, NULL);
18591860
if (ret) {
18601861
mlog_errno(ret);

fs/ocfs2/aops.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
4848
loff_t pos, unsigned len, unsigned copied,
4949
struct page *page, void *fsdata);
5050

51-
int ocfs2_write_begin_nolock(struct address_space *mapping,
51+
int ocfs2_write_begin_nolock(struct file *filp,
52+
struct address_space *mapping,
5253
loff_t pos, unsigned len, unsigned flags,
5354
struct page **pagep, void **fsdata,
5455
struct buffer_head *di_bh, struct page *mmap_page);

fs/ocfs2/file.c

+10-7
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ static int ocfs2_cow_file_pos(struct inode *inode,
360360
if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
361361
goto out;
362362

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);
364364

365365
out:
366366
return status;
@@ -903,8 +903,8 @@ static int ocfs2_zero_extend_get_range(struct inode *inode,
903903
zero_clusters = last_cpos - zero_cpos;
904904

905905
if (needs_cow) {
906-
rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters,
907-
UINT_MAX);
906+
rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos,
907+
zero_clusters, UINT_MAX);
908908
if (rc) {
909909
mlog_errno(rc);
910910
goto out;
@@ -2052,6 +2052,7 @@ int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos,
20522052
}
20532053

20542054
static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
2055+
struct file *file,
20552056
loff_t pos, size_t count,
20562057
int *meta_level)
20572058
{
@@ -2069,22 +2070,23 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
20692070

20702071
*meta_level = 1;
20712072

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);
20732074
if (ret)
20742075
mlog_errno(ret);
20752076
out:
20762077
brelse(di_bh);
20772078
return ret;
20782079
}
20792080

2080-
static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
2081+
static int ocfs2_prepare_inode_for_write(struct file *file,
20812082
loff_t *ppos,
20822083
size_t count,
20832084
int appending,
20842085
int *direct_io,
20852086
int *has_refcount)
20862087
{
20872088
int ret = 0, meta_level = 0;
2089+
struct dentry *dentry = file->f_path.dentry;
20882090
struct inode *inode = dentry->d_inode;
20892091
loff_t saved_pos, end;
20902092

@@ -2140,6 +2142,7 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
21402142
meta_level = -1;
21412143

21422144
ret = ocfs2_prepare_inode_for_refcount(inode,
2145+
file,
21432146
saved_pos,
21442147
count,
21452148
&meta_level);
@@ -2254,7 +2257,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
22542257
}
22552258

22562259
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,
22582261
iocb->ki_left, appending,
22592262
&can_do_direct, &has_refcount);
22602263
if (ret < 0) {
@@ -2373,7 +2376,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe,
23732376
{
23742377
int ret;
23752378

2376-
ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos,
2379+
ret = ocfs2_prepare_inode_for_write(out, &sd->pos,
23772380
sd->total_len, 0, NULL, NULL);
23782381
if (ret < 0) {
23792382
mlog_errno(ret);

fs/ocfs2/mmap.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
5959
return ret;
6060
}
6161

62-
static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh,
62+
static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
6363
struct page *page)
6464
{
6565
int ret;
66+
struct inode *inode = file->f_path.dentry->d_inode;
6667
struct address_space *mapping = inode->i_mapping;
6768
loff_t pos = page_offset(page);
6869
unsigned int len = PAGE_CACHE_SIZE;
@@ -111,7 +112,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh,
111112
if (page->index == last_index)
112113
len = ((size - 1) & ~PAGE_CACHE_MASK) + 1;
113114

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,
115116
&fsdata, di_bh, page);
116117
if (ret) {
117118
if (ret != -ENOSPC)
@@ -159,7 +160,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
159160
*/
160161
down_write(&OCFS2_I(inode)->ip_alloc_sem);
161162

162-
ret = __ocfs2_page_mkwrite(inode, di_bh, page);
163+
ret = __ocfs2_page_mkwrite(vma->vm_file, di_bh, page);
163164

164165
up_write(&OCFS2_I(inode)->ip_alloc_sem);
165166

fs/ocfs2/refcounttree.c

+41-2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
struct ocfs2_cow_context {
5151
struct inode *inode;
52+
struct file *file;
5253
u32 cow_start;
5354
u32 cow_len;
5455
struct ocfs2_extent_tree data_et;
@@ -2932,13 +2933,16 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
29322933
u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
29332934
struct page *page;
29342935
pgoff_t page_index;
2935-
unsigned int from, to;
2936+
unsigned int from, to, readahead_pages;
29362937
loff_t offset, end, map_end;
29372938
struct address_space *mapping = context->inode->i_mapping;
29382939

29392940
mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster,
29402941
new_cluster, new_len, cpos);
29412942

2943+
readahead_pages =
2944+
(ocfs2_cow_contig_clusters(sb) <<
2945+
OCFS2_SB(sb)->s_clustersize_bits) >> PAGE_CACHE_SHIFT;
29422946
offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits;
29432947
end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits);
29442948
/*
@@ -2969,6 +2973,14 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
29692973
if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize)
29702974
BUG_ON(PageDirty(page));
29712975

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+
29722984
if (!PageUptodate(page)) {
29732985
ret = block_read_full_page(page, ocfs2_get_block);
29742986
if (ret) {
@@ -3409,12 +3421,35 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context)
34093421
return ret;
34103422
}
34113423

3424+
static 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+
34123446
/*
34133447
* Starting at cpos, try to CoW write_len clusters. Don't CoW
34143448
* past max_cpos. This will stop when it runs into a hole or an
34153449
* unrefcounted extent.
34163450
*/
34173451
static int ocfs2_refcount_cow_hunk(struct inode *inode,
3452+
struct file *file,
34183453
struct buffer_head *di_bh,
34193454
u32 cpos, u32 write_len, u32 max_cpos)
34203455
{
@@ -3443,6 +3478,8 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
34433478

34443479
BUG_ON(cow_len == 0);
34453480

3481+
ocfs2_readahead_for_cow(inode, file, cow_start, cow_len);
3482+
34463483
context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
34473484
if (!context) {
34483485
ret = -ENOMEM;
@@ -3464,6 +3501,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
34643501
context->ref_root_bh = ref_root_bh;
34653502
context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page;
34663503
context->get_clusters = ocfs2_di_get_clusters;
3504+
context->file = file;
34673505

34683506
ocfs2_init_dinode_extent_tree(&context->data_et,
34693507
INODE_CACHE(inode), di_bh);
@@ -3492,6 +3530,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
34923530
* clusters between cpos and cpos+write_len are safe to modify.
34933531
*/
34943532
int ocfs2_refcount_cow(struct inode *inode,
3533+
struct file *file,
34953534
struct buffer_head *di_bh,
34963535
u32 cpos, u32 write_len, u32 max_cpos)
34973536
{
@@ -3511,7 +3550,7 @@ int ocfs2_refcount_cow(struct inode *inode,
35113550
num_clusters = write_len;
35123551

35133552
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,
35153554
num_clusters, max_cpos);
35163555
if (ret) {
35173556
mlog_errno(ret);

fs/ocfs2/refcounttree.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
5252
u32 clusters,
5353
int *credits,
5454
int *ref_blocks);
55-
int ocfs2_refcount_cow(struct inode *inode, struct buffer_head *di_bh,
55+
int ocfs2_refcount_cow(struct inode *inode,
56+
struct file *filep, struct buffer_head *di_bh,
5657
u32 cpos, u32 write_len, u32 max_cpos);
5758

5859
typedef int (ocfs2_post_refcount_func)(struct inode *inode,

0 commit comments

Comments
 (0)