diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-05 14:22:07 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-05 14:22:07 -0500 |
commit | 0fcb9d21b4e18ede3727b8905e74acd0d1daef56 (patch) | |
tree | f8181c110c8bed5b6322122ba086f34bbfb269f9 | |
parent | d000f8d67f2bb464c9cf4fb5103f78d8cb406c05 (diff) | |
parent | beaa57dd986d4f398728c060692fc2452895cfd8 (diff) |
Merge tag 'for-f2fs-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim:
"Most part of the patches include enhancing the stability and
performance of in-memory extent caches feature.
In addition, it introduces several new features and configurable
points:
- F2FS_GOING_DOWN_METAFLUSH ioctl to test power failures
- F2FS_IOC_WRITE_CHECKPOINT ioctl to trigger checkpoint by users
- background_gc=sync mount option to do gc synchronously
- periodic checkpoints
- sysfs entry to control readahead blocks for free nids
And the following bug fixes have been merged.
- fix SSA corruption by collapse/insert_range
- correct a couple of gc behaviors
- fix the results of f2fs_map_blocks
- fix error case handling of volatile/atomic writes"
* tag 'for-f2fs-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (54 commits)
f2fs: fix to skip shrinking extent nodes
f2fs: fix error path of ->symlink
f2fs: fix to clear GCed flag for atomic written page
f2fs: don't need to submit bio on error case
f2fs: fix leakage of inmemory atomic pages
f2fs: refactor __find_rev_next_{zero}_bit
f2fs: support fiemap for inline_data
f2fs: flush dirty data for bmap
f2fs: relocate the tracepoint for background_gc
f2fs crypto: fix racing of accessing encrypted page among
f2fs: export ra_nid_pages to sysfs
f2fs: readahead for free nids building
f2fs: support lower priority asynchronous readahead in ra_meta_pages
f2fs: don't tag REQ_META for temporary non-meta pages
f2fs: add a tracepoint for f2fs_read_data_pages
f2fs: set GFP_NOFS for grab_cache_page
f2fs: fix SSA updates resulting in corruption
Revert "f2fs: do not skip dentry block writes"
f2fs: add F2FS_GOING_DOWN_METAFLUSH to test power-failure
f2fs: merge meta writes as many possible
...
-rw-r--r-- | Documentation/ABI/testing/sysfs-fs-f2fs | 12 | ||||
-rw-r--r-- | Documentation/filesystems/f2fs.txt | 3 | ||||
-rw-r--r-- | fs/f2fs/checkpoint.c | 49 | ||||
-rw-r--r-- | fs/f2fs/data.c | 176 | ||||
-rw-r--r-- | fs/f2fs/debug.c | 36 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 19 | ||||
-rw-r--r-- | fs/f2fs/extent_cache.c | 195 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 86 | ||||
-rw-r--r-- | fs/f2fs/file.c | 327 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 77 | ||||
-rw-r--r-- | fs/f2fs/gc.h | 6 | ||||
-rw-r--r-- | fs/f2fs/inline.c | 42 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 8 | ||||
-rw-r--r-- | fs/f2fs/namei.c | 19 | ||||
-rw-r--r-- | fs/f2fs/node.c | 26 | ||||
-rw-r--r-- | fs/f2fs/node.h | 4 | ||||
-rw-r--r-- | fs/f2fs/recovery.c | 15 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 206 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 4 | ||||
-rw-r--r-- | fs/f2fs/super.c | 37 | ||||
-rw-r--r-- | include/trace/events/f2fs.h | 69 |
21 files changed, 869 insertions, 547 deletions
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 2c4cc42006e8..0345f2d1c727 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs | |||
@@ -80,3 +80,15 @@ Date: February 2015 | |||
80 | Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> | 80 | Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> |
81 | Description: | 81 | Description: |
82 | Controls the trimming rate in batch mode. | 82 | Controls the trimming rate in batch mode. |
83 | |||
84 | What: /sys/fs/f2fs/<disk>/cp_interval | ||
85 | Date: October 2015 | ||
86 | Contact: "Jaegeuk Kim" <jaegeuk@kernel.org> | ||
87 | Description: | ||
88 | Controls the checkpoint timing. | ||
89 | |||
90 | What: /sys/fs/f2fs/<disk>/ra_nid_pages | ||
91 | Date: October 2015 | ||
92 | Contact: "Chao Yu" <chao2.yu@samsung.com> | ||
93 | Description: | ||
94 | Controls the count of nid pages to be readaheaded. | ||
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index e2d5105b7214..b102b436563e 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt | |||
@@ -102,7 +102,8 @@ background_gc=%s Turn on/off cleaning operations, namely garbage | |||
102 | collection, triggered in background when I/O subsystem is | 102 | collection, triggered in background when I/O subsystem is |
103 | idle. If background_gc=on, it will turn on the garbage | 103 | idle. If background_gc=on, it will turn on the garbage |
104 | collection and if background_gc=off, garbage collection | 104 | collection and if background_gc=off, garbage collection |
105 | will be truned off. | 105 | will be truned off. If background_gc=sync, it will turn |
106 | on synchronous garbage collection running in background. | ||
106 | Default value for this option is on. So garbage | 107 | Default value for this option is on. So garbage |
107 | collection is on by default. | 108 | collection is on by default. |
108 | disable_roll_forward Disable the roll-forward recovery routine | 109 | disable_roll_forward Disable the roll-forward recovery routine |
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index c5a38e352a80..f661d80474be 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -47,7 +47,8 @@ repeat: | |||
47 | /* | 47 | /* |
48 | * We guarantee no failure on the returned page. | 48 | * We guarantee no failure on the returned page. |
49 | */ | 49 | */ |
50 | struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) | 50 | static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, |
51 | bool is_meta) | ||
51 | { | 52 | { |
52 | struct address_space *mapping = META_MAPPING(sbi); | 53 | struct address_space *mapping = META_MAPPING(sbi); |
53 | struct page *page; | 54 | struct page *page; |
@@ -58,6 +59,9 @@ struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) | |||
58 | .blk_addr = index, | 59 | .blk_addr = index, |
59 | .encrypted_page = NULL, | 60 | .encrypted_page = NULL, |
60 | }; | 61 | }; |
62 | |||
63 | if (unlikely(!is_meta)) | ||
64 | fio.rw &= ~REQ_META; | ||
61 | repeat: | 65 | repeat: |
62 | page = grab_cache_page(mapping, index); | 66 | page = grab_cache_page(mapping, index); |
63 | if (!page) { | 67 | if (!page) { |
@@ -91,6 +95,17 @@ out: | |||
91 | return page; | 95 | return page; |
92 | } | 96 | } |
93 | 97 | ||
98 | struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) | ||
99 | { | ||
100 | return __get_meta_page(sbi, index, true); | ||
101 | } | ||
102 | |||
103 | /* for POR only */ | ||
104 | struct page *get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index) | ||
105 | { | ||
106 | return __get_meta_page(sbi, index, false); | ||
107 | } | ||
108 | |||
94 | bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) | 109 | bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) |
95 | { | 110 | { |
96 | switch (type) { | 111 | switch (type) { |
@@ -125,7 +140,8 @@ bool is_valid_blkaddr(struct f2fs_sb_info *sbi, block_t blkaddr, int type) | |||
125 | /* | 140 | /* |
126 | * Readahead CP/NAT/SIT/SSA pages | 141 | * Readahead CP/NAT/SIT/SSA pages |
127 | */ | 142 | */ |
128 | int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type) | 143 | int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, |
144 | int type, bool sync) | ||
129 | { | 145 | { |
130 | block_t prev_blk_addr = 0; | 146 | block_t prev_blk_addr = 0; |
131 | struct page *page; | 147 | struct page *page; |
@@ -133,10 +149,13 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type | |||
133 | struct f2fs_io_info fio = { | 149 | struct f2fs_io_info fio = { |
134 | .sbi = sbi, | 150 | .sbi = sbi, |
135 | .type = META, | 151 | .type = META, |
136 | .rw = READ_SYNC | REQ_META | REQ_PRIO, | 152 | .rw = sync ? (READ_SYNC | REQ_META | REQ_PRIO) : READA, |
137 | .encrypted_page = NULL, | 153 | .encrypted_page = NULL, |
138 | }; | 154 | }; |
139 | 155 | ||
156 | if (unlikely(type == META_POR)) | ||
157 | fio.rw &= ~REQ_META; | ||
158 | |||
140 | for (; nrpages-- > 0; blkno++) { | 159 | for (; nrpages-- > 0; blkno++) { |
141 | 160 | ||
142 | if (!is_valid_blkaddr(sbi, blkno, type)) | 161 | if (!is_valid_blkaddr(sbi, blkno, type)) |
@@ -196,7 +215,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index) | |||
196 | f2fs_put_page(page, 0); | 215 | f2fs_put_page(page, 0); |
197 | 216 | ||
198 | if (readahead) | 217 | if (readahead) |
199 | ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR); | 218 | ra_meta_pages(sbi, index, MAX_BIO_BLOCKS(sbi), META_POR, true); |
200 | } | 219 | } |
201 | 220 | ||
202 | static int f2fs_write_meta_page(struct page *page, | 221 | static int f2fs_write_meta_page(struct page *page, |
@@ -257,7 +276,7 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, | |||
257 | long nr_to_write) | 276 | long nr_to_write) |
258 | { | 277 | { |
259 | struct address_space *mapping = META_MAPPING(sbi); | 278 | struct address_space *mapping = META_MAPPING(sbi); |
260 | pgoff_t index = 0, end = LONG_MAX; | 279 | pgoff_t index = 0, end = LONG_MAX, prev = LONG_MAX; |
261 | struct pagevec pvec; | 280 | struct pagevec pvec; |
262 | long nwritten = 0; | 281 | long nwritten = 0; |
263 | struct writeback_control wbc = { | 282 | struct writeback_control wbc = { |
@@ -277,6 +296,13 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, | |||
277 | for (i = 0; i < nr_pages; i++) { | 296 | for (i = 0; i < nr_pages; i++) { |
278 | struct page *page = pvec.pages[i]; | 297 | struct page *page = pvec.pages[i]; |
279 | 298 | ||
299 | if (prev == LONG_MAX) | ||
300 | prev = page->index - 1; | ||
301 | if (nr_to_write != LONG_MAX && page->index != prev + 1) { | ||
302 | pagevec_release(&pvec); | ||
303 | goto stop; | ||
304 | } | ||
305 | |||
280 | lock_page(page); | 306 | lock_page(page); |
281 | 307 | ||
282 | if (unlikely(page->mapping != mapping)) { | 308 | if (unlikely(page->mapping != mapping)) { |
@@ -297,13 +323,14 @@ continue_unlock: | |||
297 | break; | 323 | break; |
298 | } | 324 | } |
299 | nwritten++; | 325 | nwritten++; |
326 | prev = page->index; | ||
300 | if (unlikely(nwritten >= nr_to_write)) | 327 | if (unlikely(nwritten >= nr_to_write)) |
301 | break; | 328 | break; |
302 | } | 329 | } |
303 | pagevec_release(&pvec); | 330 | pagevec_release(&pvec); |
304 | cond_resched(); | 331 | cond_resched(); |
305 | } | 332 | } |
306 | 333 | stop: | |
307 | if (nwritten) | 334 | if (nwritten) |
308 | f2fs_submit_merged_bio(sbi, type, WRITE); | 335 | f2fs_submit_merged_bio(sbi, type, WRITE); |
309 | 336 | ||
@@ -495,7 +522,7 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi) | |||
495 | start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi); | 522 | start_blk = __start_cp_addr(sbi) + 1 + __cp_payload(sbi); |
496 | orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi); | 523 | orphan_blocks = __start_sum_addr(sbi) - 1 - __cp_payload(sbi); |
497 | 524 | ||
498 | ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP); | 525 | ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true); |
499 | 526 | ||
500 | for (i = 0; i < orphan_blocks; i++) { | 527 | for (i = 0; i < orphan_blocks; i++) { |
501 | struct page *page = get_meta_page(sbi, start_blk + i); | 528 | struct page *page = get_meta_page(sbi, start_blk + i); |
@@ -1000,6 +1027,11 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1000 | 1027 | ||
1001 | start_blk = __start_cp_addr(sbi); | 1028 | start_blk = __start_cp_addr(sbi); |
1002 | 1029 | ||
1030 | /* need to wait for end_io results */ | ||
1031 | wait_on_all_pages_writeback(sbi); | ||
1032 | if (unlikely(f2fs_cp_error(sbi))) | ||
1033 | return; | ||
1034 | |||
1003 | /* write out checkpoint buffer at block 0 */ | 1035 | /* write out checkpoint buffer at block 0 */ |
1004 | update_meta_page(sbi, ckpt, start_blk++); | 1036 | update_meta_page(sbi, ckpt, start_blk++); |
1005 | 1037 | ||
@@ -1109,6 +1141,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1109 | if (cpc->reason == CP_RECOVERY) | 1141 | if (cpc->reason == CP_RECOVERY) |
1110 | f2fs_msg(sbi->sb, KERN_NOTICE, | 1142 | f2fs_msg(sbi->sb, KERN_NOTICE, |
1111 | "checkpoint: version = %llx", ckpt_ver); | 1143 | "checkpoint: version = %llx", ckpt_ver); |
1144 | |||
1145 | /* do checkpoint periodically */ | ||
1146 | sbi->cp_expires = round_jiffies_up(jiffies + HZ * sbi->cp_interval); | ||
1112 | out: | 1147 | out: |
1113 | mutex_unlock(&sbi->cp_mutex); | 1148 | mutex_unlock(&sbi->cp_mutex); |
1114 | trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); | 1149 | trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a82abe921b89..972eab7ac071 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -275,7 +275,8 @@ int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index) | |||
275 | return f2fs_reserve_block(dn, index); | 275 | return f2fs_reserve_block(dn, index); |
276 | } | 276 | } |
277 | 277 | ||
278 | struct page *get_read_data_page(struct inode *inode, pgoff_t index, int rw) | 278 | struct page *get_read_data_page(struct inode *inode, pgoff_t index, |
279 | int rw, bool for_write) | ||
279 | { | 280 | { |
280 | struct address_space *mapping = inode->i_mapping; | 281 | struct address_space *mapping = inode->i_mapping; |
281 | struct dnode_of_data dn; | 282 | struct dnode_of_data dn; |
@@ -292,7 +293,7 @@ struct page *get_read_data_page(struct inode *inode, pgoff_t index, int rw) | |||
292 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) | 293 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) |
293 | return read_mapping_page(mapping, index, NULL); | 294 | return read_mapping_page(mapping, index, NULL); |
294 | 295 | ||
295 | page = grab_cache_page(mapping, index); | 296 | page = f2fs_grab_cache_page(mapping, index, for_write); |
296 | if (!page) | 297 | if (!page) |
297 | return ERR_PTR(-ENOMEM); | 298 | return ERR_PTR(-ENOMEM); |
298 | 299 | ||
@@ -352,7 +353,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index) | |||
352 | return page; | 353 | return page; |
353 | f2fs_put_page(page, 0); | 354 | f2fs_put_page(page, 0); |
354 | 355 | ||
355 | page = get_read_data_page(inode, index, READ_SYNC); | 356 | page = get_read_data_page(inode, index, READ_SYNC, false); |
356 | if (IS_ERR(page)) | 357 | if (IS_ERR(page)) |
357 | return page; | 358 | return page; |
358 | 359 | ||
@@ -372,12 +373,13 @@ struct page *find_data_page(struct inode *inode, pgoff_t index) | |||
372 | * Because, the callers, functions in dir.c and GC, should be able to know | 373 | * Because, the callers, functions in dir.c and GC, should be able to know |
373 | * whether this page exists or not. | 374 | * whether this page exists or not. |
374 | */ | 375 | */ |
375 | struct page *get_lock_data_page(struct inode *inode, pgoff_t index) | 376 | struct page *get_lock_data_page(struct inode *inode, pgoff_t index, |
377 | bool for_write) | ||
376 | { | 378 | { |
377 | struct address_space *mapping = inode->i_mapping; | 379 | struct address_space *mapping = inode->i_mapping; |
378 | struct page *page; | 380 | struct page *page; |
379 | repeat: | 381 | repeat: |
380 | page = get_read_data_page(inode, index, READ_SYNC); | 382 | page = get_read_data_page(inode, index, READ_SYNC, for_write); |
381 | if (IS_ERR(page)) | 383 | if (IS_ERR(page)) |
382 | return page; | 384 | return page; |
383 | 385 | ||
@@ -411,7 +413,7 @@ struct page *get_new_data_page(struct inode *inode, | |||
411 | struct dnode_of_data dn; | 413 | struct dnode_of_data dn; |
412 | int err; | 414 | int err; |
413 | repeat: | 415 | repeat: |
414 | page = grab_cache_page(mapping, index); | 416 | page = f2fs_grab_cache_page(mapping, index, true); |
415 | if (!page) { | 417 | if (!page) { |
416 | /* | 418 | /* |
417 | * before exiting, we should make sure ipage will be released | 419 | * before exiting, we should make sure ipage will be released |
@@ -439,7 +441,7 @@ repeat: | |||
439 | } else { | 441 | } else { |
440 | f2fs_put_page(page, 1); | 442 | f2fs_put_page(page, 1); |
441 | 443 | ||
442 | page = get_read_data_page(inode, index, READ_SYNC); | 444 | page = get_read_data_page(inode, index, READ_SYNC, true); |
443 | if (IS_ERR(page)) | 445 | if (IS_ERR(page)) |
444 | goto repeat; | 446 | goto repeat; |
445 | 447 | ||
@@ -447,9 +449,9 @@ repeat: | |||
447 | lock_page(page); | 449 | lock_page(page); |
448 | } | 450 | } |
449 | got_it: | 451 | got_it: |
450 | if (new_i_size && | 452 | if (new_i_size && i_size_read(inode) < |
451 | i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) { | 453 | ((loff_t)(index + 1) << PAGE_CACHE_SHIFT)) { |
452 | i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT)); | 454 | i_size_write(inode, ((loff_t)(index + 1) << PAGE_CACHE_SHIFT)); |
453 | /* Only the directory inode sets new_i_size */ | 455 | /* Only the directory inode sets new_i_size */ |
454 | set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); | 456 | set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR); |
455 | } | 457 | } |
@@ -489,8 +491,9 @@ alloc: | |||
489 | /* update i_size */ | 491 | /* update i_size */ |
490 | fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) + | 492 | fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) + |
491 | dn->ofs_in_node; | 493 | dn->ofs_in_node; |
492 | if (i_size_read(dn->inode) < ((fofs + 1) << PAGE_CACHE_SHIFT)) | 494 | if (i_size_read(dn->inode) < ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT)) |
493 | i_size_write(dn->inode, ((fofs + 1) << PAGE_CACHE_SHIFT)); | 495 | i_size_write(dn->inode, |
496 | ((loff_t)(fofs + 1) << PAGE_CACHE_SHIFT)); | ||
494 | 497 | ||
495 | /* direct IO doesn't use extent cache to maximize the performance */ | 498 | /* direct IO doesn't use extent cache to maximize the performance */ |
496 | f2fs_drop_largest_extent(dn->inode, fofs); | 499 | f2fs_drop_largest_extent(dn->inode, fofs); |
@@ -523,6 +526,9 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset, | |||
523 | while (dn.ofs_in_node < end_offset && len) { | 526 | while (dn.ofs_in_node < end_offset && len) { |
524 | block_t blkaddr; | 527 | block_t blkaddr; |
525 | 528 | ||
529 | if (unlikely(f2fs_cp_error(sbi))) | ||
530 | goto sync_out; | ||
531 | |||
526 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); | 532 | blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); |
527 | if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) { | 533 | if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) { |
528 | if (__allocate_data_block(&dn)) | 534 | if (__allocate_data_block(&dn)) |
@@ -565,6 +571,7 @@ static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, | |||
565 | { | 571 | { |
566 | unsigned int maxblocks = map->m_len; | 572 | unsigned int maxblocks = map->m_len; |
567 | struct dnode_of_data dn; | 573 | struct dnode_of_data dn; |
574 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
568 | int mode = create ? ALLOC_NODE : LOOKUP_NODE_RA; | 575 | int mode = create ? ALLOC_NODE : LOOKUP_NODE_RA; |
569 | pgoff_t pgofs, end_offset; | 576 | pgoff_t pgofs, end_offset; |
570 | int err = 0, ofs = 1; | 577 | int err = 0, ofs = 1; |
@@ -595,40 +602,40 @@ static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, | |||
595 | err = 0; | 602 | err = 0; |
596 | goto unlock_out; | 603 | goto unlock_out; |
597 | } | 604 | } |
598 | if (dn.data_blkaddr == NEW_ADDR) { | 605 | |
599 | if (flag == F2FS_GET_BLOCK_BMAP) { | 606 | if (dn.data_blkaddr == NEW_ADDR || dn.data_blkaddr == NULL_ADDR) { |
600 | err = -ENOENT; | 607 | if (create) { |
601 | goto put_out; | 608 | if (unlikely(f2fs_cp_error(sbi))) { |
602 | } else if (flag == F2FS_GET_BLOCK_READ || | 609 | err = -EIO; |
603 | flag == F2FS_GET_BLOCK_DIO) { | 610 | goto put_out; |
604 | goto put_out; | 611 | } |
612 | err = __allocate_data_block(&dn); | ||
613 | if (err) | ||
614 | goto put_out; | ||
615 | allocated = true; | ||
616 | map->m_flags = F2FS_MAP_NEW; | ||
617 | } else { | ||
618 | if (flag != F2FS_GET_BLOCK_FIEMAP || | ||
619 | dn.data_blkaddr != NEW_ADDR) { | ||
620 | if (flag == F2FS_GET_BLOCK_BMAP) | ||
621 | err = -ENOENT; | ||
622 | goto put_out; | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * preallocated unwritten block should be mapped | ||
627 | * for fiemap. | ||
628 | */ | ||
629 | if (dn.data_blkaddr == NEW_ADDR) | ||
630 | map->m_flags = F2FS_MAP_UNWRITTEN; | ||
605 | } | 631 | } |
606 | /* | ||
607 | * if it is in fiemap call path (flag = F2FS_GET_BLOCK_FIEMAP), | ||
608 | * mark it as mapped and unwritten block. | ||
609 | */ | ||
610 | } | 632 | } |
611 | 633 | ||
612 | if (dn.data_blkaddr != NULL_ADDR) { | 634 | map->m_flags |= F2FS_MAP_MAPPED; |
613 | map->m_flags = F2FS_MAP_MAPPED; | 635 | map->m_pblk = dn.data_blkaddr; |
614 | map->m_pblk = dn.data_blkaddr; | 636 | map->m_len = 1; |
615 | if (dn.data_blkaddr == NEW_ADDR) | ||
616 | map->m_flags |= F2FS_MAP_UNWRITTEN; | ||
617 | } else if (create) { | ||
618 | err = __allocate_data_block(&dn); | ||
619 | if (err) | ||
620 | goto put_out; | ||
621 | allocated = true; | ||
622 | map->m_flags = F2FS_MAP_NEW | F2FS_MAP_MAPPED; | ||
623 | map->m_pblk = dn.data_blkaddr; | ||
624 | } else { | ||
625 | if (flag == F2FS_GET_BLOCK_BMAP) | ||
626 | err = -ENOENT; | ||
627 | goto put_out; | ||
628 | } | ||
629 | 637 | ||
630 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); | 638 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); |
631 | map->m_len = 1; | ||
632 | dn.ofs_in_node++; | 639 | dn.ofs_in_node++; |
633 | pgofs++; | 640 | pgofs++; |
634 | 641 | ||
@@ -647,23 +654,35 @@ get_next: | |||
647 | goto unlock_out; | 654 | goto unlock_out; |
648 | } | 655 | } |
649 | 656 | ||
650 | if (dn.data_blkaddr == NEW_ADDR && | ||
651 | flag != F2FS_GET_BLOCK_FIEMAP) | ||
652 | goto put_out; | ||
653 | |||
654 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); | 657 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); |
655 | } | 658 | } |
656 | 659 | ||
657 | if (maxblocks > map->m_len) { | 660 | if (maxblocks > map->m_len) { |
658 | block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); | 661 | block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); |
659 | if (blkaddr == NULL_ADDR && create) { | 662 | |
660 | err = __allocate_data_block(&dn); | 663 | if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) { |
661 | if (err) | 664 | if (create) { |
662 | goto sync_out; | 665 | if (unlikely(f2fs_cp_error(sbi))) { |
663 | allocated = true; | 666 | err = -EIO; |
664 | map->m_flags |= F2FS_MAP_NEW; | 667 | goto sync_out; |
665 | blkaddr = dn.data_blkaddr; | 668 | } |
669 | err = __allocate_data_block(&dn); | ||
670 | if (err) | ||
671 | goto sync_out; | ||
672 | allocated = true; | ||
673 | map->m_flags |= F2FS_MAP_NEW; | ||
674 | blkaddr = dn.data_blkaddr; | ||
675 | } else { | ||
676 | /* | ||
677 | * we only merge preallocated unwritten blocks | ||
678 | * for fiemap. | ||
679 | */ | ||
680 | if (flag != F2FS_GET_BLOCK_FIEMAP || | ||
681 | blkaddr != NEW_ADDR) | ||
682 | goto sync_out; | ||
683 | } | ||
666 | } | 684 | } |
685 | |||
667 | /* Give more consecutive addresses for the readahead */ | 686 | /* Give more consecutive addresses for the readahead */ |
668 | if ((map->m_pblk != NEW_ADDR && | 687 | if ((map->m_pblk != NEW_ADDR && |
669 | blkaddr == (map->m_pblk + ofs)) || | 688 | blkaddr == (map->m_pblk + ofs)) || |
@@ -752,6 +771,12 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
752 | if (ret) | 771 | if (ret) |
753 | return ret; | 772 | return ret; |
754 | 773 | ||
774 | if (f2fs_has_inline_data(inode)) { | ||
775 | ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len); | ||
776 | if (ret != -EAGAIN) | ||
777 | return ret; | ||
778 | } | ||
779 | |||
755 | mutex_lock(&inode->i_mutex); | 780 | mutex_lock(&inode->i_mutex); |
756 | 781 | ||
757 | if (len >= isize) { | 782 | if (len >= isize) { |
@@ -903,7 +928,8 @@ static int f2fs_mpage_readpages(struct address_space *mapping, | |||
903 | map.m_lblk = block_in_file; | 928 | map.m_lblk = block_in_file; |
904 | map.m_len = last_block - block_in_file; | 929 | map.m_len = last_block - block_in_file; |
905 | 930 | ||
906 | if (f2fs_map_blocks(inode, &map, 0, false)) | 931 | if (f2fs_map_blocks(inode, &map, 0, |
932 | F2FS_GET_BLOCK_READ)) | ||
907 | goto set_error_page; | 933 | goto set_error_page; |
908 | } | 934 | } |
909 | got_it: | 935 | got_it: |
@@ -936,21 +962,14 @@ submit_and_realloc: | |||
936 | 962 | ||
937 | if (f2fs_encrypted_inode(inode) && | 963 | if (f2fs_encrypted_inode(inode) && |
938 | S_ISREG(inode->i_mode)) { | 964 | S_ISREG(inode->i_mode)) { |
939 | struct page *cpage; | ||
940 | 965 | ||
941 | ctx = f2fs_get_crypto_ctx(inode); | 966 | ctx = f2fs_get_crypto_ctx(inode); |
942 | if (IS_ERR(ctx)) | 967 | if (IS_ERR(ctx)) |
943 | goto set_error_page; | 968 | goto set_error_page; |
944 | 969 | ||
945 | /* wait the page to be moved by cleaning */ | 970 | /* wait the page to be moved by cleaning */ |
946 | cpage = find_lock_page( | 971 | f2fs_wait_on_encrypted_page_writeback( |
947 | META_MAPPING(F2FS_I_SB(inode)), | 972 | F2FS_I_SB(inode), block_nr); |
948 | block_nr); | ||
949 | if (cpage) { | ||
950 | f2fs_wait_on_page_writeback(cpage, | ||
951 | DATA); | ||
952 | f2fs_put_page(cpage, 1); | ||
953 | } | ||
954 | } | 973 | } |
955 | 974 | ||
956 | bio = bio_alloc(GFP_KERNEL, | 975 | bio = bio_alloc(GFP_KERNEL, |
@@ -1012,6 +1031,9 @@ static int f2fs_read_data_pages(struct file *file, | |||
1012 | struct list_head *pages, unsigned nr_pages) | 1031 | struct list_head *pages, unsigned nr_pages) |
1013 | { | 1032 | { |
1014 | struct inode *inode = file->f_mapping->host; | 1033 | struct inode *inode = file->f_mapping->host; |
1034 | struct page *page = list_entry(pages->prev, struct page, lru); | ||
1035 | |||
1036 | trace_f2fs_readpages(inode, page, nr_pages); | ||
1015 | 1037 | ||
1016 | /* If the file has inline data, skip readpages */ | 1038 | /* If the file has inline data, skip readpages */ |
1017 | if (f2fs_has_inline_data(inode)) | 1039 | if (f2fs_has_inline_data(inode)) |
@@ -1041,6 +1063,11 @@ int do_write_data_page(struct f2fs_io_info *fio) | |||
1041 | } | 1063 | } |
1042 | 1064 | ||
1043 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { | 1065 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { |
1066 | |||
1067 | /* wait for GCed encrypted page writeback */ | ||
1068 | f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode), | ||
1069 | fio->blk_addr); | ||
1070 | |||
1044 | fio->encrypted_page = f2fs_encrypt(inode, fio->page); | 1071 | fio->encrypted_page = f2fs_encrypt(inode, fio->page); |
1045 | if (IS_ERR(fio->encrypted_page)) { | 1072 | if (IS_ERR(fio->encrypted_page)) { |
1046 | err = PTR_ERR(fio->encrypted_page); | 1073 | err = PTR_ERR(fio->encrypted_page); |
@@ -1429,6 +1456,10 @@ put_next: | |||
1429 | 1456 | ||
1430 | f2fs_wait_on_page_writeback(page, DATA); | 1457 | f2fs_wait_on_page_writeback(page, DATA); |
1431 | 1458 | ||
1459 | /* wait for GCed encrypted page writeback */ | ||
1460 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) | ||
1461 | f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); | ||
1462 | |||
1432 | if (len == PAGE_CACHE_SIZE) | 1463 | if (len == PAGE_CACHE_SIZE) |
1433 | goto out_update; | 1464 | goto out_update; |
1434 | if (PageUptodate(page)) | 1465 | if (PageUptodate(page)) |
@@ -1551,10 +1582,16 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
1551 | 1582 | ||
1552 | trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); | 1583 | trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); |
1553 | 1584 | ||
1554 | if (iov_iter_rw(iter) == WRITE) | 1585 | if (iov_iter_rw(iter) == WRITE) { |
1555 | __allocate_data_blocks(inode, offset, count); | 1586 | __allocate_data_blocks(inode, offset, count); |
1587 | if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) { | ||
1588 | err = -EIO; | ||
1589 | goto out; | ||
1590 | } | ||
1591 | } | ||
1556 | 1592 | ||
1557 | err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block_dio); | 1593 | err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block_dio); |
1594 | out: | ||
1558 | if (err < 0 && iov_iter_rw(iter) == WRITE) | 1595 | if (err < 0 && iov_iter_rw(iter) == WRITE) |
1559 | f2fs_write_failed(mapping, offset + count); | 1596 | f2fs_write_failed(mapping, offset + count); |
1560 | 1597 | ||
@@ -1636,12 +1673,13 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) | |||
1636 | { | 1673 | { |
1637 | struct inode *inode = mapping->host; | 1674 | struct inode *inode = mapping->host; |
1638 | 1675 | ||
1639 | /* we don't need to use inline_data strictly */ | 1676 | if (f2fs_has_inline_data(inode)) |
1640 | if (f2fs_has_inline_data(inode)) { | 1677 | return 0; |
1641 | int err = f2fs_convert_inline_inode(inode); | 1678 | |
1642 | if (err) | 1679 | /* make sure allocating whole blocks */ |
1643 | return err; | 1680 | if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) |
1644 | } | 1681 | filemap_write_and_wait(mapping); |
1682 | |||
1645 | return generic_block_bmap(mapping, block, get_data_block_bmap); | 1683 | return generic_block_bmap(mapping, block, get_data_block_bmap); |
1646 | } | 1684 | } |
1647 | 1685 | ||
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index d013d8479753..478e5d54154f 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c | |||
@@ -33,11 +33,11 @@ static void update_general_status(struct f2fs_sb_info *sbi) | |||
33 | int i; | 33 | int i; |
34 | 34 | ||
35 | /* validation check of the segment numbers */ | 35 | /* validation check of the segment numbers */ |
36 | si->hit_largest = atomic_read(&sbi->read_hit_largest); | 36 | si->hit_largest = atomic64_read(&sbi->read_hit_largest); |
37 | si->hit_cached = atomic_read(&sbi->read_hit_cached); | 37 | si->hit_cached = atomic64_read(&sbi->read_hit_cached); |
38 | si->hit_rbtree = atomic_read(&sbi->read_hit_rbtree); | 38 | si->hit_rbtree = atomic64_read(&sbi->read_hit_rbtree); |
39 | si->hit_total = si->hit_largest + si->hit_cached + si->hit_rbtree; | 39 | si->hit_total = si->hit_largest + si->hit_cached + si->hit_rbtree; |
40 | si->total_ext = atomic_read(&sbi->total_hit_ext); | 40 | si->total_ext = atomic64_read(&sbi->total_hit_ext); |
41 | si->ext_tree = sbi->total_ext_tree; | 41 | si->ext_tree = sbi->total_ext_tree; |
42 | si->ext_node = atomic_read(&sbi->total_ext_node); | 42 | si->ext_node = atomic_read(&sbi->total_ext_node); |
43 | si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); | 43 | si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); |
@@ -118,7 +118,7 @@ static void update_sit_info(struct f2fs_sb_info *sbi) | |||
118 | } | 118 | } |
119 | } | 119 | } |
120 | dist = div_u64(MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec, 100); | 120 | dist = div_u64(MAIN_SECS(sbi) * hblks_per_sec * hblks_per_sec, 100); |
121 | si->bimodal = div_u64(bimodal, dist); | 121 | si->bimodal = div64_u64(bimodal, dist); |
122 | if (si->dirty_count) | 122 | if (si->dirty_count) |
123 | si->avg_vblocks = div_u64(total_vblocks, ndirty); | 123 | si->avg_vblocks = div_u64(total_vblocks, ndirty); |
124 | else | 124 | else |
@@ -198,9 +198,9 @@ get_cache: | |||
198 | 198 | ||
199 | si->page_mem = 0; | 199 | si->page_mem = 0; |
200 | npages = NODE_MAPPING(sbi)->nrpages; | 200 | npages = NODE_MAPPING(sbi)->nrpages; |
201 | si->page_mem += npages << PAGE_CACHE_SHIFT; | 201 | si->page_mem += (unsigned long long)npages << PAGE_CACHE_SHIFT; |
202 | npages = META_MAPPING(sbi)->nrpages; | 202 | npages = META_MAPPING(sbi)->nrpages; |
203 | si->page_mem += npages << PAGE_CACHE_SHIFT; | 203 | si->page_mem += (unsigned long long)npages << PAGE_CACHE_SHIFT; |
204 | } | 204 | } |
205 | 205 | ||
206 | static int stat_show(struct seq_file *s, void *v) | 206 | static int stat_show(struct seq_file *s, void *v) |
@@ -283,12 +283,12 @@ static int stat_show(struct seq_file *s, void *v) | |||
283 | seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks, | 283 | seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks, |
284 | si->bg_node_blks); | 284 | si->bg_node_blks); |
285 | seq_puts(s, "\nExtent Cache:\n"); | 285 | seq_puts(s, "\nExtent Cache:\n"); |
286 | seq_printf(s, " - Hit Count: L1-1:%d L1-2:%d L2:%d\n", | 286 | seq_printf(s, " - Hit Count: L1-1:%llu L1-2:%llu L2:%llu\n", |
287 | si->hit_largest, si->hit_cached, | 287 | si->hit_largest, si->hit_cached, |
288 | si->hit_rbtree); | 288 | si->hit_rbtree); |
289 | seq_printf(s, " - Hit Ratio: %d%% (%d / %d)\n", | 289 | seq_printf(s, " - Hit Ratio: %llu%% (%llu / %llu)\n", |
290 | !si->total_ext ? 0 : | 290 | !si->total_ext ? 0 : |
291 | (si->hit_total * 100) / si->total_ext, | 291 | div64_u64(si->hit_total * 100, si->total_ext), |
292 | si->hit_total, si->total_ext); | 292 | si->hit_total, si->total_ext); |
293 | seq_printf(s, " - Inner Struct Count: tree: %d, node: %d\n", | 293 | seq_printf(s, " - Inner Struct Count: tree: %d, node: %d\n", |
294 | si->ext_tree, si->ext_node); | 294 | si->ext_tree, si->ext_node); |
@@ -333,13 +333,13 @@ static int stat_show(struct seq_file *s, void *v) | |||
333 | 333 | ||
334 | /* memory footprint */ | 334 | /* memory footprint */ |
335 | update_mem_info(si->sbi); | 335 | update_mem_info(si->sbi); |
336 | seq_printf(s, "\nMemory: %u KB\n", | 336 | seq_printf(s, "\nMemory: %llu KB\n", |
337 | (si->base_mem + si->cache_mem + si->page_mem) >> 10); | 337 | (si->base_mem + si->cache_mem + si->page_mem) >> 10); |
338 | seq_printf(s, " - static: %u KB\n", | 338 | seq_printf(s, " - static: %llu KB\n", |
339 | si->base_mem >> 10); | 339 | si->base_mem >> 10); |
340 | seq_printf(s, " - cached: %u KB\n", | 340 | seq_printf(s, " - cached: %llu KB\n", |
341 | si->cache_mem >> 10); | 341 | si->cache_mem >> 10); |
342 | seq_printf(s, " - paged : %u KB\n", | 342 | seq_printf(s, " - paged : %llu KB\n", |
343 | si->page_mem >> 10); | 343 | si->page_mem >> 10); |
344 | } | 344 | } |
345 | mutex_unlock(&f2fs_stat_mutex); | 345 | mutex_unlock(&f2fs_stat_mutex); |
@@ -378,10 +378,10 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi) | |||
378 | si->sbi = sbi; | 378 | si->sbi = sbi; |
379 | sbi->stat_info = si; | 379 | sbi->stat_info = si; |
380 | 380 | ||
381 | atomic_set(&sbi->total_hit_ext, 0); | 381 | atomic64_set(&sbi->total_hit_ext, 0); |
382 | atomic_set(&sbi->read_hit_rbtree, 0); | 382 | atomic64_set(&sbi->read_hit_rbtree, 0); |
383 | atomic_set(&sbi->read_hit_largest, 0); | 383 | atomic64_set(&sbi->read_hit_largest, 0); |
384 | atomic_set(&sbi->read_hit_cached, 0); | 384 | atomic64_set(&sbi->read_hit_cached, 0); |
385 | 385 | ||
386 | atomic_set(&sbi->inline_xattr, 0); | 386 | atomic_set(&sbi->inline_xattr, 0); |
387 | atomic_set(&sbi->inline_inode, 0); | 387 | atomic_set(&sbi->inline_inode, 0); |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 8f15fc134040..7c1678ba8f92 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -258,7 +258,7 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *dir, struct page **p) | |||
258 | if (f2fs_has_inline_dentry(dir)) | 258 | if (f2fs_has_inline_dentry(dir)) |
259 | return f2fs_parent_inline_dir(dir, p); | 259 | return f2fs_parent_inline_dir(dir, p); |
260 | 260 | ||
261 | page = get_lock_data_page(dir, 0); | 261 | page = get_lock_data_page(dir, 0, false); |
262 | if (IS_ERR(page)) | 262 | if (IS_ERR(page)) |
263 | return NULL; | 263 | return NULL; |
264 | 264 | ||
@@ -740,7 +740,7 @@ bool f2fs_empty_dir(struct inode *dir) | |||
740 | return f2fs_empty_inline_dir(dir); | 740 | return f2fs_empty_inline_dir(dir); |
741 | 741 | ||
742 | for (bidx = 0; bidx < nblock; bidx++) { | 742 | for (bidx = 0; bidx < nblock; bidx++) { |
743 | dentry_page = get_lock_data_page(dir, bidx); | 743 | dentry_page = get_lock_data_page(dir, bidx, false); |
744 | if (IS_ERR(dentry_page)) { | 744 | if (IS_ERR(dentry_page)) { |
745 | if (PTR_ERR(dentry_page) == -ENOENT) | 745 | if (PTR_ERR(dentry_page) == -ENOENT) |
746 | continue; | 746 | continue; |
@@ -787,7 +787,6 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, | |||
787 | else | 787 | else |
788 | d_type = DT_UNKNOWN; | 788 | d_type = DT_UNKNOWN; |
789 | 789 | ||
790 | /* encrypted case */ | ||
791 | de_name.name = d->filename[bit_pos]; | 790 | de_name.name = d->filename[bit_pos]; |
792 | de_name.len = le16_to_cpu(de->name_len); | 791 | de_name.len = le16_to_cpu(de->name_len); |
793 | 792 | ||
@@ -795,12 +794,20 @@ bool f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, | |||
795 | int save_len = fstr->len; | 794 | int save_len = fstr->len; |
796 | int ret; | 795 | int ret; |
797 | 796 | ||
797 | de_name.name = kmalloc(de_name.len, GFP_NOFS); | ||
798 | if (!de_name.name) | ||
799 | return false; | ||
800 | |||
801 | memcpy(de_name.name, d->filename[bit_pos], de_name.len); | ||
802 | |||
798 | ret = f2fs_fname_disk_to_usr(d->inode, &de->hash_code, | 803 | ret = f2fs_fname_disk_to_usr(d->inode, &de->hash_code, |
799 | &de_name, fstr); | 804 | &de_name, fstr); |
800 | de_name = *fstr; | 805 | kfree(de_name.name); |
801 | fstr->len = save_len; | ||
802 | if (ret < 0) | 806 | if (ret < 0) |
803 | return true; | 807 | return true; |
808 | |||
809 | de_name = *fstr; | ||
810 | fstr->len = save_len; | ||
804 | } | 811 | } |
805 | 812 | ||
806 | if (!dir_emit(ctx, de_name.name, de_name.len, | 813 | if (!dir_emit(ctx, de_name.name, de_name.len, |
@@ -847,7 +854,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx) | |||
847 | min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES)); | 854 | min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES)); |
848 | 855 | ||
849 | for (; n < npages; n++) { | 856 | for (; n < npages; n++) { |
850 | dentry_page = get_lock_data_page(inode, n); | 857 | dentry_page = get_lock_data_page(inode, n, false); |
851 | if (IS_ERR(dentry_page)) | 858 | if (IS_ERR(dentry_page)) |
852 | continue; | 859 | continue; |
853 | 860 | ||
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 997ac86f2a1d..7ddba812e11b 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c | |||
@@ -155,11 +155,12 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi, | |||
155 | return count - et->count; | 155 | return count - et->count; |
156 | } | 156 | } |
157 | 157 | ||
158 | static void __drop_largest_extent(struct inode *inode, pgoff_t fofs) | 158 | static void __drop_largest_extent(struct inode *inode, |
159 | pgoff_t fofs, unsigned int len) | ||
159 | { | 160 | { |
160 | struct extent_info *largest = &F2FS_I(inode)->extent_tree->largest; | 161 | struct extent_info *largest = &F2FS_I(inode)->extent_tree->largest; |
161 | 162 | ||
162 | if (largest->fofs <= fofs && largest->fofs + largest->len > fofs) | 163 | if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs) |
163 | largest->len = 0; | 164 | largest->len = 0; |
164 | } | 165 | } |
165 | 166 | ||
@@ -168,7 +169,7 @@ void f2fs_drop_largest_extent(struct inode *inode, pgoff_t fofs) | |||
168 | if (!f2fs_may_extent_tree(inode)) | 169 | if (!f2fs_may_extent_tree(inode)) |
169 | return; | 170 | return; |
170 | 171 | ||
171 | __drop_largest_extent(inode, fofs); | 172 | __drop_largest_extent(inode, fofs, 1); |
172 | } | 173 | } |
173 | 174 | ||
174 | void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) | 175 | void f2fs_init_extent_tree(struct inode *inode, struct f2fs_extent *i_ext) |
@@ -350,8 +351,7 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi, | |||
350 | } | 351 | } |
351 | 352 | ||
352 | if (en) { | 353 | if (en) { |
353 | if (en->ei.len > et->largest.len) | 354 | __try_update_largest_extent(et, en); |
354 | et->largest = en->ei; | ||
355 | et->cached_en = en; | 355 | et->cached_en = en; |
356 | } | 356 | } |
357 | return en; | 357 | return en; |
@@ -388,18 +388,17 @@ do_insert: | |||
388 | if (!en) | 388 | if (!en) |
389 | return NULL; | 389 | return NULL; |
390 | 390 | ||
391 | if (en->ei.len > et->largest.len) | 391 | __try_update_largest_extent(et, en); |
392 | et->largest = en->ei; | ||
393 | et->cached_en = en; | 392 | et->cached_en = en; |
394 | return en; | 393 | return en; |
395 | } | 394 | } |
396 | 395 | ||
397 | unsigned int f2fs_update_extent_tree_range(struct inode *inode, | 396 | static unsigned int f2fs_update_extent_tree_range(struct inode *inode, |
398 | pgoff_t fofs, block_t blkaddr, unsigned int len) | 397 | pgoff_t fofs, block_t blkaddr, unsigned int len) |
399 | { | 398 | { |
400 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 399 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
401 | struct extent_tree *et = F2FS_I(inode)->extent_tree; | 400 | struct extent_tree *et = F2FS_I(inode)->extent_tree; |
402 | struct extent_node *en = NULL, *en1 = NULL, *en2 = NULL, *en3 = NULL; | 401 | struct extent_node *en = NULL, *en1 = NULL; |
403 | struct extent_node *prev_en = NULL, *next_en = NULL; | 402 | struct extent_node *prev_en = NULL, *next_en = NULL; |
404 | struct extent_info ei, dei, prev; | 403 | struct extent_info ei, dei, prev; |
405 | struct rb_node **insert_p = NULL, *insert_parent = NULL; | 404 | struct rb_node **insert_p = NULL, *insert_parent = NULL; |
@@ -409,6 +408,8 @@ unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
409 | if (!et) | 408 | if (!et) |
410 | return false; | 409 | return false; |
411 | 410 | ||
411 | trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len); | ||
412 | |||
412 | write_lock(&et->lock); | 413 | write_lock(&et->lock); |
413 | 414 | ||
414 | if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) { | 415 | if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) { |
@@ -419,148 +420,99 @@ unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
419 | prev = et->largest; | 420 | prev = et->largest; |
420 | dei.len = 0; | 421 | dei.len = 0; |
421 | 422 | ||
422 | /* we do not guarantee that the largest extent is cached all the time */ | 423 | /* |
423 | __drop_largest_extent(inode, fofs); | 424 | * drop largest extent before lookup, in case it's already |
425 | * been shrunk from extent tree | ||
426 | */ | ||
427 | __drop_largest_extent(inode, fofs, len); | ||
424 | 428 | ||
425 | /* 1. lookup first extent node in range [fofs, fofs + len - 1] */ | 429 | /* 1. lookup first extent node in range [fofs, fofs + len - 1] */ |
426 | en = __lookup_extent_tree_ret(et, fofs, &prev_en, &next_en, | 430 | en = __lookup_extent_tree_ret(et, fofs, &prev_en, &next_en, |
427 | &insert_p, &insert_parent); | 431 | &insert_p, &insert_parent); |
428 | if (!en) { | 432 | if (!en) |
429 | if (next_en) { | 433 | en = next_en; |
430 | en = next_en; | ||
431 | f2fs_bug_on(sbi, en->ei.fofs <= pos); | ||
432 | pos = en->ei.fofs; | ||
433 | } else { | ||
434 | /* | ||
435 | * skip searching in the tree since there is no | ||
436 | * larger extent node in the cache. | ||
437 | */ | ||
438 | goto update_extent; | ||
439 | } | ||
440 | } | ||
441 | 434 | ||
442 | /* 2. invlidate all extent nodes in range [fofs, fofs + len - 1] */ | 435 | /* 2. invlidate all extent nodes in range [fofs, fofs + len - 1] */ |
443 | while (en) { | 436 | while (en && en->ei.fofs < end) { |
444 | struct rb_node *node; | 437 | unsigned int org_end; |
438 | int parts = 0; /* # of parts current extent split into */ | ||
445 | 439 | ||
446 | if (pos >= end) | 440 | next_en = en1 = NULL; |
447 | break; | ||
448 | 441 | ||
449 | dei = en->ei; | 442 | dei = en->ei; |
450 | en1 = en2 = NULL; | 443 | org_end = dei.fofs + dei.len; |
444 | f2fs_bug_on(sbi, pos >= org_end); | ||
451 | 445 | ||
452 | node = rb_next(&en->rb_node); | 446 | if (pos > dei.fofs && pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) { |
447 | en->ei.len = pos - en->ei.fofs; | ||
448 | prev_en = en; | ||
449 | parts = 1; | ||
450 | } | ||
453 | 451 | ||
454 | /* | 452 | if (end < org_end && org_end - end >= F2FS_MIN_EXTENT_LEN) { |
455 | * 2.1 there are four cases when we invalidate blkaddr in extent | 453 | if (parts) { |
456 | * node, |V: valid address, X: will be invalidated| | 454 | set_extent_info(&ei, end, |
457 | */ | 455 | end - dei.fofs + dei.blk, |
458 | /* case#1, invalidate right part of extent node |VVVVVXXXXX| */ | 456 | org_end - end); |
459 | if (pos > dei.fofs && end >= dei.fofs + dei.len) { | 457 | en1 = __insert_extent_tree(sbi, et, &ei, |
460 | en->ei.len = pos - dei.fofs; | 458 | NULL, NULL); |
461 | 459 | next_en = en1; | |
462 | if (en->ei.len < F2FS_MIN_EXTENT_LEN) { | 460 | } else { |
463 | __detach_extent_node(sbi, et, en); | 461 | en->ei.fofs = end; |
464 | insert_p = NULL; | 462 | en->ei.blk += end - dei.fofs; |
465 | insert_parent = NULL; | 463 | en->ei.len -= end - dei.fofs; |
466 | goto update; | 464 | next_en = en; |
467 | } | 465 | } |
468 | 466 | parts++; | |
469 | if (__is_extent_same(&dei, &et->largest)) | ||
470 | et->largest = en->ei; | ||
471 | goto next; | ||
472 | } | 467 | } |
473 | 468 | ||
474 | /* case#2, invalidate left part of extent node |XXXXXVVVVV| */ | 469 | if (!next_en) { |
475 | if (pos <= dei.fofs && end < dei.fofs + dei.len) { | 470 | struct rb_node *node = rb_next(&en->rb_node); |
476 | en->ei.fofs = end; | ||
477 | en->ei.blk += end - dei.fofs; | ||
478 | en->ei.len -= end - dei.fofs; | ||
479 | |||
480 | if (en->ei.len < F2FS_MIN_EXTENT_LEN) { | ||
481 | __detach_extent_node(sbi, et, en); | ||
482 | insert_p = NULL; | ||
483 | insert_parent = NULL; | ||
484 | goto update; | ||
485 | } | ||
486 | 471 | ||
487 | if (__is_extent_same(&dei, &et->largest)) | 472 | next_en = node ? |
488 | et->largest = en->ei; | 473 | rb_entry(node, struct extent_node, rb_node) |
489 | goto next; | 474 | : NULL; |
490 | } | 475 | } |
491 | 476 | ||
492 | __detach_extent_node(sbi, et, en); | 477 | if (parts) |
478 | __try_update_largest_extent(et, en); | ||
479 | else | ||
480 | __detach_extent_node(sbi, et, en); | ||
493 | 481 | ||
494 | /* | 482 | /* |
495 | * if we remove node in rb-tree, our parent node pointer may | 483 | * if original extent is split into zero or two parts, extent |
496 | * point the wrong place, discard them. | 484 | * tree has been altered by deletion or insertion, therefore |
485 | * invalidate pointers regard to tree. | ||
497 | */ | 486 | */ |
498 | insert_p = NULL; | 487 | if (parts != 1) { |
499 | insert_parent = NULL; | 488 | insert_p = NULL; |
500 | 489 | insert_parent = NULL; | |
501 | /* case#3, invalidate entire extent node |XXXXXXXXXX| */ | ||
502 | if (pos <= dei.fofs && end >= dei.fofs + dei.len) { | ||
503 | if (__is_extent_same(&dei, &et->largest)) | ||
504 | et->largest.len = 0; | ||
505 | goto update; | ||
506 | } | 490 | } |
507 | 491 | ||
508 | /* | 492 | /* update in global extent list */ |
509 | * case#4, invalidate data in the middle of extent node | ||
510 | * |VVVXXXXVVV| | ||
511 | */ | ||
512 | if (dei.len > F2FS_MIN_EXTENT_LEN) { | ||
513 | unsigned int endofs; | ||
514 | |||
515 | /* insert left part of split extent into cache */ | ||
516 | if (pos - dei.fofs >= F2FS_MIN_EXTENT_LEN) { | ||
517 | set_extent_info(&ei, dei.fofs, dei.blk, | ||
518 | pos - dei.fofs); | ||
519 | en1 = __insert_extent_tree(sbi, et, &ei, | ||
520 | NULL, NULL); | ||
521 | } | ||
522 | |||
523 | /* insert right part of split extent into cache */ | ||
524 | endofs = dei.fofs + dei.len; | ||
525 | if (endofs - end >= F2FS_MIN_EXTENT_LEN) { | ||
526 | set_extent_info(&ei, end, | ||
527 | end - dei.fofs + dei.blk, | ||
528 | endofs - end); | ||
529 | en2 = __insert_extent_tree(sbi, et, &ei, | ||
530 | NULL, NULL); | ||
531 | } | ||
532 | } | ||
533 | update: | ||
534 | /* 2.2 update in global extent list */ | ||
535 | spin_lock(&sbi->extent_lock); | 493 | spin_lock(&sbi->extent_lock); |
536 | if (en && !list_empty(&en->list)) | 494 | if (!parts && !list_empty(&en->list)) |
537 | list_del(&en->list); | 495 | list_del(&en->list); |
538 | if (en1) | 496 | if (en1) |
539 | list_add_tail(&en1->list, &sbi->extent_list); | 497 | list_add_tail(&en1->list, &sbi->extent_list); |
540 | if (en2) | ||
541 | list_add_tail(&en2->list, &sbi->extent_list); | ||
542 | spin_unlock(&sbi->extent_lock); | 498 | spin_unlock(&sbi->extent_lock); |
543 | 499 | ||
544 | /* 2.3 release extent node */ | 500 | /* release extent node */ |
545 | if (en) | 501 | if (!parts) |
546 | kmem_cache_free(extent_node_slab, en); | 502 | kmem_cache_free(extent_node_slab, en); |
547 | next: | 503 | |
548 | en = node ? rb_entry(node, struct extent_node, rb_node) : NULL; | 504 | en = next_en; |
549 | next_en = en; | ||
550 | if (en) | ||
551 | pos = en->ei.fofs; | ||
552 | } | 505 | } |
553 | 506 | ||
554 | update_extent: | ||
555 | /* 3. update extent in extent cache */ | 507 | /* 3. update extent in extent cache */ |
556 | if (blkaddr) { | 508 | if (blkaddr) { |
557 | struct extent_node *den = NULL; | 509 | struct extent_node *den = NULL; |
558 | 510 | ||
559 | set_extent_info(&ei, fofs, blkaddr, len); | 511 | set_extent_info(&ei, fofs, blkaddr, len); |
560 | en3 = __try_merge_extent_node(sbi, et, &ei, &den, | 512 | en1 = __try_merge_extent_node(sbi, et, &ei, &den, |
561 | prev_en, next_en); | 513 | prev_en, next_en); |
562 | if (!en3) | 514 | if (!en1) |
563 | en3 = __insert_extent_tree(sbi, et, &ei, | 515 | en1 = __insert_extent_tree(sbi, et, &ei, |
564 | insert_p, insert_parent); | 516 | insert_p, insert_parent); |
565 | 517 | ||
566 | /* give up extent_cache, if split and small updates happen */ | 518 | /* give up extent_cache, if split and small updates happen */ |
@@ -572,11 +524,11 @@ update_extent: | |||
572 | } | 524 | } |
573 | 525 | ||
574 | spin_lock(&sbi->extent_lock); | 526 | spin_lock(&sbi->extent_lock); |
575 | if (en3) { | 527 | if (en1) { |
576 | if (list_empty(&en3->list)) | 528 | if (list_empty(&en1->list)) |
577 | list_add_tail(&en3->list, &sbi->extent_list); | 529 | list_add_tail(&en1->list, &sbi->extent_list); |
578 | else | 530 | else |
579 | list_move_tail(&en3->list, &sbi->extent_list); | 531 | list_move_tail(&en1->list, &sbi->extent_list); |
580 | } | 532 | } |
581 | if (den && !list_empty(&den->list)) | 533 | if (den && !list_empty(&den->list)) |
582 | list_del(&den->list); | 534 | list_del(&den->list); |
@@ -650,6 +602,11 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | |||
650 | } | 602 | } |
651 | spin_unlock(&sbi->extent_lock); | 603 | spin_unlock(&sbi->extent_lock); |
652 | 604 | ||
605 | /* | ||
606 | * reset ino for searching victims from beginning of global extent tree. | ||
607 | */ | ||
608 | ino = F2FS_ROOT_INO(sbi); | ||
609 | |||
653 | while ((found = radix_tree_gang_lookup(root, | 610 | while ((found = radix_tree_gang_lookup(root, |
654 | (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { | 611 | (void **)treevec, ino, EXT_TREE_VEC_SIZE))) { |
655 | unsigned i; | 612 | unsigned i; |
@@ -663,7 +620,7 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | |||
663 | write_unlock(&et->lock); | 620 | write_unlock(&et->lock); |
664 | 621 | ||
665 | if (node_cnt + tree_cnt >= nr_shrink) | 622 | if (node_cnt + tree_cnt >= nr_shrink) |
666 | break; | 623 | goto unlock_out; |
667 | } | 624 | } |
668 | } | 625 | } |
669 | unlock_out: | 626 | unlock_out: |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f1a90ffd7cad..9db5500d63d9 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/magic.h> | 19 | #include <linux/magic.h> |
20 | #include <linux/kobject.h> | 20 | #include <linux/kobject.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/vmalloc.h> | ||
22 | #include <linux/bio.h> | 23 | #include <linux/bio.h> |
23 | 24 | ||
24 | #ifdef CONFIG_F2FS_CHECK_FS | 25 | #ifdef CONFIG_F2FS_CHECK_FS |
@@ -52,6 +53,7 @@ | |||
52 | #define F2FS_MOUNT_NOBARRIER 0x00000800 | 53 | #define F2FS_MOUNT_NOBARRIER 0x00000800 |
53 | #define F2FS_MOUNT_FASTBOOT 0x00001000 | 54 | #define F2FS_MOUNT_FASTBOOT 0x00001000 |
54 | #define F2FS_MOUNT_EXTENT_CACHE 0x00002000 | 55 | #define F2FS_MOUNT_EXTENT_CACHE 0x00002000 |
56 | #define F2FS_MOUNT_FORCE_FG_GC 0x00004000 | ||
55 | 57 | ||
56 | #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option) | 58 | #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option) |
57 | #define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option) | 59 | #define set_opt(sbi, option) (sbi->mount_opt.opt |= F2FS_MOUNT_##option) |
@@ -122,6 +124,7 @@ enum { | |||
122 | (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) | 124 | (SM_I(sbi)->trim_sections * (sbi)->segs_per_sec) |
123 | #define BATCHED_TRIM_BLOCKS(sbi) \ | 125 | #define BATCHED_TRIM_BLOCKS(sbi) \ |
124 | (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) | 126 | (BATCHED_TRIM_SEGMENTS(sbi) << (sbi)->log_blocks_per_seg) |
127 | #define DEF_CP_INTERVAL 60 /* 60 secs */ | ||
125 | 128 | ||
126 | struct cp_control { | 129 | struct cp_control { |
127 | int reason; | 130 | int reason; |
@@ -230,6 +233,7 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, | |||
230 | #define F2FS_IOC_RELEASE_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 4) | 233 | #define F2FS_IOC_RELEASE_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 4) |
231 | #define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) | 234 | #define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) |
232 | #define F2FS_IOC_GARBAGE_COLLECT _IO(F2FS_IOCTL_MAGIC, 6) | 235 | #define F2FS_IOC_GARBAGE_COLLECT _IO(F2FS_IOCTL_MAGIC, 6) |
236 | #define F2FS_IOC_WRITE_CHECKPOINT _IO(F2FS_IOCTL_MAGIC, 7) | ||
233 | 237 | ||
234 | #define F2FS_IOC_SET_ENCRYPTION_POLICY \ | 238 | #define F2FS_IOC_SET_ENCRYPTION_POLICY \ |
235 | _IOR('f', 19, struct f2fs_encryption_policy) | 239 | _IOR('f', 19, struct f2fs_encryption_policy) |
@@ -246,6 +250,7 @@ static inline bool __has_cursum_space(struct f2fs_summary_block *sum, int size, | |||
246 | #define F2FS_GOING_DOWN_FULLSYNC 0x0 /* going down with full sync */ | 250 | #define F2FS_GOING_DOWN_FULLSYNC 0x0 /* going down with full sync */ |
247 | #define F2FS_GOING_DOWN_METASYNC 0x1 /* going down with metadata */ | 251 | #define F2FS_GOING_DOWN_METASYNC 0x1 /* going down with metadata */ |
248 | #define F2FS_GOING_DOWN_NOSYNC 0x2 /* going down */ | 252 | #define F2FS_GOING_DOWN_NOSYNC 0x2 /* going down */ |
253 | #define F2FS_GOING_DOWN_METAFLUSH 0x3 /* going down with meta flush */ | ||
249 | 254 | ||
250 | #if defined(__KERNEL__) && defined(CONFIG_COMPAT) | 255 | #if defined(__KERNEL__) && defined(CONFIG_COMPAT) |
251 | /* | 256 | /* |
@@ -492,12 +497,20 @@ static inline bool __is_front_mergeable(struct extent_info *cur, | |||
492 | return __is_extent_mergeable(cur, front); | 497 | return __is_extent_mergeable(cur, front); |
493 | } | 498 | } |
494 | 499 | ||
500 | static inline void __try_update_largest_extent(struct extent_tree *et, | ||
501 | struct extent_node *en) | ||
502 | { | ||
503 | if (en->ei.len > et->largest.len) | ||
504 | et->largest = en->ei; | ||
505 | } | ||
506 | |||
495 | struct f2fs_nm_info { | 507 | struct f2fs_nm_info { |
496 | block_t nat_blkaddr; /* base disk address of NAT */ | 508 | block_t nat_blkaddr; /* base disk address of NAT */ |
497 | nid_t max_nid; /* maximum possible node ids */ | 509 | nid_t max_nid; /* maximum possible node ids */ |
498 | nid_t available_nids; /* maximum available node ids */ | 510 | nid_t available_nids; /* maximum available node ids */ |
499 | nid_t next_scan_nid; /* the next nid to be scanned */ | 511 | nid_t next_scan_nid; /* the next nid to be scanned */ |
500 | unsigned int ram_thresh; /* control the memory footprint */ | 512 | unsigned int ram_thresh; /* control the memory footprint */ |
513 | unsigned int ra_nid_pages; /* # of nid pages to be readaheaded */ | ||
501 | 514 | ||
502 | /* NAT cache management */ | 515 | /* NAT cache management */ |
503 | struct radix_tree_root nat_root;/* root of the nat entry cache */ | 516 | struct radix_tree_root nat_root;/* root of the nat entry cache */ |
@@ -724,6 +737,7 @@ struct f2fs_sb_info { | |||
724 | struct rw_semaphore node_write; /* locking node writes */ | 737 | struct rw_semaphore node_write; /* locking node writes */ |
725 | struct mutex writepages; /* mutex for writepages() */ | 738 | struct mutex writepages; /* mutex for writepages() */ |
726 | wait_queue_head_t cp_wait; | 739 | wait_queue_head_t cp_wait; |
740 | long cp_expires, cp_interval; /* next expected periodic cp */ | ||
727 | 741 | ||
728 | struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ | 742 | struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ |
729 | 743 | ||
@@ -787,10 +801,10 @@ struct f2fs_sb_info { | |||
787 | unsigned int segment_count[2]; /* # of allocated segments */ | 801 | unsigned int segment_count[2]; /* # of allocated segments */ |
788 | unsigned int block_count[2]; /* # of allocated blocks */ | 802 | unsigned int block_count[2]; /* # of allocated blocks */ |
789 | atomic_t inplace_count; /* # of inplace update */ | 803 | atomic_t inplace_count; /* # of inplace update */ |
790 | atomic_t total_hit_ext; /* # of lookup extent cache */ | 804 | atomic64_t total_hit_ext; /* # of lookup extent cache */ |
791 | atomic_t read_hit_rbtree; /* # of hit rbtree extent node */ | 805 | atomic64_t read_hit_rbtree; /* # of hit rbtree extent node */ |
792 | atomic_t read_hit_largest; /* # of hit largest extent node */ | 806 | atomic64_t read_hit_largest; /* # of hit largest extent node */ |
793 | atomic_t read_hit_cached; /* # of hit cached extent node */ | 807 | atomic64_t read_hit_cached; /* # of hit cached extent node */ |
794 | atomic_t inline_xattr; /* # of inline_xattr inodes */ | 808 | atomic_t inline_xattr; /* # of inline_xattr inodes */ |
795 | atomic_t inline_inode; /* # of inline_data inodes */ | 809 | atomic_t inline_inode; /* # of inline_data inodes */ |
796 | atomic_t inline_dir; /* # of inline_dentry inodes */ | 810 | atomic_t inline_dir; /* # of inline_dentry inodes */ |
@@ -1220,6 +1234,24 @@ static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi) | |||
1220 | return sbi->total_valid_inode_count; | 1234 | return sbi->total_valid_inode_count; |
1221 | } | 1235 | } |
1222 | 1236 | ||
1237 | static inline struct page *f2fs_grab_cache_page(struct address_space *mapping, | ||
1238 | pgoff_t index, bool for_write) | ||
1239 | { | ||
1240 | if (!for_write) | ||
1241 | return grab_cache_page(mapping, index); | ||
1242 | return grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS); | ||
1243 | } | ||
1244 | |||
1245 | static inline void f2fs_copy_page(struct page *src, struct page *dst) | ||
1246 | { | ||
1247 | char *src_kaddr = kmap(src); | ||
1248 | char *dst_kaddr = kmap(dst); | ||
1249 | |||
1250 | memcpy(dst_kaddr, src_kaddr, PAGE_SIZE); | ||
1251 | kunmap(dst); | ||
1252 | kunmap(src); | ||
1253 | } | ||
1254 | |||
1223 | static inline void f2fs_put_page(struct page *page, int unlock) | 1255 | static inline void f2fs_put_page(struct page *page, int unlock) |
1224 | { | 1256 | { |
1225 | if (!page) | 1257 | if (!page) |
@@ -1579,6 +1611,26 @@ static inline bool f2fs_may_extent_tree(struct inode *inode) | |||
1579 | return S_ISREG(mode); | 1611 | return S_ISREG(mode); |
1580 | } | 1612 | } |
1581 | 1613 | ||
1614 | static inline void *f2fs_kvmalloc(size_t size, gfp_t flags) | ||
1615 | { | ||
1616 | void *ret; | ||
1617 | |||
1618 | ret = kmalloc(size, flags | __GFP_NOWARN); | ||
1619 | if (!ret) | ||
1620 | ret = __vmalloc(size, flags, PAGE_KERNEL); | ||
1621 | return ret; | ||
1622 | } | ||
1623 | |||
1624 | static inline void *f2fs_kvzalloc(size_t size, gfp_t flags) | ||
1625 | { | ||
1626 | void *ret; | ||
1627 | |||
1628 | ret = kzalloc(size, flags | __GFP_NOWARN); | ||
1629 | if (!ret) | ||
1630 | ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL); | ||
1631 | return ret; | ||
1632 | } | ||
1633 | |||
1582 | #define get_inode_mode(i) \ | 1634 | #define get_inode_mode(i) \ |
1583 | ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \ | 1635 | ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \ |
1584 | (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) | 1636 | (F2FS_I(i)->i_acl_mode) : ((i)->i_mode)) |
@@ -1721,6 +1773,7 @@ int f2fs_issue_flush(struct f2fs_sb_info *); | |||
1721 | int create_flush_cmd_control(struct f2fs_sb_info *); | 1773 | int create_flush_cmd_control(struct f2fs_sb_info *); |
1722 | void destroy_flush_cmd_control(struct f2fs_sb_info *); | 1774 | void destroy_flush_cmd_control(struct f2fs_sb_info *); |
1723 | void invalidate_blocks(struct f2fs_sb_info *, block_t); | 1775 | void invalidate_blocks(struct f2fs_sb_info *, block_t); |
1776 | bool is_checkpointed_data(struct f2fs_sb_info *, block_t); | ||
1724 | void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); | 1777 | void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); |
1725 | void clear_prefree_segments(struct f2fs_sb_info *, struct cp_control *); | 1778 | void clear_prefree_segments(struct f2fs_sb_info *, struct cp_control *); |
1726 | void release_discard_addrs(struct f2fs_sb_info *); | 1779 | void release_discard_addrs(struct f2fs_sb_info *); |
@@ -1739,6 +1792,7 @@ void f2fs_replace_block(struct f2fs_sb_info *, struct dnode_of_data *, | |||
1739 | void allocate_data_block(struct f2fs_sb_info *, struct page *, | 1792 | void allocate_data_block(struct f2fs_sb_info *, struct page *, |
1740 | block_t, block_t *, struct f2fs_summary *, int); | 1793 | block_t, block_t *, struct f2fs_summary *, int); |
1741 | void f2fs_wait_on_page_writeback(struct page *, enum page_type); | 1794 | void f2fs_wait_on_page_writeback(struct page *, enum page_type); |
1795 | void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *, block_t); | ||
1742 | void write_data_summaries(struct f2fs_sb_info *, block_t); | 1796 | void write_data_summaries(struct f2fs_sb_info *, block_t); |
1743 | void write_node_summaries(struct f2fs_sb_info *, block_t); | 1797 | void write_node_summaries(struct f2fs_sb_info *, block_t); |
1744 | int lookup_journal_in_cursum(struct f2fs_summary_block *, | 1798 | int lookup_journal_in_cursum(struct f2fs_summary_block *, |
@@ -1754,8 +1808,9 @@ void destroy_segment_manager_caches(void); | |||
1754 | */ | 1808 | */ |
1755 | struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t); | 1809 | struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t); |
1756 | struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t); | 1810 | struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t); |
1811 | struct page *get_tmp_page(struct f2fs_sb_info *, pgoff_t); | ||
1757 | bool is_valid_blkaddr(struct f2fs_sb_info *, block_t, int); | 1812 | bool is_valid_blkaddr(struct f2fs_sb_info *, block_t, int); |
1758 | int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int); | 1813 | int ra_meta_pages(struct f2fs_sb_info *, block_t, int, int, bool); |
1759 | void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t); | 1814 | void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t); |
1760 | long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); | 1815 | long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); |
1761 | void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type); | 1816 | void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type); |
@@ -1787,9 +1842,9 @@ void set_data_blkaddr(struct dnode_of_data *); | |||
1787 | int reserve_new_block(struct dnode_of_data *); | 1842 | int reserve_new_block(struct dnode_of_data *); |
1788 | int f2fs_get_block(struct dnode_of_data *, pgoff_t); | 1843 | int f2fs_get_block(struct dnode_of_data *, pgoff_t); |
1789 | int f2fs_reserve_block(struct dnode_of_data *, pgoff_t); | 1844 | int f2fs_reserve_block(struct dnode_of_data *, pgoff_t); |
1790 | struct page *get_read_data_page(struct inode *, pgoff_t, int); | 1845 | struct page *get_read_data_page(struct inode *, pgoff_t, int, bool); |
1791 | struct page *find_data_page(struct inode *, pgoff_t); | 1846 | struct page *find_data_page(struct inode *, pgoff_t); |
1792 | struct page *get_lock_data_page(struct inode *, pgoff_t); | 1847 | struct page *get_lock_data_page(struct inode *, pgoff_t, bool); |
1793 | struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); | 1848 | struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); |
1794 | int do_write_data_page(struct f2fs_io_info *); | 1849 | int do_write_data_page(struct f2fs_io_info *); |
1795 | int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *, u64, u64); | 1850 | int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *, u64, u64); |
@@ -1802,7 +1857,7 @@ int f2fs_release_page(struct page *, gfp_t); | |||
1802 | int start_gc_thread(struct f2fs_sb_info *); | 1857 | int start_gc_thread(struct f2fs_sb_info *); |
1803 | void stop_gc_thread(struct f2fs_sb_info *); | 1858 | void stop_gc_thread(struct f2fs_sb_info *); |
1804 | block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *); | 1859 | block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *); |
1805 | int f2fs_gc(struct f2fs_sb_info *); | 1860 | int f2fs_gc(struct f2fs_sb_info *, bool); |
1806 | void build_gc_manager(struct f2fs_sb_info *); | 1861 | void build_gc_manager(struct f2fs_sb_info *); |
1807 | 1862 | ||
1808 | /* | 1863 | /* |
@@ -1820,7 +1875,8 @@ struct f2fs_stat_info { | |||
1820 | struct f2fs_sb_info *sbi; | 1875 | struct f2fs_sb_info *sbi; |
1821 | int all_area_segs, sit_area_segs, nat_area_segs, ssa_area_segs; | 1876 | int all_area_segs, sit_area_segs, nat_area_segs, ssa_area_segs; |
1822 | int main_area_segs, main_area_sections, main_area_zones; | 1877 | int main_area_segs, main_area_sections, main_area_zones; |
1823 | int hit_largest, hit_cached, hit_rbtree, hit_total, total_ext; | 1878 | unsigned long long hit_largest, hit_cached, hit_rbtree; |
1879 | unsigned long long hit_total, total_ext; | ||
1824 | int ext_tree, ext_node; | 1880 | int ext_tree, ext_node; |
1825 | int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta; | 1881 | int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta; |
1826 | int nats, dirty_nats, sits, dirty_sits, fnids; | 1882 | int nats, dirty_nats, sits, dirty_sits, fnids; |
@@ -1844,7 +1900,7 @@ struct f2fs_stat_info { | |||
1844 | unsigned int segment_count[2]; | 1900 | unsigned int segment_count[2]; |
1845 | unsigned int block_count[2]; | 1901 | unsigned int block_count[2]; |
1846 | unsigned int inplace_count; | 1902 | unsigned int inplace_count; |
1847 | unsigned base_mem, cache_mem, page_mem; | 1903 | unsigned long long base_mem, cache_mem, page_mem; |
1848 | }; | 1904 | }; |
1849 | 1905 | ||
1850 | static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) | 1906 | static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) |
@@ -1857,10 +1913,10 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi) | |||
1857 | #define stat_inc_bggc_count(sbi) ((sbi)->bg_gc++) | 1913 | #define stat_inc_bggc_count(sbi) ((sbi)->bg_gc++) |
1858 | #define stat_inc_dirty_dir(sbi) ((sbi)->n_dirty_dirs++) | 1914 | #define stat_inc_dirty_dir(sbi) ((sbi)->n_dirty_dirs++) |
1859 | #define stat_dec_dirty_dir(sbi) ((sbi)->n_dirty_dirs--) | 1915 | #define stat_dec_dirty_dir(sbi) ((sbi)->n_dirty_dirs--) |
1860 | #define stat_inc_total_hit(sbi) (atomic_inc(&(sbi)->total_hit_ext)) | 1916 | #define stat_inc_total_hit(sbi) (atomic64_inc(&(sbi)->total_hit_ext)) |
1861 | #define stat_inc_rbtree_node_hit(sbi) (atomic_inc(&(sbi)->read_hit_rbtree)) | 1917 | #define stat_inc_rbtree_node_hit(sbi) (atomic64_inc(&(sbi)->read_hit_rbtree)) |
1862 | #define stat_inc_largest_node_hit(sbi) (atomic_inc(&(sbi)->read_hit_largest)) | 1918 | #define stat_inc_largest_node_hit(sbi) (atomic64_inc(&(sbi)->read_hit_largest)) |
1863 | #define stat_inc_cached_node_hit(sbi) (atomic_inc(&(sbi)->read_hit_cached)) | 1919 | #define stat_inc_cached_node_hit(sbi) (atomic64_inc(&(sbi)->read_hit_cached)) |
1864 | #define stat_inc_inline_xattr(inode) \ | 1920 | #define stat_inc_inline_xattr(inode) \ |
1865 | do { \ | 1921 | do { \ |
1866 | if (f2fs_has_inline_xattr(inode)) \ | 1922 | if (f2fs_has_inline_xattr(inode)) \ |
@@ -1998,6 +2054,8 @@ void f2fs_delete_inline_entry(struct f2fs_dir_entry *, struct page *, | |||
1998 | bool f2fs_empty_inline_dir(struct inode *); | 2054 | bool f2fs_empty_inline_dir(struct inode *); |
1999 | int f2fs_read_inline_dir(struct file *, struct dir_context *, | 2055 | int f2fs_read_inline_dir(struct file *, struct dir_context *, |
2000 | struct f2fs_str *); | 2056 | struct f2fs_str *); |
2057 | int f2fs_inline_data_fiemap(struct inode *, | ||
2058 | struct fiemap_extent_info *, __u64, __u64); | ||
2001 | 2059 | ||
2002 | /* | 2060 | /* |
2003 | * shrinker.c | 2061 | * shrinker.c |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 8120f8685141..a197215ad52b 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -74,7 +74,8 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, | |||
74 | goto mapped; | 74 | goto mapped; |
75 | 75 | ||
76 | /* page is wholly or partially inside EOF */ | 76 | /* page is wholly or partially inside EOF */ |
77 | if (((page->index + 1) << PAGE_CACHE_SHIFT) > i_size_read(inode)) { | 77 | if (((loff_t)(page->index + 1) << PAGE_CACHE_SHIFT) > |
78 | i_size_read(inode)) { | ||
78 | unsigned offset; | 79 | unsigned offset; |
79 | offset = i_size_read(inode) & ~PAGE_CACHE_MASK; | 80 | offset = i_size_read(inode) & ~PAGE_CACHE_MASK; |
80 | zero_user_segment(page, offset, PAGE_CACHE_SIZE); | 81 | zero_user_segment(page, offset, PAGE_CACHE_SIZE); |
@@ -86,6 +87,11 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, | |||
86 | mapped: | 87 | mapped: |
87 | /* fill the page */ | 88 | /* fill the page */ |
88 | f2fs_wait_on_page_writeback(page, DATA); | 89 | f2fs_wait_on_page_writeback(page, DATA); |
90 | |||
91 | /* wait for GCed encrypted page writeback */ | ||
92 | if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) | ||
93 | f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr); | ||
94 | |||
89 | /* if gced page is attached, don't write to cold segment */ | 95 | /* if gced page is attached, don't write to cold segment */ |
90 | clear_cold_data(page); | 96 | clear_cold_data(page); |
91 | out: | 97 | out: |
@@ -343,7 +349,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) | |||
343 | 349 | ||
344 | dirty = __get_first_dirty_index(inode->i_mapping, pgofs, whence); | 350 | dirty = __get_first_dirty_index(inode->i_mapping, pgofs, whence); |
345 | 351 | ||
346 | for (; data_ofs < isize; data_ofs = pgofs << PAGE_CACHE_SHIFT) { | 352 | for (; data_ofs < isize; data_ofs = (loff_t)pgofs << PAGE_CACHE_SHIFT) { |
347 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 353 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
348 | err = get_dnode_of_data(&dn, pgofs, LOOKUP_NODE_RA); | 354 | err = get_dnode_of_data(&dn, pgofs, LOOKUP_NODE_RA); |
349 | if (err && err != -ENOENT) { | 355 | if (err && err != -ENOENT) { |
@@ -504,14 +510,14 @@ static int truncate_partial_data_page(struct inode *inode, u64 from, | |||
504 | return 0; | 510 | return 0; |
505 | 511 | ||
506 | if (cache_only) { | 512 | if (cache_only) { |
507 | page = grab_cache_page(mapping, index); | 513 | page = f2fs_grab_cache_page(mapping, index, false); |
508 | if (page && PageUptodate(page)) | 514 | if (page && PageUptodate(page)) |
509 | goto truncate_out; | 515 | goto truncate_out; |
510 | f2fs_put_page(page, 1); | 516 | f2fs_put_page(page, 1); |
511 | return 0; | 517 | return 0; |
512 | } | 518 | } |
513 | 519 | ||
514 | page = get_lock_data_page(inode, index); | 520 | page = get_lock_data_page(inode, index, true); |
515 | if (IS_ERR(page)) | 521 | if (IS_ERR(page)) |
516 | return 0; | 522 | return 0; |
517 | truncate_out: | 523 | truncate_out: |
@@ -680,6 +686,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) | |||
680 | * larger than i_size. | 686 | * larger than i_size. |
681 | */ | 687 | */ |
682 | truncate_setsize(inode, attr->ia_size); | 688 | truncate_setsize(inode, attr->ia_size); |
689 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
683 | } | 690 | } |
684 | } | 691 | } |
685 | 692 | ||
@@ -738,23 +745,31 @@ static int fill_zero(struct inode *inode, pgoff_t index, | |||
738 | 745 | ||
739 | int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end) | 746 | int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end) |
740 | { | 747 | { |
741 | pgoff_t index; | ||
742 | int err; | 748 | int err; |
743 | 749 | ||
744 | for (index = pg_start; index < pg_end; index++) { | 750 | while (pg_start < pg_end) { |
745 | struct dnode_of_data dn; | 751 | struct dnode_of_data dn; |
752 | pgoff_t end_offset, count; | ||
746 | 753 | ||
747 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 754 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
748 | err = get_dnode_of_data(&dn, index, LOOKUP_NODE); | 755 | err = get_dnode_of_data(&dn, pg_start, LOOKUP_NODE); |
749 | if (err) { | 756 | if (err) { |
750 | if (err == -ENOENT) | 757 | if (err == -ENOENT) { |
758 | pg_start++; | ||
751 | continue; | 759 | continue; |
760 | } | ||
752 | return err; | 761 | return err; |
753 | } | 762 | } |
754 | 763 | ||
755 | if (dn.data_blkaddr != NULL_ADDR) | 764 | end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); |
756 | truncate_data_blocks_range(&dn, 1); | 765 | count = min(end_offset - dn.ofs_in_node, pg_end - pg_start); |
766 | |||
767 | f2fs_bug_on(F2FS_I_SB(inode), count == 0 || count > end_offset); | ||
768 | |||
769 | truncate_data_blocks_range(&dn, count); | ||
757 | f2fs_put_dnode(&dn); | 770 | f2fs_put_dnode(&dn); |
771 | |||
772 | pg_start += count; | ||
758 | } | 773 | } |
759 | return 0; | 774 | return 0; |
760 | } | 775 | } |
@@ -765,9 +780,6 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
765 | loff_t off_start, off_end; | 780 | loff_t off_start, off_end; |
766 | int ret = 0; | 781 | int ret = 0; |
767 | 782 | ||
768 | if (!S_ISREG(inode->i_mode)) | ||
769 | return -EOPNOTSUPP; | ||
770 | |||
771 | if (f2fs_has_inline_data(inode)) { | 783 | if (f2fs_has_inline_data(inode)) { |
772 | ret = f2fs_convert_inline_inode(inode); | 784 | ret = f2fs_convert_inline_inode(inode); |
773 | if (ret) | 785 | if (ret) |
@@ -805,8 +817,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
805 | 817 | ||
806 | f2fs_balance_fs(sbi); | 818 | f2fs_balance_fs(sbi); |
807 | 819 | ||
808 | blk_start = pg_start << PAGE_CACHE_SHIFT; | 820 | blk_start = (loff_t)pg_start << PAGE_CACHE_SHIFT; |
809 | blk_end = pg_end << PAGE_CACHE_SHIFT; | 821 | blk_end = (loff_t)pg_end << PAGE_CACHE_SHIFT; |
810 | truncate_inode_pages_range(mapping, blk_start, | 822 | truncate_inode_pages_range(mapping, blk_start, |
811 | blk_end - 1); | 823 | blk_end - 1); |
812 | 824 | ||
@@ -819,86 +831,100 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) | |||
819 | return ret; | 831 | return ret; |
820 | } | 832 | } |
821 | 833 | ||
822 | static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end) | 834 | static int __exchange_data_block(struct inode *inode, pgoff_t src, |
835 | pgoff_t dst, bool full) | ||
823 | { | 836 | { |
824 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 837 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
825 | struct dnode_of_data dn; | 838 | struct dnode_of_data dn; |
826 | pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE; | 839 | block_t new_addr; |
827 | int ret = 0; | 840 | bool do_replace = false; |
828 | 841 | int ret; | |
829 | for (; end < nrpages; start++, end++) { | ||
830 | block_t new_addr, old_addr; | ||
831 | |||
832 | f2fs_lock_op(sbi); | ||
833 | 842 | ||
834 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 843 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
835 | ret = get_dnode_of_data(&dn, end, LOOKUP_NODE_RA); | 844 | ret = get_dnode_of_data(&dn, src, LOOKUP_NODE_RA); |
836 | if (ret && ret != -ENOENT) { | 845 | if (ret && ret != -ENOENT) { |
837 | goto out; | 846 | return ret; |
838 | } else if (ret == -ENOENT) { | 847 | } else if (ret == -ENOENT) { |
839 | new_addr = NULL_ADDR; | 848 | new_addr = NULL_ADDR; |
840 | } else { | 849 | } else { |
841 | new_addr = dn.data_blkaddr; | 850 | new_addr = dn.data_blkaddr; |
842 | truncate_data_blocks_range(&dn, 1); | 851 | if (!is_checkpointed_data(sbi, new_addr)) { |
843 | f2fs_put_dnode(&dn); | 852 | dn.data_blkaddr = NULL_ADDR; |
853 | /* do not invalidate this block address */ | ||
854 | set_data_blkaddr(&dn); | ||
855 | f2fs_update_extent_cache(&dn); | ||
856 | do_replace = true; | ||
844 | } | 857 | } |
858 | f2fs_put_dnode(&dn); | ||
859 | } | ||
845 | 860 | ||
846 | if (new_addr == NULL_ADDR) { | 861 | if (new_addr == NULL_ADDR) |
847 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 862 | return full ? truncate_hole(inode, dst, dst + 1) : 0; |
848 | ret = get_dnode_of_data(&dn, start, LOOKUP_NODE_RA); | ||
849 | if (ret && ret != -ENOENT) { | ||
850 | goto out; | ||
851 | } else if (ret == -ENOENT) { | ||
852 | f2fs_unlock_op(sbi); | ||
853 | continue; | ||
854 | } | ||
855 | 863 | ||
856 | if (dn.data_blkaddr == NULL_ADDR) { | 864 | if (do_replace) { |
857 | f2fs_put_dnode(&dn); | 865 | struct page *ipage = get_node_page(sbi, inode->i_ino); |
858 | f2fs_unlock_op(sbi); | 866 | struct node_info ni; |
859 | continue; | ||
860 | } else { | ||
861 | truncate_data_blocks_range(&dn, 1); | ||
862 | } | ||
863 | 867 | ||
864 | f2fs_put_dnode(&dn); | 868 | if (IS_ERR(ipage)) { |
865 | } else { | 869 | ret = PTR_ERR(ipage); |
866 | struct page *ipage; | 870 | goto err_out; |
871 | } | ||
867 | 872 | ||
868 | ipage = get_node_page(sbi, inode->i_ino); | 873 | set_new_dnode(&dn, inode, ipage, NULL, 0); |
869 | if (IS_ERR(ipage)) { | 874 | ret = f2fs_reserve_block(&dn, dst); |
870 | ret = PTR_ERR(ipage); | 875 | if (ret) |
871 | goto out; | 876 | goto err_out; |
872 | } | ||
873 | 877 | ||
874 | set_new_dnode(&dn, inode, ipage, NULL, 0); | 878 | truncate_data_blocks_range(&dn, 1); |
875 | ret = f2fs_reserve_block(&dn, start); | ||
876 | if (ret) | ||
877 | goto out; | ||
878 | 879 | ||
879 | old_addr = dn.data_blkaddr; | 880 | get_node_info(sbi, dn.nid, &ni); |
880 | if (old_addr != NEW_ADDR && new_addr == NEW_ADDR) { | 881 | f2fs_replace_block(sbi, &dn, dn.data_blkaddr, new_addr, |
881 | dn.data_blkaddr = NULL_ADDR; | 882 | ni.version, true); |
882 | f2fs_update_extent_cache(&dn); | 883 | f2fs_put_dnode(&dn); |
883 | invalidate_blocks(sbi, old_addr); | 884 | } else { |
885 | struct page *psrc, *pdst; | ||
886 | |||
887 | psrc = get_lock_data_page(inode, src, true); | ||
888 | if (IS_ERR(psrc)) | ||
889 | return PTR_ERR(psrc); | ||
890 | pdst = get_new_data_page(inode, NULL, dst, false); | ||
891 | if (IS_ERR(pdst)) { | ||
892 | f2fs_put_page(psrc, 1); | ||
893 | return PTR_ERR(pdst); | ||
894 | } | ||
895 | f2fs_copy_page(psrc, pdst); | ||
896 | set_page_dirty(pdst); | ||
897 | f2fs_put_page(pdst, 1); | ||
898 | f2fs_put_page(psrc, 1); | ||
884 | 899 | ||
885 | dn.data_blkaddr = new_addr; | 900 | return truncate_hole(inode, src, src + 1); |
886 | set_data_blkaddr(&dn); | 901 | } |
887 | } else if (new_addr != NEW_ADDR) { | 902 | return 0; |
888 | struct node_info ni; | ||
889 | 903 | ||
890 | get_node_info(sbi, dn.nid, &ni); | 904 | err_out: |
891 | f2fs_replace_block(sbi, &dn, old_addr, new_addr, | 905 | if (!get_dnode_of_data(&dn, src, LOOKUP_NODE)) { |
892 | ni.version, true); | 906 | dn.data_blkaddr = new_addr; |
893 | } | 907 | set_data_blkaddr(&dn); |
908 | f2fs_update_extent_cache(&dn); | ||
909 | f2fs_put_dnode(&dn); | ||
910 | } | ||
911 | return ret; | ||
912 | } | ||
894 | 913 | ||
895 | f2fs_put_dnode(&dn); | 914 | static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end) |
896 | } | 915 | { |
916 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
917 | pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE; | ||
918 | int ret = 0; | ||
919 | |||
920 | for (; end < nrpages; start++, end++) { | ||
921 | f2fs_balance_fs(sbi); | ||
922 | f2fs_lock_op(sbi); | ||
923 | ret = __exchange_data_block(inode, end, start, true); | ||
897 | f2fs_unlock_op(sbi); | 924 | f2fs_unlock_op(sbi); |
925 | if (ret) | ||
926 | break; | ||
898 | } | 927 | } |
899 | return 0; | ||
900 | out: | ||
901 | f2fs_unlock_op(sbi); | ||
902 | return ret; | 928 | return ret; |
903 | } | 929 | } |
904 | 930 | ||
@@ -908,9 +934,6 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
908 | loff_t new_size; | 934 | loff_t new_size; |
909 | int ret; | 935 | int ret; |
910 | 936 | ||
911 | if (!S_ISREG(inode->i_mode)) | ||
912 | return -EINVAL; | ||
913 | |||
914 | if (offset + len >= i_size_read(inode)) | 937 | if (offset + len >= i_size_read(inode)) |
915 | return -EINVAL; | 938 | return -EINVAL; |
916 | 939 | ||
@@ -940,7 +963,12 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
940 | if (ret) | 963 | if (ret) |
941 | return ret; | 964 | return ret; |
942 | 965 | ||
966 | /* write out all moved pages, if possible */ | ||
967 | filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); | ||
968 | truncate_pagecache(inode, offset); | ||
969 | |||
943 | new_size = i_size_read(inode) - len; | 970 | new_size = i_size_read(inode) - len; |
971 | truncate_pagecache(inode, new_size); | ||
944 | 972 | ||
945 | ret = truncate_blocks(inode, new_size, true); | 973 | ret = truncate_blocks(inode, new_size, true); |
946 | if (!ret) | 974 | if (!ret) |
@@ -959,9 +987,6 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, | |||
959 | loff_t off_start, off_end; | 987 | loff_t off_start, off_end; |
960 | int ret = 0; | 988 | int ret = 0; |
961 | 989 | ||
962 | if (!S_ISREG(inode->i_mode)) | ||
963 | return -EINVAL; | ||
964 | |||
965 | ret = inode_newsize_ok(inode, (len + offset)); | 990 | ret = inode_newsize_ok(inode, (len + offset)); |
966 | if (ret) | 991 | if (ret) |
967 | return ret; | 992 | return ret; |
@@ -1003,7 +1028,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, | |||
1003 | return ret; | 1028 | return ret; |
1004 | 1029 | ||
1005 | new_size = max_t(loff_t, new_size, | 1030 | new_size = max_t(loff_t, new_size, |
1006 | pg_start << PAGE_CACHE_SHIFT); | 1031 | (loff_t)pg_start << PAGE_CACHE_SHIFT); |
1007 | } | 1032 | } |
1008 | 1033 | ||
1009 | for (index = pg_start; index < pg_end; index++) { | 1034 | for (index = pg_start; index < pg_end; index++) { |
@@ -1039,7 +1064,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, | |||
1039 | f2fs_unlock_op(sbi); | 1064 | f2fs_unlock_op(sbi); |
1040 | 1065 | ||
1041 | new_size = max_t(loff_t, new_size, | 1066 | new_size = max_t(loff_t, new_size, |
1042 | (index + 1) << PAGE_CACHE_SHIFT); | 1067 | (loff_t)(index + 1) << PAGE_CACHE_SHIFT); |
1043 | } | 1068 | } |
1044 | 1069 | ||
1045 | if (off_end) { | 1070 | if (off_end) { |
@@ -1066,10 +1091,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) | |||
1066 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 1091 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
1067 | pgoff_t pg_start, pg_end, delta, nrpages, idx; | 1092 | pgoff_t pg_start, pg_end, delta, nrpages, idx; |
1068 | loff_t new_size; | 1093 | loff_t new_size; |
1069 | int ret; | 1094 | int ret = 0; |
1070 | |||
1071 | if (!S_ISREG(inode->i_mode)) | ||
1072 | return -EINVAL; | ||
1073 | 1095 | ||
1074 | new_size = i_size_read(inode) + len; | 1096 | new_size = i_size_read(inode) + len; |
1075 | if (new_size > inode->i_sb->s_maxbytes) | 1097 | if (new_size > inode->i_sb->s_maxbytes) |
@@ -1107,57 +1129,19 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) | |||
1107 | nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE; | 1129 | nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE; |
1108 | 1130 | ||
1109 | for (idx = nrpages - 1; idx >= pg_start && idx != -1; idx--) { | 1131 | for (idx = nrpages - 1; idx >= pg_start && idx != -1; idx--) { |
1110 | struct dnode_of_data dn; | ||
1111 | struct page *ipage; | ||
1112 | block_t new_addr, old_addr; | ||
1113 | |||
1114 | f2fs_lock_op(sbi); | 1132 | f2fs_lock_op(sbi); |
1115 | 1133 | ret = __exchange_data_block(inode, idx, idx + delta, false); | |
1116 | set_new_dnode(&dn, inode, NULL, NULL, 0); | ||
1117 | ret = get_dnode_of_data(&dn, idx, LOOKUP_NODE_RA); | ||
1118 | if (ret && ret != -ENOENT) { | ||
1119 | goto out; | ||
1120 | } else if (ret == -ENOENT) { | ||
1121 | goto next; | ||
1122 | } else if (dn.data_blkaddr == NULL_ADDR) { | ||
1123 | f2fs_put_dnode(&dn); | ||
1124 | goto next; | ||
1125 | } else { | ||
1126 | new_addr = dn.data_blkaddr; | ||
1127 | truncate_data_blocks_range(&dn, 1); | ||
1128 | f2fs_put_dnode(&dn); | ||
1129 | } | ||
1130 | |||
1131 | ipage = get_node_page(sbi, inode->i_ino); | ||
1132 | if (IS_ERR(ipage)) { | ||
1133 | ret = PTR_ERR(ipage); | ||
1134 | goto out; | ||
1135 | } | ||
1136 | |||
1137 | set_new_dnode(&dn, inode, ipage, NULL, 0); | ||
1138 | ret = f2fs_reserve_block(&dn, idx + delta); | ||
1139 | if (ret) | ||
1140 | goto out; | ||
1141 | |||
1142 | old_addr = dn.data_blkaddr; | ||
1143 | f2fs_bug_on(sbi, old_addr != NEW_ADDR); | ||
1144 | |||
1145 | if (new_addr != NEW_ADDR) { | ||
1146 | struct node_info ni; | ||
1147 | |||
1148 | get_node_info(sbi, dn.nid, &ni); | ||
1149 | f2fs_replace_block(sbi, &dn, old_addr, new_addr, | ||
1150 | ni.version, true); | ||
1151 | } | ||
1152 | f2fs_put_dnode(&dn); | ||
1153 | next: | ||
1154 | f2fs_unlock_op(sbi); | 1134 | f2fs_unlock_op(sbi); |
1135 | if (ret) | ||
1136 | break; | ||
1155 | } | 1137 | } |
1156 | 1138 | ||
1157 | i_size_write(inode, new_size); | 1139 | /* write out all moved pages, if possible */ |
1158 | return 0; | 1140 | filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); |
1159 | out: | 1141 | truncate_pagecache(inode, offset); |
1160 | f2fs_unlock_op(sbi); | 1142 | |
1143 | if (!ret) | ||
1144 | i_size_write(inode, new_size); | ||
1161 | return ret; | 1145 | return ret; |
1162 | } | 1146 | } |
1163 | 1147 | ||
@@ -1204,9 +1188,10 @@ noalloc: | |||
1204 | if (pg_start == pg_end) | 1188 | if (pg_start == pg_end) |
1205 | new_size = offset + len; | 1189 | new_size = offset + len; |
1206 | else if (index == pg_start && off_start) | 1190 | else if (index == pg_start && off_start) |
1207 | new_size = (index + 1) << PAGE_CACHE_SHIFT; | 1191 | new_size = (loff_t)(index + 1) << PAGE_CACHE_SHIFT; |
1208 | else if (index == pg_end) | 1192 | else if (index == pg_end) |
1209 | new_size = (index << PAGE_CACHE_SHIFT) + off_end; | 1193 | new_size = ((loff_t)index << PAGE_CACHE_SHIFT) + |
1194 | off_end; | ||
1210 | else | 1195 | else |
1211 | new_size += PAGE_CACHE_SIZE; | 1196 | new_size += PAGE_CACHE_SIZE; |
1212 | } | 1197 | } |
@@ -1228,6 +1213,10 @@ static long f2fs_fallocate(struct file *file, int mode, | |||
1228 | struct inode *inode = file_inode(file); | 1213 | struct inode *inode = file_inode(file); |
1229 | long ret = 0; | 1214 | long ret = 0; |
1230 | 1215 | ||
1216 | /* f2fs only support ->fallocate for regular file */ | ||
1217 | if (!S_ISREG(inode->i_mode)) | ||
1218 | return -EINVAL; | ||
1219 | |||
1231 | if (f2fs_encrypted_inode(inode) && | 1220 | if (f2fs_encrypted_inode(inode) && |
1232 | (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE))) | 1221 | (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE))) |
1233 | return -EOPNOTSUPP; | 1222 | return -EOPNOTSUPP; |
@@ -1437,8 +1426,7 @@ static int f2fs_ioc_release_volatile_write(struct file *filp) | |||
1437 | if (!f2fs_is_first_block_written(inode)) | 1426 | if (!f2fs_is_first_block_written(inode)) |
1438 | return truncate_partial_data_page(inode, 0, true); | 1427 | return truncate_partial_data_page(inode, 0, true); |
1439 | 1428 | ||
1440 | punch_hole(inode, 0, F2FS_BLKSIZE); | 1429 | return punch_hole(inode, 0, F2FS_BLKSIZE); |
1441 | return 0; | ||
1442 | } | 1430 | } |
1443 | 1431 | ||
1444 | static int f2fs_ioc_abort_volatile_write(struct file *filp) | 1432 | static int f2fs_ioc_abort_volatile_write(struct file *filp) |
@@ -1455,13 +1443,9 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp) | |||
1455 | 1443 | ||
1456 | f2fs_balance_fs(F2FS_I_SB(inode)); | 1444 | f2fs_balance_fs(F2FS_I_SB(inode)); |
1457 | 1445 | ||
1458 | if (f2fs_is_atomic_file(inode)) { | 1446 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); |
1459 | clear_inode_flag(F2FS_I(inode), FI_ATOMIC_FILE); | 1447 | clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); |
1460 | commit_inmem_pages(inode, true); | 1448 | commit_inmem_pages(inode, true); |
1461 | } | ||
1462 | |||
1463 | if (f2fs_is_volatile_file(inode)) | ||
1464 | clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE); | ||
1465 | 1449 | ||
1466 | mnt_drop_write_file(filp); | 1450 | mnt_drop_write_file(filp); |
1467 | return ret; | 1451 | return ret; |
@@ -1496,6 +1480,10 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg) | |||
1496 | case F2FS_GOING_DOWN_NOSYNC: | 1480 | case F2FS_GOING_DOWN_NOSYNC: |
1497 | f2fs_stop_checkpoint(sbi); | 1481 | f2fs_stop_checkpoint(sbi); |
1498 | break; | 1482 | break; |
1483 | case F2FS_GOING_DOWN_METAFLUSH: | ||
1484 | sync_meta_pages(sbi, META, LONG_MAX); | ||
1485 | f2fs_stop_checkpoint(sbi); | ||
1486 | break; | ||
1499 | default: | 1487 | default: |
1500 | return -EINVAL; | 1488 | return -EINVAL; |
1501 | } | 1489 | } |
@@ -1616,27 +1604,44 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg) | |||
1616 | { | 1604 | { |
1617 | struct inode *inode = file_inode(filp); | 1605 | struct inode *inode = file_inode(filp); |
1618 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 1606 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
1619 | __u32 i, count; | 1607 | __u32 sync; |
1620 | 1608 | ||
1621 | if (!capable(CAP_SYS_ADMIN)) | 1609 | if (!capable(CAP_SYS_ADMIN)) |
1622 | return -EPERM; | 1610 | return -EPERM; |
1623 | 1611 | ||
1624 | if (get_user(count, (__u32 __user *)arg)) | 1612 | if (get_user(sync, (__u32 __user *)arg)) |
1625 | return -EFAULT; | 1613 | return -EFAULT; |
1626 | 1614 | ||
1627 | if (!count || count > F2FS_BATCH_GC_MAX_NUM) | 1615 | if (f2fs_readonly(sbi->sb)) |
1628 | return -EINVAL; | 1616 | return -EROFS; |
1629 | 1617 | ||
1630 | for (i = 0; i < count; i++) { | 1618 | if (!sync) { |
1631 | if (!mutex_trylock(&sbi->gc_mutex)) | 1619 | if (!mutex_trylock(&sbi->gc_mutex)) |
1632 | break; | 1620 | return -EBUSY; |
1633 | 1621 | } else { | |
1634 | if (f2fs_gc(sbi)) | 1622 | mutex_lock(&sbi->gc_mutex); |
1635 | break; | ||
1636 | } | 1623 | } |
1637 | 1624 | ||
1638 | if (put_user(i, (__u32 __user *)arg)) | 1625 | return f2fs_gc(sbi, sync); |
1639 | return -EFAULT; | 1626 | } |
1627 | |||
1628 | static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg) | ||
1629 | { | ||
1630 | struct inode *inode = file_inode(filp); | ||
1631 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | ||
1632 | struct cp_control cpc; | ||
1633 | |||
1634 | if (!capable(CAP_SYS_ADMIN)) | ||
1635 | return -EPERM; | ||
1636 | |||
1637 | if (f2fs_readonly(sbi->sb)) | ||
1638 | return -EROFS; | ||
1639 | |||
1640 | cpc.reason = __get_cp_reason(sbi); | ||
1641 | |||
1642 | mutex_lock(&sbi->gc_mutex); | ||
1643 | write_checkpoint(sbi, &cpc); | ||
1644 | mutex_unlock(&sbi->gc_mutex); | ||
1640 | 1645 | ||
1641 | return 0; | 1646 | return 0; |
1642 | } | 1647 | } |
@@ -1672,6 +1677,8 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1672 | return f2fs_ioc_get_encryption_pwsalt(filp, arg); | 1677 | return f2fs_ioc_get_encryption_pwsalt(filp, arg); |
1673 | case F2FS_IOC_GARBAGE_COLLECT: | 1678 | case F2FS_IOC_GARBAGE_COLLECT: |
1674 | return f2fs_ioc_gc(filp, arg); | 1679 | return f2fs_ioc_gc(filp, arg); |
1680 | case F2FS_IOC_WRITE_CHECKPOINT: | ||
1681 | return f2fs_ioc_write_checkpoint(filp, arg); | ||
1675 | default: | 1682 | default: |
1676 | return -ENOTTY; | 1683 | return -ENOTTY; |
1677 | } | 1684 | } |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 782b8e72c094..fedbf67a0842 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -78,9 +78,12 @@ static int gc_thread_func(void *data) | |||
78 | stat_inc_bggc_count(sbi); | 78 | stat_inc_bggc_count(sbi); |
79 | 79 | ||
80 | /* if return value is not zero, no victim was selected */ | 80 | /* if return value is not zero, no victim was selected */ |
81 | if (f2fs_gc(sbi)) | 81 | if (f2fs_gc(sbi, test_opt(sbi, FORCE_FG_GC))) |
82 | wait_ms = gc_th->no_gc_sleep_time; | 82 | wait_ms = gc_th->no_gc_sleep_time; |
83 | 83 | ||
84 | trace_f2fs_background_gc(sbi->sb, wait_ms, | ||
85 | prefree_segments(sbi), free_segments(sbi)); | ||
86 | |||
84 | /* balancing f2fs's metadata periodically */ | 87 | /* balancing f2fs's metadata periodically */ |
85 | f2fs_balance_fs_bg(sbi); | 88 | f2fs_balance_fs_bg(sbi); |
86 | 89 | ||
@@ -257,6 +260,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, | |||
257 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); | 260 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); |
258 | struct victim_sel_policy p; | 261 | struct victim_sel_policy p; |
259 | unsigned int secno, max_cost; | 262 | unsigned int secno, max_cost; |
263 | unsigned int last_segment = MAIN_SEGS(sbi); | ||
260 | int nsearched = 0; | 264 | int nsearched = 0; |
261 | 265 | ||
262 | mutex_lock(&dirty_i->seglist_lock); | 266 | mutex_lock(&dirty_i->seglist_lock); |
@@ -267,6 +271,9 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, | |||
267 | p.min_segno = NULL_SEGNO; | 271 | p.min_segno = NULL_SEGNO; |
268 | p.min_cost = max_cost = get_max_cost(sbi, &p); | 272 | p.min_cost = max_cost = get_max_cost(sbi, &p); |
269 | 273 | ||
274 | if (p.max_search == 0) | ||
275 | goto out; | ||
276 | |||
270 | if (p.alloc_mode == LFS && gc_type == FG_GC) { | 277 | if (p.alloc_mode == LFS && gc_type == FG_GC) { |
271 | p.min_segno = check_bg_victims(sbi); | 278 | p.min_segno = check_bg_victims(sbi); |
272 | if (p.min_segno != NULL_SEGNO) | 279 | if (p.min_segno != NULL_SEGNO) |
@@ -277,9 +284,10 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi, | |||
277 | unsigned long cost; | 284 | unsigned long cost; |
278 | unsigned int segno; | 285 | unsigned int segno; |
279 | 286 | ||
280 | segno = find_next_bit(p.dirty_segmap, MAIN_SEGS(sbi), p.offset); | 287 | segno = find_next_bit(p.dirty_segmap, last_segment, p.offset); |
281 | if (segno >= MAIN_SEGS(sbi)) { | 288 | if (segno >= last_segment) { |
282 | if (sbi->last_victim[p.gc_mode]) { | 289 | if (sbi->last_victim[p.gc_mode]) { |
290 | last_segment = sbi->last_victim[p.gc_mode]; | ||
283 | sbi->last_victim[p.gc_mode] = 0; | 291 | sbi->last_victim[p.gc_mode] = 0; |
284 | p.offset = 0; | 292 | p.offset = 0; |
285 | continue; | 293 | continue; |
@@ -327,6 +335,7 @@ got_it: | |||
327 | sbi->cur_victim_sec, | 335 | sbi->cur_victim_sec, |
328 | prefree_segments(sbi), free_segments(sbi)); | 336 | prefree_segments(sbi), free_segments(sbi)); |
329 | } | 337 | } |
338 | out: | ||
330 | mutex_unlock(&dirty_i->seglist_lock); | 339 | mutex_unlock(&dirty_i->seglist_lock); |
331 | 340 | ||
332 | return (p.min_segno == NULL_SEGNO) ? 0 : 1; | 341 | return (p.min_segno == NULL_SEGNO) ? 0 : 1; |
@@ -541,7 +550,7 @@ static void move_encrypted_block(struct inode *inode, block_t bidx) | |||
541 | int err; | 550 | int err; |
542 | 551 | ||
543 | /* do not read out */ | 552 | /* do not read out */ |
544 | page = grab_cache_page(inode->i_mapping, bidx); | 553 | page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); |
545 | if (!page) | 554 | if (!page) |
546 | return; | 555 | return; |
547 | 556 | ||
@@ -550,8 +559,16 @@ static void move_encrypted_block(struct inode *inode, block_t bidx) | |||
550 | if (err) | 559 | if (err) |
551 | goto out; | 560 | goto out; |
552 | 561 | ||
553 | if (unlikely(dn.data_blkaddr == NULL_ADDR)) | 562 | if (unlikely(dn.data_blkaddr == NULL_ADDR)) { |
563 | ClearPageUptodate(page); | ||
554 | goto put_out; | 564 | goto put_out; |
565 | } | ||
566 | |||
567 | /* | ||
568 | * don't cache encrypted data into meta inode until previous dirty | ||
569 | * data were writebacked to avoid racing between GC and flush. | ||
570 | */ | ||
571 | f2fs_wait_on_page_writeback(page, DATA); | ||
555 | 572 | ||
556 | get_node_info(fio.sbi, dn.nid, &ni); | 573 | get_node_info(fio.sbi, dn.nid, &ni); |
557 | set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); | 574 | set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version); |
@@ -580,7 +597,7 @@ static void move_encrypted_block(struct inode *inode, block_t bidx) | |||
580 | goto put_page_out; | 597 | goto put_page_out; |
581 | 598 | ||
582 | set_page_dirty(fio.encrypted_page); | 599 | set_page_dirty(fio.encrypted_page); |
583 | f2fs_wait_on_page_writeback(fio.encrypted_page, META); | 600 | f2fs_wait_on_page_writeback(fio.encrypted_page, DATA); |
584 | if (clear_page_dirty_for_io(fio.encrypted_page)) | 601 | if (clear_page_dirty_for_io(fio.encrypted_page)) |
585 | dec_page_count(fio.sbi, F2FS_DIRTY_META); | 602 | dec_page_count(fio.sbi, F2FS_DIRTY_META); |
586 | 603 | ||
@@ -611,7 +628,7 @@ static void move_data_page(struct inode *inode, block_t bidx, int gc_type) | |||
611 | { | 628 | { |
612 | struct page *page; | 629 | struct page *page; |
613 | 630 | ||
614 | page = get_lock_data_page(inode, bidx); | 631 | page = get_lock_data_page(inode, bidx, true); |
615 | if (IS_ERR(page)) | 632 | if (IS_ERR(page)) |
616 | return; | 633 | return; |
617 | 634 | ||
@@ -705,7 +722,7 @@ next_step: | |||
705 | 722 | ||
706 | start_bidx = start_bidx_of_node(nofs, F2FS_I(inode)); | 723 | start_bidx = start_bidx_of_node(nofs, F2FS_I(inode)); |
707 | data_page = get_read_data_page(inode, | 724 | data_page = get_read_data_page(inode, |
708 | start_bidx + ofs_in_node, READA); | 725 | start_bidx + ofs_in_node, READA, true); |
709 | if (IS_ERR(data_page)) { | 726 | if (IS_ERR(data_page)) { |
710 | iput(inode); | 727 | iput(inode); |
711 | continue; | 728 | continue; |
@@ -797,13 +814,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, | |||
797 | return nfree; | 814 | return nfree; |
798 | } | 815 | } |
799 | 816 | ||
800 | int f2fs_gc(struct f2fs_sb_info *sbi) | 817 | int f2fs_gc(struct f2fs_sb_info *sbi, bool sync) |
801 | { | 818 | { |
802 | unsigned int segno = NULL_SEGNO; | 819 | unsigned int segno, i; |
803 | unsigned int i; | 820 | int gc_type = sync ? FG_GC : BG_GC; |
804 | int gc_type = BG_GC; | 821 | int sec_freed = 0; |
805 | int nfree = 0; | 822 | int ret = -EINVAL; |
806 | int ret = -1; | ||
807 | struct cp_control cpc; | 823 | struct cp_control cpc; |
808 | struct gc_inode_list gc_list = { | 824 | struct gc_inode_list gc_list = { |
809 | .ilist = LIST_HEAD_INIT(gc_list.ilist), | 825 | .ilist = LIST_HEAD_INIT(gc_list.ilist), |
@@ -812,12 +828,14 @@ int f2fs_gc(struct f2fs_sb_info *sbi) | |||
812 | 828 | ||
813 | cpc.reason = __get_cp_reason(sbi); | 829 | cpc.reason = __get_cp_reason(sbi); |
814 | gc_more: | 830 | gc_more: |
831 | segno = NULL_SEGNO; | ||
832 | |||
815 | if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) | 833 | if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) |
816 | goto stop; | 834 | goto stop; |
817 | if (unlikely(f2fs_cp_error(sbi))) | 835 | if (unlikely(f2fs_cp_error(sbi))) |
818 | goto stop; | 836 | goto stop; |
819 | 837 | ||
820 | if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) { | 838 | if (gc_type == BG_GC && has_not_enough_free_secs(sbi, sec_freed)) { |
821 | gc_type = FG_GC; | 839 | gc_type = FG_GC; |
822 | if (__get_victim(sbi, &segno, gc_type) || prefree_segments(sbi)) | 840 | if (__get_victim(sbi, &segno, gc_type) || prefree_segments(sbi)) |
823 | write_checkpoint(sbi, &cpc); | 841 | write_checkpoint(sbi, &cpc); |
@@ -830,23 +848,38 @@ gc_more: | |||
830 | /* readahead multi ssa blocks those have contiguous address */ | 848 | /* readahead multi ssa blocks those have contiguous address */ |
831 | if (sbi->segs_per_sec > 1) | 849 | if (sbi->segs_per_sec > 1) |
832 | ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), sbi->segs_per_sec, | 850 | ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), sbi->segs_per_sec, |
833 | META_SSA); | 851 | META_SSA, true); |
834 | 852 | ||
835 | for (i = 0; i < sbi->segs_per_sec; i++) | 853 | for (i = 0; i < sbi->segs_per_sec; i++) { |
836 | nfree += do_garbage_collect(sbi, segno + i, &gc_list, gc_type); | 854 | /* |
855 | * for FG_GC case, halt gcing left segments once failed one | ||
856 | * of segments in selected section to avoid long latency. | ||
857 | */ | ||
858 | if (!do_garbage_collect(sbi, segno + i, &gc_list, gc_type) && | ||
859 | gc_type == FG_GC) | ||
860 | break; | ||
861 | } | ||
862 | |||
863 | if (i == sbi->segs_per_sec && gc_type == FG_GC) | ||
864 | sec_freed++; | ||
837 | 865 | ||
838 | if (gc_type == FG_GC) | 866 | if (gc_type == FG_GC) |
839 | sbi->cur_victim_sec = NULL_SEGNO; | 867 | sbi->cur_victim_sec = NULL_SEGNO; |
840 | 868 | ||
841 | if (has_not_enough_free_secs(sbi, nfree)) | 869 | if (!sync) { |
842 | goto gc_more; | 870 | if (has_not_enough_free_secs(sbi, sec_freed)) |
871 | goto gc_more; | ||
843 | 872 | ||
844 | if (gc_type == FG_GC) | 873 | if (gc_type == FG_GC) |
845 | write_checkpoint(sbi, &cpc); | 874 | write_checkpoint(sbi, &cpc); |
875 | } | ||
846 | stop: | 876 | stop: |
847 | mutex_unlock(&sbi->gc_mutex); | 877 | mutex_unlock(&sbi->gc_mutex); |
848 | 878 | ||
849 | put_gc_inode(&gc_list); | 879 | put_gc_inode(&gc_list); |
880 | |||
881 | if (sync) | ||
882 | ret = sec_freed ? 0 : -EAGAIN; | ||
850 | return ret; | 883 | return ret; |
851 | } | 884 | } |
852 | 885 | ||
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index c5a055b3376e..b4a65be9f7d3 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h | |||
@@ -19,12 +19,6 @@ | |||
19 | #define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */ | 19 | #define LIMIT_INVALID_BLOCK 40 /* percentage over total user space */ |
20 | #define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ | 20 | #define LIMIT_FREE_BLOCK 40 /* percentage over invalid + free space */ |
21 | 21 | ||
22 | /* | ||
23 | * with this macro, we can control the max time we do garbage collection, | ||
24 | * when user triggers batch mode gc by ioctl. | ||
25 | */ | ||
26 | #define F2FS_BATCH_GC_MAX_NUM 16 | ||
27 | |||
28 | /* Search max. number of dirty segments to select a victim segment */ | 22 | /* Search max. number of dirty segments to select a victim segment */ |
29 | #define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */ | 23 | #define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */ |
30 | 24 | ||
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 3d143be42895..bda7126466c0 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/f2fs_fs.h> | 12 | #include <linux/f2fs_fs.h> |
13 | 13 | ||
14 | #include "f2fs.h" | 14 | #include "f2fs.h" |
15 | #include "node.h" | ||
15 | 16 | ||
16 | bool f2fs_may_inline_data(struct inode *inode) | 17 | bool f2fs_may_inline_data(struct inode *inode) |
17 | { | 18 | { |
@@ -274,12 +275,14 @@ process_inline: | |||
274 | if (f2fs_has_inline_data(inode)) { | 275 | if (f2fs_has_inline_data(inode)) { |
275 | ipage = get_node_page(sbi, inode->i_ino); | 276 | ipage = get_node_page(sbi, inode->i_ino); |
276 | f2fs_bug_on(sbi, IS_ERR(ipage)); | 277 | f2fs_bug_on(sbi, IS_ERR(ipage)); |
277 | truncate_inline_inode(ipage, 0); | 278 | if (!truncate_inline_inode(ipage, 0)) |
279 | return false; | ||
278 | f2fs_clear_inline_inode(inode); | 280 | f2fs_clear_inline_inode(inode); |
279 | update_inode(inode, ipage); | 281 | update_inode(inode, ipage); |
280 | f2fs_put_page(ipage, 1); | 282 | f2fs_put_page(ipage, 1); |
281 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { | 283 | } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { |
282 | truncate_blocks(inode, 0, false); | 284 | if (truncate_blocks(inode, 0, false)) |
285 | return false; | ||
283 | goto process_inline; | 286 | goto process_inline; |
284 | } | 287 | } |
285 | return false; | 288 | return false; |
@@ -568,3 +571,38 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx, | |||
568 | f2fs_put_page(ipage, 1); | 571 | f2fs_put_page(ipage, 1); |
569 | return 0; | 572 | return 0; |
570 | } | 573 | } |
574 | |||
575 | int f2fs_inline_data_fiemap(struct inode *inode, | ||
576 | struct fiemap_extent_info *fieinfo, __u64 start, __u64 len) | ||
577 | { | ||
578 | __u64 byteaddr, ilen; | ||
579 | __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED | | ||
580 | FIEMAP_EXTENT_LAST; | ||
581 | struct node_info ni; | ||
582 | struct page *ipage; | ||
583 | int err = 0; | ||
584 | |||
585 | ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); | ||
586 | if (IS_ERR(ipage)) | ||
587 | return PTR_ERR(ipage); | ||
588 | |||
589 | if (!f2fs_has_inline_data(inode)) { | ||
590 | err = -EAGAIN; | ||
591 | goto out; | ||
592 | } | ||
593 | |||
594 | ilen = min_t(size_t, MAX_INLINE_DATA, i_size_read(inode)); | ||
595 | if (start >= ilen) | ||
596 | goto out; | ||
597 | if (start + len < ilen) | ||
598 | ilen = start + len; | ||
599 | ilen -= start; | ||
600 | |||
601 | get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni); | ||
602 | byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits; | ||
603 | byteaddr += (char *)inline_data_addr(ipage) - (char *)F2FS_INODE(ipage); | ||
604 | err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags); | ||
605 | out: | ||
606 | f2fs_put_page(ipage, 1); | ||
607 | return err; | ||
608 | } | ||
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 35aae65b3e5d..97e20decacb4 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -296,16 +296,12 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
296 | return 0; | 296 | return 0; |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * We need to lock here to prevent from producing dirty node pages | 299 | * We need to balance fs here to prevent from producing dirty node pages |
300 | * during the urgent cleaning time when runing out of free sections. | 300 | * during the urgent cleaning time when runing out of free sections. |
301 | */ | 301 | */ |
302 | f2fs_lock_op(sbi); | ||
303 | update_inode_page(inode); | 302 | update_inode_page(inode); |
304 | f2fs_unlock_op(sbi); | ||
305 | |||
306 | if (wbc) | ||
307 | f2fs_balance_fs(sbi); | ||
308 | 303 | ||
304 | f2fs_balance_fs(sbi); | ||
309 | return 0; | 305 | return 0; |
310 | } | 306 | } |
311 | 307 | ||
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index a680bf38e4f0..e48b80c49090 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -410,11 +410,14 @@ err_out: | |||
410 | * If the symlink path is stored into inline_data, there is no | 410 | * If the symlink path is stored into inline_data, there is no |
411 | * performance regression. | 411 | * performance regression. |
412 | */ | 412 | */ |
413 | if (!err) | 413 | if (!err) { |
414 | filemap_write_and_wait_range(inode->i_mapping, 0, p_len - 1); | 414 | filemap_write_and_wait_range(inode->i_mapping, 0, p_len - 1); |
415 | 415 | ||
416 | if (IS_DIRSYNC(dir)) | 416 | if (IS_DIRSYNC(dir)) |
417 | f2fs_sync_fs(sbi->sb, 1); | 417 | f2fs_sync_fs(sbi->sb, 1); |
418 | } else { | ||
419 | f2fs_unlink(dir, dentry); | ||
420 | } | ||
418 | 421 | ||
419 | kfree(sd); | 422 | kfree(sd); |
420 | f2fs_fname_crypto_free_buffer(&disk_link); | 423 | f2fs_fname_crypto_free_buffer(&disk_link); |
@@ -947,8 +950,13 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook | |||
947 | 950 | ||
948 | /* Symlink is encrypted */ | 951 | /* Symlink is encrypted */ |
949 | sd = (struct f2fs_encrypted_symlink_data *)caddr; | 952 | sd = (struct f2fs_encrypted_symlink_data *)caddr; |
950 | cstr.name = sd->encrypted_path; | ||
951 | cstr.len = le16_to_cpu(sd->len); | 953 | cstr.len = le16_to_cpu(sd->len); |
954 | cstr.name = kmalloc(cstr.len, GFP_NOFS); | ||
955 | if (!cstr.name) { | ||
956 | res = -ENOMEM; | ||
957 | goto errout; | ||
958 | } | ||
959 | memcpy(cstr.name, sd->encrypted_path, cstr.len); | ||
952 | 960 | ||
953 | /* this is broken symlink case */ | 961 | /* this is broken symlink case */ |
954 | if (cstr.name[0] == 0 && cstr.len == 0) { | 962 | if (cstr.name[0] == 0 && cstr.len == 0) { |
@@ -970,6 +978,8 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook | |||
970 | if (res < 0) | 978 | if (res < 0) |
971 | goto errout; | 979 | goto errout; |
972 | 980 | ||
981 | kfree(cstr.name); | ||
982 | |||
973 | paddr = pstr.name; | 983 | paddr = pstr.name; |
974 | 984 | ||
975 | /* Null-terminate the name */ | 985 | /* Null-terminate the name */ |
@@ -979,6 +989,7 @@ static const char *f2fs_encrypted_follow_link(struct dentry *dentry, void **cook | |||
979 | page_cache_release(cpage); | 989 | page_cache_release(cpage); |
980 | return *cookie = paddr; | 990 | return *cookie = paddr; |
981 | errout: | 991 | errout: |
992 | kfree(cstr.name); | ||
982 | f2fs_fname_crypto_free_buffer(&pstr); | 993 | f2fs_fname_crypto_free_buffer(&pstr); |
983 | kunmap(cpage); | 994 | kunmap(cpage); |
984 | page_cache_release(cpage); | 995 | page_cache_release(cpage); |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 27d1a74dd6f3..7bcbc6e9c40d 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -1323,23 +1323,24 @@ static int f2fs_write_node_page(struct page *page, | |||
1323 | nid = nid_of_node(page); | 1323 | nid = nid_of_node(page); |
1324 | f2fs_bug_on(sbi, page->index != nid); | 1324 | f2fs_bug_on(sbi, page->index != nid); |
1325 | 1325 | ||
1326 | if (wbc->for_reclaim) { | ||
1327 | if (!down_read_trylock(&sbi->node_write)) | ||
1328 | goto redirty_out; | ||
1329 | } else { | ||
1330 | down_read(&sbi->node_write); | ||
1331 | } | ||
1332 | |||
1326 | get_node_info(sbi, nid, &ni); | 1333 | get_node_info(sbi, nid, &ni); |
1327 | 1334 | ||
1328 | /* This page is already truncated */ | 1335 | /* This page is already truncated */ |
1329 | if (unlikely(ni.blk_addr == NULL_ADDR)) { | 1336 | if (unlikely(ni.blk_addr == NULL_ADDR)) { |
1330 | ClearPageUptodate(page); | 1337 | ClearPageUptodate(page); |
1331 | dec_page_count(sbi, F2FS_DIRTY_NODES); | 1338 | dec_page_count(sbi, F2FS_DIRTY_NODES); |
1339 | up_read(&sbi->node_write); | ||
1332 | unlock_page(page); | 1340 | unlock_page(page); |
1333 | return 0; | 1341 | return 0; |
1334 | } | 1342 | } |
1335 | 1343 | ||
1336 | if (wbc->for_reclaim) { | ||
1337 | if (!down_read_trylock(&sbi->node_write)) | ||
1338 | goto redirty_out; | ||
1339 | } else { | ||
1340 | down_read(&sbi->node_write); | ||
1341 | } | ||
1342 | |||
1343 | set_page_writeback(page); | 1344 | set_page_writeback(page); |
1344 | fio.blk_addr = ni.blk_addr; | 1345 | fio.blk_addr = ni.blk_addr; |
1345 | write_node_page(nid, &fio); | 1346 | write_node_page(nid, &fio); |
@@ -1528,7 +1529,8 @@ static void build_free_nids(struct f2fs_sb_info *sbi) | |||
1528 | return; | 1529 | return; |
1529 | 1530 | ||
1530 | /* readahead nat pages to be scanned */ | 1531 | /* readahead nat pages to be scanned */ |
1531 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT); | 1532 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, |
1533 | META_NAT, true); | ||
1532 | 1534 | ||
1533 | while (1) { | 1535 | while (1) { |
1534 | struct page *page = get_current_nat_page(sbi, nid); | 1536 | struct page *page = get_current_nat_page(sbi, nid); |
@@ -1558,6 +1560,9 @@ static void build_free_nids(struct f2fs_sb_info *sbi) | |||
1558 | remove_free_nid(nm_i, nid); | 1560 | remove_free_nid(nm_i, nid); |
1559 | } | 1561 | } |
1560 | mutex_unlock(&curseg->curseg_mutex); | 1562 | mutex_unlock(&curseg->curseg_mutex); |
1563 | |||
1564 | ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), | ||
1565 | nm_i->ra_nid_pages, META_NAT, false); | ||
1561 | } | 1566 | } |
1562 | 1567 | ||
1563 | /* | 1568 | /* |
@@ -1803,10 +1808,10 @@ int restore_node_summary(struct f2fs_sb_info *sbi, | |||
1803 | nrpages = min(last_offset - i, bio_blocks); | 1808 | nrpages = min(last_offset - i, bio_blocks); |
1804 | 1809 | ||
1805 | /* readahead node pages */ | 1810 | /* readahead node pages */ |
1806 | ra_meta_pages(sbi, addr, nrpages, META_POR); | 1811 | ra_meta_pages(sbi, addr, nrpages, META_POR, true); |
1807 | 1812 | ||
1808 | for (idx = addr; idx < addr + nrpages; idx++) { | 1813 | for (idx = addr; idx < addr + nrpages; idx++) { |
1809 | struct page *page = get_meta_page(sbi, idx); | 1814 | struct page *page = get_tmp_page(sbi, idx); |
1810 | 1815 | ||
1811 | rn = F2FS_NODE(page); | 1816 | rn = F2FS_NODE(page); |
1812 | sum_entry->nid = rn->footer.nid; | 1817 | sum_entry->nid = rn->footer.nid; |
@@ -2000,6 +2005,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) | |||
2000 | nm_i->fcnt = 0; | 2005 | nm_i->fcnt = 0; |
2001 | nm_i->nat_cnt = 0; | 2006 | nm_i->nat_cnt = 0; |
2002 | nm_i->ram_thresh = DEF_RAM_THRESHOLD; | 2007 | nm_i->ram_thresh = DEF_RAM_THRESHOLD; |
2008 | nm_i->ra_nid_pages = DEF_RA_NID_PAGES; | ||
2003 | 2009 | ||
2004 | INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC); | 2010 | INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC); |
2005 | INIT_LIST_HEAD(&nm_i->free_nid_list); | 2011 | INIT_LIST_HEAD(&nm_i->free_nid_list); |
diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 7427e956ad81..e4fffd2d98c4 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h | |||
@@ -14,9 +14,11 @@ | |||
14 | /* node block offset on the NAT area dedicated to the given start node id */ | 14 | /* node block offset on the NAT area dedicated to the given start node id */ |
15 | #define NAT_BLOCK_OFFSET(start_nid) (start_nid / NAT_ENTRY_PER_BLOCK) | 15 | #define NAT_BLOCK_OFFSET(start_nid) (start_nid / NAT_ENTRY_PER_BLOCK) |
16 | 16 | ||
17 | /* # of pages to perform readahead before building free nids */ | 17 | /* # of pages to perform synchronous readahead before building free nids */ |
18 | #define FREE_NID_PAGES 4 | 18 | #define FREE_NID_PAGES 4 |
19 | 19 | ||
20 | #define DEF_RA_NID_PAGES 4 /* # of nid pages to be readaheaded */ | ||
21 | |||
20 | /* maximum readahead size for node during getting data blocks */ | 22 | /* maximum readahead size for node during getting data blocks */ |
21 | #define MAX_RA_NODE 128 | 23 | #define MAX_RA_NODE 128 |
22 | 24 | ||
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index faec2ca004b9..cbf74f47cce8 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
@@ -180,7 +180,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | |||
180 | curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); | 180 | curseg = CURSEG_I(sbi, CURSEG_WARM_NODE); |
181 | blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); | 181 | blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); |
182 | 182 | ||
183 | ra_meta_pages(sbi, blkaddr, 1, META_POR); | 183 | ra_meta_pages(sbi, blkaddr, 1, META_POR, true); |
184 | 184 | ||
185 | while (1) { | 185 | while (1) { |
186 | struct fsync_inode_entry *entry; | 186 | struct fsync_inode_entry *entry; |
@@ -188,7 +188,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | |||
188 | if (!is_valid_blkaddr(sbi, blkaddr, META_POR)) | 188 | if (!is_valid_blkaddr(sbi, blkaddr, META_POR)) |
189 | return 0; | 189 | return 0; |
190 | 190 | ||
191 | page = get_meta_page(sbi, blkaddr); | 191 | page = get_tmp_page(sbi, blkaddr); |
192 | 192 | ||
193 | if (cp_ver != cpver_of_node(page)) | 193 | if (cp_ver != cpver_of_node(page)) |
194 | break; | 194 | break; |
@@ -383,15 +383,11 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, | |||
383 | start = start_bidx_of_node(ofs_of_node(page), fi); | 383 | start = start_bidx_of_node(ofs_of_node(page), fi); |
384 | end = start + ADDRS_PER_PAGE(page, fi); | 384 | end = start + ADDRS_PER_PAGE(page, fi); |
385 | 385 | ||
386 | f2fs_lock_op(sbi); | ||
387 | |||
388 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 386 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
389 | 387 | ||
390 | err = get_dnode_of_data(&dn, start, ALLOC_NODE); | 388 | err = get_dnode_of_data(&dn, start, ALLOC_NODE); |
391 | if (err) { | 389 | if (err) |
392 | f2fs_unlock_op(sbi); | ||
393 | goto out; | 390 | goto out; |
394 | } | ||
395 | 391 | ||
396 | f2fs_wait_on_page_writeback(dn.node_page, NODE); | 392 | f2fs_wait_on_page_writeback(dn.node_page, NODE); |
397 | 393 | ||
@@ -456,7 +452,6 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, | |||
456 | set_page_dirty(dn.node_page); | 452 | set_page_dirty(dn.node_page); |
457 | err: | 453 | err: |
458 | f2fs_put_dnode(&dn); | 454 | f2fs_put_dnode(&dn); |
459 | f2fs_unlock_op(sbi); | ||
460 | out: | 455 | out: |
461 | f2fs_msg(sbi->sb, KERN_NOTICE, | 456 | f2fs_msg(sbi->sb, KERN_NOTICE, |
462 | "recover_data: ino = %lx, recovered = %d blocks, err = %d", | 457 | "recover_data: ino = %lx, recovered = %d blocks, err = %d", |
@@ -485,7 +480,7 @@ static int recover_data(struct f2fs_sb_info *sbi, | |||
485 | 480 | ||
486 | ra_meta_pages_cond(sbi, blkaddr); | 481 | ra_meta_pages_cond(sbi, blkaddr); |
487 | 482 | ||
488 | page = get_meta_page(sbi, blkaddr); | 483 | page = get_tmp_page(sbi, blkaddr); |
489 | 484 | ||
490 | if (cp_ver != cpver_of_node(page)) { | 485 | if (cp_ver != cpver_of_node(page)) { |
491 | f2fs_put_page(page, 1); | 486 | f2fs_put_page(page, 1); |
@@ -570,7 +565,7 @@ out: | |||
570 | 565 | ||
571 | /* truncate meta pages to be used by the recovery */ | 566 | /* truncate meta pages to be used by the recovery */ |
572 | truncate_inode_pages_range(META_MAPPING(sbi), | 567 | truncate_inode_pages_range(META_MAPPING(sbi), |
573 | MAIN_BLKADDR(sbi) << PAGE_CACHE_SHIFT, -1); | 568 | (loff_t)MAIN_BLKADDR(sbi) << PAGE_CACHE_SHIFT, -1); |
574 | 569 | ||
575 | if (err) { | 570 | if (err) { |
576 | truncate_inode_pages_final(NODE_MAPPING(sbi)); | 571 | truncate_inode_pages_final(NODE_MAPPING(sbi)); |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 78e6d0696847..f77b3258454a 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -14,8 +14,8 @@ | |||
14 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
15 | #include <linux/prefetch.h> | 15 | #include <linux/prefetch.h> |
16 | #include <linux/kthread.h> | 16 | #include <linux/kthread.h> |
17 | #include <linux/vmalloc.h> | ||
18 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
18 | #include <linux/timer.h> | ||
19 | 19 | ||
20 | #include "f2fs.h" | 20 | #include "f2fs.h" |
21 | #include "segment.h" | 21 | #include "segment.h" |
@@ -29,6 +29,21 @@ static struct kmem_cache *discard_entry_slab; | |||
29 | static struct kmem_cache *sit_entry_set_slab; | 29 | static struct kmem_cache *sit_entry_set_slab; |
30 | static struct kmem_cache *inmem_entry_slab; | 30 | static struct kmem_cache *inmem_entry_slab; |
31 | 31 | ||
32 | static unsigned long __reverse_ulong(unsigned char *str) | ||
33 | { | ||
34 | unsigned long tmp = 0; | ||
35 | int shift = 24, idx = 0; | ||
36 | |||
37 | #if BITS_PER_LONG == 64 | ||
38 | shift = 56; | ||
39 | #endif | ||
40 | while (shift >= 0) { | ||
41 | tmp |= (unsigned long)str[idx++] << shift; | ||
42 | shift -= BITS_PER_BYTE; | ||
43 | } | ||
44 | return tmp; | ||
45 | } | ||
46 | |||
32 | /* | 47 | /* |
33 | * __reverse_ffs is copied from include/asm-generic/bitops/__ffs.h since | 48 | * __reverse_ffs is copied from include/asm-generic/bitops/__ffs.h since |
34 | * MSB and LSB are reversed in a byte by f2fs_set_bit. | 49 | * MSB and LSB are reversed in a byte by f2fs_set_bit. |
@@ -38,27 +53,31 @@ static inline unsigned long __reverse_ffs(unsigned long word) | |||
38 | int num = 0; | 53 | int num = 0; |
39 | 54 | ||
40 | #if BITS_PER_LONG == 64 | 55 | #if BITS_PER_LONG == 64 |
41 | if ((word & 0xffffffff) == 0) { | 56 | if ((word & 0xffffffff00000000UL) == 0) |
42 | num += 32; | 57 | num += 32; |
58 | else | ||
43 | word >>= 32; | 59 | word >>= 32; |
44 | } | ||
45 | #endif | 60 | #endif |
46 | if ((word & 0xffff) == 0) { | 61 | if ((word & 0xffff0000) == 0) |
47 | num += 16; | 62 | num += 16; |
63 | else | ||
48 | word >>= 16; | 64 | word >>= 16; |
49 | } | 65 | |
50 | if ((word & 0xff) == 0) { | 66 | if ((word & 0xff00) == 0) |
51 | num += 8; | 67 | num += 8; |
68 | else | ||
52 | word >>= 8; | 69 | word >>= 8; |
53 | } | 70 | |
54 | if ((word & 0xf0) == 0) | 71 | if ((word & 0xf0) == 0) |
55 | num += 4; | 72 | num += 4; |
56 | else | 73 | else |
57 | word >>= 4; | 74 | word >>= 4; |
75 | |||
58 | if ((word & 0xc) == 0) | 76 | if ((word & 0xc) == 0) |
59 | num += 2; | 77 | num += 2; |
60 | else | 78 | else |
61 | word >>= 2; | 79 | word >>= 2; |
80 | |||
62 | if ((word & 0x2) == 0) | 81 | if ((word & 0x2) == 0) |
63 | num += 1; | 82 | num += 1; |
64 | return num; | 83 | return num; |
@@ -68,26 +87,16 @@ static inline unsigned long __reverse_ffs(unsigned long word) | |||
68 | * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c because | 87 | * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c because |
69 | * f2fs_set_bit makes MSB and LSB reversed in a byte. | 88 | * f2fs_set_bit makes MSB and LSB reversed in a byte. |
70 | * Example: | 89 | * Example: |
71 | * LSB <--> MSB | 90 | * MSB <--> LSB |
72 | * f2fs_set_bit(0, bitmap) => 0000 0001 | 91 | * f2fs_set_bit(0, bitmap) => 1000 0000 |
73 | * f2fs_set_bit(7, bitmap) => 1000 0000 | 92 | * f2fs_set_bit(7, bitmap) => 0000 0001 |
74 | */ | 93 | */ |
75 | static unsigned long __find_rev_next_bit(const unsigned long *addr, | 94 | static unsigned long __find_rev_next_bit(const unsigned long *addr, |
76 | unsigned long size, unsigned long offset) | 95 | unsigned long size, unsigned long offset) |
77 | { | 96 | { |
78 | while (!f2fs_test_bit(offset, (unsigned char *)addr)) | ||
79 | offset++; | ||
80 | |||
81 | if (offset > size) | ||
82 | offset = size; | ||
83 | |||
84 | return offset; | ||
85 | #if 0 | ||
86 | const unsigned long *p = addr + BIT_WORD(offset); | 97 | const unsigned long *p = addr + BIT_WORD(offset); |
87 | unsigned long result = offset & ~(BITS_PER_LONG - 1); | 98 | unsigned long result = offset & ~(BITS_PER_LONG - 1); |
88 | unsigned long tmp; | 99 | unsigned long tmp; |
89 | unsigned long mask, submask; | ||
90 | unsigned long quot, rest; | ||
91 | 100 | ||
92 | if (offset >= size) | 101 | if (offset >= size) |
93 | return size; | 102 | return size; |
@@ -97,14 +106,9 @@ static unsigned long __find_rev_next_bit(const unsigned long *addr, | |||
97 | if (!offset) | 106 | if (!offset) |
98 | goto aligned; | 107 | goto aligned; |
99 | 108 | ||
100 | tmp = *(p++); | 109 | tmp = __reverse_ulong((unsigned char *)p); |
101 | quot = (offset >> 3) << 3; | 110 | tmp &= ~0UL >> offset; |
102 | rest = offset & 0x7; | 111 | |
103 | mask = ~0UL << quot; | ||
104 | submask = (unsigned char)(0xff << rest) >> rest; | ||
105 | submask <<= quot; | ||
106 | mask &= submask; | ||
107 | tmp &= mask; | ||
108 | if (size < BITS_PER_LONG) | 112 | if (size < BITS_PER_LONG) |
109 | goto found_first; | 113 | goto found_first; |
110 | if (tmp) | 114 | if (tmp) |
@@ -112,42 +116,34 @@ static unsigned long __find_rev_next_bit(const unsigned long *addr, | |||
112 | 116 | ||
113 | size -= BITS_PER_LONG; | 117 | size -= BITS_PER_LONG; |
114 | result += BITS_PER_LONG; | 118 | result += BITS_PER_LONG; |
119 | p++; | ||
115 | aligned: | 120 | aligned: |
116 | while (size & ~(BITS_PER_LONG-1)) { | 121 | while (size & ~(BITS_PER_LONG-1)) { |
117 | tmp = *(p++); | 122 | tmp = __reverse_ulong((unsigned char *)p); |
118 | if (tmp) | 123 | if (tmp) |
119 | goto found_middle; | 124 | goto found_middle; |
120 | result += BITS_PER_LONG; | 125 | result += BITS_PER_LONG; |
121 | size -= BITS_PER_LONG; | 126 | size -= BITS_PER_LONG; |
127 | p++; | ||
122 | } | 128 | } |
123 | if (!size) | 129 | if (!size) |
124 | return result; | 130 | return result; |
125 | tmp = *p; | 131 | |
132 | tmp = __reverse_ulong((unsigned char *)p); | ||
126 | found_first: | 133 | found_first: |
127 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | 134 | tmp &= (~0UL << (BITS_PER_LONG - size)); |
128 | if (tmp == 0UL) /* Are any bits set? */ | 135 | if (!tmp) /* Are any bits set? */ |
129 | return result + size; /* Nope. */ | 136 | return result + size; /* Nope. */ |
130 | found_middle: | 137 | found_middle: |
131 | return result + __reverse_ffs(tmp); | 138 | return result + __reverse_ffs(tmp); |
132 | #endif | ||
133 | } | 139 | } |
134 | 140 | ||
135 | static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, | 141 | static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, |
136 | unsigned long size, unsigned long offset) | 142 | unsigned long size, unsigned long offset) |
137 | { | 143 | { |
138 | while (f2fs_test_bit(offset, (unsigned char *)addr)) | ||
139 | offset++; | ||
140 | |||
141 | if (offset > size) | ||
142 | offset = size; | ||
143 | |||
144 | return offset; | ||
145 | #if 0 | ||
146 | const unsigned long *p = addr + BIT_WORD(offset); | 144 | const unsigned long *p = addr + BIT_WORD(offset); |
147 | unsigned long result = offset & ~(BITS_PER_LONG - 1); | 145 | unsigned long result = offset & ~(BITS_PER_LONG - 1); |
148 | unsigned long tmp; | 146 | unsigned long tmp; |
149 | unsigned long mask, submask; | ||
150 | unsigned long quot, rest; | ||
151 | 147 | ||
152 | if (offset >= size) | 148 | if (offset >= size) |
153 | return size; | 149 | return size; |
@@ -157,40 +153,36 @@ static unsigned long __find_rev_next_zero_bit(const unsigned long *addr, | |||
157 | if (!offset) | 153 | if (!offset) |
158 | goto aligned; | 154 | goto aligned; |
159 | 155 | ||
160 | tmp = *(p++); | 156 | tmp = __reverse_ulong((unsigned char *)p); |
161 | quot = (offset >> 3) << 3; | 157 | tmp |= ~((~0UL << offset) >> offset); |
162 | rest = offset & 0x7; | 158 | |
163 | mask = ~(~0UL << quot); | ||
164 | submask = (unsigned char)~((unsigned char)(0xff << rest) >> rest); | ||
165 | submask <<= quot; | ||
166 | mask += submask; | ||
167 | tmp |= mask; | ||
168 | if (size < BITS_PER_LONG) | 159 | if (size < BITS_PER_LONG) |
169 | goto found_first; | 160 | goto found_first; |
170 | if (~tmp) | 161 | if (tmp != ~0UL) |
171 | goto found_middle; | 162 | goto found_middle; |
172 | 163 | ||
173 | size -= BITS_PER_LONG; | 164 | size -= BITS_PER_LONG; |
174 | result += BITS_PER_LONG; | 165 | result += BITS_PER_LONG; |
166 | p++; | ||
175 | aligned: | 167 | aligned: |
176 | while (size & ~(BITS_PER_LONG - 1)) { | 168 | while (size & ~(BITS_PER_LONG - 1)) { |
177 | tmp = *(p++); | 169 | tmp = __reverse_ulong((unsigned char *)p); |
178 | if (~tmp) | 170 | if (tmp != ~0UL) |
179 | goto found_middle; | 171 | goto found_middle; |
180 | result += BITS_PER_LONG; | 172 | result += BITS_PER_LONG; |
181 | size -= BITS_PER_LONG; | 173 | size -= BITS_PER_LONG; |
174 | p++; | ||
182 | } | 175 | } |
183 | if (!size) | 176 | if (!size) |
184 | return result; | 177 | return result; |
185 | tmp = *p; | ||
186 | 178 | ||
179 | tmp = __reverse_ulong((unsigned char *)p); | ||
187 | found_first: | 180 | found_first: |
188 | tmp |= ~0UL << size; | 181 | tmp |= ~(~0UL << (BITS_PER_LONG - size)); |
189 | if (tmp == ~0UL) /* Are any bits zero? */ | 182 | if (tmp == ~0UL) /* Are any bits zero? */ |
190 | return result + size; /* Nope. */ | 183 | return result + size; /* Nope. */ |
191 | found_middle: | 184 | found_middle: |
192 | return result + __reverse_ffz(tmp); | 185 | return result + __reverse_ffz(tmp); |
193 | #endif | ||
194 | } | 186 | } |
195 | 187 | ||
196 | void register_inmem_page(struct inode *inode, struct page *page) | 188 | void register_inmem_page(struct inode *inode, struct page *page) |
@@ -257,11 +249,12 @@ int commit_inmem_pages(struct inode *inode, bool abort) | |||
257 | trace_f2fs_commit_inmem_page(cur->page, INMEM); | 249 | trace_f2fs_commit_inmem_page(cur->page, INMEM); |
258 | fio.page = cur->page; | 250 | fio.page = cur->page; |
259 | err = do_write_data_page(&fio); | 251 | err = do_write_data_page(&fio); |
260 | submit_bio = true; | ||
261 | if (err) { | 252 | if (err) { |
262 | unlock_page(cur->page); | 253 | unlock_page(cur->page); |
263 | break; | 254 | break; |
264 | } | 255 | } |
256 | clear_cold_data(cur->page); | ||
257 | submit_bio = true; | ||
265 | } | 258 | } |
266 | } else { | 259 | } else { |
267 | trace_f2fs_commit_inmem_page(cur->page, INMEM_DROP); | 260 | trace_f2fs_commit_inmem_page(cur->page, INMEM_DROP); |
@@ -296,7 +289,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi) | |||
296 | */ | 289 | */ |
297 | if (has_not_enough_free_secs(sbi, 0)) { | 290 | if (has_not_enough_free_secs(sbi, 0)) { |
298 | mutex_lock(&sbi->gc_mutex); | 291 | mutex_lock(&sbi->gc_mutex); |
299 | f2fs_gc(sbi); | 292 | f2fs_gc(sbi, false); |
300 | } | 293 | } |
301 | } | 294 | } |
302 | 295 | ||
@@ -316,7 +309,8 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) | |||
316 | /* checkpoint is the only way to shrink partial cached entries */ | 309 | /* checkpoint is the only way to shrink partial cached entries */ |
317 | if (!available_free_memory(sbi, NAT_ENTRIES) || | 310 | if (!available_free_memory(sbi, NAT_ENTRIES) || |
318 | excess_prefree_segs(sbi) || | 311 | excess_prefree_segs(sbi) || |
319 | !available_free_memory(sbi, INO_ENTRIES)) | 312 | !available_free_memory(sbi, INO_ENTRIES) || |
313 | jiffies > sbi->cp_expires) | ||
320 | f2fs_sync_fs(sbi->sb, true); | 314 | f2fs_sync_fs(sbi->sb, true); |
321 | } | 315 | } |
322 | 316 | ||
@@ -767,6 +761,30 @@ void invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) | |||
767 | mutex_unlock(&sit_i->sentry_lock); | 761 | mutex_unlock(&sit_i->sentry_lock); |
768 | } | 762 | } |
769 | 763 | ||
764 | bool is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr) | ||
765 | { | ||
766 | struct sit_info *sit_i = SIT_I(sbi); | ||
767 | unsigned int segno, offset; | ||
768 | struct seg_entry *se; | ||
769 | bool is_cp = false; | ||
770 | |||
771 | if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR) | ||
772 | return true; | ||
773 | |||
774 | mutex_lock(&sit_i->sentry_lock); | ||
775 | |||
776 | segno = GET_SEGNO(sbi, blkaddr); | ||
777 | se = get_seg_entry(sbi, segno); | ||
778 | offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr); | ||
779 | |||
780 | if (f2fs_test_bit(offset, se->ckpt_valid_map)) | ||
781 | is_cp = true; | ||
782 | |||
783 | mutex_unlock(&sit_i->sentry_lock); | ||
784 | |||
785 | return is_cp; | ||
786 | } | ||
787 | |||
770 | /* | 788 | /* |
771 | * This function should be resided under the curseg_mutex lock | 789 | * This function should be resided under the curseg_mutex lock |
772 | */ | 790 | */ |
@@ -1292,6 +1310,9 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page) | |||
1292 | .encrypted_page = NULL, | 1310 | .encrypted_page = NULL, |
1293 | }; | 1311 | }; |
1294 | 1312 | ||
1313 | if (unlikely(page->index >= MAIN_BLKADDR(sbi))) | ||
1314 | fio.rw &= ~REQ_META; | ||
1315 | |||
1295 | set_page_writeback(page); | 1316 | set_page_writeback(page); |
1296 | f2fs_submit_page_mbio(&fio); | 1317 | f2fs_submit_page_mbio(&fio); |
1297 | } | 1318 | } |
@@ -1369,7 +1390,14 @@ static void __f2fs_replace_block(struct f2fs_sb_info *sbi, | |||
1369 | curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); | 1390 | curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); |
1370 | __add_sum_entry(sbi, type, sum); | 1391 | __add_sum_entry(sbi, type, sum); |
1371 | 1392 | ||
1372 | refresh_sit_entry(sbi, old_blkaddr, new_blkaddr); | 1393 | if (!recover_curseg) |
1394 | update_sit_entry(sbi, new_blkaddr, 1); | ||
1395 | if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) | ||
1396 | update_sit_entry(sbi, old_blkaddr, -1); | ||
1397 | |||
1398 | locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr)); | ||
1399 | locate_dirty_segment(sbi, GET_SEGNO(sbi, new_blkaddr)); | ||
1400 | |||
1373 | locate_dirty_segment(sbi, old_cursegno); | 1401 | locate_dirty_segment(sbi, old_cursegno); |
1374 | 1402 | ||
1375 | if (recover_curseg) { | 1403 | if (recover_curseg) { |
@@ -1449,6 +1477,23 @@ void f2fs_wait_on_page_writeback(struct page *page, | |||
1449 | } | 1477 | } |
1450 | } | 1478 | } |
1451 | 1479 | ||
1480 | void f2fs_wait_on_encrypted_page_writeback(struct f2fs_sb_info *sbi, | ||
1481 | block_t blkaddr) | ||
1482 | { | ||
1483 | struct page *cpage; | ||
1484 | |||
1485 | if (blkaddr == NEW_ADDR) | ||
1486 | return; | ||
1487 | |||
1488 | f2fs_bug_on(sbi, blkaddr == NULL_ADDR); | ||
1489 | |||
1490 | cpage = find_lock_page(META_MAPPING(sbi), blkaddr); | ||
1491 | if (cpage) { | ||
1492 | f2fs_wait_on_page_writeback(cpage, DATA); | ||
1493 | f2fs_put_page(cpage, 1); | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1452 | static int read_compacted_summaries(struct f2fs_sb_info *sbi) | 1497 | static int read_compacted_summaries(struct f2fs_sb_info *sbi) |
1453 | { | 1498 | { |
1454 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); | 1499 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); |
@@ -1586,7 +1631,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) | |||
1586 | 1631 | ||
1587 | if (npages >= 2) | 1632 | if (npages >= 2) |
1588 | ra_meta_pages(sbi, start_sum_block(sbi), npages, | 1633 | ra_meta_pages(sbi, start_sum_block(sbi), npages, |
1589 | META_CP); | 1634 | META_CP, true); |
1590 | 1635 | ||
1591 | /* restore for compacted data summary */ | 1636 | /* restore for compacted data summary */ |
1592 | if (read_compacted_summaries(sbi)) | 1637 | if (read_compacted_summaries(sbi)) |
@@ -1596,7 +1641,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) | |||
1596 | 1641 | ||
1597 | if (__exist_node_summaries(sbi)) | 1642 | if (__exist_node_summaries(sbi)) |
1598 | ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), | 1643 | ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), |
1599 | NR_CURSEG_TYPE - type, META_CP); | 1644 | NR_CURSEG_TYPE - type, META_CP, true); |
1600 | 1645 | ||
1601 | for (; type <= CURSEG_COLD_NODE; type++) { | 1646 | for (; type <= CURSEG_COLD_NODE; type++) { |
1602 | err = read_normal_summaries(sbi, type); | 1647 | err = read_normal_summaries(sbi, type); |
@@ -1955,12 +2000,13 @@ static int build_sit_info(struct f2fs_sb_info *sbi) | |||
1955 | 2000 | ||
1956 | SM_I(sbi)->sit_info = sit_i; | 2001 | SM_I(sbi)->sit_info = sit_i; |
1957 | 2002 | ||
1958 | sit_i->sentries = vzalloc(MAIN_SEGS(sbi) * sizeof(struct seg_entry)); | 2003 | sit_i->sentries = f2fs_kvzalloc(MAIN_SEGS(sbi) * |
2004 | sizeof(struct seg_entry), GFP_KERNEL); | ||
1959 | if (!sit_i->sentries) | 2005 | if (!sit_i->sentries) |
1960 | return -ENOMEM; | 2006 | return -ENOMEM; |
1961 | 2007 | ||
1962 | bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); | 2008 | bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); |
1963 | sit_i->dirty_sentries_bitmap = kzalloc(bitmap_size, GFP_KERNEL); | 2009 | sit_i->dirty_sentries_bitmap = f2fs_kvzalloc(bitmap_size, GFP_KERNEL); |
1964 | if (!sit_i->dirty_sentries_bitmap) | 2010 | if (!sit_i->dirty_sentries_bitmap) |
1965 | return -ENOMEM; | 2011 | return -ENOMEM; |
1966 | 2012 | ||
@@ -1982,8 +2028,8 @@ static int build_sit_info(struct f2fs_sb_info *sbi) | |||
1982 | return -ENOMEM; | 2028 | return -ENOMEM; |
1983 | 2029 | ||
1984 | if (sbi->segs_per_sec > 1) { | 2030 | if (sbi->segs_per_sec > 1) { |
1985 | sit_i->sec_entries = vzalloc(MAIN_SECS(sbi) * | 2031 | sit_i->sec_entries = f2fs_kvzalloc(MAIN_SECS(sbi) * |
1986 | sizeof(struct sec_entry)); | 2032 | sizeof(struct sec_entry), GFP_KERNEL); |
1987 | if (!sit_i->sec_entries) | 2033 | if (!sit_i->sec_entries) |
1988 | return -ENOMEM; | 2034 | return -ENOMEM; |
1989 | } | 2035 | } |
@@ -2028,12 +2074,12 @@ static int build_free_segmap(struct f2fs_sb_info *sbi) | |||
2028 | SM_I(sbi)->free_info = free_i; | 2074 | SM_I(sbi)->free_info = free_i; |
2029 | 2075 | ||
2030 | bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); | 2076 | bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); |
2031 | free_i->free_segmap = kmalloc(bitmap_size, GFP_KERNEL); | 2077 | free_i->free_segmap = f2fs_kvmalloc(bitmap_size, GFP_KERNEL); |
2032 | if (!free_i->free_segmap) | 2078 | if (!free_i->free_segmap) |
2033 | return -ENOMEM; | 2079 | return -ENOMEM; |
2034 | 2080 | ||
2035 | sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); | 2081 | sec_bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); |
2036 | free_i->free_secmap = kmalloc(sec_bitmap_size, GFP_KERNEL); | 2082 | free_i->free_secmap = f2fs_kvmalloc(sec_bitmap_size, GFP_KERNEL); |
2037 | if (!free_i->free_secmap) | 2083 | if (!free_i->free_secmap) |
2038 | return -ENOMEM; | 2084 | return -ENOMEM; |
2039 | 2085 | ||
@@ -2082,7 +2128,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) | |||
2082 | int nrpages = MAX_BIO_BLOCKS(sbi); | 2128 | int nrpages = MAX_BIO_BLOCKS(sbi); |
2083 | 2129 | ||
2084 | do { | 2130 | do { |
2085 | readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT); | 2131 | readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true); |
2086 | 2132 | ||
2087 | start = start_blk * sit_i->sents_per_block; | 2133 | start = start_blk * sit_i->sents_per_block; |
2088 | end = (start_blk + readed) * sit_i->sents_per_block; | 2134 | end = (start_blk + readed) * sit_i->sents_per_block; |
@@ -2174,7 +2220,7 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi) | |||
2174 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); | 2220 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); |
2175 | unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); | 2221 | unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi)); |
2176 | 2222 | ||
2177 | dirty_i->victim_secmap = kzalloc(bitmap_size, GFP_KERNEL); | 2223 | dirty_i->victim_secmap = f2fs_kvzalloc(bitmap_size, GFP_KERNEL); |
2178 | if (!dirty_i->victim_secmap) | 2224 | if (!dirty_i->victim_secmap) |
2179 | return -ENOMEM; | 2225 | return -ENOMEM; |
2180 | return 0; | 2226 | return 0; |
@@ -2196,7 +2242,7 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi) | |||
2196 | bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); | 2242 | bitmap_size = f2fs_bitmap_size(MAIN_SEGS(sbi)); |
2197 | 2243 | ||
2198 | for (i = 0; i < NR_DIRTY_TYPE; i++) { | 2244 | for (i = 0; i < NR_DIRTY_TYPE; i++) { |
2199 | dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL); | 2245 | dirty_i->dirty_segmap[i] = f2fs_kvzalloc(bitmap_size, GFP_KERNEL); |
2200 | if (!dirty_i->dirty_segmap[i]) | 2246 | if (!dirty_i->dirty_segmap[i]) |
2201 | return -ENOMEM; | 2247 | return -ENOMEM; |
2202 | } | 2248 | } |
@@ -2301,7 +2347,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi, | |||
2301 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); | 2347 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); |
2302 | 2348 | ||
2303 | mutex_lock(&dirty_i->seglist_lock); | 2349 | mutex_lock(&dirty_i->seglist_lock); |
2304 | kfree(dirty_i->dirty_segmap[dirty_type]); | 2350 | kvfree(dirty_i->dirty_segmap[dirty_type]); |
2305 | dirty_i->nr_dirty[dirty_type] = 0; | 2351 | dirty_i->nr_dirty[dirty_type] = 0; |
2306 | mutex_unlock(&dirty_i->seglist_lock); | 2352 | mutex_unlock(&dirty_i->seglist_lock); |
2307 | } | 2353 | } |
@@ -2309,7 +2355,7 @@ static void discard_dirty_segmap(struct f2fs_sb_info *sbi, | |||
2309 | static void destroy_victim_secmap(struct f2fs_sb_info *sbi) | 2355 | static void destroy_victim_secmap(struct f2fs_sb_info *sbi) |
2310 | { | 2356 | { |
2311 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); | 2357 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); |
2312 | kfree(dirty_i->victim_secmap); | 2358 | kvfree(dirty_i->victim_secmap); |
2313 | } | 2359 | } |
2314 | 2360 | ||
2315 | static void destroy_dirty_segmap(struct f2fs_sb_info *sbi) | 2361 | static void destroy_dirty_segmap(struct f2fs_sb_info *sbi) |
@@ -2348,8 +2394,8 @@ static void destroy_free_segmap(struct f2fs_sb_info *sbi) | |||
2348 | if (!free_i) | 2394 | if (!free_i) |
2349 | return; | 2395 | return; |
2350 | SM_I(sbi)->free_info = NULL; | 2396 | SM_I(sbi)->free_info = NULL; |
2351 | kfree(free_i->free_segmap); | 2397 | kvfree(free_i->free_segmap); |
2352 | kfree(free_i->free_secmap); | 2398 | kvfree(free_i->free_secmap); |
2353 | kfree(free_i); | 2399 | kfree(free_i); |
2354 | } | 2400 | } |
2355 | 2401 | ||
@@ -2370,9 +2416,9 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi) | |||
2370 | } | 2416 | } |
2371 | kfree(sit_i->tmp_map); | 2417 | kfree(sit_i->tmp_map); |
2372 | 2418 | ||
2373 | vfree(sit_i->sentries); | 2419 | kvfree(sit_i->sentries); |
2374 | vfree(sit_i->sec_entries); | 2420 | kvfree(sit_i->sec_entries); |
2375 | kfree(sit_i->dirty_sentries_bitmap); | 2421 | kvfree(sit_i->dirty_sentries_bitmap); |
2376 | 2422 | ||
2377 | SM_I(sbi)->sit_info = NULL; | 2423 | SM_I(sbi)->sit_info = NULL; |
2378 | kfree(sit_i->sit_bitmap); | 2424 | kfree(sit_i->sit_bitmap); |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index b6e4ed15c698..ee44d346ea44 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -137,10 +137,12 @@ enum { | |||
137 | /* | 137 | /* |
138 | * BG_GC means the background cleaning job. | 138 | * BG_GC means the background cleaning job. |
139 | * FG_GC means the on-demand cleaning job. | 139 | * FG_GC means the on-demand cleaning job. |
140 | * FORCE_FG_GC means on-demand cleaning job in background. | ||
140 | */ | 141 | */ |
141 | enum { | 142 | enum { |
142 | BG_GC = 0, | 143 | BG_GC = 0, |
143 | FG_GC | 144 | FG_GC, |
145 | FORCE_FG_GC, | ||
144 | }; | 146 | }; |
145 | 147 | ||
146 | /* for a function parameter to select a victim segment */ | 148 | /* for a function parameter to select a victim segment */ |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index f79478115d37..3a65e0132352 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -213,8 +213,10 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); | |||
213 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); | 213 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); |
214 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); | 214 | F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); |
215 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); | 215 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); |
216 | F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); | ||
216 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); | 217 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); |
217 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); | 218 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); |
219 | F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, cp_interval, cp_interval); | ||
218 | 220 | ||
219 | #define ATTR_LIST(name) (&f2fs_attr_##name.attr) | 221 | #define ATTR_LIST(name) (&f2fs_attr_##name.attr) |
220 | static struct attribute *f2fs_attrs[] = { | 222 | static struct attribute *f2fs_attrs[] = { |
@@ -231,6 +233,8 @@ static struct attribute *f2fs_attrs[] = { | |||
231 | ATTR_LIST(max_victim_search), | 233 | ATTR_LIST(max_victim_search), |
232 | ATTR_LIST(dir_level), | 234 | ATTR_LIST(dir_level), |
233 | ATTR_LIST(ram_thresh), | 235 | ATTR_LIST(ram_thresh), |
236 | ATTR_LIST(ra_nid_pages), | ||
237 | ATTR_LIST(cp_interval), | ||
234 | NULL, | 238 | NULL, |
235 | }; | 239 | }; |
236 | 240 | ||
@@ -292,11 +296,16 @@ static int parse_options(struct super_block *sb, char *options) | |||
292 | 296 | ||
293 | if (!name) | 297 | if (!name) |
294 | return -ENOMEM; | 298 | return -ENOMEM; |
295 | if (strlen(name) == 2 && !strncmp(name, "on", 2)) | 299 | if (strlen(name) == 2 && !strncmp(name, "on", 2)) { |
296 | set_opt(sbi, BG_GC); | 300 | set_opt(sbi, BG_GC); |
297 | else if (strlen(name) == 3 && !strncmp(name, "off", 3)) | 301 | clear_opt(sbi, FORCE_FG_GC); |
302 | } else if (strlen(name) == 3 && !strncmp(name, "off", 3)) { | ||
298 | clear_opt(sbi, BG_GC); | 303 | clear_opt(sbi, BG_GC); |
299 | else { | 304 | clear_opt(sbi, FORCE_FG_GC); |
305 | } else if (strlen(name) == 4 && !strncmp(name, "sync", 4)) { | ||
306 | set_opt(sbi, BG_GC); | ||
307 | set_opt(sbi, FORCE_FG_GC); | ||
308 | } else { | ||
300 | kfree(name); | 309 | kfree(name); |
301 | return -EINVAL; | 310 | return -EINVAL; |
302 | } | 311 | } |
@@ -631,10 +640,14 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) | |||
631 | { | 640 | { |
632 | struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb); | 641 | struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb); |
633 | 642 | ||
634 | if (!f2fs_readonly(sbi->sb) && test_opt(sbi, BG_GC)) | 643 | if (!f2fs_readonly(sbi->sb) && test_opt(sbi, BG_GC)) { |
635 | seq_printf(seq, ",background_gc=%s", "on"); | 644 | if (test_opt(sbi, FORCE_FG_GC)) |
636 | else | 645 | seq_printf(seq, ",background_gc=%s", "sync"); |
646 | else | ||
647 | seq_printf(seq, ",background_gc=%s", "on"); | ||
648 | } else { | ||
637 | seq_printf(seq, ",background_gc=%s", "off"); | 649 | seq_printf(seq, ",background_gc=%s", "off"); |
650 | } | ||
638 | if (test_opt(sbi, DISABLE_ROLL_FORWARD)) | 651 | if (test_opt(sbi, DISABLE_ROLL_FORWARD)) |
639 | seq_puts(seq, ",disable_roll_forward"); | 652 | seq_puts(seq, ",disable_roll_forward"); |
640 | if (test_opt(sbi, DISCARD)) | 653 | if (test_opt(sbi, DISCARD)) |
@@ -742,6 +755,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) | |||
742 | int err, active_logs; | 755 | int err, active_logs; |
743 | bool need_restart_gc = false; | 756 | bool need_restart_gc = false; |
744 | bool need_stop_gc = false; | 757 | bool need_stop_gc = false; |
758 | bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE); | ||
745 | 759 | ||
746 | sync_filesystem(sb); | 760 | sync_filesystem(sb); |
747 | 761 | ||
@@ -767,6 +781,14 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) | |||
767 | if (f2fs_readonly(sb) && (*flags & MS_RDONLY)) | 781 | if (f2fs_readonly(sb) && (*flags & MS_RDONLY)) |
768 | goto skip; | 782 | goto skip; |
769 | 783 | ||
784 | /* disallow enable/disable extent_cache dynamically */ | ||
785 | if (no_extent_cache == !!test_opt(sbi, EXTENT_CACHE)) { | ||
786 | err = -EINVAL; | ||
787 | f2fs_msg(sbi->sb, KERN_WARNING, | ||
788 | "switch extent_cache option is not allowed"); | ||
789 | goto restore_opts; | ||
790 | } | ||
791 | |||
770 | /* | 792 | /* |
771 | * We stop the GC thread if FS is mounted as RO | 793 | * We stop the GC thread if FS is mounted as RO |
772 | * or if background_gc = off is passed in mount | 794 | * or if background_gc = off is passed in mount |
@@ -996,6 +1018,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi) | |||
996 | atomic_set(&sbi->nr_pages[i], 0); | 1018 | atomic_set(&sbi->nr_pages[i], 0); |
997 | 1019 | ||
998 | sbi->dir_level = DEF_DIR_LEVEL; | 1020 | sbi->dir_level = DEF_DIR_LEVEL; |
1021 | sbi->cp_interval = DEF_CP_INTERVAL; | ||
999 | clear_sbi_flag(sbi, SBI_NEED_FSCK); | 1022 | clear_sbi_flag(sbi, SBI_NEED_FSCK); |
1000 | 1023 | ||
1001 | INIT_LIST_HEAD(&sbi->s_list); | 1024 | INIT_LIST_HEAD(&sbi->s_list); |
@@ -1332,6 +1355,8 @@ try_onemore: | |||
1332 | f2fs_commit_super(sbi, true); | 1355 | f2fs_commit_super(sbi, true); |
1333 | } | 1356 | } |
1334 | 1357 | ||
1358 | sbi->cp_expires = round_jiffies_up(jiffies); | ||
1359 | |||
1335 | return 0; | 1360 | return 0; |
1336 | 1361 | ||
1337 | free_kobj: | 1362 | free_kobj: |
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index a01946514b5a..00b4a6308249 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h | |||
@@ -514,6 +514,34 @@ TRACE_EVENT(f2fs_map_blocks, | |||
514 | __entry->ret) | 514 | __entry->ret) |
515 | ); | 515 | ); |
516 | 516 | ||
517 | TRACE_EVENT(f2fs_background_gc, | ||
518 | |||
519 | TP_PROTO(struct super_block *sb, long wait_ms, | ||
520 | unsigned int prefree, unsigned int free), | ||
521 | |||
522 | TP_ARGS(sb, wait_ms, prefree, free), | ||
523 | |||
524 | TP_STRUCT__entry( | ||
525 | __field(dev_t, dev) | ||
526 | __field(long, wait_ms) | ||
527 | __field(unsigned int, prefree) | ||
528 | __field(unsigned int, free) | ||
529 | ), | ||
530 | |||
531 | TP_fast_assign( | ||
532 | __entry->dev = sb->s_dev; | ||
533 | __entry->wait_ms = wait_ms; | ||
534 | __entry->prefree = prefree; | ||
535 | __entry->free = free; | ||
536 | ), | ||
537 | |||
538 | TP_printk("dev = (%d,%d), wait_ms = %ld, prefree = %u, free = %u", | ||
539 | show_dev(__entry), | ||
540 | __entry->wait_ms, | ||
541 | __entry->prefree, | ||
542 | __entry->free) | ||
543 | ); | ||
544 | |||
517 | TRACE_EVENT(f2fs_get_victim, | 545 | TRACE_EVENT(f2fs_get_victim, |
518 | 546 | ||
519 | TP_PROTO(struct super_block *sb, int type, int gc_type, | 547 | TP_PROTO(struct super_block *sb, int type, int gc_type, |
@@ -1000,6 +1028,32 @@ TRACE_EVENT(f2fs_writepages, | |||
1000 | __entry->for_sync) | 1028 | __entry->for_sync) |
1001 | ); | 1029 | ); |
1002 | 1030 | ||
1031 | TRACE_EVENT(f2fs_readpages, | ||
1032 | |||
1033 | TP_PROTO(struct inode *inode, struct page *page, unsigned int nrpage), | ||
1034 | |||
1035 | TP_ARGS(inode, page, nrpage), | ||
1036 | |||
1037 | TP_STRUCT__entry( | ||
1038 | __field(dev_t, dev) | ||
1039 | __field(ino_t, ino) | ||
1040 | __field(pgoff_t, start) | ||
1041 | __field(unsigned int, nrpage) | ||
1042 | ), | ||
1043 | |||
1044 | TP_fast_assign( | ||
1045 | __entry->dev = inode->i_sb->s_dev; | ||
1046 | __entry->ino = inode->i_ino; | ||
1047 | __entry->start = page->index; | ||
1048 | __entry->nrpage = nrpage; | ||
1049 | ), | ||
1050 | |||
1051 | TP_printk("dev = (%d,%d), ino = %lu, start = %lu nrpage = %u", | ||
1052 | show_dev_ino(__entry), | ||
1053 | (unsigned long)__entry->start, | ||
1054 | __entry->nrpage) | ||
1055 | ); | ||
1056 | |||
1003 | TRACE_EVENT(f2fs_write_checkpoint, | 1057 | TRACE_EVENT(f2fs_write_checkpoint, |
1004 | 1058 | ||
1005 | TP_PROTO(struct super_block *sb, int reason, char *msg), | 1059 | TP_PROTO(struct super_block *sb, int reason, char *msg), |
@@ -1132,17 +1186,19 @@ TRACE_EVENT_CONDITION(f2fs_lookup_extent_tree_end, | |||
1132 | __entry->len) | 1186 | __entry->len) |
1133 | ); | 1187 | ); |
1134 | 1188 | ||
1135 | TRACE_EVENT(f2fs_update_extent_tree, | 1189 | TRACE_EVENT(f2fs_update_extent_tree_range, |
1136 | 1190 | ||
1137 | TP_PROTO(struct inode *inode, unsigned int pgofs, block_t blkaddr), | 1191 | TP_PROTO(struct inode *inode, unsigned int pgofs, block_t blkaddr, |
1192 | unsigned int len), | ||
1138 | 1193 | ||
1139 | TP_ARGS(inode, pgofs, blkaddr), | 1194 | TP_ARGS(inode, pgofs, blkaddr, len), |
1140 | 1195 | ||
1141 | TP_STRUCT__entry( | 1196 | TP_STRUCT__entry( |
1142 | __field(dev_t, dev) | 1197 | __field(dev_t, dev) |
1143 | __field(ino_t, ino) | 1198 | __field(ino_t, ino) |
1144 | __field(unsigned int, pgofs) | 1199 | __field(unsigned int, pgofs) |
1145 | __field(u32, blk) | 1200 | __field(u32, blk) |
1201 | __field(unsigned int, len) | ||
1146 | ), | 1202 | ), |
1147 | 1203 | ||
1148 | TP_fast_assign( | 1204 | TP_fast_assign( |
@@ -1150,12 +1206,15 @@ TRACE_EVENT(f2fs_update_extent_tree, | |||
1150 | __entry->ino = inode->i_ino; | 1206 | __entry->ino = inode->i_ino; |
1151 | __entry->pgofs = pgofs; | 1207 | __entry->pgofs = pgofs; |
1152 | __entry->blk = blkaddr; | 1208 | __entry->blk = blkaddr; |
1209 | __entry->len = len; | ||
1153 | ), | 1210 | ), |
1154 | 1211 | ||
1155 | TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, blkaddr = %u", | 1212 | TP_printk("dev = (%d,%d), ino = %lu, pgofs = %u, " |
1213 | "blkaddr = %u, len = %u", | ||
1156 | show_dev_ino(__entry), | 1214 | show_dev_ino(__entry), |
1157 | __entry->pgofs, | 1215 | __entry->pgofs, |
1158 | __entry->blk) | 1216 | __entry->blk, |
1217 | __entry->len) | ||
1159 | ); | 1218 | ); |
1160 | 1219 | ||
1161 | TRACE_EVENT(f2fs_shrink_extent_tree, | 1220 | TRACE_EVENT(f2fs_shrink_extent_tree, |