aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 18:11:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 18:11:48 -0400
commit942d33da999b86821c9aee9615fcb81207ee04c7 (patch)
treedb14ab92982f936c0a2ea2202f5e301310f33bdd /fs/f2fs/super.c
parent246e6a0d781091c4657890ffa497c2576bd99095 (diff)
parent59bbd474abb9dd6a0c1a74df758ec29c7a8b150f (diff)
Merge tag 'f2fs-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "This patch-set includes the following major enhancement patches. - introduce a new gloabl lock scheme - add tracepoints on several major functions - fix the overall cleaning process focused on victim selection - apply the block plugging to merge IOs as much as possible - enhance management of free nids and its list - enhance the readahead mode for node pages - address several cretical deadlock conditions - reduce lock_page calls The other minor bug fixes and enhancements are as follows. - calculation mistakes: overflow - bio types: READ, READA, and READ_SYNC - fix the recovery flow, data races, and null pointer errors" * tag 'f2fs-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (68 commits) f2fs: cover free_nid management with spin_lock f2fs: optimize scan_nat_page() f2fs: code cleanup for scan_nat_page() and build_free_nids() f2fs: bugfix for alloc_nid_failed() f2fs: recover when journal contains deleted files f2fs: continue to mount after failing recovery f2fs: avoid deadlock during evict after f2fs_gc f2fs: modify the number of issued pages to merge IOs f2fs: remove useless #include <linux/proc_fs.h> as we're now using sysfs as debug entry. f2fs: fix inconsistent using of NM_WOUT_THRESHOLD f2fs: check truncation of mapping after lock_page f2fs: enhance alloc_nid and build_free_nids flows f2fs: add a tracepoint on f2fs_new_inode f2fs: check nid == 0 in add_free_nid f2fs: add REQ_META about metadata requests for submit f2fs: give a chance to merge IOs by IO scheduler f2fs: avoid frequent background GC f2fs: add tracepoints to debug checkpoint request f2fs: add tracepoints for write page operations f2fs: add tracepoints to debug the block allocation ...
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r--fs/f2fs/super.c67
1 files changed, 54 insertions, 13 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 62e017743af6..8555f7df82c7 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -12,7 +12,6 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/statfs.h> 14#include <linux/statfs.h>
15#include <linux/proc_fs.h>
16#include <linux/buffer_head.h> 15#include <linux/buffer_head.h>
17#include <linux/backing-dev.h> 16#include <linux/backing-dev.h>
18#include <linux/kthread.h> 17#include <linux/kthread.h>
@@ -21,12 +20,17 @@
21#include <linux/seq_file.h> 20#include <linux/seq_file.h>
22#include <linux/random.h> 21#include <linux/random.h>
23#include <linux/exportfs.h> 22#include <linux/exportfs.h>
23#include <linux/blkdev.h>
24#include <linux/f2fs_fs.h> 24#include <linux/f2fs_fs.h>
25 25
26#include "f2fs.h" 26#include "f2fs.h"
27#include "node.h" 27#include "node.h"
28#include "segment.h"
28#include "xattr.h" 29#include "xattr.h"
29 30
31#define CREATE_TRACE_POINTS
32#include <trace/events/f2fs.h>
33
30static struct kmem_cache *f2fs_inode_cachep; 34static struct kmem_cache *f2fs_inode_cachep;
31 35
32enum { 36enum {
@@ -94,6 +98,20 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
94 return &fi->vfs_inode; 98 return &fi->vfs_inode;
95} 99}
96 100
101static int f2fs_drop_inode(struct inode *inode)
102{
103 /*
104 * This is to avoid a deadlock condition like below.
105 * writeback_single_inode(inode)
106 * - f2fs_write_data_page
107 * - f2fs_gc -> iput -> evict
108 * - inode_wait_for_writeback(inode)
109 */
110 if (!inode_unhashed(inode) && inode->i_state & I_SYNC)
111 return 0;
112 return generic_drop_inode(inode);
113}
114
97static void f2fs_i_callback(struct rcu_head *head) 115static void f2fs_i_callback(struct rcu_head *head)
98{ 116{
99 struct inode *inode = container_of(head, struct inode, i_rcu); 117 struct inode *inode = container_of(head, struct inode, i_rcu);
@@ -132,13 +150,18 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
132{ 150{
133 struct f2fs_sb_info *sbi = F2FS_SB(sb); 151 struct f2fs_sb_info *sbi = F2FS_SB(sb);
134 152
153 trace_f2fs_sync_fs(sb, sync);
154
135 if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES)) 155 if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES))
136 return 0; 156 return 0;
137 157
138 if (sync) 158 if (sync) {
159 mutex_lock(&sbi->gc_mutex);
139 write_checkpoint(sbi, false); 160 write_checkpoint(sbi, false);
140 else 161 mutex_unlock(&sbi->gc_mutex);
162 } else {
141 f2fs_balance_fs(sbi); 163 f2fs_balance_fs(sbi);
164 }
142 165
143 return 0; 166 return 0;
144} 167}
@@ -180,7 +203,7 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
180 buf->f_files = sbi->total_node_count; 203 buf->f_files = sbi->total_node_count;
181 buf->f_ffree = sbi->total_node_count - valid_inode_count(sbi); 204 buf->f_ffree = sbi->total_node_count - valid_inode_count(sbi);
182 205
183 buf->f_namelen = F2FS_MAX_NAME_LEN; 206 buf->f_namelen = F2FS_NAME_LEN;
184 buf->f_fsid.val[0] = (u32)id; 207 buf->f_fsid.val[0] = (u32)id;
185 buf->f_fsid.val[1] = (u32)(id >> 32); 208 buf->f_fsid.val[1] = (u32)(id >> 32);
186 209
@@ -223,6 +246,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
223 246
224static struct super_operations f2fs_sops = { 247static struct super_operations f2fs_sops = {
225 .alloc_inode = f2fs_alloc_inode, 248 .alloc_inode = f2fs_alloc_inode,
249 .drop_inode = f2fs_drop_inode,
226 .destroy_inode = f2fs_destroy_inode, 250 .destroy_inode = f2fs_destroy_inode,
227 .write_inode = f2fs_write_inode, 251 .write_inode = f2fs_write_inode,
228 .show_options = f2fs_show_options, 252 .show_options = f2fs_show_options,
@@ -457,6 +481,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
457 sbi->root_ino_num = le32_to_cpu(raw_super->root_ino); 481 sbi->root_ino_num = le32_to_cpu(raw_super->root_ino);
458 sbi->node_ino_num = le32_to_cpu(raw_super->node_ino); 482 sbi->node_ino_num = le32_to_cpu(raw_super->node_ino);
459 sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino); 483 sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino);
484 sbi->cur_victim_sec = NULL_SECNO;
460 485
461 for (i = 0; i < NR_COUNT_TYPE; i++) 486 for (i = 0; i < NR_COUNT_TYPE; i++)
462 atomic_set(&sbi->nr_pages[i], 0); 487 atomic_set(&sbi->nr_pages[i], 0);
@@ -473,7 +498,7 @@ static int validate_superblock(struct super_block *sb,
473 if (!*raw_super_buf) { 498 if (!*raw_super_buf) {
474 f2fs_msg(sb, KERN_ERR, "unable to read %s superblock", 499 f2fs_msg(sb, KERN_ERR, "unable to read %s superblock",
475 super); 500 super);
476 return 1; 501 return -EIO;
477 } 502 }
478 503
479 *raw_super = (struct f2fs_super_block *) 504 *raw_super = (struct f2fs_super_block *)
@@ -485,7 +510,7 @@ static int validate_superblock(struct super_block *sb,
485 510
486 f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem " 511 f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem "
487 "in %s superblock", super); 512 "in %s superblock", super);
488 return 1; 513 return -EINVAL;
489} 514}
490 515
491static int f2fs_fill_super(struct super_block *sb, void *data, int silent) 516static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
@@ -508,9 +533,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
508 goto free_sbi; 533 goto free_sbi;
509 } 534 }
510 535
511 if (validate_superblock(sb, &raw_super, &raw_super_buf, 0)) { 536 err = validate_superblock(sb, &raw_super, &raw_super_buf, 0);
537 if (err) {
512 brelse(raw_super_buf); 538 brelse(raw_super_buf);
513 if (validate_superblock(sb, &raw_super, &raw_super_buf, 1)) 539 /* check secondary superblock when primary failed */
540 err = validate_superblock(sb, &raw_super, &raw_super_buf, 1);
541 if (err)
514 goto free_sb_buf; 542 goto free_sb_buf;
515 } 543 }
516 /* init some FS parameters */ 544 /* init some FS parameters */
@@ -525,7 +553,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
525 set_opt(sbi, POSIX_ACL); 553 set_opt(sbi, POSIX_ACL);
526#endif 554#endif
527 /* parse mount options */ 555 /* parse mount options */
528 if (parse_options(sb, sbi, (char *)data)) 556 err = parse_options(sb, sbi, (char *)data);
557 if (err)
529 goto free_sb_buf; 558 goto free_sb_buf;
530 559
531 sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); 560 sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize));
@@ -547,11 +576,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
547 sbi->raw_super = raw_super; 576 sbi->raw_super = raw_super;
548 sbi->raw_super_buf = raw_super_buf; 577 sbi->raw_super_buf = raw_super_buf;
549 mutex_init(&sbi->gc_mutex); 578 mutex_init(&sbi->gc_mutex);
550 mutex_init(&sbi->write_inode);
551 mutex_init(&sbi->writepages); 579 mutex_init(&sbi->writepages);
552 mutex_init(&sbi->cp_mutex); 580 mutex_init(&sbi->cp_mutex);
553 for (i = 0; i < NR_LOCK_TYPE; i++) 581 for (i = 0; i < NR_GLOBAL_LOCKS; i++)
554 mutex_init(&sbi->fs_lock[i]); 582 mutex_init(&sbi->fs_lock[i]);
583 mutex_init(&sbi->node_write);
555 sbi->por_doing = 0; 584 sbi->por_doing = 0;
556 spin_lock_init(&sbi->stat_lock); 585 spin_lock_init(&sbi->stat_lock);
557 init_rwsem(&sbi->bio_sem); 586 init_rwsem(&sbi->bio_sem);
@@ -638,8 +667,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
638 } 667 }
639 668
640 /* recover fsynced data */ 669 /* recover fsynced data */
641 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) 670 if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) {
642 recover_fsync_data(sbi); 671 err = recover_fsync_data(sbi);
672 if (err)
673 f2fs_msg(sb, KERN_ERR,
674 "Cannot recover all fsync data errno=%ld", err);
675 }
643 676
644 /* After POR, we can run background GC thread */ 677 /* After POR, we can run background GC thread */
645 err = start_gc_thread(sbi); 678 err = start_gc_thread(sbi);
@@ -650,6 +683,14 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
650 if (err) 683 if (err)
651 goto fail; 684 goto fail;
652 685
686 if (test_opt(sbi, DISCARD)) {
687 struct request_queue *q = bdev_get_queue(sb->s_bdev);
688 if (!blk_queue_discard(q))
689 f2fs_msg(sb, KERN_WARNING,
690 "mounting with \"discard\" option, but "
691 "the device does not support discard");
692 }
693
653 return 0; 694 return 0;
654fail: 695fail:
655 stop_gc_thread(sbi); 696 stop_gc_thread(sbi);