diff options
Diffstat (limited to 'fs/f2fs/extent_cache.c')
-rw-r--r-- | fs/f2fs/extent_cache.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 4db44da7ef69..c6934f014e0f 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c | |||
@@ -77,7 +77,7 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) | |||
77 | struct extent_tree *et; | 77 | struct extent_tree *et; |
78 | nid_t ino = inode->i_ino; | 78 | nid_t ino = inode->i_ino; |
79 | 79 | ||
80 | down_write(&sbi->extent_tree_lock); | 80 | mutex_lock(&sbi->extent_tree_lock); |
81 | et = radix_tree_lookup(&sbi->extent_tree_root, ino); | 81 | et = radix_tree_lookup(&sbi->extent_tree_root, ino); |
82 | if (!et) { | 82 | if (!et) { |
83 | et = f2fs_kmem_cache_alloc(extent_tree_slab, GFP_NOFS); | 83 | et = f2fs_kmem_cache_alloc(extent_tree_slab, GFP_NOFS); |
@@ -94,7 +94,7 @@ static struct extent_tree *__grab_extent_tree(struct inode *inode) | |||
94 | atomic_dec(&sbi->total_zombie_tree); | 94 | atomic_dec(&sbi->total_zombie_tree); |
95 | list_del_init(&et->list); | 95 | list_del_init(&et->list); |
96 | } | 96 | } |
97 | up_write(&sbi->extent_tree_lock); | 97 | mutex_unlock(&sbi->extent_tree_lock); |
98 | 98 | ||
99 | /* never died until evict_inode */ | 99 | /* never died until evict_inode */ |
100 | F2FS_I(inode)->extent_tree = et; | 100 | F2FS_I(inode)->extent_tree = et; |
@@ -311,28 +311,24 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et, | |||
311 | tmp_node = parent; | 311 | tmp_node = parent; |
312 | if (parent && fofs > en->ei.fofs) | 312 | if (parent && fofs > en->ei.fofs) |
313 | tmp_node = rb_next(parent); | 313 | tmp_node = rb_next(parent); |
314 | *next_ex = tmp_node ? | 314 | *next_ex = rb_entry_safe(tmp_node, struct extent_node, rb_node); |
315 | rb_entry(tmp_node, struct extent_node, rb_node) : NULL; | ||
316 | 315 | ||
317 | tmp_node = parent; | 316 | tmp_node = parent; |
318 | if (parent && fofs < en->ei.fofs) | 317 | if (parent && fofs < en->ei.fofs) |
319 | tmp_node = rb_prev(parent); | 318 | tmp_node = rb_prev(parent); |
320 | *prev_ex = tmp_node ? | 319 | *prev_ex = rb_entry_safe(tmp_node, struct extent_node, rb_node); |
321 | rb_entry(tmp_node, struct extent_node, rb_node) : NULL; | ||
322 | return NULL; | 320 | return NULL; |
323 | 321 | ||
324 | lookup_neighbors: | 322 | lookup_neighbors: |
325 | if (fofs == en->ei.fofs) { | 323 | if (fofs == en->ei.fofs) { |
326 | /* lookup prev node for merging backward later */ | 324 | /* lookup prev node for merging backward later */ |
327 | tmp_node = rb_prev(&en->rb_node); | 325 | tmp_node = rb_prev(&en->rb_node); |
328 | *prev_ex = tmp_node ? | 326 | *prev_ex = rb_entry_safe(tmp_node, struct extent_node, rb_node); |
329 | rb_entry(tmp_node, struct extent_node, rb_node) : NULL; | ||
330 | } | 327 | } |
331 | if (fofs == en->ei.fofs + en->ei.len - 1) { | 328 | if (fofs == en->ei.fofs + en->ei.len - 1) { |
332 | /* lookup next node for merging frontward later */ | 329 | /* lookup next node for merging frontward later */ |
333 | tmp_node = rb_next(&en->rb_node); | 330 | tmp_node = rb_next(&en->rb_node); |
334 | *next_ex = tmp_node ? | 331 | *next_ex = rb_entry_safe(tmp_node, struct extent_node, rb_node); |
335 | rb_entry(tmp_node, struct extent_node, rb_node) : NULL; | ||
336 | } | 332 | } |
337 | return en; | 333 | return en; |
338 | } | 334 | } |
@@ -352,11 +348,12 @@ static struct extent_node *__try_merge_extent_node(struct inode *inode, | |||
352 | } | 348 | } |
353 | 349 | ||
354 | if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) { | 350 | if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) { |
355 | if (en) | ||
356 | __release_extent_node(sbi, et, prev_ex); | ||
357 | next_ex->ei.fofs = ei->fofs; | 351 | next_ex->ei.fofs = ei->fofs; |
358 | next_ex->ei.blk = ei->blk; | 352 | next_ex->ei.blk = ei->blk; |
359 | next_ex->ei.len += ei->len; | 353 | next_ex->ei.len += ei->len; |
354 | if (en) | ||
355 | __release_extent_node(sbi, et, prev_ex); | ||
356 | |||
360 | en = next_ex; | 357 | en = next_ex; |
361 | } | 358 | } |
362 | 359 | ||
@@ -416,7 +413,7 @@ do_insert: | |||
416 | return en; | 413 | return en; |
417 | } | 414 | } |
418 | 415 | ||
419 | static unsigned int f2fs_update_extent_tree_range(struct inode *inode, | 416 | static void f2fs_update_extent_tree_range(struct inode *inode, |
420 | pgoff_t fofs, block_t blkaddr, unsigned int len) | 417 | pgoff_t fofs, block_t blkaddr, unsigned int len) |
421 | { | 418 | { |
422 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 419 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
@@ -429,7 +426,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
429 | unsigned int pos = (unsigned int)fofs; | 426 | unsigned int pos = (unsigned int)fofs; |
430 | 427 | ||
431 | if (!et) | 428 | if (!et) |
432 | return false; | 429 | return; |
433 | 430 | ||
434 | trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len); | 431 | trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, len); |
435 | 432 | ||
@@ -437,7 +434,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
437 | 434 | ||
438 | if (is_inode_flag_set(inode, FI_NO_EXTENT)) { | 435 | if (is_inode_flag_set(inode, FI_NO_EXTENT)) { |
439 | write_unlock(&et->lock); | 436 | write_unlock(&et->lock); |
440 | return false; | 437 | return; |
441 | } | 438 | } |
442 | 439 | ||
443 | prev = et->largest; | 440 | prev = et->largest; |
@@ -492,9 +489,8 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
492 | if (!next_en) { | 489 | if (!next_en) { |
493 | struct rb_node *node = rb_next(&en->rb_node); | 490 | struct rb_node *node = rb_next(&en->rb_node); |
494 | 491 | ||
495 | next_en = node ? | 492 | next_en = rb_entry_safe(node, struct extent_node, |
496 | rb_entry(node, struct extent_node, rb_node) | 493 | rb_node); |
497 | : NULL; | ||
498 | } | 494 | } |
499 | 495 | ||
500 | if (parts) | 496 | if (parts) |
@@ -535,8 +531,6 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode, | |||
535 | __free_extent_tree(sbi, et); | 531 | __free_extent_tree(sbi, et); |
536 | 532 | ||
537 | write_unlock(&et->lock); | 533 | write_unlock(&et->lock); |
538 | |||
539 | return !__is_extent_same(&prev, &et->largest); | ||
540 | } | 534 | } |
541 | 535 | ||
542 | unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | 536 | unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) |
@@ -552,7 +546,7 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | |||
552 | if (!atomic_read(&sbi->total_zombie_tree)) | 546 | if (!atomic_read(&sbi->total_zombie_tree)) |
553 | goto free_node; | 547 | goto free_node; |
554 | 548 | ||
555 | if (!down_write_trylock(&sbi->extent_tree_lock)) | 549 | if (!mutex_trylock(&sbi->extent_tree_lock)) |
556 | goto out; | 550 | goto out; |
557 | 551 | ||
558 | /* 1. remove unreferenced extent tree */ | 552 | /* 1. remove unreferenced extent tree */ |
@@ -574,11 +568,11 @@ unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) | |||
574 | goto unlock_out; | 568 | goto unlock_out; |
575 | cond_resched(); | 569 | cond_resched(); |
576 | } | 570 | } |
577 | up_write(&sbi->extent_tree_lock); | 571 | mutex_unlock(&sbi->extent_tree_lock); |
578 | 572 | ||
579 | free_node: | 573 | free_node: |
580 | /* 2. remove LRU extent entries */ | 574 | /* 2. remove LRU extent entries */ |
581 | if (!down_write_trylock(&sbi->extent_tree_lock)) | 575 | if (!mutex_trylock(&sbi->extent_tree_lock)) |
582 | goto out; | 576 | goto out; |
583 | 577 | ||
584 | remained = nr_shrink - (node_cnt + tree_cnt); | 578 | remained = nr_shrink - (node_cnt + tree_cnt); |
@@ -608,7 +602,7 @@ free_node: | |||
608 | spin_unlock(&sbi->extent_lock); | 602 | spin_unlock(&sbi->extent_lock); |
609 | 603 | ||
610 | unlock_out: | 604 | unlock_out: |
611 | up_write(&sbi->extent_tree_lock); | 605 | mutex_unlock(&sbi->extent_tree_lock); |
612 | out: | 606 | out: |
613 | trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt); | 607 | trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt); |
614 | 608 | ||
@@ -655,10 +649,10 @@ void f2fs_destroy_extent_tree(struct inode *inode) | |||
655 | 649 | ||
656 | if (inode->i_nlink && !is_bad_inode(inode) && | 650 | if (inode->i_nlink && !is_bad_inode(inode) && |
657 | atomic_read(&et->node_cnt)) { | 651 | atomic_read(&et->node_cnt)) { |
658 | down_write(&sbi->extent_tree_lock); | 652 | mutex_lock(&sbi->extent_tree_lock); |
659 | list_add_tail(&et->list, &sbi->zombie_list); | 653 | list_add_tail(&et->list, &sbi->zombie_list); |
660 | atomic_inc(&sbi->total_zombie_tree); | 654 | atomic_inc(&sbi->total_zombie_tree); |
661 | up_write(&sbi->extent_tree_lock); | 655 | mutex_unlock(&sbi->extent_tree_lock); |
662 | return; | 656 | return; |
663 | } | 657 | } |
664 | 658 | ||
@@ -666,12 +660,12 @@ void f2fs_destroy_extent_tree(struct inode *inode) | |||
666 | node_cnt = f2fs_destroy_extent_node(inode); | 660 | node_cnt = f2fs_destroy_extent_node(inode); |
667 | 661 | ||
668 | /* delete extent tree entry in radix tree */ | 662 | /* delete extent tree entry in radix tree */ |
669 | down_write(&sbi->extent_tree_lock); | 663 | mutex_lock(&sbi->extent_tree_lock); |
670 | f2fs_bug_on(sbi, atomic_read(&et->node_cnt)); | 664 | f2fs_bug_on(sbi, atomic_read(&et->node_cnt)); |
671 | radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); | 665 | radix_tree_delete(&sbi->extent_tree_root, inode->i_ino); |
672 | kmem_cache_free(extent_tree_slab, et); | 666 | kmem_cache_free(extent_tree_slab, et); |
673 | atomic_dec(&sbi->total_ext_tree); | 667 | atomic_dec(&sbi->total_ext_tree); |
674 | up_write(&sbi->extent_tree_lock); | 668 | mutex_unlock(&sbi->extent_tree_lock); |
675 | 669 | ||
676 | F2FS_I(inode)->extent_tree = NULL; | 670 | F2FS_I(inode)->extent_tree = NULL; |
677 | 671 | ||
@@ -718,7 +712,7 @@ void f2fs_update_extent_cache_range(struct dnode_of_data *dn, | |||
718 | void init_extent_cache_info(struct f2fs_sb_info *sbi) | 712 | void init_extent_cache_info(struct f2fs_sb_info *sbi) |
719 | { | 713 | { |
720 | INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO); | 714 | INIT_RADIX_TREE(&sbi->extent_tree_root, GFP_NOIO); |
721 | init_rwsem(&sbi->extent_tree_lock); | 715 | mutex_init(&sbi->extent_tree_lock); |
722 | INIT_LIST_HEAD(&sbi->extent_list); | 716 | INIT_LIST_HEAD(&sbi->extent_list); |
723 | spin_lock_init(&sbi->extent_lock); | 717 | spin_lock_init(&sbi->extent_lock); |
724 | atomic_set(&sbi->total_ext_tree, 0); | 718 | atomic_set(&sbi->total_ext_tree, 0); |