diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 17:50:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 17:50:15 -0500 |
commit | 1085db4aa68ce960f8c987a67a104ba834022fef (patch) | |
tree | 3e40d92b9a8126670f755d78a14a36c64b7d9995 | |
parent | 3c834b6f41fa21a48389b13c3bf63aa8df1d7080 (diff) | |
parent | 7dd690c82029ed34aafdb58ce7463cdead69abb5 (diff) |
Merge tag 'f2fs-for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs update from Jaegeuk Kim:
"[Major bug fixes]
o Store device file information correctly
o Fix -EIO handling with respect to power-off-recovery
o Allocate blocks with global locks
o Fix wrong calculation of the SSR cost
[Cleanups]
o Get rid of fake on-stack dentries
[Enhancement]
o Support (un)freeze_fs
o Enhance the f2fs_gc flow
o Support 32-bit binary execution on 64-bit kernel"
* tag 'f2fs-for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (29 commits)
f2fs: avoid build warning
f2fs: add compat_ioctl to provide backward compatability
f2fs: fix calculation of max. gc cost in the SSR case
f2fs: clarify and enhance the f2fs_gc flow
f2fs: optimize the return condition for has_not_enough_free_secs
f2fs: make an accessor to get sections for particular block type
f2fs: mark gc_thread as NULL when thread creation is failed
f2fs: name gc task as per the block device
f2fs: remove unnecessary gc option check and balance_fs
f2fs: remove repeated F2FS_SET_SB_DIRT call
f2fs: when check superblock failed, try to check another superblock
f2fs: use F2FS_BLKSIZE to judge bloksize and page_cache_size
f2fs: add device name in debugfs
f2fs: stop repeated checking if cp is needed
f2fs: avoid balanc_fs during evict_inode
f2fs: remove the use of page_cache_release
f2fs: fix typo mistake for data_version description
f2fs: reorganize code for ra_node_page
f2fs: avoid redundant call to has_not_enough_free_secs in f2fs_gc
f2fs: add un/freeze_fs into super_operations
...
-rw-r--r-- | fs/f2fs/checkpoint.c | 63 | ||||
-rw-r--r-- | fs/f2fs/debug.c | 4 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 29 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 44 | ||||
-rw-r--r-- | fs/f2fs/file.c | 35 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 124 | ||||
-rw-r--r-- | fs/f2fs/gc.h | 21 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 53 | ||||
-rw-r--r-- | fs/f2fs/node.c | 20 | ||||
-rw-r--r-- | fs/f2fs/recovery.c | 16 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 29 | ||||
-rw-r--r-- | fs/f2fs/segment.h | 23 | ||||
-rw-r--r-- | fs/f2fs/super.c | 92 |
13 files changed, 292 insertions, 261 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index ff3c8439af87..2b6fc131e2ce 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -72,22 +72,22 @@ static int f2fs_write_meta_page(struct page *page, | |||
72 | { | 72 | { |
73 | struct inode *inode = page->mapping->host; | 73 | struct inode *inode = page->mapping->host; |
74 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 74 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
75 | int err; | ||
76 | 75 | ||
77 | wait_on_page_writeback(page); | 76 | /* Should not write any meta pages, if any IO error was occurred */ |
78 | 77 | if (wbc->for_reclaim || | |
79 | err = write_meta_page(sbi, page, wbc); | 78 | is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)) { |
80 | if (err) { | 79 | dec_page_count(sbi, F2FS_DIRTY_META); |
81 | wbc->pages_skipped++; | 80 | wbc->pages_skipped++; |
82 | set_page_dirty(page); | 81 | set_page_dirty(page); |
82 | return AOP_WRITEPAGE_ACTIVATE; | ||
83 | } | 83 | } |
84 | 84 | ||
85 | dec_page_count(sbi, F2FS_DIRTY_META); | 85 | wait_on_page_writeback(page); |
86 | 86 | ||
87 | /* In this case, we should not unlock this page */ | 87 | write_meta_page(sbi, page); |
88 | if (err != AOP_WRITEPAGE_ACTIVATE) | 88 | dec_page_count(sbi, F2FS_DIRTY_META); |
89 | unlock_page(page); | 89 | unlock_page(page); |
90 | return err; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static int f2fs_write_meta_pages(struct address_space *mapping, | 93 | static int f2fs_write_meta_pages(struct address_space *mapping, |
@@ -138,7 +138,10 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, | |||
138 | BUG_ON(page->mapping != mapping); | 138 | BUG_ON(page->mapping != mapping); |
139 | BUG_ON(!PageDirty(page)); | 139 | BUG_ON(!PageDirty(page)); |
140 | clear_page_dirty_for_io(page); | 140 | clear_page_dirty_for_io(page); |
141 | f2fs_write_meta_page(page, &wbc); | 141 | if (f2fs_write_meta_page(page, &wbc)) { |
142 | unlock_page(page); | ||
143 | break; | ||
144 | } | ||
142 | if (nwritten++ >= nr_to_write) | 145 | if (nwritten++ >= nr_to_write) |
143 | break; | 146 | break; |
144 | } | 147 | } |
@@ -161,7 +164,6 @@ static int f2fs_set_meta_page_dirty(struct page *page) | |||
161 | if (!PageDirty(page)) { | 164 | if (!PageDirty(page)) { |
162 | __set_page_dirty_nobuffers(page); | 165 | __set_page_dirty_nobuffers(page); |
163 | inc_page_count(sbi, F2FS_DIRTY_META); | 166 | inc_page_count(sbi, F2FS_DIRTY_META); |
164 | F2FS_SET_SB_DIRT(sbi); | ||
165 | return 1; | 167 | return 1; |
166 | } | 168 | } |
167 | return 0; | 169 | return 0; |
@@ -216,19 +218,11 @@ retry: | |||
216 | new->ino = ino; | 218 | new->ino = ino; |
217 | 219 | ||
218 | /* add new_oentry into list which is sorted by inode number */ | 220 | /* add new_oentry into list which is sorted by inode number */ |
219 | if (orphan) { | 221 | if (orphan) |
220 | struct orphan_inode_entry *prev; | 222 | list_add(&new->list, this->prev); |
221 | 223 | else | |
222 | /* get previous entry */ | ||
223 | prev = list_entry(orphan->list.prev, typeof(*prev), list); | ||
224 | if (&prev->list != head) | ||
225 | /* insert new orphan inode entry */ | ||
226 | list_add(&new->list, &prev->list); | ||
227 | else | ||
228 | list_add(&new->list, head); | ||
229 | } else { | ||
230 | list_add_tail(&new->list, head); | 224 | list_add_tail(&new->list, head); |
231 | } | 225 | |
232 | sbi->n_orphans++; | 226 | sbi->n_orphans++; |
233 | out: | 227 | out: |
234 | mutex_unlock(&sbi->orphan_inode_mutex); | 228 | mutex_unlock(&sbi->orphan_inode_mutex); |
@@ -545,7 +539,7 @@ retry: | |||
545 | /* | 539 | /* |
546 | * Freeze all the FS-operations for checkpoint. | 540 | * Freeze all the FS-operations for checkpoint. |
547 | */ | 541 | */ |
548 | void block_operations(struct f2fs_sb_info *sbi) | 542 | static void block_operations(struct f2fs_sb_info *sbi) |
549 | { | 543 | { |
550 | int t; | 544 | int t; |
551 | struct writeback_control wbc = { | 545 | struct writeback_control wbc = { |
@@ -717,27 +711,24 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
717 | sbi->alloc_valid_block_count = 0; | 711 | sbi->alloc_valid_block_count = 0; |
718 | 712 | ||
719 | /* Here, we only have one bio having CP pack */ | 713 | /* Here, we only have one bio having CP pack */ |
720 | if (is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) | 714 | sync_meta_pages(sbi, META_FLUSH, LONG_MAX); |
721 | sbi->sb->s_flags |= MS_RDONLY; | ||
722 | else | ||
723 | sync_meta_pages(sbi, META_FLUSH, LONG_MAX); | ||
724 | 715 | ||
725 | clear_prefree_segments(sbi); | 716 | if (!is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) { |
726 | F2FS_RESET_SB_DIRT(sbi); | 717 | clear_prefree_segments(sbi); |
718 | F2FS_RESET_SB_DIRT(sbi); | ||
719 | } | ||
727 | } | 720 | } |
728 | 721 | ||
729 | /* | 722 | /* |
730 | * We guarantee that this checkpoint procedure should not fail. | 723 | * We guarantee that this checkpoint procedure should not fail. |
731 | */ | 724 | */ |
732 | void write_checkpoint(struct f2fs_sb_info *sbi, bool blocked, bool is_umount) | 725 | void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) |
733 | { | 726 | { |
734 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); | 727 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); |
735 | unsigned long long ckpt_ver; | 728 | unsigned long long ckpt_ver; |
736 | 729 | ||
737 | if (!blocked) { | 730 | mutex_lock(&sbi->cp_mutex); |
738 | mutex_lock(&sbi->cp_mutex); | 731 | block_operations(sbi); |
739 | block_operations(sbi); | ||
740 | } | ||
741 | 732 | ||
742 | f2fs_submit_bio(sbi, DATA, true); | 733 | f2fs_submit_bio(sbi, DATA, true); |
743 | f2fs_submit_bio(sbi, NODE, true); | 734 | f2fs_submit_bio(sbi, NODE, true); |
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index c8c37307b326..025b9e2f935d 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c | |||
@@ -183,10 +183,12 @@ static int stat_show(struct seq_file *s, void *v) | |||
183 | 183 | ||
184 | mutex_lock(&f2fs_stat_mutex); | 184 | mutex_lock(&f2fs_stat_mutex); |
185 | list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) { | 185 | list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) { |
186 | char devname[BDEVNAME_SIZE]; | ||
186 | 187 | ||
187 | update_general_status(si->sbi); | 188 | update_general_status(si->sbi); |
188 | 189 | ||
189 | seq_printf(s, "\n=====[ partition info. #%d ]=====\n", i++); | 190 | seq_printf(s, "\n=====[ partition info(%s). #%d ]=====\n", |
191 | bdevname(si->sbi->sb->s_bdev, devname), i++); | ||
190 | seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ", | 192 | seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ", |
191 | si->sit_area_segs, si->nat_area_segs); | 193 | si->sit_area_segs, si->nat_area_segs); |
192 | seq_printf(s, "[SSA: %d] [MAIN: %d", | 194 | seq_printf(s, "[SSA: %d] [MAIN: %d", |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 989980e16d0b..c395c5012973 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -265,7 +265,7 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de, | |||
265 | mutex_unlock_op(sbi, DENTRY_OPS); | 265 | mutex_unlock_op(sbi, DENTRY_OPS); |
266 | } | 266 | } |
267 | 267 | ||
268 | void init_dent_inode(struct dentry *dentry, struct page *ipage) | 268 | void init_dent_inode(const struct qstr *name, struct page *ipage) |
269 | { | 269 | { |
270 | struct f2fs_node *rn; | 270 | struct f2fs_node *rn; |
271 | 271 | ||
@@ -274,20 +274,19 @@ void init_dent_inode(struct dentry *dentry, struct page *ipage) | |||
274 | 274 | ||
275 | wait_on_page_writeback(ipage); | 275 | wait_on_page_writeback(ipage); |
276 | 276 | ||
277 | /* copy dentry info. to this inode page */ | 277 | /* copy name info. to this inode page */ |
278 | rn = (struct f2fs_node *)page_address(ipage); | 278 | rn = (struct f2fs_node *)page_address(ipage); |
279 | rn->i.i_namelen = cpu_to_le32(dentry->d_name.len); | 279 | rn->i.i_namelen = cpu_to_le32(name->len); |
280 | memcpy(rn->i.i_name, dentry->d_name.name, dentry->d_name.len); | 280 | memcpy(rn->i.i_name, name->name, name->len); |
281 | set_page_dirty(ipage); | 281 | set_page_dirty(ipage); |
282 | } | 282 | } |
283 | 283 | ||
284 | static int init_inode_metadata(struct inode *inode, struct dentry *dentry) | 284 | static int init_inode_metadata(struct inode *inode, |
285 | struct inode *dir, const struct qstr *name) | ||
285 | { | 286 | { |
286 | struct inode *dir = dentry->d_parent->d_inode; | ||
287 | |||
288 | if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { | 287 | if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) { |
289 | int err; | 288 | int err; |
290 | err = new_inode_page(inode, dentry); | 289 | err = new_inode_page(inode, name); |
291 | if (err) | 290 | if (err) |
292 | return err; | 291 | return err; |
293 | 292 | ||
@@ -310,7 +309,7 @@ static int init_inode_metadata(struct inode *inode, struct dentry *dentry) | |||
310 | if (IS_ERR(ipage)) | 309 | if (IS_ERR(ipage)) |
311 | return PTR_ERR(ipage); | 310 | return PTR_ERR(ipage); |
312 | set_cold_node(inode, ipage); | 311 | set_cold_node(inode, ipage); |
313 | init_dent_inode(dentry, ipage); | 312 | init_dent_inode(name, ipage); |
314 | f2fs_put_page(ipage, 1); | 313 | f2fs_put_page(ipage, 1); |
315 | } | 314 | } |
316 | if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { | 315 | if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) { |
@@ -371,7 +370,7 @@ next: | |||
371 | goto next; | 370 | goto next; |
372 | } | 371 | } |
373 | 372 | ||
374 | int f2fs_add_link(struct dentry *dentry, struct inode *inode) | 373 | int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode) |
375 | { | 374 | { |
376 | unsigned int bit_pos; | 375 | unsigned int bit_pos; |
377 | unsigned int level; | 376 | unsigned int level; |
@@ -380,17 +379,15 @@ int f2fs_add_link(struct dentry *dentry, struct inode *inode) | |||
380 | f2fs_hash_t dentry_hash; | 379 | f2fs_hash_t dentry_hash; |
381 | struct f2fs_dir_entry *de; | 380 | struct f2fs_dir_entry *de; |
382 | unsigned int nbucket, nblock; | 381 | unsigned int nbucket, nblock; |
383 | struct inode *dir = dentry->d_parent->d_inode; | ||
384 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); | 382 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); |
385 | const char *name = dentry->d_name.name; | 383 | size_t namelen = name->len; |
386 | size_t namelen = dentry->d_name.len; | ||
387 | struct page *dentry_page = NULL; | 384 | struct page *dentry_page = NULL; |
388 | struct f2fs_dentry_block *dentry_blk = NULL; | 385 | struct f2fs_dentry_block *dentry_blk = NULL; |
389 | int slots = GET_DENTRY_SLOTS(namelen); | 386 | int slots = GET_DENTRY_SLOTS(namelen); |
390 | int err = 0; | 387 | int err = 0; |
391 | int i; | 388 | int i; |
392 | 389 | ||
393 | dentry_hash = f2fs_dentry_hash(name, dentry->d_name.len); | 390 | dentry_hash = f2fs_dentry_hash(name->name, name->len); |
394 | level = 0; | 391 | level = 0; |
395 | current_depth = F2FS_I(dir)->i_current_depth; | 392 | current_depth = F2FS_I(dir)->i_current_depth; |
396 | if (F2FS_I(dir)->chash == dentry_hash) { | 393 | if (F2FS_I(dir)->chash == dentry_hash) { |
@@ -433,7 +430,7 @@ start: | |||
433 | ++level; | 430 | ++level; |
434 | goto start; | 431 | goto start; |
435 | add_dentry: | 432 | add_dentry: |
436 | err = init_inode_metadata(inode, dentry); | 433 | err = init_inode_metadata(inode, dir, name); |
437 | if (err) | 434 | if (err) |
438 | goto fail; | 435 | goto fail; |
439 | 436 | ||
@@ -442,7 +439,7 @@ add_dentry: | |||
442 | de = &dentry_blk->dentry[bit_pos]; | 439 | de = &dentry_blk->dentry[bit_pos]; |
443 | de->hash_code = dentry_hash; | 440 | de->hash_code = dentry_hash; |
444 | de->name_len = cpu_to_le16(namelen); | 441 | de->name_len = cpu_to_le16(namelen); |
445 | memcpy(dentry_blk->filename[bit_pos], name, namelen); | 442 | memcpy(dentry_blk->filename[bit_pos], name->name, name->len); |
446 | de->ino = cpu_to_le32(inode->i_ino); | 443 | de->ino = cpu_to_le32(inode->i_ino); |
447 | set_de_type(de, inode); | 444 | set_de_type(de, inode); |
448 | for (i = 0; i < slots; i++) | 445 | for (i = 0; i < slots; i++) |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index c8e2d751ef9c..cc2213afdcc7 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -104,6 +104,20 @@ static inline int update_sits_in_cursum(struct f2fs_summary_block *rs, int i) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * ioctl commands | ||
108 | */ | ||
109 | #define F2FS_IOC_GETFLAGS FS_IOC_GETFLAGS | ||
110 | #define F2FS_IOC_SETFLAGS FS_IOC_SETFLAGS | ||
111 | |||
112 | #if defined(__KERNEL__) && defined(CONFIG_COMPAT) | ||
113 | /* | ||
114 | * ioctl commands in 32 bit emulation | ||
115 | */ | ||
116 | #define F2FS_IOC32_GETFLAGS FS_IOC32_GETFLAGS | ||
117 | #define F2FS_IOC32_SETFLAGS FS_IOC32_SETFLAGS | ||
118 | #endif | ||
119 | |||
120 | /* | ||
107 | * For INODE and NODE manager | 121 | * For INODE and NODE manager |
108 | */ | 122 | */ |
109 | #define XATTR_NODE_OFFSET (-1) /* | 123 | #define XATTR_NODE_OFFSET (-1) /* |
@@ -141,7 +155,7 @@ struct f2fs_inode_info { | |||
141 | 155 | ||
142 | /* Use below internally in f2fs*/ | 156 | /* Use below internally in f2fs*/ |
143 | unsigned long flags; /* use to pass per-file flags */ | 157 | unsigned long flags; /* use to pass per-file flags */ |
144 | unsigned long long data_version;/* lastes version of data for fsync */ | 158 | unsigned long long data_version;/* latest version of data for fsync */ |
145 | atomic_t dirty_dents; /* # of dirty dentry pages */ | 159 | atomic_t dirty_dents; /* # of dirty dentry pages */ |
146 | f2fs_hash_t chash; /* hash value of given file name */ | 160 | f2fs_hash_t chash; /* hash value of given file name */ |
147 | unsigned int clevel; /* maximum level of given file name */ | 161 | unsigned int clevel; /* maximum level of given file name */ |
@@ -573,6 +587,14 @@ static inline int get_pages(struct f2fs_sb_info *sbi, int count_type) | |||
573 | return atomic_read(&sbi->nr_pages[count_type]); | 587 | return atomic_read(&sbi->nr_pages[count_type]); |
574 | } | 588 | } |
575 | 589 | ||
590 | static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type) | ||
591 | { | ||
592 | unsigned int pages_per_sec = sbi->segs_per_sec * | ||
593 | (1 << sbi->log_blocks_per_seg); | ||
594 | return ((get_pages(sbi, block_type) + pages_per_sec - 1) | ||
595 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
596 | } | ||
597 | |||
576 | static inline block_t valid_user_blocks(struct f2fs_sb_info *sbi) | 598 | static inline block_t valid_user_blocks(struct f2fs_sb_info *sbi) |
577 | { | 599 | { |
578 | block_t ret; | 600 | block_t ret; |
@@ -842,12 +864,12 @@ void f2fs_truncate(struct inode *); | |||
842 | int f2fs_setattr(struct dentry *, struct iattr *); | 864 | int f2fs_setattr(struct dentry *, struct iattr *); |
843 | int truncate_hole(struct inode *, pgoff_t, pgoff_t); | 865 | int truncate_hole(struct inode *, pgoff_t, pgoff_t); |
844 | long f2fs_ioctl(struct file *, unsigned int, unsigned long); | 866 | long f2fs_ioctl(struct file *, unsigned int, unsigned long); |
867 | long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long); | ||
845 | 868 | ||
846 | /* | 869 | /* |
847 | * inode.c | 870 | * inode.c |
848 | */ | 871 | */ |
849 | void f2fs_set_inode_flags(struct inode *); | 872 | void f2fs_set_inode_flags(struct inode *); |
850 | struct inode *f2fs_iget_nowait(struct super_block *, unsigned long); | ||
851 | struct inode *f2fs_iget(struct super_block *, unsigned long); | 873 | struct inode *f2fs_iget(struct super_block *, unsigned long); |
852 | void update_inode(struct inode *, struct page *); | 874 | void update_inode(struct inode *, struct page *); |
853 | int f2fs_write_inode(struct inode *, struct writeback_control *); | 875 | int f2fs_write_inode(struct inode *, struct writeback_control *); |
@@ -867,12 +889,18 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **); | |||
867 | ino_t f2fs_inode_by_name(struct inode *, struct qstr *); | 889 | ino_t f2fs_inode_by_name(struct inode *, struct qstr *); |
868 | void f2fs_set_link(struct inode *, struct f2fs_dir_entry *, | 890 | void f2fs_set_link(struct inode *, struct f2fs_dir_entry *, |
869 | struct page *, struct inode *); | 891 | struct page *, struct inode *); |
870 | void init_dent_inode(struct dentry *, struct page *); | 892 | void init_dent_inode(const struct qstr *, struct page *); |
871 | int f2fs_add_link(struct dentry *, struct inode *); | 893 | int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *); |
872 | void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *); | 894 | void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *); |
873 | int f2fs_make_empty(struct inode *, struct inode *); | 895 | int f2fs_make_empty(struct inode *, struct inode *); |
874 | bool f2fs_empty_dir(struct inode *); | 896 | bool f2fs_empty_dir(struct inode *); |
875 | 897 | ||
898 | static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode) | ||
899 | { | ||
900 | return __f2fs_add_link(dentry->d_parent->d_inode, &dentry->d_name, | ||
901 | inode); | ||
902 | } | ||
903 | |||
876 | /* | 904 | /* |
877 | * super.c | 905 | * super.c |
878 | */ | 906 | */ |
@@ -896,7 +924,7 @@ void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *); | |||
896 | int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int); | 924 | int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int); |
897 | int truncate_inode_blocks(struct inode *, pgoff_t); | 925 | int truncate_inode_blocks(struct inode *, pgoff_t); |
898 | int remove_inode_page(struct inode *); | 926 | int remove_inode_page(struct inode *); |
899 | int new_inode_page(struct inode *, struct dentry *); | 927 | int new_inode_page(struct inode *, const struct qstr *); |
900 | struct page *new_node_page(struct dnode_of_data *, unsigned int); | 928 | struct page *new_node_page(struct dnode_of_data *, unsigned int); |
901 | void ra_node_page(struct f2fs_sb_info *, nid_t); | 929 | void ra_node_page(struct f2fs_sb_info *, nid_t); |
902 | struct page *get_node_page(struct f2fs_sb_info *, pgoff_t); | 930 | struct page *get_node_page(struct f2fs_sb_info *, pgoff_t); |
@@ -929,8 +957,7 @@ void allocate_new_segments(struct f2fs_sb_info *); | |||
929 | struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); | 957 | struct page *get_sum_page(struct f2fs_sb_info *, unsigned int); |
930 | struct bio *f2fs_bio_alloc(struct block_device *, int); | 958 | struct bio *f2fs_bio_alloc(struct block_device *, int); |
931 | void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync); | 959 | void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync); |
932 | int write_meta_page(struct f2fs_sb_info *, struct page *, | 960 | void write_meta_page(struct f2fs_sb_info *, struct page *); |
933 | struct writeback_control *); | ||
934 | void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int, | 961 | void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int, |
935 | block_t, block_t *); | 962 | block_t, block_t *); |
936 | void write_data_page(struct inode *, struct page *, struct dnode_of_data*, | 963 | void write_data_page(struct inode *, struct page *, struct dnode_of_data*, |
@@ -963,8 +990,7 @@ int get_valid_checkpoint(struct f2fs_sb_info *); | |||
963 | void set_dirty_dir_page(struct inode *, struct page *); | 990 | void set_dirty_dir_page(struct inode *, struct page *); |
964 | void remove_dirty_dir_inode(struct inode *); | 991 | void remove_dirty_dir_inode(struct inode *); |
965 | void sync_dirty_dir_inodes(struct f2fs_sb_info *); | 992 | void sync_dirty_dir_inodes(struct f2fs_sb_info *); |
966 | void block_operations(struct f2fs_sb_info *); | 993 | void write_checkpoint(struct f2fs_sb_info *, bool); |
967 | void write_checkpoint(struct f2fs_sb_info *, bool, bool); | ||
968 | void init_orphan_info(struct f2fs_sb_info *); | 994 | void init_orphan_info(struct f2fs_sb_info *); |
969 | int __init create_checkpoint_caches(void); | 995 | int __init create_checkpoint_caches(void); |
970 | void destroy_checkpoint_caches(void); | 996 | void destroy_checkpoint_caches(void); |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3191b52aafb0..b7a053d4c6d3 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/writeback.h> | 15 | #include <linux/writeback.h> |
16 | #include <linux/falloc.h> | 16 | #include <linux/falloc.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/compat.h> | ||
18 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
19 | #include <linux/mount.h> | 20 | #include <linux/mount.h> |
20 | 21 | ||
@@ -157,11 +158,11 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
157 | 158 | ||
158 | if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) | 159 | if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) |
159 | need_cp = true; | 160 | need_cp = true; |
160 | if (is_inode_flag_set(F2FS_I(inode), FI_NEED_CP)) | 161 | else if (is_inode_flag_set(F2FS_I(inode), FI_NEED_CP)) |
161 | need_cp = true; | 162 | need_cp = true; |
162 | if (!space_for_roll_forward(sbi)) | 163 | else if (!space_for_roll_forward(sbi)) |
163 | need_cp = true; | 164 | need_cp = true; |
164 | if (need_to_sync_dir(sbi, inode)) | 165 | else if (need_to_sync_dir(sbi, inode)) |
165 | need_cp = true; | 166 | need_cp = true; |
166 | 167 | ||
167 | if (need_cp) { | 168 | if (need_cp) { |
@@ -298,8 +299,6 @@ void f2fs_truncate(struct inode *inode) | |||
298 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 299 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
299 | mark_inode_dirty(inode); | 300 | mark_inode_dirty(inode); |
300 | } | 301 | } |
301 | |||
302 | f2fs_balance_fs(F2FS_SB(inode->i_sb)); | ||
303 | } | 302 | } |
304 | 303 | ||
305 | static int f2fs_getattr(struct vfsmount *mnt, | 304 | static int f2fs_getattr(struct vfsmount *mnt, |
@@ -356,6 +355,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) | |||
356 | attr->ia_size != i_size_read(inode)) { | 355 | attr->ia_size != i_size_read(inode)) { |
357 | truncate_setsize(inode, attr->ia_size); | 356 | truncate_setsize(inode, attr->ia_size); |
358 | f2fs_truncate(inode); | 357 | f2fs_truncate(inode); |
358 | f2fs_balance_fs(F2FS_SB(inode->i_sb)); | ||
359 | } | 359 | } |
360 | 360 | ||
361 | __setattr_copy(inode, attr); | 361 | __setattr_copy(inode, attr); |
@@ -387,12 +387,17 @@ const struct inode_operations f2fs_file_inode_operations = { | |||
387 | static void fill_zero(struct inode *inode, pgoff_t index, | 387 | static void fill_zero(struct inode *inode, pgoff_t index, |
388 | loff_t start, loff_t len) | 388 | loff_t start, loff_t len) |
389 | { | 389 | { |
390 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | ||
390 | struct page *page; | 391 | struct page *page; |
391 | 392 | ||
392 | if (!len) | 393 | if (!len) |
393 | return; | 394 | return; |
394 | 395 | ||
396 | f2fs_balance_fs(sbi); | ||
397 | |||
398 | mutex_lock_op(sbi, DATA_NEW); | ||
395 | page = get_new_data_page(inode, index, false); | 399 | page = get_new_data_page(inode, index, false); |
400 | mutex_unlock_op(sbi, DATA_NEW); | ||
396 | 401 | ||
397 | if (!IS_ERR(page)) { | 402 | if (!IS_ERR(page)) { |
398 | wait_on_page_writeback(page); | 403 | wait_on_page_writeback(page); |
@@ -630,6 +635,23 @@ out: | |||
630 | } | 635 | } |
631 | } | 636 | } |
632 | 637 | ||
638 | #ifdef CONFIG_COMPAT | ||
639 | long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
640 | { | ||
641 | switch (cmd) { | ||
642 | case F2FS_IOC32_GETFLAGS: | ||
643 | cmd = F2FS_IOC_GETFLAGS; | ||
644 | break; | ||
645 | case F2FS_IOC32_SETFLAGS: | ||
646 | cmd = F2FS_IOC_SETFLAGS; | ||
647 | break; | ||
648 | default: | ||
649 | return -ENOIOCTLCMD; | ||
650 | } | ||
651 | return f2fs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); | ||
652 | } | ||
653 | #endif | ||
654 | |||
633 | const struct file_operations f2fs_file_operations = { | 655 | const struct file_operations f2fs_file_operations = { |
634 | .llseek = generic_file_llseek, | 656 | .llseek = generic_file_llseek, |
635 | .read = do_sync_read, | 657 | .read = do_sync_read, |
@@ -641,6 +663,9 @@ const struct file_operations f2fs_file_operations = { | |||
641 | .fsync = f2fs_sync_file, | 663 | .fsync = f2fs_sync_file, |
642 | .fallocate = f2fs_fallocate, | 664 | .fallocate = f2fs_fallocate, |
643 | .unlocked_ioctl = f2fs_ioctl, | 665 | .unlocked_ioctl = f2fs_ioctl, |
666 | #ifdef CONFIG_COMPAT | ||
667 | .compat_ioctl = f2fs_compat_ioctl, | ||
668 | #endif | ||
644 | .splice_read = generic_file_splice_read, | 669 | .splice_read = generic_file_splice_read, |
645 | .splice_write = generic_file_splice_write, | 670 | .splice_write = generic_file_splice_write, |
646 | }; | 671 | }; |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index c386910dacc5..94b8a0c48453 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -44,10 +44,10 @@ static int gc_thread_func(void *data) | |||
44 | if (kthread_should_stop()) | 44 | if (kthread_should_stop()) |
45 | break; | 45 | break; |
46 | 46 | ||
47 | f2fs_balance_fs(sbi); | 47 | if (sbi->sb->s_writers.frozen >= SB_FREEZE_WRITE) { |
48 | 48 | wait_ms = GC_THREAD_MAX_SLEEP_TIME; | |
49 | if (!test_opt(sbi, BG_GC)) | ||
50 | continue; | 49 | continue; |
50 | } | ||
51 | 51 | ||
52 | /* | 52 | /* |
53 | * [GC triggering condition] | 53 | * [GC triggering condition] |
@@ -78,7 +78,8 @@ static int gc_thread_func(void *data) | |||
78 | 78 | ||
79 | sbi->bg_gc++; | 79 | sbi->bg_gc++; |
80 | 80 | ||
81 | if (f2fs_gc(sbi) == GC_NONE) | 81 | /* if return value is not zero, no victim was selected */ |
82 | if (f2fs_gc(sbi)) | ||
82 | wait_ms = GC_THREAD_NOGC_SLEEP_TIME; | 83 | wait_ms = GC_THREAD_NOGC_SLEEP_TIME; |
83 | else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) | 84 | else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) |
84 | wait_ms = GC_THREAD_MAX_SLEEP_TIME; | 85 | wait_ms = GC_THREAD_MAX_SLEEP_TIME; |
@@ -90,7 +91,10 @@ static int gc_thread_func(void *data) | |||
90 | int start_gc_thread(struct f2fs_sb_info *sbi) | 91 | int start_gc_thread(struct f2fs_sb_info *sbi) |
91 | { | 92 | { |
92 | struct f2fs_gc_kthread *gc_th; | 93 | struct f2fs_gc_kthread *gc_th; |
94 | dev_t dev = sbi->sb->s_bdev->bd_dev; | ||
93 | 95 | ||
96 | if (!test_opt(sbi, BG_GC)) | ||
97 | return 0; | ||
94 | gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL); | 98 | gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL); |
95 | if (!gc_th) | 99 | if (!gc_th) |
96 | return -ENOMEM; | 100 | return -ENOMEM; |
@@ -98,9 +102,10 @@ int start_gc_thread(struct f2fs_sb_info *sbi) | |||
98 | sbi->gc_thread = gc_th; | 102 | sbi->gc_thread = gc_th; |
99 | init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head); | 103 | init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head); |
100 | sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi, | 104 | sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi, |
101 | GC_THREAD_NAME); | 105 | "f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev)); |
102 | if (IS_ERR(gc_th->f2fs_gc_task)) { | 106 | if (IS_ERR(gc_th->f2fs_gc_task)) { |
103 | kfree(gc_th); | 107 | kfree(gc_th); |
108 | sbi->gc_thread = NULL; | ||
104 | return -ENOMEM; | 109 | return -ENOMEM; |
105 | } | 110 | } |
106 | return 0; | 111 | return 0; |
@@ -141,6 +146,9 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type, | |||
141 | static unsigned int get_max_cost(struct f2fs_sb_info *sbi, | 146 | static unsigned int get_max_cost(struct f2fs_sb_info *sbi, |
142 | struct victim_sel_policy *p) | 147 | struct victim_sel_policy *p) |
143 | { | 148 | { |
149 | /* SSR allocates in a segment unit */ | ||
150 | if (p->alloc_mode == SSR) | ||
151 | return 1 << sbi->log_blocks_per_seg; | ||
144 | if (p->gc_mode == GC_GREEDY) | 152 | if (p->gc_mode == GC_GREEDY) |
145 | return (1 << sbi->log_blocks_per_seg) * p->ofs_unit; | 153 | return (1 << sbi->log_blocks_per_seg) * p->ofs_unit; |
146 | else if (p->gc_mode == GC_CB) | 154 | else if (p->gc_mode == GC_CB) |
@@ -356,7 +364,7 @@ static int check_valid_map(struct f2fs_sb_info *sbi, | |||
356 | sentry = get_seg_entry(sbi, segno); | 364 | sentry = get_seg_entry(sbi, segno); |
357 | ret = f2fs_test_bit(offset, sentry->cur_valid_map); | 365 | ret = f2fs_test_bit(offset, sentry->cur_valid_map); |
358 | mutex_unlock(&sit_i->sentry_lock); | 366 | mutex_unlock(&sit_i->sentry_lock); |
359 | return ret ? GC_OK : GC_NEXT; | 367 | return ret; |
360 | } | 368 | } |
361 | 369 | ||
362 | /* | 370 | /* |
@@ -364,7 +372,7 @@ static int check_valid_map(struct f2fs_sb_info *sbi, | |||
364 | * On validity, copy that node with cold status, otherwise (invalid node) | 372 | * On validity, copy that node with cold status, otherwise (invalid node) |
365 | * ignore that. | 373 | * ignore that. |
366 | */ | 374 | */ |
367 | static int gc_node_segment(struct f2fs_sb_info *sbi, | 375 | static void gc_node_segment(struct f2fs_sb_info *sbi, |
368 | struct f2fs_summary *sum, unsigned int segno, int gc_type) | 376 | struct f2fs_summary *sum, unsigned int segno, int gc_type) |
369 | { | 377 | { |
370 | bool initial = true; | 378 | bool initial = true; |
@@ -376,21 +384,12 @@ next_step: | |||
376 | for (off = 0; off < sbi->blocks_per_seg; off++, entry++) { | 384 | for (off = 0; off < sbi->blocks_per_seg; off++, entry++) { |
377 | nid_t nid = le32_to_cpu(entry->nid); | 385 | nid_t nid = le32_to_cpu(entry->nid); |
378 | struct page *node_page; | 386 | struct page *node_page; |
379 | int err; | ||
380 | 387 | ||
381 | /* | 388 | /* stop BG_GC if there is not enough free sections. */ |
382 | * It makes sure that free segments are able to write | 389 | if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0)) |
383 | * all the dirty node pages before CP after this CP. | 390 | return; |
384 | * So let's check the space of dirty node pages. | ||
385 | */ | ||
386 | if (should_do_checkpoint(sbi)) { | ||
387 | mutex_lock(&sbi->cp_mutex); | ||
388 | block_operations(sbi); | ||
389 | return GC_BLOCKED; | ||
390 | } | ||
391 | 391 | ||
392 | err = check_valid_map(sbi, segno, off); | 392 | if (check_valid_map(sbi, segno, off) == 0) |
393 | if (err == GC_NEXT) | ||
394 | continue; | 393 | continue; |
395 | 394 | ||
396 | if (initial) { | 395 | if (initial) { |
@@ -420,7 +419,6 @@ next_step: | |||
420 | }; | 419 | }; |
421 | sync_node_pages(sbi, 0, &wbc); | 420 | sync_node_pages(sbi, 0, &wbc); |
422 | } | 421 | } |
423 | return GC_DONE; | ||
424 | } | 422 | } |
425 | 423 | ||
426 | /* | 424 | /* |
@@ -463,13 +461,13 @@ static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, | |||
463 | 461 | ||
464 | node_page = get_node_page(sbi, nid); | 462 | node_page = get_node_page(sbi, nid); |
465 | if (IS_ERR(node_page)) | 463 | if (IS_ERR(node_page)) |
466 | return GC_NEXT; | 464 | return 0; |
467 | 465 | ||
468 | get_node_info(sbi, nid, dni); | 466 | get_node_info(sbi, nid, dni); |
469 | 467 | ||
470 | if (sum->version != dni->version) { | 468 | if (sum->version != dni->version) { |
471 | f2fs_put_page(node_page, 1); | 469 | f2fs_put_page(node_page, 1); |
472 | return GC_NEXT; | 470 | return 0; |
473 | } | 471 | } |
474 | 472 | ||
475 | *nofs = ofs_of_node(node_page); | 473 | *nofs = ofs_of_node(node_page); |
@@ -477,8 +475,8 @@ static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, | |||
477 | f2fs_put_page(node_page, 1); | 475 | f2fs_put_page(node_page, 1); |
478 | 476 | ||
479 | if (source_blkaddr != blkaddr) | 477 | if (source_blkaddr != blkaddr) |
480 | return GC_NEXT; | 478 | return 0; |
481 | return GC_OK; | 479 | return 1; |
482 | } | 480 | } |
483 | 481 | ||
484 | static void move_data_page(struct inode *inode, struct page *page, int gc_type) | 482 | static void move_data_page(struct inode *inode, struct page *page, int gc_type) |
@@ -519,13 +517,13 @@ out: | |||
519 | * If the parent node is not valid or the data block address is different, | 517 | * If the parent node is not valid or the data block address is different, |
520 | * the victim data block is ignored. | 518 | * the victim data block is ignored. |
521 | */ | 519 | */ |
522 | static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, | 520 | static void gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, |
523 | struct list_head *ilist, unsigned int segno, int gc_type) | 521 | struct list_head *ilist, unsigned int segno, int gc_type) |
524 | { | 522 | { |
525 | struct super_block *sb = sbi->sb; | 523 | struct super_block *sb = sbi->sb; |
526 | struct f2fs_summary *entry; | 524 | struct f2fs_summary *entry; |
527 | block_t start_addr; | 525 | block_t start_addr; |
528 | int err, off; | 526 | int off; |
529 | int phase = 0; | 527 | int phase = 0; |
530 | 528 | ||
531 | start_addr = START_BLOCK(sbi, segno); | 529 | start_addr = START_BLOCK(sbi, segno); |
@@ -539,20 +537,11 @@ next_step: | |||
539 | unsigned int ofs_in_node, nofs; | 537 | unsigned int ofs_in_node, nofs; |
540 | block_t start_bidx; | 538 | block_t start_bidx; |
541 | 539 | ||
542 | /* | 540 | /* stop BG_GC if there is not enough free sections. */ |
543 | * It makes sure that free segments are able to write | 541 | if (gc_type == BG_GC && has_not_enough_free_secs(sbi, 0)) |
544 | * all the dirty node pages before CP after this CP. | 542 | return; |
545 | * So let's check the space of dirty node pages. | ||
546 | */ | ||
547 | if (should_do_checkpoint(sbi)) { | ||
548 | mutex_lock(&sbi->cp_mutex); | ||
549 | block_operations(sbi); | ||
550 | err = GC_BLOCKED; | ||
551 | goto stop; | ||
552 | } | ||
553 | 543 | ||
554 | err = check_valid_map(sbi, segno, off); | 544 | if (check_valid_map(sbi, segno, off) == 0) |
555 | if (err == GC_NEXT) | ||
556 | continue; | 545 | continue; |
557 | 546 | ||
558 | if (phase == 0) { | 547 | if (phase == 0) { |
@@ -561,8 +550,7 @@ next_step: | |||
561 | } | 550 | } |
562 | 551 | ||
563 | /* Get an inode by ino with checking validity */ | 552 | /* Get an inode by ino with checking validity */ |
564 | err = check_dnode(sbi, entry, &dni, start_addr + off, &nofs); | 553 | if (check_dnode(sbi, entry, &dni, start_addr + off, &nofs) == 0) |
565 | if (err == GC_NEXT) | ||
566 | continue; | 554 | continue; |
567 | 555 | ||
568 | if (phase == 1) { | 556 | if (phase == 1) { |
@@ -574,7 +562,7 @@ next_step: | |||
574 | ofs_in_node = le16_to_cpu(entry->ofs_in_node); | 562 | ofs_in_node = le16_to_cpu(entry->ofs_in_node); |
575 | 563 | ||
576 | if (phase == 2) { | 564 | if (phase == 2) { |
577 | inode = f2fs_iget_nowait(sb, dni.ino); | 565 | inode = f2fs_iget(sb, dni.ino); |
578 | if (IS_ERR(inode)) | 566 | if (IS_ERR(inode)) |
579 | continue; | 567 | continue; |
580 | 568 | ||
@@ -602,11 +590,9 @@ next_iput: | |||
602 | } | 590 | } |
603 | if (++phase < 4) | 591 | if (++phase < 4) |
604 | goto next_step; | 592 | goto next_step; |
605 | err = GC_DONE; | 593 | |
606 | stop: | ||
607 | if (gc_type == FG_GC) | 594 | if (gc_type == FG_GC) |
608 | f2fs_submit_bio(sbi, DATA, true); | 595 | f2fs_submit_bio(sbi, DATA, true); |
609 | return err; | ||
610 | } | 596 | } |
611 | 597 | ||
612 | static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, | 598 | static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, |
@@ -620,17 +606,16 @@ static int __get_victim(struct f2fs_sb_info *sbi, unsigned int *victim, | |||
620 | return ret; | 606 | return ret; |
621 | } | 607 | } |
622 | 608 | ||
623 | static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, | 609 | static void do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, |
624 | struct list_head *ilist, int gc_type) | 610 | struct list_head *ilist, int gc_type) |
625 | { | 611 | { |
626 | struct page *sum_page; | 612 | struct page *sum_page; |
627 | struct f2fs_summary_block *sum; | 613 | struct f2fs_summary_block *sum; |
628 | int ret = GC_DONE; | ||
629 | 614 | ||
630 | /* read segment summary of victim */ | 615 | /* read segment summary of victim */ |
631 | sum_page = get_sum_page(sbi, segno); | 616 | sum_page = get_sum_page(sbi, segno); |
632 | if (IS_ERR(sum_page)) | 617 | if (IS_ERR(sum_page)) |
633 | return GC_ERROR; | 618 | return; |
634 | 619 | ||
635 | /* | 620 | /* |
636 | * CP needs to lock sum_page. In this time, we don't need | 621 | * CP needs to lock sum_page. In this time, we don't need |
@@ -642,17 +627,16 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, | |||
642 | 627 | ||
643 | switch (GET_SUM_TYPE((&sum->footer))) { | 628 | switch (GET_SUM_TYPE((&sum->footer))) { |
644 | case SUM_TYPE_NODE: | 629 | case SUM_TYPE_NODE: |
645 | ret = gc_node_segment(sbi, sum->entries, segno, gc_type); | 630 | gc_node_segment(sbi, sum->entries, segno, gc_type); |
646 | break; | 631 | break; |
647 | case SUM_TYPE_DATA: | 632 | case SUM_TYPE_DATA: |
648 | ret = gc_data_segment(sbi, sum->entries, ilist, segno, gc_type); | 633 | gc_data_segment(sbi, sum->entries, ilist, segno, gc_type); |
649 | break; | 634 | break; |
650 | } | 635 | } |
651 | stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer))); | 636 | stat_inc_seg_count(sbi, GET_SUM_TYPE((&sum->footer))); |
652 | stat_inc_call_count(sbi->stat_info); | 637 | stat_inc_call_count(sbi->stat_info); |
653 | 638 | ||
654 | f2fs_put_page(sum_page, 0); | 639 | f2fs_put_page(sum_page, 0); |
655 | return ret; | ||
656 | } | 640 | } |
657 | 641 | ||
658 | int f2fs_gc(struct f2fs_sb_info *sbi) | 642 | int f2fs_gc(struct f2fs_sb_info *sbi) |
@@ -660,40 +644,38 @@ int f2fs_gc(struct f2fs_sb_info *sbi) | |||
660 | struct list_head ilist; | 644 | struct list_head ilist; |
661 | unsigned int segno, i; | 645 | unsigned int segno, i; |
662 | int gc_type = BG_GC; | 646 | int gc_type = BG_GC; |
663 | int gc_status = GC_NONE; | 647 | int nfree = 0; |
648 | int ret = -1; | ||
664 | 649 | ||
665 | INIT_LIST_HEAD(&ilist); | 650 | INIT_LIST_HEAD(&ilist); |
666 | gc_more: | 651 | gc_more: |
667 | if (!(sbi->sb->s_flags & MS_ACTIVE)) | 652 | if (!(sbi->sb->s_flags & MS_ACTIVE)) |
668 | goto stop; | 653 | goto stop; |
669 | 654 | ||
670 | if (has_not_enough_free_secs(sbi)) | 655 | if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) |
671 | gc_type = FG_GC; | 656 | gc_type = FG_GC; |
672 | 657 | ||
673 | if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) | 658 | if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) |
674 | goto stop; | 659 | goto stop; |
660 | ret = 0; | ||
675 | 661 | ||
676 | for (i = 0; i < sbi->segs_per_sec; i++) { | 662 | for (i = 0; i < sbi->segs_per_sec; i++) |
677 | /* | 663 | do_garbage_collect(sbi, segno + i, &ilist, gc_type); |
678 | * do_garbage_collect will give us three gc_status: | 664 | |
679 | * GC_ERROR, GC_DONE, and GC_BLOCKED. | 665 | if (gc_type == FG_GC && |
680 | * If GC is finished uncleanly, we have to return | 666 | get_valid_blocks(sbi, segno, sbi->segs_per_sec) == 0) |
681 | * the victim to dirty segment list. | 667 | nfree++; |
682 | */ | 668 | |
683 | gc_status = do_garbage_collect(sbi, segno + i, &ilist, gc_type); | 669 | if (has_not_enough_free_secs(sbi, nfree)) |
684 | if (gc_status != GC_DONE) | 670 | goto gc_more; |
685 | break; | 671 | |
686 | } | 672 | if (gc_type == FG_GC) |
687 | if (has_not_enough_free_secs(sbi)) { | 673 | write_checkpoint(sbi, false); |
688 | write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); | ||
689 | if (has_not_enough_free_secs(sbi)) | ||
690 | goto gc_more; | ||
691 | } | ||
692 | stop: | 674 | stop: |
693 | mutex_unlock(&sbi->gc_mutex); | 675 | mutex_unlock(&sbi->gc_mutex); |
694 | 676 | ||
695 | put_gc_inode(&ilist); | 677 | put_gc_inode(&ilist); |
696 | return gc_status; | 678 | return ret; |
697 | } | 679 | } |
698 | 680 | ||
699 | void build_gc_manager(struct f2fs_sb_info *sbi) | 681 | void build_gc_manager(struct f2fs_sb_info *sbi) |
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index b026d9354ccd..30b2db003acd 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h | |||
@@ -8,7 +8,6 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | #define GC_THREAD_NAME "f2fs_gc_task" | ||
12 | #define GC_THREAD_MIN_WB_PAGES 1 /* | 11 | #define GC_THREAD_MIN_WB_PAGES 1 /* |
13 | * a threshold to determine | 12 | * a threshold to determine |
14 | * whether IO subsystem is idle | 13 | * whether IO subsystem is idle |
@@ -23,15 +22,6 @@ | |||
23 | /* Search max. number of dirty segments to select a victim segment */ | 22 | /* Search max. number of dirty segments to select a victim segment */ |
24 | #define MAX_VICTIM_SEARCH 20 | 23 | #define MAX_VICTIM_SEARCH 20 |
25 | 24 | ||
26 | enum { | ||
27 | GC_NONE = 0, | ||
28 | GC_ERROR, | ||
29 | GC_OK, | ||
30 | GC_NEXT, | ||
31 | GC_BLOCKED, | ||
32 | GC_DONE, | ||
33 | }; | ||
34 | |||
35 | struct f2fs_gc_kthread { | 25 | struct f2fs_gc_kthread { |
36 | struct task_struct *f2fs_gc_task; | 26 | struct task_struct *f2fs_gc_task; |
37 | wait_queue_head_t gc_wait_queue_head; | 27 | wait_queue_head_t gc_wait_queue_head; |
@@ -104,14 +94,3 @@ static inline int is_idle(struct f2fs_sb_info *sbi) | |||
104 | struct request_list *rl = &q->root_rl; | 94 | struct request_list *rl = &q->root_rl; |
105 | return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]); | 95 | return !(rl->count[BLK_RW_SYNC]) && !(rl->count[BLK_RW_ASYNC]); |
106 | } | 96 | } |
107 | |||
108 | static inline bool should_do_checkpoint(struct f2fs_sb_info *sbi) | ||
109 | { | ||
110 | unsigned int pages_per_sec = sbi->segs_per_sec * | ||
111 | (1 << sbi->log_blocks_per_seg); | ||
112 | int node_secs = ((get_pages(sbi, F2FS_DIRTY_NODES) + pages_per_sec - 1) | ||
113 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
114 | int dent_secs = ((get_pages(sbi, F2FS_DIRTY_DENTS) + pages_per_sec - 1) | ||
115 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
116 | return free_sections(sbi) <= (node_secs + 2 * dent_secs + 2); | ||
117 | } | ||
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 794241777322..ddae412d30c8 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -16,11 +16,6 @@ | |||
16 | #include "f2fs.h" | 16 | #include "f2fs.h" |
17 | #include "node.h" | 17 | #include "node.h" |
18 | 18 | ||
19 | struct f2fs_iget_args { | ||
20 | u64 ino; | ||
21 | int on_free; | ||
22 | }; | ||
23 | |||
24 | void f2fs_set_inode_flags(struct inode *inode) | 19 | void f2fs_set_inode_flags(struct inode *inode) |
25 | { | 20 | { |
26 | unsigned int flags = F2FS_I(inode)->i_flags; | 21 | unsigned int flags = F2FS_I(inode)->i_flags; |
@@ -40,34 +35,6 @@ void f2fs_set_inode_flags(struct inode *inode) | |||
40 | inode->i_flags |= S_DIRSYNC; | 35 | inode->i_flags |= S_DIRSYNC; |
41 | } | 36 | } |
42 | 37 | ||
43 | static int f2fs_iget_test(struct inode *inode, void *data) | ||
44 | { | ||
45 | struct f2fs_iget_args *args = data; | ||
46 | |||
47 | if (inode->i_ino != args->ino) | ||
48 | return 0; | ||
49 | if (inode->i_state & (I_FREEING | I_WILL_FREE)) { | ||
50 | args->on_free = 1; | ||
51 | return 0; | ||
52 | } | ||
53 | return 1; | ||
54 | } | ||
55 | |||
56 | struct inode *f2fs_iget_nowait(struct super_block *sb, unsigned long ino) | ||
57 | { | ||
58 | struct f2fs_iget_args args = { | ||
59 | .ino = ino, | ||
60 | .on_free = 0 | ||
61 | }; | ||
62 | struct inode *inode = ilookup5(sb, ino, f2fs_iget_test, &args); | ||
63 | |||
64 | if (inode) | ||
65 | return inode; | ||
66 | if (!args.on_free) | ||
67 | return f2fs_iget(sb, ino); | ||
68 | return ERR_PTR(-ENOENT); | ||
69 | } | ||
70 | |||
71 | static int do_read_inode(struct inode *inode) | 38 | static int do_read_inode(struct inode *inode) |
72 | { | 39 | { |
73 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 40 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
@@ -100,6 +67,10 @@ static int do_read_inode(struct inode *inode) | |||
100 | inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec); | 67 | inode->i_ctime.tv_nsec = le32_to_cpu(ri->i_ctime_nsec); |
101 | inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); | 68 | inode->i_mtime.tv_nsec = le32_to_cpu(ri->i_mtime_nsec); |
102 | inode->i_generation = le32_to_cpu(ri->i_generation); | 69 | inode->i_generation = le32_to_cpu(ri->i_generation); |
70 | if (ri->i_addr[0]) | ||
71 | inode->i_rdev = old_decode_dev(le32_to_cpu(ri->i_addr[0])); | ||
72 | else | ||
73 | inode->i_rdev = new_decode_dev(le32_to_cpu(ri->i_addr[1])); | ||
103 | 74 | ||
104 | fi->i_current_depth = le32_to_cpu(ri->i_current_depth); | 75 | fi->i_current_depth = le32_to_cpu(ri->i_current_depth); |
105 | fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); | 76 | fi->i_xattr_nid = le32_to_cpu(ri->i_xattr_nid); |
@@ -203,6 +174,20 @@ void update_inode(struct inode *inode, struct page *node_page) | |||
203 | ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); | 174 | ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); |
204 | ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); | 175 | ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); |
205 | ri->i_generation = cpu_to_le32(inode->i_generation); | 176 | ri->i_generation = cpu_to_le32(inode->i_generation); |
177 | |||
178 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { | ||
179 | if (old_valid_dev(inode->i_rdev)) { | ||
180 | ri->i_addr[0] = | ||
181 | cpu_to_le32(old_encode_dev(inode->i_rdev)); | ||
182 | ri->i_addr[1] = 0; | ||
183 | } else { | ||
184 | ri->i_addr[0] = 0; | ||
185 | ri->i_addr[1] = | ||
186 | cpu_to_le32(new_encode_dev(inode->i_rdev)); | ||
187 | ri->i_addr[2] = 0; | ||
188 | } | ||
189 | } | ||
190 | |||
206 | set_cold_node(inode, node_page); | 191 | set_cold_node(inode, node_page); |
207 | set_page_dirty(node_page); | 192 | set_page_dirty(node_page); |
208 | } | 193 | } |
@@ -260,6 +245,7 @@ void f2fs_evict_inode(struct inode *inode) | |||
260 | if (inode->i_nlink || is_bad_inode(inode)) | 245 | if (inode->i_nlink || is_bad_inode(inode)) |
261 | goto no_delete; | 246 | goto no_delete; |
262 | 247 | ||
248 | sb_start_intwrite(inode->i_sb); | ||
263 | set_inode_flag(F2FS_I(inode), FI_NO_ALLOC); | 249 | set_inode_flag(F2FS_I(inode), FI_NO_ALLOC); |
264 | i_size_write(inode, 0); | 250 | i_size_write(inode, 0); |
265 | 251 | ||
@@ -267,6 +253,7 @@ void f2fs_evict_inode(struct inode *inode) | |||
267 | f2fs_truncate(inode); | 253 | f2fs_truncate(inode); |
268 | 254 | ||
269 | remove_inode_page(inode); | 255 | remove_inode_page(inode); |
256 | sb_end_intwrite(inode->i_sb); | ||
270 | no_delete: | 257 | no_delete: |
271 | clear_inode(inode); | 258 | clear_inode(inode); |
272 | } | 259 | } |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 9bda63c9c166..e275218904ed 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -104,7 +104,7 @@ static void ra_nat_pages(struct f2fs_sb_info *sbi, int nid) | |||
104 | f2fs_put_page(page, 1); | 104 | f2fs_put_page(page, 1); |
105 | continue; | 105 | continue; |
106 | } | 106 | } |
107 | page_cache_release(page); | 107 | f2fs_put_page(page, 0); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
@@ -660,7 +660,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from) | |||
660 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 660 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
661 | int err = 0, cont = 1; | 661 | int err = 0, cont = 1; |
662 | int level, offset[4], noffset[4]; | 662 | int level, offset[4], noffset[4]; |
663 | unsigned int nofs; | 663 | unsigned int nofs = 0; |
664 | struct f2fs_node *rn; | 664 | struct f2fs_node *rn; |
665 | struct dnode_of_data dn; | 665 | struct dnode_of_data dn; |
666 | struct page *page; | 666 | struct page *page; |
@@ -780,7 +780,7 @@ int remove_inode_page(struct inode *inode) | |||
780 | return 0; | 780 | return 0; |
781 | } | 781 | } |
782 | 782 | ||
783 | int new_inode_page(struct inode *inode, struct dentry *dentry) | 783 | int new_inode_page(struct inode *inode, const struct qstr *name) |
784 | { | 784 | { |
785 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 785 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
786 | struct page *page; | 786 | struct page *page; |
@@ -790,7 +790,7 @@ int new_inode_page(struct inode *inode, struct dentry *dentry) | |||
790 | set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); | 790 | set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); |
791 | mutex_lock_op(sbi, NODE_NEW); | 791 | mutex_lock_op(sbi, NODE_NEW); |
792 | page = new_node_page(&dn, 0); | 792 | page = new_node_page(&dn, 0); |
793 | init_dent_inode(dentry, page); | 793 | init_dent_inode(name, page); |
794 | mutex_unlock_op(sbi, NODE_NEW); | 794 | mutex_unlock_op(sbi, NODE_NEW); |
795 | if (IS_ERR(page)) | 795 | if (IS_ERR(page)) |
796 | return PTR_ERR(page); | 796 | return PTR_ERR(page); |
@@ -874,15 +874,11 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) | |||
874 | return; | 874 | return; |
875 | 875 | ||
876 | if (read_node_page(apage, READA)) | 876 | if (read_node_page(apage, READA)) |
877 | goto unlock_out; | 877 | unlock_page(apage); |
878 | 878 | ||
879 | page_cache_release(apage); | ||
880 | return; | ||
881 | |||
882 | unlock_out: | ||
883 | unlock_page(apage); | ||
884 | release_out: | 879 | release_out: |
885 | page_cache_release(apage); | 880 | f2fs_put_page(apage, 0); |
881 | return; | ||
886 | } | 882 | } |
887 | 883 | ||
888 | struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) | 884 | struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) |
@@ -1139,7 +1135,7 @@ static int f2fs_write_node_pages(struct address_space *mapping, | |||
1139 | 1135 | ||
1140 | /* First check balancing cached NAT entries */ | 1136 | /* First check balancing cached NAT entries */ |
1141 | if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) { | 1137 | if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) { |
1142 | write_checkpoint(sbi, false, false); | 1138 | write_checkpoint(sbi, false); |
1143 | return 0; | 1139 | return 0; |
1144 | } | 1140 | } |
1145 | 1141 | ||
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index f42e4060b399..b235215ac138 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
@@ -42,7 +42,7 @@ static int recover_dentry(struct page *ipage, struct inode *inode) | |||
42 | { | 42 | { |
43 | struct f2fs_node *raw_node = (struct f2fs_node *)kmap(ipage); | 43 | struct f2fs_node *raw_node = (struct f2fs_node *)kmap(ipage); |
44 | struct f2fs_inode *raw_inode = &(raw_node->i); | 44 | struct f2fs_inode *raw_inode = &(raw_node->i); |
45 | struct dentry dent, parent; | 45 | struct qstr name; |
46 | struct f2fs_dir_entry *de; | 46 | struct f2fs_dir_entry *de; |
47 | struct page *page; | 47 | struct page *page; |
48 | struct inode *dir; | 48 | struct inode *dir; |
@@ -57,17 +57,15 @@ static int recover_dentry(struct page *ipage, struct inode *inode) | |||
57 | goto out; | 57 | goto out; |
58 | } | 58 | } |
59 | 59 | ||
60 | parent.d_inode = dir; | 60 | name.len = le32_to_cpu(raw_inode->i_namelen); |
61 | dent.d_parent = &parent; | 61 | name.name = raw_inode->i_name; |
62 | dent.d_name.len = le32_to_cpu(raw_inode->i_namelen); | ||
63 | dent.d_name.name = raw_inode->i_name; | ||
64 | 62 | ||
65 | de = f2fs_find_entry(dir, &dent.d_name, &page); | 63 | de = f2fs_find_entry(dir, &name, &page); |
66 | if (de) { | 64 | if (de) { |
67 | kunmap(page); | 65 | kunmap(page); |
68 | f2fs_put_page(page, 0); | 66 | f2fs_put_page(page, 0); |
69 | } else { | 67 | } else { |
70 | err = f2fs_add_link(&dent, inode); | 68 | err = __f2fs_add_link(dir, &name, inode); |
71 | } | 69 | } |
72 | iput(dir); | 70 | iput(dir); |
73 | out: | 71 | out: |
@@ -226,7 +224,7 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi, | |||
226 | f2fs_put_page(node_page, 1); | 224 | f2fs_put_page(node_page, 1); |
227 | 225 | ||
228 | /* Deallocate previous index in the node page */ | 226 | /* Deallocate previous index in the node page */ |
229 | inode = f2fs_iget_nowait(sbi->sb, ino); | 227 | inode = f2fs_iget(sbi->sb, ino); |
230 | if (IS_ERR(inode)) | 228 | if (IS_ERR(inode)) |
231 | return; | 229 | return; |
232 | 230 | ||
@@ -373,5 +371,5 @@ void recover_fsync_data(struct f2fs_sb_info *sbi) | |||
373 | out: | 371 | out: |
374 | destroy_fsync_dnodes(sbi, &inode_list); | 372 | destroy_fsync_dnodes(sbi, &inode_list); |
375 | kmem_cache_destroy(fsync_entry_slab); | 373 | kmem_cache_destroy(fsync_entry_slab); |
376 | write_checkpoint(sbi, false, false); | 374 | write_checkpoint(sbi, false); |
377 | } | 375 | } |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 4b0099066582..777f17e496e6 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -29,7 +29,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi) | |||
29 | * We should do GC or end up with checkpoint, if there are so many dirty | 29 | * We should do GC or end up with checkpoint, if there are so many dirty |
30 | * dir/node pages without enough free segments. | 30 | * dir/node pages without enough free segments. |
31 | */ | 31 | */ |
32 | if (has_not_enough_free_secs(sbi)) { | 32 | if (has_not_enough_free_secs(sbi, 0)) { |
33 | mutex_lock(&sbi->gc_mutex); | 33 | mutex_lock(&sbi->gc_mutex); |
34 | f2fs_gc(sbi); | 34 | f2fs_gc(sbi); |
35 | } | 35 | } |
@@ -308,7 +308,7 @@ static unsigned int check_prefree_segments(struct f2fs_sb_info *sbi, | |||
308 | * If there is not enough reserved sections, | 308 | * If there is not enough reserved sections, |
309 | * we should not reuse prefree segments. | 309 | * we should not reuse prefree segments. |
310 | */ | 310 | */ |
311 | if (has_not_enough_free_secs(sbi)) | 311 | if (has_not_enough_free_secs(sbi, 0)) |
312 | return NULL_SEGNO; | 312 | return NULL_SEGNO; |
313 | 313 | ||
314 | /* | 314 | /* |
@@ -536,6 +536,23 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type, bool reuse) | |||
536 | } | 536 | } |
537 | } | 537 | } |
538 | 538 | ||
539 | static int get_ssr_segment(struct f2fs_sb_info *sbi, int type) | ||
540 | { | ||
541 | struct curseg_info *curseg = CURSEG_I(sbi, type); | ||
542 | const struct victim_selection *v_ops = DIRTY_I(sbi)->v_ops; | ||
543 | |||
544 | if (IS_NODESEG(type) || !has_not_enough_free_secs(sbi, 0)) | ||
545 | return v_ops->get_victim(sbi, | ||
546 | &(curseg)->next_segno, BG_GC, type, SSR); | ||
547 | |||
548 | /* For data segments, let's do SSR more intensively */ | ||
549 | for (; type >= CURSEG_HOT_DATA; type--) | ||
550 | if (v_ops->get_victim(sbi, &(curseg)->next_segno, | ||
551 | BG_GC, type, SSR)) | ||
552 | return 1; | ||
553 | return 0; | ||
554 | } | ||
555 | |||
539 | /* | 556 | /* |
540 | * flush out current segment and replace it with new segment | 557 | * flush out current segment and replace it with new segment |
541 | * This function should be returned with success, otherwise BUG | 558 | * This function should be returned with success, otherwise BUG |
@@ -600,6 +617,7 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
600 | if (page->mapping) | 617 | if (page->mapping) |
601 | set_bit(AS_EIO, &page->mapping->flags); | 618 | set_bit(AS_EIO, &page->mapping->flags); |
602 | set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); | 619 | set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); |
620 | p->sbi->sb->s_flags |= MS_RDONLY; | ||
603 | } | 621 | } |
604 | end_page_writeback(page); | 622 | end_page_writeback(page); |
605 | dec_page_count(p->sbi, F2FS_WRITEBACK); | 623 | dec_page_count(p->sbi, F2FS_WRITEBACK); |
@@ -815,15 +833,10 @@ static void do_write_page(struct f2fs_sb_info *sbi, struct page *page, | |||
815 | mutex_unlock(&curseg->curseg_mutex); | 833 | mutex_unlock(&curseg->curseg_mutex); |
816 | } | 834 | } |
817 | 835 | ||
818 | int write_meta_page(struct f2fs_sb_info *sbi, struct page *page, | 836 | void write_meta_page(struct f2fs_sb_info *sbi, struct page *page) |
819 | struct writeback_control *wbc) | ||
820 | { | 837 | { |
821 | if (wbc->for_reclaim) | ||
822 | return AOP_WRITEPAGE_ACTIVATE; | ||
823 | |||
824 | set_page_writeback(page); | 838 | set_page_writeback(page); |
825 | submit_write_page(sbi, page, page->index, META); | 839 | submit_write_page(sbi, page, page->index, META); |
826 | return 0; | ||
827 | } | 840 | } |
828 | 841 | ||
829 | void write_node_page(struct f2fs_sb_info *sbi, struct page *page, | 842 | void write_node_page(struct f2fs_sb_info *sbi, struct page *page, |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 66a288a52fd3..552dadbb2327 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
@@ -450,29 +450,16 @@ static inline bool need_SSR(struct f2fs_sb_info *sbi) | |||
450 | return (free_sections(sbi) < overprovision_sections(sbi)); | 450 | return (free_sections(sbi) < overprovision_sections(sbi)); |
451 | } | 451 | } |
452 | 452 | ||
453 | static inline int get_ssr_segment(struct f2fs_sb_info *sbi, int type) | 453 | static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed) |
454 | { | 454 | { |
455 | struct curseg_info *curseg = CURSEG_I(sbi, type); | 455 | int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); |
456 | return DIRTY_I(sbi)->v_ops->get_victim(sbi, | 456 | int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); |
457 | &(curseg)->next_segno, BG_GC, type, SSR); | ||
458 | } | ||
459 | |||
460 | static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi) | ||
461 | { | ||
462 | unsigned int pages_per_sec = (1 << sbi->log_blocks_per_seg) * | ||
463 | sbi->segs_per_sec; | ||
464 | int node_secs = ((get_pages(sbi, F2FS_DIRTY_NODES) + pages_per_sec - 1) | ||
465 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
466 | int dent_secs = ((get_pages(sbi, F2FS_DIRTY_DENTS) + pages_per_sec - 1) | ||
467 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
468 | 457 | ||
469 | if (sbi->por_doing) | 458 | if (sbi->por_doing) |
470 | return false; | 459 | return false; |
471 | 460 | ||
472 | if (free_sections(sbi) <= (node_secs + 2 * dent_secs + | 461 | return ((free_sections(sbi) + freed) <= (node_secs + 2 * dent_secs + |
473 | reserved_sections(sbi))) | 462 | reserved_sections(sbi))); |
474 | return true; | ||
475 | return false; | ||
476 | } | 463 | } |
477 | 464 | ||
478 | static inline int utilization(struct f2fs_sb_info *sbi) | 465 | static inline int utilization(struct f2fs_sb_info *sbi) |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 37fad04c8669..8c117649a035 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -112,7 +112,7 @@ static void f2fs_put_super(struct super_block *sb) | |||
112 | f2fs_destroy_stats(sbi); | 112 | f2fs_destroy_stats(sbi); |
113 | stop_gc_thread(sbi); | 113 | stop_gc_thread(sbi); |
114 | 114 | ||
115 | write_checkpoint(sbi, false, true); | 115 | write_checkpoint(sbi, true); |
116 | 116 | ||
117 | iput(sbi->node_inode); | 117 | iput(sbi->node_inode); |
118 | iput(sbi->meta_inode); | 118 | iput(sbi->meta_inode); |
@@ -136,13 +136,29 @@ int f2fs_sync_fs(struct super_block *sb, int sync) | |||
136 | return 0; | 136 | return 0; |
137 | 137 | ||
138 | if (sync) | 138 | if (sync) |
139 | write_checkpoint(sbi, false, false); | 139 | write_checkpoint(sbi, false); |
140 | else | 140 | else |
141 | f2fs_balance_fs(sbi); | 141 | f2fs_balance_fs(sbi); |
142 | 142 | ||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int f2fs_freeze(struct super_block *sb) | ||
147 | { | ||
148 | int err; | ||
149 | |||
150 | if (sb->s_flags & MS_RDONLY) | ||
151 | return 0; | ||
152 | |||
153 | err = f2fs_sync_fs(sb, 1); | ||
154 | return err; | ||
155 | } | ||
156 | |||
157 | static int f2fs_unfreeze(struct super_block *sb) | ||
158 | { | ||
159 | return 0; | ||
160 | } | ||
161 | |||
146 | static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) | 162 | static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) |
147 | { | 163 | { |
148 | struct super_block *sb = dentry->d_sb; | 164 | struct super_block *sb = dentry->d_sb; |
@@ -198,7 +214,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) | |||
198 | seq_puts(seq, ",noacl"); | 214 | seq_puts(seq, ",noacl"); |
199 | #endif | 215 | #endif |
200 | if (test_opt(sbi, DISABLE_EXT_IDENTIFY)) | 216 | if (test_opt(sbi, DISABLE_EXT_IDENTIFY)) |
201 | seq_puts(seq, ",disable_ext_indentify"); | 217 | seq_puts(seq, ",disable_ext_identify"); |
202 | 218 | ||
203 | seq_printf(seq, ",active_logs=%u", sbi->active_logs); | 219 | seq_printf(seq, ",active_logs=%u", sbi->active_logs); |
204 | 220 | ||
@@ -213,6 +229,8 @@ static struct super_operations f2fs_sops = { | |||
213 | .evict_inode = f2fs_evict_inode, | 229 | .evict_inode = f2fs_evict_inode, |
214 | .put_super = f2fs_put_super, | 230 | .put_super = f2fs_put_super, |
215 | .sync_fs = f2fs_sync_fs, | 231 | .sync_fs = f2fs_sync_fs, |
232 | .freeze_fs = f2fs_freeze, | ||
233 | .unfreeze_fs = f2fs_unfreeze, | ||
216 | .statfs = f2fs_statfs, | 234 | .statfs = f2fs_statfs, |
217 | }; | 235 | }; |
218 | 236 | ||
@@ -366,14 +384,23 @@ static int sanity_check_raw_super(struct super_block *sb, | |||
366 | return 1; | 384 | return 1; |
367 | } | 385 | } |
368 | 386 | ||
387 | /* Currently, support only 4KB page cache size */ | ||
388 | if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) { | ||
389 | f2fs_msg(sb, KERN_INFO, | ||
390 | "Invalid page_cache_size (%lu), supports only 4KB\n", | ||
391 | PAGE_CACHE_SIZE); | ||
392 | return 1; | ||
393 | } | ||
394 | |||
369 | /* Currently, support only 4KB block size */ | 395 | /* Currently, support only 4KB block size */ |
370 | blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); | 396 | blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); |
371 | if (blocksize != PAGE_CACHE_SIZE) { | 397 | if (blocksize != F2FS_BLKSIZE) { |
372 | f2fs_msg(sb, KERN_INFO, | 398 | f2fs_msg(sb, KERN_INFO, |
373 | "Invalid blocksize (%u), supports only 4KB\n", | 399 | "Invalid blocksize (%u), supports only 4KB\n", |
374 | blocksize); | 400 | blocksize); |
375 | return 1; | 401 | return 1; |
376 | } | 402 | } |
403 | |||
377 | if (le32_to_cpu(raw_super->log_sectorsize) != | 404 | if (le32_to_cpu(raw_super->log_sectorsize) != |
378 | F2FS_LOG_SECTOR_SIZE) { | 405 | F2FS_LOG_SECTOR_SIZE) { |
379 | f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize"); | 406 | f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize"); |
@@ -387,10 +414,11 @@ static int sanity_check_raw_super(struct super_block *sb, | |||
387 | return 0; | 414 | return 0; |
388 | } | 415 | } |
389 | 416 | ||
390 | static int sanity_check_ckpt(struct f2fs_super_block *raw_super, | 417 | static int sanity_check_ckpt(struct f2fs_sb_info *sbi) |
391 | struct f2fs_checkpoint *ckpt) | ||
392 | { | 418 | { |
393 | unsigned int total, fsmeta; | 419 | unsigned int total, fsmeta; |
420 | struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); | ||
421 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); | ||
394 | 422 | ||
395 | total = le32_to_cpu(raw_super->segment_count); | 423 | total = le32_to_cpu(raw_super->segment_count); |
396 | fsmeta = le32_to_cpu(raw_super->segment_count_ckpt); | 424 | fsmeta = le32_to_cpu(raw_super->segment_count_ckpt); |
@@ -401,6 +429,11 @@ static int sanity_check_ckpt(struct f2fs_super_block *raw_super, | |||
401 | 429 | ||
402 | if (fsmeta >= total) | 430 | if (fsmeta >= total) |
403 | return 1; | 431 | return 1; |
432 | |||
433 | if (is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) { | ||
434 | f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); | ||
435 | return 1; | ||
436 | } | ||
404 | return 0; | 437 | return 0; |
405 | } | 438 | } |
406 | 439 | ||
@@ -429,6 +462,32 @@ static void init_sb_info(struct f2fs_sb_info *sbi) | |||
429 | atomic_set(&sbi->nr_pages[i], 0); | 462 | atomic_set(&sbi->nr_pages[i], 0); |
430 | } | 463 | } |
431 | 464 | ||
465 | static int validate_superblock(struct super_block *sb, | ||
466 | struct f2fs_super_block **raw_super, | ||
467 | struct buffer_head **raw_super_buf, sector_t block) | ||
468 | { | ||
469 | const char *super = (block == 0 ? "first" : "second"); | ||
470 | |||
471 | /* read f2fs raw super block */ | ||
472 | *raw_super_buf = sb_bread(sb, block); | ||
473 | if (!*raw_super_buf) { | ||
474 | f2fs_msg(sb, KERN_ERR, "unable to read %s superblock", | ||
475 | super); | ||
476 | return 1; | ||
477 | } | ||
478 | |||
479 | *raw_super = (struct f2fs_super_block *) | ||
480 | ((char *)(*raw_super_buf)->b_data + F2FS_SUPER_OFFSET); | ||
481 | |||
482 | /* sanity checking of raw super */ | ||
483 | if (!sanity_check_raw_super(sb, *raw_super)) | ||
484 | return 0; | ||
485 | |||
486 | f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem " | ||
487 | "in %s superblock", super); | ||
488 | return 1; | ||
489 | } | ||
490 | |||
432 | static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | 491 | static int f2fs_fill_super(struct super_block *sb, void *data, int silent) |
433 | { | 492 | { |
434 | struct f2fs_sb_info *sbi; | 493 | struct f2fs_sb_info *sbi; |
@@ -449,16 +508,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
449 | goto free_sbi; | 508 | goto free_sbi; |
450 | } | 509 | } |
451 | 510 | ||
452 | /* read f2fs raw super block */ | 511 | if (validate_superblock(sb, &raw_super, &raw_super_buf, 0)) { |
453 | raw_super_buf = sb_bread(sb, 0); | 512 | brelse(raw_super_buf); |
454 | if (!raw_super_buf) { | 513 | if (validate_superblock(sb, &raw_super, &raw_super_buf, 1)) |
455 | err = -EIO; | 514 | goto free_sb_buf; |
456 | f2fs_msg(sb, KERN_ERR, "unable to read superblock"); | ||
457 | goto free_sbi; | ||
458 | } | 515 | } |
459 | raw_super = (struct f2fs_super_block *) | ||
460 | ((char *)raw_super_buf->b_data + F2FS_SUPER_OFFSET); | ||
461 | |||
462 | /* init some FS parameters */ | 516 | /* init some FS parameters */ |
463 | sbi->active_logs = NR_CURSEG_TYPE; | 517 | sbi->active_logs = NR_CURSEG_TYPE; |
464 | 518 | ||
@@ -474,12 +528,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
474 | if (parse_options(sb, sbi, (char *)data)) | 528 | if (parse_options(sb, sbi, (char *)data)) |
475 | goto free_sb_buf; | 529 | goto free_sb_buf; |
476 | 530 | ||
477 | /* sanity checking of raw super */ | ||
478 | if (sanity_check_raw_super(sb, raw_super)) { | ||
479 | f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem"); | ||
480 | goto free_sb_buf; | ||
481 | } | ||
482 | |||
483 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); | 531 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); |
484 | sb->s_max_links = F2FS_LINK_MAX; | 532 | sb->s_max_links = F2FS_LINK_MAX; |
485 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 533 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
@@ -525,7 +573,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
525 | 573 | ||
526 | /* sanity checking of checkpoint */ | 574 | /* sanity checking of checkpoint */ |
527 | err = -EINVAL; | 575 | err = -EINVAL; |
528 | if (sanity_check_ckpt(raw_super, sbi->ckpt)) { | 576 | if (sanity_check_ckpt(sbi)) { |
529 | f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint"); | 577 | f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint"); |
530 | goto free_cp; | 578 | goto free_cp; |
531 | } | 579 | } |