Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
729963a1
Commit
729963a1
authored
Sep 10, 2010
by
Joel Becker
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'cow_readahead' of
git://oss.oracle.com/git/tma/linux-2.6
into merge-2
parents
17ae5211
6ea4843f
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
17 deletions
+63
-17
fs/ocfs2/aops.c
fs/ocfs2/aops.c
+4
-3
fs/ocfs2/aops.h
fs/ocfs2/aops.h
+2
-1
fs/ocfs2/file.c
fs/ocfs2/file.c
+10
-7
fs/ocfs2/mmap.c
fs/ocfs2/mmap.c
+4
-3
fs/ocfs2/refcounttree.c
fs/ocfs2/refcounttree.c
+41
-2
fs/ocfs2/refcounttree.h
fs/ocfs2/refcounttree.h
+2
-1
No files found.
fs/ocfs2/aops.c
View file @
729963a1
...
...
@@ -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
)
...
...
@@ -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
);
...
...
@@ -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
);
...
...
fs/ocfs2/aops.h
View file @
729963a1
...
...
@@ -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
);
...
...
fs/ocfs2/file.c
View file @
729963a1
...
...
@@ -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
;
...
...
@@ -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_cluster
s
,
UINT_MAX
);
rc
=
ocfs2_refcount_cow
(
inode
,
NULL
,
di_bh
,
zero_cpo
s
,
zero_clusters
,
UINT_MAX
);
if
(
rc
)
{
mlog_errno
(
rc
);
goto
out
;
...
...
@@ -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
)
{
...
...
@@ -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:
...
...
@@ -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
,
...
...
@@ -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
;
...
...
@@ -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
);
...
...
@@ -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
)
{
...
...
@@ -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
);
...
...
fs/ocfs2/mmap.c
View file @
729963a1
...
...
@@ -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
*
inod
e
,
struct
buffer_head
*
di_bh
,
static
int
__ocfs2_page_mkwrite
(
struct
file
*
fil
e
,
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
;
...
...
@@ -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
)
...
...
@@ -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
(
inod
e
,
di_bh
,
page
);
ret
=
__ocfs2_page_mkwrite
(
vma
->
vm_fil
e
,
di_bh
,
page
);
up_write
(
&
OCFS2_I
(
inode
)
->
ip_alloc_sem
);
...
...
fs/ocfs2/refcounttree.c
View file @
729963a1
...
...
@@ -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
;
...
...
@@ -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
);
/*
...
...
@@ -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
)
{
...
...
@@ -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
)
{
...
...
@@ -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
;
...
...
@@ -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
);
...
...
@@ -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
)
{
...
...
@@ -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
);
...
...
fs/ocfs2/refcounttree.h
View file @
729963a1
...
...
@@ -52,7 +52,8 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
u32
clusters
,
int
*
credits
,
int
*
ref_blocks
);
int
ocfs2_refcount_cow
(
struct
inode
*
inode
,
struct
buffer_head
*
di_bh
,
int
ocfs2_refcount_cow
(
struct
inode
*
inode
,
struct
file
*
filep
,
struct
buffer_head
*
di_bh
,
u32
cpos
,
u32
write_len
,
u32
max_cpos
);
typedef
int
(
ocfs2_post_refcount_func
)(
struct
inode
*
inode
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment