diff options
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/acl.c | 13 | ||||
-rw-r--r-- | fs/f2fs/checkpoint.c | 3 | ||||
-rw-r--r-- | fs/f2fs/data.c | 17 | ||||
-rw-r--r-- | fs/f2fs/debug.c | 50 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 2 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 18 | ||||
-rw-r--r-- | fs/f2fs/file.c | 16 | ||||
-rw-r--r-- | fs/f2fs/gc.c | 68 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 3 | ||||
-rw-r--r-- | fs/f2fs/node.c | 19 | ||||
-rw-r--r-- | fs/f2fs/recovery.c | 10 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 2 | ||||
-rw-r--r-- | fs/f2fs/super.c | 97 | ||||
-rw-r--r-- | fs/f2fs/xattr.c | 2 |
14 files changed, 189 insertions, 131 deletions
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index e95b94945d5f..137af4255da6 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c | |||
@@ -191,15 +191,14 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type) | |||
191 | retval = f2fs_getxattr(inode, name_index, "", value, retval); | 191 | retval = f2fs_getxattr(inode, name_index, "", value, retval); |
192 | } | 192 | } |
193 | 193 | ||
194 | if (retval < 0) { | 194 | if (retval > 0) |
195 | if (retval == -ENODATA) | ||
196 | acl = NULL; | ||
197 | else | ||
198 | acl = ERR_PTR(retval); | ||
199 | } else { | ||
200 | acl = f2fs_acl_from_disk(value, retval); | 195 | acl = f2fs_acl_from_disk(value, retval); |
201 | } | 196 | else if (retval == -ENODATA) |
197 | acl = NULL; | ||
198 | else | ||
199 | acl = ERR_PTR(retval); | ||
202 | kfree(value); | 200 | kfree(value); |
201 | |||
203 | if (!IS_ERR(acl)) | 202 | if (!IS_ERR(acl)) |
204 | set_cached_acl(inode, type, acl); | 203 | set_cached_acl(inode, type, acl); |
205 | 204 | ||
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 6ef36c37e2be..ff3c8439af87 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -214,7 +214,6 @@ retry: | |||
214 | goto retry; | 214 | goto retry; |
215 | } | 215 | } |
216 | new->ino = ino; | 216 | new->ino = ino; |
217 | INIT_LIST_HEAD(&new->list); | ||
218 | 217 | ||
219 | /* add new_oentry into list which is sorted by inode number */ | 218 | /* add new_oentry into list which is sorted by inode number */ |
220 | if (orphan) { | 219 | if (orphan) { |
@@ -772,7 +771,7 @@ void init_orphan_info(struct f2fs_sb_info *sbi) | |||
772 | sbi->n_orphans = 0; | 771 | sbi->n_orphans = 0; |
773 | } | 772 | } |
774 | 773 | ||
775 | int create_checkpoint_caches(void) | 774 | int __init create_checkpoint_caches(void) |
776 | { | 775 | { |
777 | orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry", | 776 | orphan_entry_slab = f2fs_kmem_cache_create("f2fs_orphan_entry", |
778 | sizeof(struct orphan_inode_entry), NULL); | 777 | sizeof(struct orphan_inode_entry), NULL); |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3aa5ce7cab83..7bd22a201125 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -547,6 +547,15 @@ redirty_out: | |||
547 | 547 | ||
548 | #define MAX_DESIRED_PAGES_WP 4096 | 548 | #define MAX_DESIRED_PAGES_WP 4096 |
549 | 549 | ||
550 | static int __f2fs_writepage(struct page *page, struct writeback_control *wbc, | ||
551 | void *data) | ||
552 | { | ||
553 | struct address_space *mapping = data; | ||
554 | int ret = mapping->a_ops->writepage(page, wbc); | ||
555 | mapping_set_error(mapping, ret); | ||
556 | return ret; | ||
557 | } | ||
558 | |||
550 | static int f2fs_write_data_pages(struct address_space *mapping, | 559 | static int f2fs_write_data_pages(struct address_space *mapping, |
551 | struct writeback_control *wbc) | 560 | struct writeback_control *wbc) |
552 | { | 561 | { |
@@ -563,7 +572,7 @@ static int f2fs_write_data_pages(struct address_space *mapping, | |||
563 | 572 | ||
564 | if (!S_ISDIR(inode->i_mode)) | 573 | if (!S_ISDIR(inode->i_mode)) |
565 | mutex_lock(&sbi->writepages); | 574 | mutex_lock(&sbi->writepages); |
566 | ret = generic_writepages(mapping, wbc); | 575 | ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping); |
567 | if (!S_ISDIR(inode->i_mode)) | 576 | if (!S_ISDIR(inode->i_mode)) |
568 | mutex_unlock(&sbi->writepages); | 577 | mutex_unlock(&sbi->writepages); |
569 | f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL)); | 578 | f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL)); |
@@ -689,6 +698,11 @@ static int f2fs_set_data_page_dirty(struct page *page) | |||
689 | return 0; | 698 | return 0; |
690 | } | 699 | } |
691 | 700 | ||
701 | static sector_t f2fs_bmap(struct address_space *mapping, sector_t block) | ||
702 | { | ||
703 | return generic_block_bmap(mapping, block, get_data_block_ro); | ||
704 | } | ||
705 | |||
692 | const struct address_space_operations f2fs_dblock_aops = { | 706 | const struct address_space_operations f2fs_dblock_aops = { |
693 | .readpage = f2fs_read_data_page, | 707 | .readpage = f2fs_read_data_page, |
694 | .readpages = f2fs_read_data_pages, | 708 | .readpages = f2fs_read_data_pages, |
@@ -700,4 +714,5 @@ const struct address_space_operations f2fs_dblock_aops = { | |||
700 | .invalidatepage = f2fs_invalidate_data_page, | 714 | .invalidatepage = f2fs_invalidate_data_page, |
701 | .releasepage = f2fs_release_data_page, | 715 | .releasepage = f2fs_release_data_page, |
702 | .direct_IO = f2fs_direct_IO, | 716 | .direct_IO = f2fs_direct_IO, |
717 | .bmap = f2fs_bmap, | ||
703 | }; | 718 | }; |
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 0e0380a588ad..c8c37307b326 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | static LIST_HEAD(f2fs_stat_list); | 27 | static LIST_HEAD(f2fs_stat_list); |
28 | static struct dentry *debugfs_root; | 28 | static struct dentry *debugfs_root; |
29 | static DEFINE_MUTEX(f2fs_stat_mutex); | ||
29 | 30 | ||
30 | static void update_general_status(struct f2fs_sb_info *sbi) | 31 | static void update_general_status(struct f2fs_sb_info *sbi) |
31 | { | 32 | { |
@@ -180,18 +181,14 @@ static int stat_show(struct seq_file *s, void *v) | |||
180 | int i = 0; | 181 | int i = 0; |
181 | int j; | 182 | int j; |
182 | 183 | ||
184 | mutex_lock(&f2fs_stat_mutex); | ||
183 | 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) { |
184 | 186 | ||
185 | mutex_lock(&si->stat_lock); | ||
186 | if (!si->sbi) { | ||
187 | mutex_unlock(&si->stat_lock); | ||
188 | continue; | ||
189 | } | ||
190 | update_general_status(si->sbi); | 187 | update_general_status(si->sbi); |
191 | 188 | ||
192 | seq_printf(s, "\n=====[ partition info. #%d ]=====\n", i++); | 189 | seq_printf(s, "\n=====[ partition info. #%d ]=====\n", i++); |
193 | seq_printf(s, "[SB: 1] [CP: 2] [NAT: %d] [SIT: %d] ", | 190 | seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ", |
194 | si->nat_area_segs, si->sit_area_segs); | 191 | si->sit_area_segs, si->nat_area_segs); |
195 | seq_printf(s, "[SSA: %d] [MAIN: %d", | 192 | seq_printf(s, "[SSA: %d] [MAIN: %d", |
196 | si->ssa_area_segs, si->main_area_segs); | 193 | si->ssa_area_segs, si->main_area_segs); |
197 | seq_printf(s, "(OverProv:%d Resv:%d)]\n\n", | 194 | seq_printf(s, "(OverProv:%d Resv:%d)]\n\n", |
@@ -286,8 +283,8 @@ static int stat_show(struct seq_file *s, void *v) | |||
286 | seq_printf(s, "\nMemory: %u KB = static: %u + cached: %u\n", | 283 | seq_printf(s, "\nMemory: %u KB = static: %u + cached: %u\n", |
287 | (si->base_mem + si->cache_mem) >> 10, | 284 | (si->base_mem + si->cache_mem) >> 10, |
288 | si->base_mem >> 10, si->cache_mem >> 10); | 285 | si->base_mem >> 10, si->cache_mem >> 10); |
289 | mutex_unlock(&si->stat_lock); | ||
290 | } | 286 | } |
287 | mutex_unlock(&f2fs_stat_mutex); | ||
291 | return 0; | 288 | return 0; |
292 | } | 289 | } |
293 | 290 | ||
@@ -303,7 +300,7 @@ static const struct file_operations stat_fops = { | |||
303 | .release = single_release, | 300 | .release = single_release, |
304 | }; | 301 | }; |
305 | 302 | ||
306 | static int init_stats(struct f2fs_sb_info *sbi) | 303 | int f2fs_build_stats(struct f2fs_sb_info *sbi) |
307 | { | 304 | { |
308 | struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); | 305 | struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi); |
309 | struct f2fs_stat_info *si; | 306 | struct f2fs_stat_info *si; |
@@ -313,9 +310,6 @@ static int init_stats(struct f2fs_sb_info *sbi) | |||
313 | return -ENOMEM; | 310 | return -ENOMEM; |
314 | 311 | ||
315 | si = sbi->stat_info; | 312 | si = sbi->stat_info; |
316 | mutex_init(&si->stat_lock); | ||
317 | list_add_tail(&si->stat_list, &f2fs_stat_list); | ||
318 | |||
319 | si->all_area_segs = le32_to_cpu(raw_super->segment_count); | 313 | si->all_area_segs = le32_to_cpu(raw_super->segment_count); |
320 | si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit); | 314 | si->sit_area_segs = le32_to_cpu(raw_super->segment_count_sit); |
321 | si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat); | 315 | si->nat_area_segs = le32_to_cpu(raw_super->segment_count_nat); |
@@ -325,21 +319,11 @@ static int init_stats(struct f2fs_sb_info *sbi) | |||
325 | si->main_area_zones = si->main_area_sections / | 319 | si->main_area_zones = si->main_area_sections / |
326 | le32_to_cpu(raw_super->secs_per_zone); | 320 | le32_to_cpu(raw_super->secs_per_zone); |
327 | si->sbi = sbi; | 321 | si->sbi = sbi; |
328 | return 0; | ||
329 | } | ||
330 | 322 | ||
331 | int f2fs_build_stats(struct f2fs_sb_info *sbi) | 323 | mutex_lock(&f2fs_stat_mutex); |
332 | { | 324 | list_add_tail(&si->stat_list, &f2fs_stat_list); |
333 | int retval; | 325 | mutex_unlock(&f2fs_stat_mutex); |
334 | |||
335 | retval = init_stats(sbi); | ||
336 | if (retval) | ||
337 | return retval; | ||
338 | |||
339 | if (!debugfs_root) | ||
340 | debugfs_root = debugfs_create_dir("f2fs", NULL); | ||
341 | 326 | ||
342 | debugfs_create_file("status", S_IRUGO, debugfs_root, NULL, &stat_fops); | ||
343 | return 0; | 327 | return 0; |
344 | } | 328 | } |
345 | 329 | ||
@@ -347,14 +331,22 @@ void f2fs_destroy_stats(struct f2fs_sb_info *sbi) | |||
347 | { | 331 | { |
348 | struct f2fs_stat_info *si = sbi->stat_info; | 332 | struct f2fs_stat_info *si = sbi->stat_info; |
349 | 333 | ||
334 | mutex_lock(&f2fs_stat_mutex); | ||
350 | list_del(&si->stat_list); | 335 | list_del(&si->stat_list); |
351 | mutex_lock(&si->stat_lock); | 336 | mutex_unlock(&f2fs_stat_mutex); |
352 | si->sbi = NULL; | 337 | |
353 | mutex_unlock(&si->stat_lock); | ||
354 | kfree(sbi->stat_info); | 338 | kfree(sbi->stat_info); |
355 | } | 339 | } |
356 | 340 | ||
357 | void destroy_root_stats(void) | 341 | void __init f2fs_create_root_stats(void) |
342 | { | ||
343 | debugfs_root = debugfs_create_dir("f2fs", NULL); | ||
344 | if (debugfs_root) | ||
345 | debugfs_create_file("status", S_IRUGO, debugfs_root, | ||
346 | NULL, &stat_fops); | ||
347 | } | ||
348 | |||
349 | void f2fs_destroy_root_stats(void) | ||
358 | { | 350 | { |
359 | debugfs_remove_recursive(debugfs_root); | 351 | debugfs_remove_recursive(debugfs_root); |
360 | debugfs_root = NULL; | 352 | debugfs_root = NULL; |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 951ed52748f6..989980e16d0b 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -503,7 +503,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
503 | } | 503 | } |
504 | 504 | ||
505 | if (inode) { | 505 | if (inode) { |
506 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 506 | inode->i_ctime = CURRENT_TIME; |
507 | drop_nlink(inode); | 507 | drop_nlink(inode); |
508 | if (S_ISDIR(inode->i_mode)) { | 508 | if (S_ISDIR(inode->i_mode)) { |
509 | drop_nlink(inode); | 509 | drop_nlink(inode); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 13c6dfbb7183..c8e2d751ef9c 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -211,11 +211,11 @@ struct dnode_of_data { | |||
211 | static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode, | 211 | static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode, |
212 | struct page *ipage, struct page *npage, nid_t nid) | 212 | struct page *ipage, struct page *npage, nid_t nid) |
213 | { | 213 | { |
214 | memset(dn, 0, sizeof(*dn)); | ||
214 | dn->inode = inode; | 215 | dn->inode = inode; |
215 | dn->inode_page = ipage; | 216 | dn->inode_page = ipage; |
216 | dn->node_page = npage; | 217 | dn->node_page = npage; |
217 | dn->nid = nid; | 218 | dn->nid = nid; |
218 | dn->inode_page_locked = 0; | ||
219 | } | 219 | } |
220 | 220 | ||
221 | /* | 221 | /* |
@@ -877,6 +877,8 @@ bool f2fs_empty_dir(struct inode *); | |||
877 | * super.c | 877 | * super.c |
878 | */ | 878 | */ |
879 | int f2fs_sync_fs(struct super_block *, int); | 879 | int f2fs_sync_fs(struct super_block *, int); |
880 | extern __printf(3, 4) | ||
881 | void f2fs_msg(struct super_block *, const char *, const char *, ...); | ||
880 | 882 | ||
881 | /* | 883 | /* |
882 | * hash.c | 884 | * hash.c |
@@ -912,7 +914,7 @@ int restore_node_summary(struct f2fs_sb_info *, unsigned int, | |||
912 | void flush_nat_entries(struct f2fs_sb_info *); | 914 | void flush_nat_entries(struct f2fs_sb_info *); |
913 | int build_node_manager(struct f2fs_sb_info *); | 915 | int build_node_manager(struct f2fs_sb_info *); |
914 | void destroy_node_manager(struct f2fs_sb_info *); | 916 | void destroy_node_manager(struct f2fs_sb_info *); |
915 | int create_node_manager_caches(void); | 917 | int __init create_node_manager_caches(void); |
916 | void destroy_node_manager_caches(void); | 918 | void destroy_node_manager_caches(void); |
917 | 919 | ||
918 | /* | 920 | /* |
@@ -964,7 +966,7 @@ void sync_dirty_dir_inodes(struct f2fs_sb_info *); | |||
964 | void block_operations(struct f2fs_sb_info *); | 966 | void block_operations(struct f2fs_sb_info *); |
965 | void write_checkpoint(struct f2fs_sb_info *, bool, bool); | 967 | void write_checkpoint(struct f2fs_sb_info *, bool, bool); |
966 | void init_orphan_info(struct f2fs_sb_info *); | 968 | void init_orphan_info(struct f2fs_sb_info *); |
967 | int create_checkpoint_caches(void); | 969 | int __init create_checkpoint_caches(void); |
968 | void destroy_checkpoint_caches(void); | 970 | void destroy_checkpoint_caches(void); |
969 | 971 | ||
970 | /* | 972 | /* |
@@ -984,9 +986,9 @@ int do_write_data_page(struct page *); | |||
984 | int start_gc_thread(struct f2fs_sb_info *); | 986 | int start_gc_thread(struct f2fs_sb_info *); |
985 | void stop_gc_thread(struct f2fs_sb_info *); | 987 | void stop_gc_thread(struct f2fs_sb_info *); |
986 | block_t start_bidx_of_node(unsigned int); | 988 | block_t start_bidx_of_node(unsigned int); |
987 | int f2fs_gc(struct f2fs_sb_info *, int); | 989 | int f2fs_gc(struct f2fs_sb_info *); |
988 | void build_gc_manager(struct f2fs_sb_info *); | 990 | void build_gc_manager(struct f2fs_sb_info *); |
989 | int create_gc_caches(void); | 991 | int __init create_gc_caches(void); |
990 | void destroy_gc_caches(void); | 992 | void destroy_gc_caches(void); |
991 | 993 | ||
992 | /* | 994 | /* |
@@ -1058,7 +1060,8 @@ struct f2fs_stat_info { | |||
1058 | 1060 | ||
1059 | int f2fs_build_stats(struct f2fs_sb_info *); | 1061 | int f2fs_build_stats(struct f2fs_sb_info *); |
1060 | void f2fs_destroy_stats(struct f2fs_sb_info *); | 1062 | void f2fs_destroy_stats(struct f2fs_sb_info *); |
1061 | void destroy_root_stats(void); | 1063 | void __init f2fs_create_root_stats(void); |
1064 | void f2fs_destroy_root_stats(void); | ||
1062 | #else | 1065 | #else |
1063 | #define stat_inc_call_count(si) | 1066 | #define stat_inc_call_count(si) |
1064 | #define stat_inc_seg_count(si, type) | 1067 | #define stat_inc_seg_count(si, type) |
@@ -1068,7 +1071,8 @@ void destroy_root_stats(void); | |||
1068 | 1071 | ||
1069 | static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; } | 1072 | static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; } |
1070 | static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { } | 1073 | static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { } |
1071 | static inline void destroy_root_stats(void) { } | 1074 | static inline void __init f2fs_create_root_stats(void) { } |
1075 | static inline void f2fs_destroy_root_stats(void) { } | ||
1072 | #endif | 1076 | #endif |
1073 | 1077 | ||
1074 | extern const struct file_operations f2fs_dir_operations; | 1078 | extern const struct file_operations f2fs_dir_operations; |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7f9ea9271ebe..3191b52aafb0 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -96,8 +96,9 @@ out: | |||
96 | } | 96 | } |
97 | 97 | ||
98 | static const struct vm_operations_struct f2fs_file_vm_ops = { | 98 | static const struct vm_operations_struct f2fs_file_vm_ops = { |
99 | .fault = filemap_fault, | 99 | .fault = filemap_fault, |
100 | .page_mkwrite = f2fs_vm_page_mkwrite, | 100 | .page_mkwrite = f2fs_vm_page_mkwrite, |
101 | .remap_pages = generic_file_remap_pages, | ||
101 | }; | 102 | }; |
102 | 103 | ||
103 | static int need_to_sync_dir(struct f2fs_sb_info *sbi, struct inode *inode) | 104 | static int need_to_sync_dir(struct f2fs_sb_info *sbi, struct inode *inode) |
@@ -137,6 +138,9 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
137 | if (ret) | 138 | if (ret) |
138 | return ret; | 139 | return ret; |
139 | 140 | ||
141 | /* guarantee free sections for fsync */ | ||
142 | f2fs_balance_fs(sbi); | ||
143 | |||
140 | mutex_lock(&inode->i_mutex); | 144 | mutex_lock(&inode->i_mutex); |
141 | 145 | ||
142 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) | 146 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) |
@@ -407,6 +411,8 @@ int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end) | |||
407 | struct dnode_of_data dn; | 411 | struct dnode_of_data dn; |
408 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | 412 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); |
409 | 413 | ||
414 | f2fs_balance_fs(sbi); | ||
415 | |||
410 | mutex_lock_op(sbi, DATA_TRUNC); | 416 | mutex_lock_op(sbi, DATA_TRUNC); |
411 | set_new_dnode(&dn, inode, NULL, NULL, 0); | 417 | set_new_dnode(&dn, inode, NULL, NULL, 0); |
412 | err = get_dnode_of_data(&dn, index, RDONLY_NODE); | 418 | err = get_dnode_of_data(&dn, index, RDONLY_NODE); |
@@ -534,7 +540,6 @@ static long f2fs_fallocate(struct file *file, int mode, | |||
534 | loff_t offset, loff_t len) | 540 | loff_t offset, loff_t len) |
535 | { | 541 | { |
536 | struct inode *inode = file->f_path.dentry->d_inode; | 542 | struct inode *inode = file->f_path.dentry->d_inode; |
537 | struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); | ||
538 | long ret; | 543 | long ret; |
539 | 544 | ||
540 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) | 545 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) |
@@ -545,7 +550,10 @@ static long f2fs_fallocate(struct file *file, int mode, | |||
545 | else | 550 | else |
546 | ret = expand_inode_data(inode, offset, len, mode); | 551 | ret = expand_inode_data(inode, offset, len, mode); |
547 | 552 | ||
548 | f2fs_balance_fs(sbi); | 553 | if (!ret) { |
554 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
555 | mark_inode_dirty(inode); | ||
556 | } | ||
549 | return ret; | 557 | return ret; |
550 | } | 558 | } |
551 | 559 | ||
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index b0ec721e984a..c386910dacc5 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
@@ -78,7 +78,7 @@ static int gc_thread_func(void *data) | |||
78 | 78 | ||
79 | sbi->bg_gc++; | 79 | sbi->bg_gc++; |
80 | 80 | ||
81 | if (f2fs_gc(sbi, 1) == GC_NONE) | 81 | if (f2fs_gc(sbi) == GC_NONE) |
82 | wait_ms = GC_THREAD_NOGC_SLEEP_TIME; | 82 | wait_ms = GC_THREAD_NOGC_SLEEP_TIME; |
83 | else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) | 83 | else if (wait_ms == GC_THREAD_NOGC_SLEEP_TIME) |
84 | wait_ms = GC_THREAD_MAX_SLEEP_TIME; | 84 | wait_ms = GC_THREAD_MAX_SLEEP_TIME; |
@@ -424,7 +424,11 @@ next_step: | |||
424 | } | 424 | } |
425 | 425 | ||
426 | /* | 426 | /* |
427 | * Calculate start block index that this node page contains | 427 | * Calculate start block index indicating the given node offset. |
428 | * Be careful, caller should give this node offset only indicating direct node | ||
429 | * blocks. If any node offsets, which point the other types of node blocks such | ||
430 | * as indirect or double indirect node blocks, are given, it must be a caller's | ||
431 | * bug. | ||
428 | */ | 432 | */ |
429 | block_t start_bidx_of_node(unsigned int node_ofs) | 433 | block_t start_bidx_of_node(unsigned int node_ofs) |
430 | { | 434 | { |
@@ -651,62 +655,44 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, unsigned int segno, | |||
651 | return ret; | 655 | return ret; |
652 | } | 656 | } |
653 | 657 | ||
654 | int f2fs_gc(struct f2fs_sb_info *sbi, int nGC) | 658 | int f2fs_gc(struct f2fs_sb_info *sbi) |
655 | { | 659 | { |
656 | unsigned int segno; | ||
657 | int old_free_secs, cur_free_secs; | ||
658 | int gc_status, nfree; | ||
659 | struct list_head ilist; | 660 | struct list_head ilist; |
661 | unsigned int segno, i; | ||
660 | int gc_type = BG_GC; | 662 | int gc_type = BG_GC; |
663 | int gc_status = GC_NONE; | ||
661 | 664 | ||
662 | INIT_LIST_HEAD(&ilist); | 665 | INIT_LIST_HEAD(&ilist); |
663 | gc_more: | 666 | gc_more: |
664 | nfree = 0; | 667 | if (!(sbi->sb->s_flags & MS_ACTIVE)) |
665 | gc_status = GC_NONE; | 668 | goto stop; |
666 | 669 | ||
667 | if (has_not_enough_free_secs(sbi)) | 670 | if (has_not_enough_free_secs(sbi)) |
668 | old_free_secs = reserved_sections(sbi); | 671 | gc_type = FG_GC; |
669 | else | ||
670 | old_free_secs = free_sections(sbi); | ||
671 | |||
672 | while (sbi->sb->s_flags & MS_ACTIVE) { | ||
673 | int i; | ||
674 | if (has_not_enough_free_secs(sbi)) | ||
675 | gc_type = FG_GC; | ||
676 | 672 | ||
677 | cur_free_secs = free_sections(sbi) + nfree; | 673 | if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) |
674 | goto stop; | ||
678 | 675 | ||
679 | /* We got free space successfully. */ | 676 | for (i = 0; i < sbi->segs_per_sec; i++) { |
680 | if (nGC < cur_free_secs - old_free_secs) | 677 | /* |
681 | break; | 678 | * do_garbage_collect will give us three gc_status: |
682 | 679 | * GC_ERROR, GC_DONE, and GC_BLOCKED. | |
683 | if (!__get_victim(sbi, &segno, gc_type, NO_CHECK_TYPE)) | 680 | * If GC is finished uncleanly, we have to return |
681 | * the victim to dirty segment list. | ||
682 | */ | ||
683 | gc_status = do_garbage_collect(sbi, segno + i, &ilist, gc_type); | ||
684 | if (gc_status != GC_DONE) | ||
684 | break; | 685 | break; |
685 | |||
686 | for (i = 0; i < sbi->segs_per_sec; i++) { | ||
687 | /* | ||
688 | * do_garbage_collect will give us three gc_status: | ||
689 | * GC_ERROR, GC_DONE, and GC_BLOCKED. | ||
690 | * If GC is finished uncleanly, we have to return | ||
691 | * the victim to dirty segment list. | ||
692 | */ | ||
693 | gc_status = do_garbage_collect(sbi, segno + i, | ||
694 | &ilist, gc_type); | ||
695 | if (gc_status != GC_DONE) | ||
696 | goto stop; | ||
697 | nfree++; | ||
698 | } | ||
699 | } | 686 | } |
700 | stop: | 687 | if (has_not_enough_free_secs(sbi)) { |
701 | if (has_not_enough_free_secs(sbi) || gc_status == GC_BLOCKED) { | ||
702 | write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); | 688 | write_checkpoint(sbi, (gc_status == GC_BLOCKED), false); |
703 | if (nfree) | 689 | if (has_not_enough_free_secs(sbi)) |
704 | goto gc_more; | 690 | goto gc_more; |
705 | } | 691 | } |
692 | stop: | ||
706 | mutex_unlock(&sbi->gc_mutex); | 693 | mutex_unlock(&sbi->gc_mutex); |
707 | 694 | ||
708 | put_gc_inode(&ilist); | 695 | put_gc_inode(&ilist); |
709 | BUG_ON(!list_empty(&ilist)); | ||
710 | return gc_status; | 696 | return gc_status; |
711 | } | 697 | } |
712 | 698 | ||
@@ -715,7 +701,7 @@ void build_gc_manager(struct f2fs_sb_info *sbi) | |||
715 | DIRTY_I(sbi)->v_ops = &default_v_ops; | 701 | DIRTY_I(sbi)->v_ops = &default_v_ops; |
716 | } | 702 | } |
717 | 703 | ||
718 | int create_gc_caches(void) | 704 | int __init create_gc_caches(void) |
719 | { | 705 | { |
720 | winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", | 706 | winode_slab = f2fs_kmem_cache_create("f2fs_gc_inodes", |
721 | sizeof(struct inode_entry), NULL); | 707 | sizeof(struct inode_entry), NULL); |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index bf20b4d03214..794241777322 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
@@ -217,6 +217,9 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
217 | inode->i_ino == F2FS_META_INO(sbi)) | 217 | inode->i_ino == F2FS_META_INO(sbi)) |
218 | return 0; | 218 | return 0; |
219 | 219 | ||
220 | if (wbc) | ||
221 | f2fs_balance_fs(sbi); | ||
222 | |||
220 | node_page = get_node_page(sbi, inode->i_ino); | 223 | node_page = get_node_page(sbi, inode->i_ino); |
221 | if (IS_ERR(node_page)) | 224 | if (IS_ERR(node_page)) |
222 | return PTR_ERR(node_page); | 225 | return PTR_ERR(node_page); |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 5066bfd256c9..9bda63c9c166 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -1124,6 +1124,12 @@ static int f2fs_write_node_page(struct page *page, | |||
1124 | return 0; | 1124 | return 0; |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | /* | ||
1128 | * It is very important to gather dirty pages and write at once, so that we can | ||
1129 | * submit a big bio without interfering other data writes. | ||
1130 | * Be default, 512 pages (2MB), a segment size, is quite reasonable. | ||
1131 | */ | ||
1132 | #define COLLECT_DIRTY_NODES 512 | ||
1127 | static int f2fs_write_node_pages(struct address_space *mapping, | 1133 | static int f2fs_write_node_pages(struct address_space *mapping, |
1128 | struct writeback_control *wbc) | 1134 | struct writeback_control *wbc) |
1129 | { | 1135 | { |
@@ -1131,17 +1137,16 @@ static int f2fs_write_node_pages(struct address_space *mapping, | |||
1131 | struct block_device *bdev = sbi->sb->s_bdev; | 1137 | struct block_device *bdev = sbi->sb->s_bdev; |
1132 | long nr_to_write = wbc->nr_to_write; | 1138 | long nr_to_write = wbc->nr_to_write; |
1133 | 1139 | ||
1134 | if (wbc->for_kupdate) | 1140 | /* First check balancing cached NAT entries */ |
1135 | return 0; | ||
1136 | |||
1137 | if (get_pages(sbi, F2FS_DIRTY_NODES) == 0) | ||
1138 | return 0; | ||
1139 | |||
1140 | if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) { | 1141 | if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) { |
1141 | write_checkpoint(sbi, false, false); | 1142 | write_checkpoint(sbi, false, false); |
1142 | return 0; | 1143 | return 0; |
1143 | } | 1144 | } |
1144 | 1145 | ||
1146 | /* collect a number of dirty node pages and write together */ | ||
1147 | if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES) | ||
1148 | return 0; | ||
1149 | |||
1145 | /* if mounting is failed, skip writing node pages */ | 1150 | /* if mounting is failed, skip writing node pages */ |
1146 | wbc->nr_to_write = bio_get_nr_vecs(bdev); | 1151 | wbc->nr_to_write = bio_get_nr_vecs(bdev); |
1147 | sync_node_pages(sbi, 0, wbc); | 1152 | sync_node_pages(sbi, 0, wbc); |
@@ -1732,7 +1737,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) | |||
1732 | kfree(nm_i); | 1737 | kfree(nm_i); |
1733 | } | 1738 | } |
1734 | 1739 | ||
1735 | int create_node_manager_caches(void) | 1740 | int __init create_node_manager_caches(void) |
1736 | { | 1741 | { |
1737 | nat_entry_slab = f2fs_kmem_cache_create("nat_entry", | 1742 | nat_entry_slab = f2fs_kmem_cache_create("nat_entry", |
1738 | sizeof(struct nat_entry), NULL); | 1743 | sizeof(struct nat_entry), NULL); |
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index b571fee677d5..f42e4060b399 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
@@ -67,7 +67,7 @@ static int recover_dentry(struct page *ipage, struct inode *inode) | |||
67 | kunmap(page); | 67 | kunmap(page); |
68 | f2fs_put_page(page, 0); | 68 | f2fs_put_page(page, 0); |
69 | } else { | 69 | } else { |
70 | f2fs_add_link(&dent, inode); | 70 | err = f2fs_add_link(&dent, inode); |
71 | } | 71 | } |
72 | iput(dir); | 72 | iput(dir); |
73 | out: | 73 | out: |
@@ -151,7 +151,6 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | |||
151 | goto out; | 151 | goto out; |
152 | } | 152 | } |
153 | 153 | ||
154 | INIT_LIST_HEAD(&entry->list); | ||
155 | list_add_tail(&entry->list, head); | 154 | list_add_tail(&entry->list, head); |
156 | entry->blkaddr = blkaddr; | 155 | entry->blkaddr = blkaddr; |
157 | } | 156 | } |
@@ -174,10 +173,9 @@ out: | |||
174 | static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi, | 173 | static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi, |
175 | struct list_head *head) | 174 | struct list_head *head) |
176 | { | 175 | { |
177 | struct list_head *this; | 176 | struct fsync_inode_entry *entry, *tmp; |
178 | struct fsync_inode_entry *entry; | 177 | |
179 | list_for_each(this, head) { | 178 | list_for_each_entry_safe(entry, tmp, head, list) { |
180 | entry = list_entry(this, struct fsync_inode_entry, list); | ||
181 | iput(entry->inode); | 179 | iput(entry->inode); |
182 | list_del(&entry->list); | 180 | list_del(&entry->list); |
183 | kmem_cache_free(fsync_entry_slab, entry); | 181 | kmem_cache_free(fsync_entry_slab, entry); |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index de6240922b0a..4b0099066582 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -31,7 +31,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi) | |||
31 | */ | 31 | */ |
32 | if (has_not_enough_free_secs(sbi)) { | 32 | if (has_not_enough_free_secs(sbi)) { |
33 | mutex_lock(&sbi->gc_mutex); | 33 | mutex_lock(&sbi->gc_mutex); |
34 | f2fs_gc(sbi, 1); | 34 | f2fs_gc(sbi); |
35 | } | 35 | } |
36 | } | 36 | } |
37 | 37 | ||
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 08a94c814bdc..37fad04c8669 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -53,6 +53,18 @@ static match_table_t f2fs_tokens = { | |||
53 | {Opt_err, NULL}, | 53 | {Opt_err, NULL}, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...) | ||
57 | { | ||
58 | struct va_format vaf; | ||
59 | va_list args; | ||
60 | |||
61 | va_start(args, fmt); | ||
62 | vaf.fmt = fmt; | ||
63 | vaf.va = &args; | ||
64 | printk("%sF2FS-fs (%s): %pV\n", level, sb->s_id, &vaf); | ||
65 | va_end(args); | ||
66 | } | ||
67 | |||
56 | static void init_once(void *foo) | 68 | static void init_once(void *foo) |
57 | { | 69 | { |
58 | struct f2fs_inode_info *fi = (struct f2fs_inode_info *) foo; | 70 | struct f2fs_inode_info *fi = (struct f2fs_inode_info *) foo; |
@@ -125,6 +137,8 @@ int f2fs_sync_fs(struct super_block *sb, int sync) | |||
125 | 137 | ||
126 | if (sync) | 138 | if (sync) |
127 | write_checkpoint(sbi, false, false); | 139 | write_checkpoint(sbi, false, false); |
140 | else | ||
141 | f2fs_balance_fs(sbi); | ||
128 | 142 | ||
129 | return 0; | 143 | return 0; |
130 | } | 144 | } |
@@ -247,7 +261,8 @@ static const struct export_operations f2fs_export_ops = { | |||
247 | .get_parent = f2fs_get_parent, | 261 | .get_parent = f2fs_get_parent, |
248 | }; | 262 | }; |
249 | 263 | ||
250 | static int parse_options(struct f2fs_sb_info *sbi, char *options) | 264 | static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi, |
265 | char *options) | ||
251 | { | 266 | { |
252 | substring_t args[MAX_OPT_ARGS]; | 267 | substring_t args[MAX_OPT_ARGS]; |
253 | char *p; | 268 | char *p; |
@@ -286,7 +301,8 @@ static int parse_options(struct f2fs_sb_info *sbi, char *options) | |||
286 | break; | 301 | break; |
287 | #else | 302 | #else |
288 | case Opt_nouser_xattr: | 303 | case Opt_nouser_xattr: |
289 | pr_info("nouser_xattr options not supported\n"); | 304 | f2fs_msg(sb, KERN_INFO, |
305 | "nouser_xattr options not supported"); | ||
290 | break; | 306 | break; |
291 | #endif | 307 | #endif |
292 | #ifdef CONFIG_F2FS_FS_POSIX_ACL | 308 | #ifdef CONFIG_F2FS_FS_POSIX_ACL |
@@ -295,7 +311,7 @@ static int parse_options(struct f2fs_sb_info *sbi, char *options) | |||
295 | break; | 311 | break; |
296 | #else | 312 | #else |
297 | case Opt_noacl: | 313 | case Opt_noacl: |
298 | pr_info("noacl options not supported\n"); | 314 | f2fs_msg(sb, KERN_INFO, "noacl options not supported"); |
299 | break; | 315 | break; |
300 | #endif | 316 | #endif |
301 | case Opt_active_logs: | 317 | case Opt_active_logs: |
@@ -309,8 +325,9 @@ static int parse_options(struct f2fs_sb_info *sbi, char *options) | |||
309 | set_opt(sbi, DISABLE_EXT_IDENTIFY); | 325 | set_opt(sbi, DISABLE_EXT_IDENTIFY); |
310 | break; | 326 | break; |
311 | default: | 327 | default: |
312 | pr_err("Unrecognized mount option \"%s\" or missing value\n", | 328 | f2fs_msg(sb, KERN_ERR, |
313 | p); | 329 | "Unrecognized mount option \"%s\" or missing value", |
330 | p); | ||
314 | return -EINVAL; | 331 | return -EINVAL; |
315 | } | 332 | } |
316 | } | 333 | } |
@@ -337,23 +354,36 @@ static loff_t max_file_size(unsigned bits) | |||
337 | return result; | 354 | return result; |
338 | } | 355 | } |
339 | 356 | ||
340 | static int sanity_check_raw_super(struct f2fs_super_block *raw_super) | 357 | static int sanity_check_raw_super(struct super_block *sb, |
358 | struct f2fs_super_block *raw_super) | ||
341 | { | 359 | { |
342 | unsigned int blocksize; | 360 | unsigned int blocksize; |
343 | 361 | ||
344 | if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) | 362 | if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) { |
363 | f2fs_msg(sb, KERN_INFO, | ||
364 | "Magic Mismatch, valid(0x%x) - read(0x%x)", | ||
365 | F2FS_SUPER_MAGIC, le32_to_cpu(raw_super->magic)); | ||
345 | return 1; | 366 | return 1; |
367 | } | ||
346 | 368 | ||
347 | /* Currently, support only 4KB block size */ | 369 | /* Currently, support only 4KB block size */ |
348 | blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); | 370 | blocksize = 1 << le32_to_cpu(raw_super->log_blocksize); |
349 | if (blocksize != PAGE_CACHE_SIZE) | 371 | if (blocksize != PAGE_CACHE_SIZE) { |
372 | f2fs_msg(sb, KERN_INFO, | ||
373 | "Invalid blocksize (%u), supports only 4KB\n", | ||
374 | blocksize); | ||
350 | return 1; | 375 | return 1; |
376 | } | ||
351 | if (le32_to_cpu(raw_super->log_sectorsize) != | 377 | if (le32_to_cpu(raw_super->log_sectorsize) != |
352 | F2FS_LOG_SECTOR_SIZE) | 378 | F2FS_LOG_SECTOR_SIZE) { |
379 | f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize"); | ||
353 | return 1; | 380 | return 1; |
381 | } | ||
354 | if (le32_to_cpu(raw_super->log_sectors_per_block) != | 382 | if (le32_to_cpu(raw_super->log_sectors_per_block) != |
355 | F2FS_LOG_SECTORS_PER_BLOCK) | 383 | F2FS_LOG_SECTORS_PER_BLOCK) { |
384 | f2fs_msg(sb, KERN_INFO, "Invalid log sectors per block"); | ||
356 | return 1; | 385 | return 1; |
386 | } | ||
357 | return 0; | 387 | return 0; |
358 | } | 388 | } |
359 | 389 | ||
@@ -413,14 +443,17 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
413 | if (!sbi) | 443 | if (!sbi) |
414 | return -ENOMEM; | 444 | return -ENOMEM; |
415 | 445 | ||
416 | /* set a temporary block size */ | 446 | /* set a block size */ |
417 | if (!sb_set_blocksize(sb, F2FS_BLKSIZE)) | 447 | if (!sb_set_blocksize(sb, F2FS_BLKSIZE)) { |
448 | f2fs_msg(sb, KERN_ERR, "unable to set blocksize"); | ||
418 | goto free_sbi; | 449 | goto free_sbi; |
450 | } | ||
419 | 451 | ||
420 | /* read f2fs raw super block */ | 452 | /* read f2fs raw super block */ |
421 | raw_super_buf = sb_bread(sb, 0); | 453 | raw_super_buf = sb_bread(sb, 0); |
422 | if (!raw_super_buf) { | 454 | if (!raw_super_buf) { |
423 | err = -EIO; | 455 | err = -EIO; |
456 | f2fs_msg(sb, KERN_ERR, "unable to read superblock"); | ||
424 | goto free_sbi; | 457 | goto free_sbi; |
425 | } | 458 | } |
426 | raw_super = (struct f2fs_super_block *) | 459 | raw_super = (struct f2fs_super_block *) |
@@ -438,12 +471,14 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
438 | set_opt(sbi, POSIX_ACL); | 471 | set_opt(sbi, POSIX_ACL); |
439 | #endif | 472 | #endif |
440 | /* parse mount options */ | 473 | /* parse mount options */ |
441 | if (parse_options(sbi, (char *)data)) | 474 | if (parse_options(sb, sbi, (char *)data)) |
442 | goto free_sb_buf; | 475 | goto free_sb_buf; |
443 | 476 | ||
444 | /* sanity checking of raw super */ | 477 | /* sanity checking of raw super */ |
445 | if (sanity_check_raw_super(raw_super)) | 478 | if (sanity_check_raw_super(sb, raw_super)) { |
479 | f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem"); | ||
446 | goto free_sb_buf; | 480 | goto free_sb_buf; |
481 | } | ||
447 | 482 | ||
448 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); | 483 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); |
449 | sb->s_max_links = F2FS_LINK_MAX; | 484 | sb->s_max_links = F2FS_LINK_MAX; |
@@ -477,18 +512,23 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
477 | /* get an inode for meta space */ | 512 | /* get an inode for meta space */ |
478 | sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); | 513 | sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); |
479 | if (IS_ERR(sbi->meta_inode)) { | 514 | if (IS_ERR(sbi->meta_inode)) { |
515 | f2fs_msg(sb, KERN_ERR, "Failed to read F2FS meta data inode"); | ||
480 | err = PTR_ERR(sbi->meta_inode); | 516 | err = PTR_ERR(sbi->meta_inode); |
481 | goto free_sb_buf; | 517 | goto free_sb_buf; |
482 | } | 518 | } |
483 | 519 | ||
484 | err = get_valid_checkpoint(sbi); | 520 | err = get_valid_checkpoint(sbi); |
485 | if (err) | 521 | if (err) { |
522 | f2fs_msg(sb, KERN_ERR, "Failed to get valid F2FS checkpoint"); | ||
486 | goto free_meta_inode; | 523 | goto free_meta_inode; |
524 | } | ||
487 | 525 | ||
488 | /* sanity checking of checkpoint */ | 526 | /* sanity checking of checkpoint */ |
489 | err = -EINVAL; | 527 | err = -EINVAL; |
490 | if (sanity_check_ckpt(raw_super, sbi->ckpt)) | 528 | if (sanity_check_ckpt(raw_super, sbi->ckpt)) { |
529 | f2fs_msg(sb, KERN_ERR, "Invalid F2FS checkpoint"); | ||
491 | goto free_cp; | 530 | goto free_cp; |
531 | } | ||
492 | 532 | ||
493 | sbi->total_valid_node_count = | 533 | sbi->total_valid_node_count = |
494 | le32_to_cpu(sbi->ckpt->valid_node_count); | 534 | le32_to_cpu(sbi->ckpt->valid_node_count); |
@@ -502,25 +542,28 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
502 | INIT_LIST_HEAD(&sbi->dir_inode_list); | 542 | INIT_LIST_HEAD(&sbi->dir_inode_list); |
503 | spin_lock_init(&sbi->dir_inode_lock); | 543 | spin_lock_init(&sbi->dir_inode_lock); |
504 | 544 | ||
505 | /* init super block */ | ||
506 | if (!sb_set_blocksize(sb, sbi->blocksize)) | ||
507 | goto free_cp; | ||
508 | |||
509 | init_orphan_info(sbi); | 545 | init_orphan_info(sbi); |
510 | 546 | ||
511 | /* setup f2fs internal modules */ | 547 | /* setup f2fs internal modules */ |
512 | err = build_segment_manager(sbi); | 548 | err = build_segment_manager(sbi); |
513 | if (err) | 549 | if (err) { |
550 | f2fs_msg(sb, KERN_ERR, | ||
551 | "Failed to initialize F2FS segment manager"); | ||
514 | goto free_sm; | 552 | goto free_sm; |
553 | } | ||
515 | err = build_node_manager(sbi); | 554 | err = build_node_manager(sbi); |
516 | if (err) | 555 | if (err) { |
556 | f2fs_msg(sb, KERN_ERR, | ||
557 | "Failed to initialize F2FS node manager"); | ||
517 | goto free_nm; | 558 | goto free_nm; |
559 | } | ||
518 | 560 | ||
519 | build_gc_manager(sbi); | 561 | build_gc_manager(sbi); |
520 | 562 | ||
521 | /* get an inode for node space */ | 563 | /* get an inode for node space */ |
522 | sbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi)); | 564 | sbi->node_inode = f2fs_iget(sb, F2FS_NODE_INO(sbi)); |
523 | if (IS_ERR(sbi->node_inode)) { | 565 | if (IS_ERR(sbi->node_inode)) { |
566 | f2fs_msg(sb, KERN_ERR, "Failed to read node inode"); | ||
524 | err = PTR_ERR(sbi->node_inode); | 567 | err = PTR_ERR(sbi->node_inode); |
525 | goto free_nm; | 568 | goto free_nm; |
526 | } | 569 | } |
@@ -533,6 +576,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
533 | /* read root inode and dentry */ | 576 | /* read root inode and dentry */ |
534 | root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); | 577 | root = f2fs_iget(sb, F2FS_ROOT_INO(sbi)); |
535 | if (IS_ERR(root)) { | 578 | if (IS_ERR(root)) { |
579 | f2fs_msg(sb, KERN_ERR, "Failed to read root inode"); | ||
536 | err = PTR_ERR(root); | 580 | err = PTR_ERR(root); |
537 | goto free_node_inode; | 581 | goto free_node_inode; |
538 | } | 582 | } |
@@ -596,7 +640,7 @@ static struct file_system_type f2fs_fs_type = { | |||
596 | .fs_flags = FS_REQUIRES_DEV, | 640 | .fs_flags = FS_REQUIRES_DEV, |
597 | }; | 641 | }; |
598 | 642 | ||
599 | static int init_inodecache(void) | 643 | static int __init init_inodecache(void) |
600 | { | 644 | { |
601 | f2fs_inode_cachep = f2fs_kmem_cache_create("f2fs_inode_cache", | 645 | f2fs_inode_cachep = f2fs_kmem_cache_create("f2fs_inode_cache", |
602 | sizeof(struct f2fs_inode_info), NULL); | 646 | sizeof(struct f2fs_inode_info), NULL); |
@@ -631,14 +675,17 @@ static int __init init_f2fs_fs(void) | |||
631 | err = create_checkpoint_caches(); | 675 | err = create_checkpoint_caches(); |
632 | if (err) | 676 | if (err) |
633 | goto fail; | 677 | goto fail; |
634 | return register_filesystem(&f2fs_fs_type); | 678 | err = register_filesystem(&f2fs_fs_type); |
679 | if (err) | ||
680 | goto fail; | ||
681 | f2fs_create_root_stats(); | ||
635 | fail: | 682 | fail: |
636 | return err; | 683 | return err; |
637 | } | 684 | } |
638 | 685 | ||
639 | static void __exit exit_f2fs_fs(void) | 686 | static void __exit exit_f2fs_fs(void) |
640 | { | 687 | { |
641 | destroy_root_stats(); | 688 | f2fs_destroy_root_stats(); |
642 | unregister_filesystem(&f2fs_fs_type); | 689 | unregister_filesystem(&f2fs_fs_type); |
643 | destroy_checkpoint_caches(); | 690 | destroy_checkpoint_caches(); |
644 | destroy_gc_caches(); | 691 | destroy_gc_caches(); |
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 940136a3d3a6..8038c0496504 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c | |||
@@ -318,6 +318,8 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, | |||
318 | if (name_len > 255 || value_len > MAX_VALUE_LEN) | 318 | if (name_len > 255 || value_len > MAX_VALUE_LEN) |
319 | return -ERANGE; | 319 | return -ERANGE; |
320 | 320 | ||
321 | f2fs_balance_fs(sbi); | ||
322 | |||
321 | mutex_lock_op(sbi, NODE_NEW); | 323 | mutex_lock_op(sbi, NODE_NEW); |
322 | if (!fi->i_xattr_nid) { | 324 | if (!fi->i_xattr_nid) { |
323 | /* Allocate new attribute block */ | 325 | /* Allocate new attribute block */ |