aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorGu Zheng <guz.fnst@cn.fujitsu.com>2013-09-27 06:08:30 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-10-06 22:33:05 -0400
commite479556bfdd136669854292eb57ed0139d7253d5 (patch)
tree95772ba1ac8cf1e79c89145daf40c417814896da /fs
parent2e5558f4a5cf16a7394fd5770087303db8912c66 (diff)
f2fs: use rw_sem instead of fs_lock(locks mutex)
The fs_locks is used to block other ops(ex, recovery) when doing checkpoint. And each other operate routine(besides checkpoint) needs to acquire a fs_lock, there is a terrible problem here, if these are too many concurrency threads acquiring fs_lock, so that they will block each other and may lead to some performance problem, but this is not the phenomenon we want to see. Though there are some optimization patches introduced to enhance the usage of fs_lock, but the thorough solution is using a *rw_sem* to replace the fs_lock. Checkpoint routine takes write_sem, and other ops take read_sem, so that we can block other ops(ex, recovery) when doing checkpoint, and other ops will not disturb each other, this can avoid the problem described above completely. Because of the weakness of rw_sem, the above change may introduce a potential problem that the checkpoint thread might get starved if other threads are intensively locking the read semaphore for I/O.(Pointed out by Xu Jin) In order to avoid this, a wait_list is introduced, the appending read semaphore ops will be dropped into the wait_list if checkpoint thread is waiting for write semaphore, and will be waked up when checkpoint thread gives up write semaphore. Thanks to Kim's previous review and test, and will be very glad to see other guys' performance tests about this patch. V2: -fix the potential starvation problem. -use more suitable func name suggested by Xu Jin. Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com> [Jaegeuk Kim: adjust minor coding standard] Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/checkpoint.c7
-rw-r--r--fs/f2fs/data.c11
-rw-r--r--fs/f2fs/f2fs.h64
-rw-r--r--fs/f2fs/file.c37
-rw-r--r--fs/f2fs/inode.c11
-rw-r--r--fs/f2fs/namei.c50
-rw-r--r--fs/f2fs/recovery.c7
-rw-r--r--fs/f2fs/super.c5
-rw-r--r--fs/f2fs/xattr.c7
9 files changed, 83 insertions, 116 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index ca3944240db5..d80882763ffd 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -619,11 +619,10 @@ static void block_operations(struct f2fs_sb_info *sbi)
619 blk_start_plug(&plug); 619 blk_start_plug(&plug);
620 620
621retry_flush_dents: 621retry_flush_dents:
622 mutex_lock_all(sbi); 622 f2fs_lock_all(sbi);
623
624 /* write all the dirty dentry pages */ 623 /* write all the dirty dentry pages */
625 if (get_pages(sbi, F2FS_DIRTY_DENTS)) { 624 if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
626 mutex_unlock_all(sbi); 625 f2fs_unlock_all(sbi);
627 sync_dirty_dir_inodes(sbi); 626 sync_dirty_dir_inodes(sbi);
628 goto retry_flush_dents; 627 goto retry_flush_dents;
629 } 628 }
@@ -646,7 +645,7 @@ retry_flush_nodes:
646static void unblock_operations(struct f2fs_sb_info *sbi) 645static void unblock_operations(struct f2fs_sb_info *sbi)
647{ 646{
648 mutex_unlock(&sbi->node_write); 647 mutex_unlock(&sbi->node_write);
649 mutex_unlock_all(sbi); 648 f2fs_unlock_all(sbi);
650} 649}
651 650
652static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) 651static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 941f9b9ca3a5..2535d3b1a763 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -560,9 +560,9 @@ write:
560 inode_dec_dirty_dents(inode); 560 inode_dec_dirty_dents(inode);
561 err = do_write_data_page(page); 561 err = do_write_data_page(page);
562 } else { 562 } else {
563 int ilock = mutex_lock_op(sbi); 563 f2fs_lock_op(sbi);
564 err = do_write_data_page(page); 564 err = do_write_data_page(page);
565 mutex_unlock_op(sbi, ilock); 565 f2fs_unlock_op(sbi);
566 need_balance_fs = true; 566 need_balance_fs = true;
567 } 567 }
568 if (err == -ENOENT) 568 if (err == -ENOENT)
@@ -641,7 +641,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
641 pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT; 641 pgoff_t index = ((unsigned long long) pos) >> PAGE_CACHE_SHIFT;
642 struct dnode_of_data dn; 642 struct dnode_of_data dn;
643 int err = 0; 643 int err = 0;
644 int ilock;
645 644
646 f2fs_balance_fs(sbi); 645 f2fs_balance_fs(sbi);
647repeat: 646repeat:
@@ -650,7 +649,7 @@ repeat:
650 return -ENOMEM; 649 return -ENOMEM;
651 *pagep = page; 650 *pagep = page;
652 651
653 ilock = mutex_lock_op(sbi); 652 f2fs_lock_op(sbi);
654 653
655 set_new_dnode(&dn, inode, NULL, NULL, 0); 654 set_new_dnode(&dn, inode, NULL, NULL, 0);
656 err = get_dnode_of_data(&dn, index, ALLOC_NODE); 655 err = get_dnode_of_data(&dn, index, ALLOC_NODE);
@@ -664,7 +663,7 @@ repeat:
664 if (err) 663 if (err)
665 goto err; 664 goto err;
666 665
667 mutex_unlock_op(sbi, ilock); 666 f2fs_unlock_op(sbi);
668 667
669 if ((len == PAGE_CACHE_SIZE) || PageUptodate(page)) 668 if ((len == PAGE_CACHE_SIZE) || PageUptodate(page))
670 return 0; 669 return 0;
@@ -700,7 +699,7 @@ out:
700 return 0; 699 return 0;
701 700
702err: 701err:
703 mutex_unlock_op(sbi, ilock); 702 f2fs_unlock_op(sbi);
704 f2fs_put_page(page, 1); 703 f2fs_put_page(page, 1);
705 return err; 704 return err;
706} 705}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 7fd99d8bd2ff..a955a59dfdbe 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -18,6 +18,8 @@
18#include <linux/crc32.h> 18#include <linux/crc32.h>
19#include <linux/magic.h> 19#include <linux/magic.h>
20#include <linux/kobject.h> 20#include <linux/kobject.h>
21#include <linux/wait.h>
22#include <linux/sched.h>
21 23
22/* 24/*
23 * For mount options 25 * For mount options
@@ -318,14 +320,6 @@ enum count_type {
318}; 320};
319 321
320/* 322/*
321 * Uses as sbi->fs_lock[NR_GLOBAL_LOCKS].
322 * The checkpoint procedure blocks all the locks in this fs_lock array.
323 * Some FS operations grab free locks, and if there is no free lock,
324 * then wait to grab a lock in a round-robin manner.
325 */
326#define NR_GLOBAL_LOCKS 8
327
328/*
329 * The below are the page types of bios used in submti_bio(). 323 * The below are the page types of bios used in submti_bio().
330 * The available types are: 324 * The available types are:
331 * DATA User data pages. It operates as async mode. 325 * DATA User data pages. It operates as async mode.
@@ -365,10 +359,10 @@ struct f2fs_sb_info {
365 struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ 359 struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */
366 struct inode *meta_inode; /* cache meta blocks */ 360 struct inode *meta_inode; /* cache meta blocks */
367 struct mutex cp_mutex; /* checkpoint procedure lock */ 361 struct mutex cp_mutex; /* checkpoint procedure lock */
368 struct mutex fs_lock[NR_GLOBAL_LOCKS]; /* blocking FS operations */ 362 struct rw_semaphore cp_rwsem; /* blocking FS operations */
363 wait_queue_head_t cp_wait; /* checkpoint wait queue */
369 struct mutex node_write; /* locking node writes */ 364 struct mutex node_write; /* locking node writes */
370 struct mutex writepages; /* mutex for writepages() */ 365 struct mutex writepages; /* mutex for writepages() */
371 unsigned char next_lock_num; /* round-robin global locks */
372 int por_doing; /* recovery is doing or not */ 366 int por_doing; /* recovery is doing or not */
373 int on_build_free_nids; /* build_free_nids is doing */ 367 int on_build_free_nids; /* build_free_nids is doing */
374 368
@@ -520,48 +514,34 @@ static inline void clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
520 cp->ckpt_flags = cpu_to_le32(ckpt_flags); 514 cp->ckpt_flags = cpu_to_le32(ckpt_flags);
521} 515}
522 516
523static inline void mutex_lock_all(struct f2fs_sb_info *sbi) 517static inline void f2fs_lock_op(struct f2fs_sb_info *sbi)
524{ 518{
525 int i; 519 /*
526 520 * If the checkpoint thread is waiting for cp_rwsem, add cuurent task
527 for (i = 0; i < NR_GLOBAL_LOCKS; i++) { 521 * into wait list to avoid the checkpoint thread starvation
528 /* 522 */
529 * This is the only time we take multiple fs_lock[] 523 while (!list_empty(&sbi->cp_rwsem.wait_list))
530 * instances; the order is immaterial since we 524 wait_event_interruptible(sbi->cp_wait,
531 * always hold cp_mutex, which serializes multiple 525 list_empty(&sbi->cp_rwsem.wait_list));
532 * such operations. 526 down_read(&sbi->cp_rwsem);
533 */
534 mutex_lock_nest_lock(&sbi->fs_lock[i], &sbi->cp_mutex);
535 }
536} 527}
537 528
538static inline void mutex_unlock_all(struct f2fs_sb_info *sbi) 529static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi)
539{ 530{
540 int i = 0; 531 up_read(&sbi->cp_rwsem);
541 for (; i < NR_GLOBAL_LOCKS; i++)
542 mutex_unlock(&sbi->fs_lock[i]);
543} 532}
544 533
545static inline int mutex_lock_op(struct f2fs_sb_info *sbi) 534static inline void f2fs_lock_all(struct f2fs_sb_info *sbi)
546{ 535{
547 unsigned char next_lock; 536 down_write_nest_lock(&sbi->cp_rwsem, &sbi->cp_mutex);
548 int i = 0;
549
550 for (; i < NR_GLOBAL_LOCKS; i++)
551 if (mutex_trylock(&sbi->fs_lock[i]))
552 return i;
553
554 next_lock = sbi->next_lock_num++ % NR_GLOBAL_LOCKS;
555 mutex_lock(&sbi->fs_lock[next_lock]);
556 return next_lock;
557} 537}
558 538
559static inline void mutex_unlock_op(struct f2fs_sb_info *sbi, int ilock) 539static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi)
560{ 540{
561 if (ilock < 0) 541 up_write(&sbi->cp_rwsem);
562 return; 542
563 BUG_ON(ilock >= NR_GLOBAL_LOCKS); 543 /* wake up all tasks blocked by checkpoint */
564 mutex_unlock(&sbi->fs_lock[ilock]); 544 wake_up_all(&sbi->cp_wait);
565} 545}
566 546
567/* 547/*
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 02c906971cc6..c80faa2fff39 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -35,18 +35,18 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
35 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 35 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
36 block_t old_blk_addr; 36 block_t old_blk_addr;
37 struct dnode_of_data dn; 37 struct dnode_of_data dn;
38 int err, ilock; 38 int err;
39 39
40 f2fs_balance_fs(sbi); 40 f2fs_balance_fs(sbi);
41 41
42 sb_start_pagefault(inode->i_sb); 42 sb_start_pagefault(inode->i_sb);
43 43
44 /* block allocation */ 44 /* block allocation */
45 ilock = mutex_lock_op(sbi); 45 f2fs_lock_op(sbi);
46 set_new_dnode(&dn, inode, NULL, NULL, 0); 46 set_new_dnode(&dn, inode, NULL, NULL, 0);
47 err = get_dnode_of_data(&dn, page->index, ALLOC_NODE); 47 err = get_dnode_of_data(&dn, page->index, ALLOC_NODE);
48 if (err) { 48 if (err) {
49 mutex_unlock_op(sbi, ilock); 49 f2fs_unlock_op(sbi);
50 goto out; 50 goto out;
51 } 51 }
52 52
@@ -56,12 +56,12 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
56 err = reserve_new_block(&dn); 56 err = reserve_new_block(&dn);
57 if (err) { 57 if (err) {
58 f2fs_put_dnode(&dn); 58 f2fs_put_dnode(&dn);
59 mutex_unlock_op(sbi, ilock); 59 f2fs_unlock_op(sbi);
60 goto out; 60 goto out;
61 } 61 }
62 } 62 }
63 f2fs_put_dnode(&dn); 63 f2fs_put_dnode(&dn);
64 mutex_unlock_op(sbi, ilock); 64 f2fs_unlock_op(sbi);
65 65
66 file_update_time(vma->vm_file); 66 file_update_time(vma->vm_file);
67 lock_page(page); 67 lock_page(page);
@@ -270,7 +270,7 @@ static int truncate_blocks(struct inode *inode, u64 from)
270 unsigned int blocksize = inode->i_sb->s_blocksize; 270 unsigned int blocksize = inode->i_sb->s_blocksize;
271 struct dnode_of_data dn; 271 struct dnode_of_data dn;
272 pgoff_t free_from; 272 pgoff_t free_from;
273 int count = 0, ilock = -1; 273 int count = 0;
274 int err; 274 int err;
275 275
276 trace_f2fs_truncate_blocks_enter(inode, from); 276 trace_f2fs_truncate_blocks_enter(inode, from);
@@ -278,13 +278,13 @@ static int truncate_blocks(struct inode *inode, u64 from)
278 free_from = (pgoff_t) 278 free_from = (pgoff_t)
279 ((from + blocksize - 1) >> (sbi->log_blocksize)); 279 ((from + blocksize - 1) >> (sbi->log_blocksize));
280 280
281 ilock = mutex_lock_op(sbi); 281 f2fs_lock_op(sbi);
282 set_new_dnode(&dn, inode, NULL, NULL, 0); 282 set_new_dnode(&dn, inode, NULL, NULL, 0);
283 err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE); 283 err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE);
284 if (err) { 284 if (err) {
285 if (err == -ENOENT) 285 if (err == -ENOENT)
286 goto free_next; 286 goto free_next;
287 mutex_unlock_op(sbi, ilock); 287 f2fs_unlock_op(sbi);
288 trace_f2fs_truncate_blocks_exit(inode, err); 288 trace_f2fs_truncate_blocks_exit(inode, err);
289 return err; 289 return err;
290 } 290 }
@@ -305,7 +305,7 @@ static int truncate_blocks(struct inode *inode, u64 from)
305 f2fs_put_dnode(&dn); 305 f2fs_put_dnode(&dn);
306free_next: 306free_next:
307 err = truncate_inode_blocks(inode, free_from); 307 err = truncate_inode_blocks(inode, free_from);
308 mutex_unlock_op(sbi, ilock); 308 f2fs_unlock_op(sbi);
309 309
310 /* lastly zero out the first data page */ 310 /* lastly zero out the first data page */
311 truncate_partial_data_page(inode, from); 311 truncate_partial_data_page(inode, from);
@@ -416,16 +416,15 @@ static void fill_zero(struct inode *inode, pgoff_t index,
416{ 416{
417 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 417 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
418 struct page *page; 418 struct page *page;
419 int ilock;
420 419
421 if (!len) 420 if (!len)
422 return; 421 return;
423 422
424 f2fs_balance_fs(sbi); 423 f2fs_balance_fs(sbi);
425 424
426 ilock = mutex_lock_op(sbi); 425 f2fs_lock_op(sbi);
427 page = get_new_data_page(inode, NULL, index, false); 426 page = get_new_data_page(inode, NULL, index, false);
428 mutex_unlock_op(sbi, ilock); 427 f2fs_unlock_op(sbi);
429 428
430 if (!IS_ERR(page)) { 429 if (!IS_ERR(page)) {
431 wait_on_page_writeback(page); 430 wait_on_page_writeback(page);
@@ -484,7 +483,6 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode)
484 struct address_space *mapping = inode->i_mapping; 483 struct address_space *mapping = inode->i_mapping;
485 loff_t blk_start, blk_end; 484 loff_t blk_start, blk_end;
486 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 485 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
487 int ilock;
488 486
489 f2fs_balance_fs(sbi); 487 f2fs_balance_fs(sbi);
490 488
@@ -493,9 +491,9 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len, int mode)
493 truncate_inode_pages_range(mapping, blk_start, 491 truncate_inode_pages_range(mapping, blk_start,
494 blk_end - 1); 492 blk_end - 1);
495 493
496 ilock = mutex_lock_op(sbi); 494 f2fs_lock_op(sbi);
497 ret = truncate_hole(inode, pg_start, pg_end); 495 ret = truncate_hole(inode, pg_start, pg_end);
498 mutex_unlock_op(sbi, ilock); 496 f2fs_unlock_op(sbi);
499 } 497 }
500 } 498 }
501 499
@@ -529,13 +527,12 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
529 527
530 for (index = pg_start; index <= pg_end; index++) { 528 for (index = pg_start; index <= pg_end; index++) {
531 struct dnode_of_data dn; 529 struct dnode_of_data dn;
532 int ilock;
533 530
534 ilock = mutex_lock_op(sbi); 531 f2fs_lock_op(sbi);
535 set_new_dnode(&dn, inode, NULL, NULL, 0); 532 set_new_dnode(&dn, inode, NULL, NULL, 0);
536 ret = get_dnode_of_data(&dn, index, ALLOC_NODE); 533 ret = get_dnode_of_data(&dn, index, ALLOC_NODE);
537 if (ret) { 534 if (ret) {
538 mutex_unlock_op(sbi, ilock); 535 f2fs_unlock_op(sbi);
539 break; 536 break;
540 } 537 }
541 538
@@ -543,12 +540,12 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
543 ret = reserve_new_block(&dn); 540 ret = reserve_new_block(&dn);
544 if (ret) { 541 if (ret) {
545 f2fs_put_dnode(&dn); 542 f2fs_put_dnode(&dn);
546 mutex_unlock_op(sbi, ilock); 543 f2fs_unlock_op(sbi);
547 break; 544 break;
548 } 545 }
549 } 546 }
550 f2fs_put_dnode(&dn); 547 f2fs_put_dnode(&dn);
551 mutex_unlock_op(sbi, ilock); 548 f2fs_unlock_op(sbi);
552 549
553 if (pg_start == pg_end) 550 if (pg_start == pg_end)
554 new_size = offset + len; 551 new_size = offset + len;
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 9339cd292047..c8c058024af8 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -214,7 +214,7 @@ int update_inode_page(struct inode *inode)
214int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) 214int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
215{ 215{
216 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 216 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
217 int ret, ilock; 217 int ret;
218 218
219 if (inode->i_ino == F2FS_NODE_INO(sbi) || 219 if (inode->i_ino == F2FS_NODE_INO(sbi) ||
220 inode->i_ino == F2FS_META_INO(sbi)) 220 inode->i_ino == F2FS_META_INO(sbi))
@@ -227,9 +227,9 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
227 * We need to lock here to prevent from producing dirty node pages 227 * We need to lock here to prevent from producing dirty node pages
228 * during the urgent cleaning time when runing out of free sections. 228 * during the urgent cleaning time when runing out of free sections.
229 */ 229 */
230 ilock = mutex_lock_op(sbi); 230 f2fs_lock_op(sbi);
231 ret = update_inode_page(inode); 231 ret = update_inode_page(inode);
232 mutex_unlock_op(sbi, ilock); 232 f2fs_unlock_op(sbi);
233 233
234 if (wbc) 234 if (wbc)
235 f2fs_balance_fs(sbi); 235 f2fs_balance_fs(sbi);
@@ -243,7 +243,6 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
243void f2fs_evict_inode(struct inode *inode) 243void f2fs_evict_inode(struct inode *inode)
244{ 244{
245 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 245 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
246 int ilock;
247 246
248 trace_f2fs_evict_inode(inode); 247 trace_f2fs_evict_inode(inode);
249 truncate_inode_pages(&inode->i_data, 0); 248 truncate_inode_pages(&inode->i_data, 0);
@@ -265,9 +264,9 @@ void f2fs_evict_inode(struct inode *inode)
265 if (F2FS_HAS_BLOCKS(inode)) 264 if (F2FS_HAS_BLOCKS(inode))
266 f2fs_truncate(inode); 265 f2fs_truncate(inode);
267 266
268 ilock = mutex_lock_op(sbi); 267 f2fs_lock_op(sbi);
269 remove_inode_page(inode); 268 remove_inode_page(inode);
270 mutex_unlock_op(sbi, ilock); 269 f2fs_unlock_op(sbi);
271 270
272 sb_end_intwrite(inode->i_sb); 271 sb_end_intwrite(inode->i_sb);
273no_delete: 272no_delete:
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 2a5359c990fc..29f73fdf958e 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -27,19 +27,19 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
27 nid_t ino; 27 nid_t ino;
28 struct inode *inode; 28 struct inode *inode;
29 bool nid_free = false; 29 bool nid_free = false;
30 int err, ilock; 30 int err;
31 31
32 inode = new_inode(sb); 32 inode = new_inode(sb);
33 if (!inode) 33 if (!inode)
34 return ERR_PTR(-ENOMEM); 34 return ERR_PTR(-ENOMEM);
35 35
36 ilock = mutex_lock_op(sbi); 36 f2fs_lock_op(sbi);
37 if (!alloc_nid(sbi, &ino)) { 37 if (!alloc_nid(sbi, &ino)) {
38 mutex_unlock_op(sbi, ilock); 38 f2fs_unlock_op(sbi);
39 err = -ENOSPC; 39 err = -ENOSPC;
40 goto fail; 40 goto fail;
41 } 41 }
42 mutex_unlock_op(sbi, ilock); 42 f2fs_unlock_op(sbi);
43 43
44 inode->i_uid = current_fsuid(); 44 inode->i_uid = current_fsuid();
45 45
@@ -115,7 +115,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
115 struct f2fs_sb_info *sbi = F2FS_SB(sb); 115 struct f2fs_sb_info *sbi = F2FS_SB(sb);
116 struct inode *inode; 116 struct inode *inode;
117 nid_t ino = 0; 117 nid_t ino = 0;
118 int err, ilock; 118 int err;
119 119
120 f2fs_balance_fs(sbi); 120 f2fs_balance_fs(sbi);
121 121
@@ -131,9 +131,9 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
131 inode->i_mapping->a_ops = &f2fs_dblock_aops; 131 inode->i_mapping->a_ops = &f2fs_dblock_aops;
132 ino = inode->i_ino; 132 ino = inode->i_ino;
133 133
134 ilock = mutex_lock_op(sbi); 134 f2fs_lock_op(sbi);
135 err = f2fs_add_link(dentry, inode); 135 err = f2fs_add_link(dentry, inode);
136 mutex_unlock_op(sbi, ilock); 136 f2fs_unlock_op(sbi);
137 if (err) 137 if (err)
138 goto out; 138 goto out;
139 139
@@ -157,7 +157,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
157 struct inode *inode = old_dentry->d_inode; 157 struct inode *inode = old_dentry->d_inode;
158 struct super_block *sb = dir->i_sb; 158 struct super_block *sb = dir->i_sb;
159 struct f2fs_sb_info *sbi = F2FS_SB(sb); 159 struct f2fs_sb_info *sbi = F2FS_SB(sb);
160 int err, ilock; 160 int err;
161 161
162 f2fs_balance_fs(sbi); 162 f2fs_balance_fs(sbi);
163 163
@@ -165,9 +165,9 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
165 ihold(inode); 165 ihold(inode);
166 166
167 set_inode_flag(F2FS_I(inode), FI_INC_LINK); 167 set_inode_flag(F2FS_I(inode), FI_INC_LINK);
168 ilock = mutex_lock_op(sbi); 168 f2fs_lock_op(sbi);
169 err = f2fs_add_link(dentry, inode); 169 err = f2fs_add_link(dentry, inode);
170 mutex_unlock_op(sbi, ilock); 170 f2fs_unlock_op(sbi);
171 if (err) 171 if (err)
172 goto out; 172 goto out;
173 173
@@ -220,7 +220,6 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
220 struct f2fs_dir_entry *de; 220 struct f2fs_dir_entry *de;
221 struct page *page; 221 struct page *page;
222 int err = -ENOENT; 222 int err = -ENOENT;
223 int ilock;
224 223
225 trace_f2fs_unlink_enter(dir, dentry); 224 trace_f2fs_unlink_enter(dir, dentry);
226 f2fs_balance_fs(sbi); 225 f2fs_balance_fs(sbi);
@@ -236,9 +235,9 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
236 goto fail; 235 goto fail;
237 } 236 }
238 237
239 ilock = mutex_lock_op(sbi); 238 f2fs_lock_op(sbi);
240 f2fs_delete_entry(de, page, inode); 239 f2fs_delete_entry(de, page, inode);
241 mutex_unlock_op(sbi, ilock); 240 f2fs_unlock_op(sbi);
242 241
243 /* In order to evict this inode, we set it dirty */ 242 /* In order to evict this inode, we set it dirty */
244 mark_inode_dirty(inode); 243 mark_inode_dirty(inode);
@@ -254,7 +253,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
254 struct f2fs_sb_info *sbi = F2FS_SB(sb); 253 struct f2fs_sb_info *sbi = F2FS_SB(sb);
255 struct inode *inode; 254 struct inode *inode;
256 size_t symlen = strlen(symname) + 1; 255 size_t symlen = strlen(symname) + 1;
257 int err, ilock; 256 int err;
258 257
259 f2fs_balance_fs(sbi); 258 f2fs_balance_fs(sbi);
260 259
@@ -265,9 +264,9 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
265 inode->i_op = &f2fs_symlink_inode_operations; 264 inode->i_op = &f2fs_symlink_inode_operations;
266 inode->i_mapping->a_ops = &f2fs_dblock_aops; 265 inode->i_mapping->a_ops = &f2fs_dblock_aops;
267 266
268 ilock = mutex_lock_op(sbi); 267 f2fs_lock_op(sbi);
269 err = f2fs_add_link(dentry, inode); 268 err = f2fs_add_link(dentry, inode);
270 mutex_unlock_op(sbi, ilock); 269 f2fs_unlock_op(sbi);
271 if (err) 270 if (err)
272 goto out; 271 goto out;
273 272
@@ -290,7 +289,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
290{ 289{
291 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 290 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
292 struct inode *inode; 291 struct inode *inode;
293 int err, ilock; 292 int err;
294 293
295 f2fs_balance_fs(sbi); 294 f2fs_balance_fs(sbi);
296 295
@@ -304,9 +303,9 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
304 mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO); 303 mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
305 304
306 set_inode_flag(F2FS_I(inode), FI_INC_LINK); 305 set_inode_flag(F2FS_I(inode), FI_INC_LINK);
307 ilock = mutex_lock_op(sbi); 306 f2fs_lock_op(sbi);
308 err = f2fs_add_link(dentry, inode); 307 err = f2fs_add_link(dentry, inode);
309 mutex_unlock_op(sbi, ilock); 308 f2fs_unlock_op(sbi);
310 if (err) 309 if (err)
311 goto out_fail; 310 goto out_fail;
312 311
@@ -342,7 +341,6 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
342 struct f2fs_sb_info *sbi = F2FS_SB(sb); 341 struct f2fs_sb_info *sbi = F2FS_SB(sb);
343 struct inode *inode; 342 struct inode *inode;
344 int err = 0; 343 int err = 0;
345 int ilock;
346 344
347 if (!new_valid_dev(rdev)) 345 if (!new_valid_dev(rdev))
348 return -EINVAL; 346 return -EINVAL;
@@ -356,9 +354,9 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
356 init_special_inode(inode, inode->i_mode, rdev); 354 init_special_inode(inode, inode->i_mode, rdev);
357 inode->i_op = &f2fs_special_inode_operations; 355 inode->i_op = &f2fs_special_inode_operations;
358 356
359 ilock = mutex_lock_op(sbi); 357 f2fs_lock_op(sbi);
360 err = f2fs_add_link(dentry, inode); 358 err = f2fs_add_link(dentry, inode);
361 mutex_unlock_op(sbi, ilock); 359 f2fs_unlock_op(sbi);
362 if (err) 360 if (err)
363 goto out; 361 goto out;
364 362
@@ -387,7 +385,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
387 struct f2fs_dir_entry *old_dir_entry = NULL; 385 struct f2fs_dir_entry *old_dir_entry = NULL;
388 struct f2fs_dir_entry *old_entry; 386 struct f2fs_dir_entry *old_entry;
389 struct f2fs_dir_entry *new_entry; 387 struct f2fs_dir_entry *new_entry;
390 int err = -ENOENT, ilock = -1; 388 int err = -ENOENT;
391 389
392 f2fs_balance_fs(sbi); 390 f2fs_balance_fs(sbi);
393 391
@@ -402,7 +400,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
402 goto out_old; 400 goto out_old;
403 } 401 }
404 402
405 ilock = mutex_lock_op(sbi); 403 f2fs_lock_op(sbi);
406 404
407 if (new_inode) { 405 if (new_inode) {
408 406
@@ -467,7 +465,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
467 update_inode_page(old_dir); 465 update_inode_page(old_dir);
468 } 466 }
469 467
470 mutex_unlock_op(sbi, ilock); 468 f2fs_unlock_op(sbi);
471 return 0; 469 return 0;
472 470
473put_out_dir: 471put_out_dir:
@@ -477,7 +475,7 @@ out_dir:
477 kunmap(old_dir_page); 475 kunmap(old_dir_page);
478 f2fs_put_page(old_dir_page, 0); 476 f2fs_put_page(old_dir_page, 0);
479 } 477 }
480 mutex_unlock_op(sbi, ilock); 478 f2fs_unlock_op(sbi);
481out_old: 479out_old:
482 kunmap(old_page); 480 kunmap(old_page);
483 f2fs_put_page(old_page, 0); 481 f2fs_put_page(old_page, 0);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index a15d122fdc50..353cf4f66c7b 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -292,7 +292,6 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
292 struct f2fs_summary sum; 292 struct f2fs_summary sum;
293 struct node_info ni; 293 struct node_info ni;
294 int err = 0, recovered = 0; 294 int err = 0, recovered = 0;
295 int ilock;
296 295
297 start = start_bidx_of_node(ofs_of_node(page), fi); 296 start = start_bidx_of_node(ofs_of_node(page), fi);
298 if (IS_INODE(page)) 297 if (IS_INODE(page))
@@ -300,12 +299,12 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
300 else 299 else
301 end = start + ADDRS_PER_BLOCK; 300 end = start + ADDRS_PER_BLOCK;
302 301
303 ilock = mutex_lock_op(sbi); 302 f2fs_lock_op(sbi);
304 set_new_dnode(&dn, inode, NULL, NULL, 0); 303 set_new_dnode(&dn, inode, NULL, NULL, 0);
305 304
306 err = get_dnode_of_data(&dn, start, ALLOC_NODE); 305 err = get_dnode_of_data(&dn, start, ALLOC_NODE);
307 if (err) { 306 if (err) {
308 mutex_unlock_op(sbi, ilock); 307 f2fs_unlock_op(sbi);
309 return err; 308 return err;
310 } 309 }
311 310
@@ -356,7 +355,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
356 recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr); 355 recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr);
357err: 356err:
358 f2fs_put_dnode(&dn); 357 f2fs_put_dnode(&dn);
359 mutex_unlock_op(sbi, ilock); 358 f2fs_unlock_op(sbi);
360 359
361 f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, " 360 f2fs_msg(sbi->sb, KERN_NOTICE, "recover_data: ino = %lx, "
362 "recovered_data = %d blocks, err = %d", 361 "recovered_data = %d blocks, err = %d",
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 13d0a0fe49dd..347d70049288 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -760,7 +760,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
760 struct buffer_head *raw_super_buf; 760 struct buffer_head *raw_super_buf;
761 struct inode *root; 761 struct inode *root;
762 long err = -EINVAL; 762 long err = -EINVAL;
763 int i;
764 763
765 /* allocate memory for f2fs-specific super block info */ 764 /* allocate memory for f2fs-specific super block info */
766 sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); 765 sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL);
@@ -818,12 +817,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
818 mutex_init(&sbi->gc_mutex); 817 mutex_init(&sbi->gc_mutex);
819 mutex_init(&sbi->writepages); 818 mutex_init(&sbi->writepages);
820 mutex_init(&sbi->cp_mutex); 819 mutex_init(&sbi->cp_mutex);
821 for (i = 0; i < NR_GLOBAL_LOCKS; i++)
822 mutex_init(&sbi->fs_lock[i]);
823 mutex_init(&sbi->node_write); 820 mutex_init(&sbi->node_write);
824 sbi->por_doing = 0; 821 sbi->por_doing = 0;
825 spin_lock_init(&sbi->stat_lock); 822 spin_lock_init(&sbi->stat_lock);
826 init_rwsem(&sbi->bio_sem); 823 init_rwsem(&sbi->bio_sem);
824 init_rwsem(&sbi->cp_rwsem);
825 init_waitqueue_head(&sbi->cp_wait);
827 init_sb_info(sbi); 826 init_sb_info(sbi);
828 827
829 /* get an inode for meta space */ 828 /* get an inode for meta space */
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 3d900ea34e47..f685138dd496 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -584,16 +584,13 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
584 const void *value, size_t value_len, struct page *ipage) 584 const void *value, size_t value_len, struct page *ipage)
585{ 585{
586 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 586 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
587 int ilock;
588 int err; 587 int err;
589 588
590 f2fs_balance_fs(sbi); 589 f2fs_balance_fs(sbi);
591 590
592 ilock = mutex_lock_op(sbi); 591 f2fs_lock_op(sbi);
593
594 err = __f2fs_setxattr(inode, name_index, name, value, value_len, ipage); 592 err = __f2fs_setxattr(inode, name_index, name, value, value_len, ipage);
595 593 f2fs_unlock_op(sbi);
596 mutex_unlock_op(sbi, ilock);
597 594
598 return err; 595 return err;
599} 596}