aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/checkpoint.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2012-11-22 02:21:29 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-04-09 05:21:18 -0400
commit399368372ed9f3c396eadb5c2bbc98be8c774a39 (patch)
treeb496c910ebf04d95e5ad6cb1b65d8cbb45aeef89 /fs/f2fs/checkpoint.c
parent1127a3d448bcf4de338e60a7cc695d54c5767433 (diff)
f2fs: introduce a new global lock scheme
In the previous version, f2fs uses global locks according to the usage types, such as directory operations, block allocation, block write, and so on. Reference the following lock types in f2fs.h. enum lock_type { RENAME, /* for renaming operations */ DENTRY_OPS, /* for directory operations */ DATA_WRITE, /* for data write */ DATA_NEW, /* for data allocation */ DATA_TRUNC, /* for data truncate */ NODE_NEW, /* for node allocation */ NODE_TRUNC, /* for node truncate */ NODE_WRITE, /* for node write */ NR_LOCK_TYPE, }; In that case, we lose the performance under the multi-threading environment, since every types of operations must be conducted one at a time. In order to address the problem, let's share the locks globally with a mutex array regardless of any types. So, let users grab a mutex and perform their jobs in parallel as much as possbile. For this, I propose a new global lock scheme as follows. 0. Data structure - f2fs_sb_info -> mutex_lock[NR_GLOBAL_LOCKS] - f2fs_sb_info -> node_write 1. mutex_lock_op(sbi) - try to get an avaiable lock from the array. - returns the index of the gottern lock variable. 2. mutex_unlock_op(sbi, index of the lock) - unlock the given index of the lock. 3. mutex_lock_all(sbi) - grab all the locks in the array before the checkpoint. 4. mutex_unlock_all(sbi) - release all the locks in the array after checkpoint. 5. block_operations() - call mutex_lock_all() - sync_dirty_dir_inodes() - grab node_write - sync_node_pages() Note that, the pairs of mutex_lock_op()/mutex_unlock_op() and mutex_lock_all()/mutex_unlock_all() should be used together. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r--fs/f2fs/checkpoint.c39
1 files changed, 12 insertions, 27 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 93fd57d491ac..be6aa2eef894 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -543,54 +543,39 @@ retry:
543 */ 543 */
544static void block_operations(struct f2fs_sb_info *sbi) 544static void block_operations(struct f2fs_sb_info *sbi)
545{ 545{
546 int t;
547 struct writeback_control wbc = { 546 struct writeback_control wbc = {
548 .sync_mode = WB_SYNC_ALL, 547 .sync_mode = WB_SYNC_ALL,
549 .nr_to_write = LONG_MAX, 548 .nr_to_write = LONG_MAX,
550 .for_reclaim = 0, 549 .for_reclaim = 0,
551 }; 550 };
551retry_flush_dents:
552 mutex_lock_all(sbi);
552 553
553 /* Stop renaming operation */
554 mutex_lock_op(sbi, RENAME);
555 mutex_lock_op(sbi, DENTRY_OPS);
556
557retry_dents:
558 /* write all the dirty dentry pages */ 554 /* write all the dirty dentry pages */
559 sync_dirty_dir_inodes(sbi);
560
561 mutex_lock_op(sbi, DATA_WRITE);
562 if (get_pages(sbi, F2FS_DIRTY_DENTS)) { 555 if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
563 mutex_unlock_op(sbi, DATA_WRITE); 556 mutex_unlock_all(sbi);
564 goto retry_dents; 557 sync_dirty_dir_inodes(sbi);
558 goto retry_flush_dents;
565 } 559 }
566 560
567 /* block all the operations */
568 for (t = DATA_NEW; t <= NODE_TRUNC; t++)
569 mutex_lock_op(sbi, t);
570
571 mutex_lock(&sbi->write_inode);
572
573 /* 561 /*
574 * POR: we should ensure that there is no dirty node pages 562 * POR: we should ensure that there is no dirty node pages
575 * until finishing nat/sit flush. 563 * until finishing nat/sit flush.
576 */ 564 */
577retry: 565retry_flush_nodes:
578 sync_node_pages(sbi, 0, &wbc); 566 mutex_lock(&sbi->node_write);
579
580 mutex_lock_op(sbi, NODE_WRITE);
581 567
582 if (get_pages(sbi, F2FS_DIRTY_NODES)) { 568 if (get_pages(sbi, F2FS_DIRTY_NODES)) {
583 mutex_unlock_op(sbi, NODE_WRITE); 569 mutex_unlock(&sbi->node_write);
584 goto retry; 570 sync_node_pages(sbi, 0, &wbc);
571 goto retry_flush_nodes;
585 } 572 }
586 mutex_unlock(&sbi->write_inode);
587} 573}
588 574
589static void unblock_operations(struct f2fs_sb_info *sbi) 575static void unblock_operations(struct f2fs_sb_info *sbi)
590{ 576{
591 int t; 577 mutex_unlock(&sbi->node_write);
592 for (t = NODE_WRITE; t >= RENAME; t--) 578 mutex_unlock_all(sbi);
593 mutex_unlock_op(sbi, t);
594} 579}
595 580
596static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) 581static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)