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
4969c06a
Commit
4969c06a
authored
Jul 01, 2019
by
Jaegeuk Kim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
f2fs: support swap file w/ DIO
Signed-off-by:
Jaegeuk Kim
<
jaegeuk@kernel.org
>
parent
cad3836f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
143 additions
and
15 deletions
+143
-15
fs/f2fs/data.c
fs/f2fs/data.c
+134
-8
fs/f2fs/f2fs.h
fs/f2fs/f2fs.h
+3
-2
include/trace/events/f2fs.h
include/trace/events/f2fs.h
+6
-5
No files found.
fs/f2fs/data.c
View file @
4969c06a
...
...
@@ -14,6 +14,7 @@
#include <linux/pagevec.h>
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/swap.h>
#include <linux/prefetch.h>
#include <linux/uio.h>
#include <linux/cleancache.h>
...
...
@@ -54,7 +55,7 @@ static bool __is_cp_guaranteed(struct page *page)
static
enum
count_type
__read_io_type
(
struct
page
*
page
)
{
struct
address_space
*
mapping
=
page
->
mapping
;
struct
address_space
*
mapping
=
page
_file_mapping
(
page
)
;
if
(
mapping
)
{
struct
inode
*
inode
=
mapping
->
host
;
...
...
@@ -1585,7 +1586,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
sector_t
block_nr
;
int
ret
=
0
;
block_in_file
=
(
sector_t
)
page
->
index
;
block_in_file
=
(
sector_t
)
page
_index
(
page
)
;
last_block
=
block_in_file
+
nr_pages
;
last_block_in_file
=
(
i_size_read
(
inode
)
+
blocksize
-
1
)
>>
blkbits
;
...
...
@@ -1618,7 +1619,8 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
block_nr
=
map
->
m_pblk
+
block_in_file
-
map
->
m_lblk
;
SetPageMappedToDisk
(
page
);
if
(
!
PageUptodate
(
page
)
&&
!
cleancache_get_page
(
page
))
{
if
(
!
PageUptodate
(
page
)
&&
(
!
PageSwapCache
(
page
)
&&
!
cleancache_get_page
(
page
)))
{
SetPageUptodate
(
page
);
goto
confused
;
}
...
...
@@ -1716,7 +1718,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
prefetchw
(
&
page
->
flags
);
list_del
(
&
page
->
lru
);
if
(
add_to_page_cache_lru
(
page
,
mapping
,
page
->
index
,
page
_index
(
page
)
,
readahead_gfp_mask
(
mapping
)))
goto
next_page
;
}
...
...
@@ -1740,7 +1742,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
static
int
f2fs_read_data_page
(
struct
file
*
file
,
struct
page
*
page
)
{
struct
inode
*
inode
=
page
->
mapping
->
host
;
struct
inode
*
inode
=
page
_file_mapping
(
page
)
->
host
;
int
ret
=
-
EAGAIN
;
trace_f2fs_readpage
(
page
,
DATA
);
...
...
@@ -1749,7 +1751,8 @@ static int f2fs_read_data_page(struct file *file, struct page *page)
if
(
f2fs_has_inline_data
(
inode
))
ret
=
f2fs_read_inline_data
(
inode
,
page
);
if
(
ret
==
-
EAGAIN
)
ret
=
f2fs_mpage_readpages
(
page
->
mapping
,
NULL
,
page
,
1
,
false
);
ret
=
f2fs_mpage_readpages
(
page_file_mapping
(
page
),
NULL
,
page
,
1
,
false
);
return
ret
;
}
...
...
@@ -2851,13 +2854,14 @@ int f2fs_release_page(struct page *page, gfp_t wait)
static
int
f2fs_set_data_page_dirty
(
struct
page
*
page
)
{
struct
address_space
*
mapping
=
page
->
mapping
;
struct
inode
*
inode
=
mapping
->
host
;
struct
inode
*
inode
=
page_file_mapping
(
page
)
->
host
;
trace_f2fs_set_page_dirty
(
page
,
DATA
);
if
(
!
PageUptodate
(
page
))
SetPageUptodate
(
page
);
if
(
PageSwapCache
(
page
))
return
__set_page_dirty_nobuffers
(
page
);
if
(
f2fs_is_atomic_file
(
inode
)
&&
!
f2fs_is_commit_atomic_write
(
inode
))
{
if
(
!
IS_ATOMIC_WRITTEN_PAGE
(
page
))
{
...
...
@@ -2949,6 +2953,126 @@ int f2fs_migrate_page(struct address_space *mapping,
}
#endif
#ifdef CONFIG_SWAP
/* Copied from generic_swapfile_activate() to check any holes */
static
int
check_swap_activate
(
struct
file
*
swap_file
,
unsigned
int
max
)
{
struct
address_space
*
mapping
=
swap_file
->
f_mapping
;
struct
inode
*
inode
=
mapping
->
host
;
unsigned
blocks_per_page
;
unsigned
long
page_no
;
unsigned
blkbits
;
sector_t
probe_block
;
sector_t
last_block
;
sector_t
lowest_block
=
-
1
;
sector_t
highest_block
=
0
;
blkbits
=
inode
->
i_blkbits
;
blocks_per_page
=
PAGE_SIZE
>>
blkbits
;
/*
* Map all the blocks into the extent list. This code doesn't try
* to be very smart.
*/
probe_block
=
0
;
page_no
=
0
;
last_block
=
i_size_read
(
inode
)
>>
blkbits
;
while
((
probe_block
+
blocks_per_page
)
<=
last_block
&&
page_no
<
max
)
{
unsigned
block_in_page
;
sector_t
first_block
;
cond_resched
();
first_block
=
bmap
(
inode
,
probe_block
);
if
(
first_block
==
0
)
goto
bad_bmap
;
/*
* It must be PAGE_SIZE aligned on-disk
*/
if
(
first_block
&
(
blocks_per_page
-
1
))
{
probe_block
++
;
goto
reprobe
;
}
for
(
block_in_page
=
1
;
block_in_page
<
blocks_per_page
;
block_in_page
++
)
{
sector_t
block
;
block
=
bmap
(
inode
,
probe_block
+
block_in_page
);
if
(
block
==
0
)
goto
bad_bmap
;
if
(
block
!=
first_block
+
block_in_page
)
{
/* Discontiguity */
probe_block
++
;
goto
reprobe
;
}
}
first_block
>>=
(
PAGE_SHIFT
-
blkbits
);
if
(
page_no
)
{
/* exclude the header page */
if
(
first_block
<
lowest_block
)
lowest_block
=
first_block
;
if
(
first_block
>
highest_block
)
highest_block
=
first_block
;
}
page_no
++
;
probe_block
+=
blocks_per_page
;
reprobe:
continue
;
}
return
0
;
bad_bmap:
pr_err
(
"swapon: swapfile has holes
\n
"
);
return
-
EINVAL
;
}
static
int
f2fs_swap_activate
(
struct
swap_info_struct
*
sis
,
struct
file
*
file
,
sector_t
*
span
)
{
struct
inode
*
inode
=
file_inode
(
file
);
int
ret
;
if
(
!
S_ISREG
(
inode
->
i_mode
))
return
-
EINVAL
;
if
(
f2fs_readonly
(
F2FS_I_SB
(
inode
)
->
sb
))
return
-
EROFS
;
ret
=
f2fs_convert_inline_inode
(
inode
);
if
(
ret
)
return
ret
;
ret
=
check_swap_activate
(
file
,
sis
->
max
);
if
(
ret
)
return
ret
;
set_inode_flag
(
inode
,
FI_PIN_FILE
);
f2fs_precache_extents
(
inode
);
f2fs_update_time
(
F2FS_I_SB
(
inode
),
REQ_TIME
);
return
0
;
}
static
void
f2fs_swap_deactivate
(
struct
file
*
file
)
{
struct
inode
*
inode
=
file_inode
(
file
);
clear_inode_flag
(
inode
,
FI_PIN_FILE
);
}
#else
static
int
f2fs_swap_activate
(
struct
swap_info_struct
*
sis
,
struct
file
*
file
,
sector_t
*
span
)
{
return
-
EOPNOTSUPP
;
}
static
void
f2fs_swap_deactivate
(
struct
file
*
file
)
{
}
#endif
const
struct
address_space_operations
f2fs_dblock_aops
=
{
.
readpage
=
f2fs_read_data_page
,
.
readpages
=
f2fs_read_data_pages
,
...
...
@@ -2961,6 +3085,8 @@ const struct address_space_operations f2fs_dblock_aops = {
.
releasepage
=
f2fs_release_page
,
.
direct_IO
=
f2fs_direct_IO
,
.
bmap
=
f2fs_bmap
,
.
swap_activate
=
f2fs_swap_activate
,
.
swap_deactivate
=
f2fs_swap_deactivate
,
#ifdef CONFIG_MIGRATION
.
migratepage
=
f2fs_migrate_page
,
#endif
...
...
fs/f2fs/f2fs.h
View file @
4969c06a
...
...
@@ -1498,7 +1498,7 @@ static inline struct f2fs_sb_info *F2FS_M_SB(struct address_space *mapping)
static
inline
struct
f2fs_sb_info
*
F2FS_P_SB
(
struct
page
*
page
)
{
return
F2FS_M_SB
(
page
->
mapping
);
return
F2FS_M_SB
(
page
_file_mapping
(
page
)
);
}
static
inline
struct
f2fs_super_block
*
F2FS_RAW_SUPER
(
struct
f2fs_sb_info
*
sbi
)
...
...
@@ -3683,7 +3683,8 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
if
(
test_opt
(
sbi
,
LFS
)
&&
(
rw
==
WRITE
)
&&
block_unaligned_IO
(
inode
,
iocb
,
iter
))
return
true
;
if
(
is_sbi_flag_set
(
F2FS_I_SB
(
inode
),
SBI_CP_DISABLED
))
if
(
is_sbi_flag_set
(
F2FS_I_SB
(
inode
),
SBI_CP_DISABLED
)
&&
!
(
inode
->
i_flags
&
S_SWAPFILE
))
return
true
;
return
false
;
...
...
include/trace/events/f2fs.h
View file @
4969c06a
...
...
@@ -1028,8 +1028,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_page_bio,
),
TP_fast_assign
(
__entry
->
dev
=
page
->
mapping
->
host
->
i_sb
->
s_dev
;
__entry
->
ino
=
page
->
mapping
->
host
->
i_ino
;
__entry
->
dev
=
page
_file_mapping
(
page
)
->
host
->
i_sb
->
s_dev
;
__entry
->
ino
=
page
_file_mapping
(
page
)
->
host
->
i_ino
;
__entry
->
index
=
page
->
index
;
__entry
->
old_blkaddr
=
fio
->
old_blkaddr
;
__entry
->
new_blkaddr
=
fio
->
new_blkaddr
;
...
...
@@ -1216,10 +1216,11 @@ DECLARE_EVENT_CLASS(f2fs__page,
),
TP_fast_assign
(
__entry
->
dev
=
page
->
mapping
->
host
->
i_sb
->
s_dev
;
__entry
->
ino
=
page
->
mapping
->
host
->
i_ino
;
__entry
->
dev
=
page
_file_mapping
(
page
)
->
host
->
i_sb
->
s_dev
;
__entry
->
ino
=
page
_file_mapping
(
page
)
->
host
->
i_ino
;
__entry
->
type
=
type
;
__entry
->
dir
=
S_ISDIR
(
page
->
mapping
->
host
->
i_mode
);
__entry
->
dir
=
S_ISDIR
(
page_file_mapping
(
page
)
->
host
->
i_mode
);
__entry
->
index
=
page
->
index
;
__entry
->
dirty
=
PageDirty
(
page
);
__entry
->
uptodate
=
PageUptodate
(
page
);
...
...
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