diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 344 |
1 files changed, 94 insertions, 250 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 7f8af1eb02de..00f6e3d62c22 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/prefetch.h> | 16 | #include <linux/prefetch.h> |
17 | #include <linux/blkdev.h> | 17 | #include <linux/blkdev.h> |
18 | #include <linux/rbtree.h> | ||
18 | 19 | ||
19 | #include "gfs2.h" | 20 | #include "gfs2.h" |
20 | #include "incore.h" | 21 | #include "incore.h" |
@@ -328,15 +329,25 @@ static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block) | |||
328 | 329 | ||
329 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) | 330 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) |
330 | { | 331 | { |
331 | struct gfs2_rgrpd *rgd; | 332 | struct rb_node **newn, *parent = NULL; |
332 | 333 | ||
333 | spin_lock(&sdp->sd_rindex_spin); | 334 | spin_lock(&sdp->sd_rindex_spin); |
334 | 335 | ||
335 | list_for_each_entry(rgd, &sdp->sd_rindex_mru_list, rd_list_mru) { | 336 | newn = &sdp->sd_rindex_tree.rb_node; |
336 | if (rgrp_contains_block(rgd, blk)) { | 337 | |
337 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | 338 | /* Figure out where to put new node */ |
339 | while (*newn) { | ||
340 | struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd, | ||
341 | rd_node); | ||
342 | |||
343 | parent = *newn; | ||
344 | if (blk < cur->rd_addr) | ||
345 | newn = &((*newn)->rb_left); | ||
346 | else if (blk > cur->rd_data0 + cur->rd_data) | ||
347 | newn = &((*newn)->rb_right); | ||
348 | else { | ||
338 | spin_unlock(&sdp->sd_rindex_spin); | 349 | spin_unlock(&sdp->sd_rindex_spin); |
339 | return rgd; | 350 | return cur; |
340 | } | 351 | } |
341 | } | 352 | } |
342 | 353 | ||
@@ -354,8 +365,13 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk) | |||
354 | 365 | ||
355 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) | 366 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) |
356 | { | 367 | { |
357 | gfs2_assert(sdp, !list_empty(&sdp->sd_rindex_list)); | 368 | const struct rb_node *n; |
358 | return list_entry(sdp->sd_rindex_list.next, struct gfs2_rgrpd, rd_list); | 369 | struct gfs2_rgrpd *rgd; |
370 | |||
371 | n = rb_first(&sdp->sd_rindex_tree); | ||
372 | rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); | ||
373 | |||
374 | return rgd; | ||
359 | } | 375 | } |
360 | 376 | ||
361 | /** | 377 | /** |
@@ -367,28 +383,34 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp) | |||
367 | 383 | ||
368 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd) | 384 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd) |
369 | { | 385 | { |
370 | if (rgd->rd_list.next == &rgd->rd_sbd->sd_rindex_list) | 386 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
387 | const struct rb_node *n; | ||
388 | |||
389 | spin_lock(&sdp->sd_rindex_spin); | ||
390 | n = rb_next(&rgd->rd_node); | ||
391 | if (n == NULL) | ||
392 | n = rb_first(&sdp->sd_rindex_tree); | ||
393 | |||
394 | if (unlikely(&rgd->rd_node == n)) { | ||
395 | spin_unlock(&sdp->sd_rindex_spin); | ||
371 | return NULL; | 396 | return NULL; |
372 | return list_entry(rgd->rd_list.next, struct gfs2_rgrpd, rd_list); | 397 | } |
398 | rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); | ||
399 | spin_unlock(&sdp->sd_rindex_spin); | ||
400 | return rgd; | ||
373 | } | 401 | } |
374 | 402 | ||
375 | static void clear_rgrpdi(struct gfs2_sbd *sdp) | 403 | static void clear_rgrpdi(struct gfs2_sbd *sdp) |
376 | { | 404 | { |
377 | struct list_head *head; | 405 | struct rb_node *n; |
378 | struct gfs2_rgrpd *rgd; | 406 | struct gfs2_rgrpd *rgd; |
379 | struct gfs2_glock *gl; | 407 | struct gfs2_glock *gl; |
380 | 408 | ||
381 | spin_lock(&sdp->sd_rindex_spin); | 409 | while ((n = rb_first(&sdp->sd_rindex_tree))) { |
382 | sdp->sd_rindex_forward = NULL; | 410 | rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); |
383 | spin_unlock(&sdp->sd_rindex_spin); | ||
384 | |||
385 | head = &sdp->sd_rindex_list; | ||
386 | while (!list_empty(head)) { | ||
387 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_list); | ||
388 | gl = rgd->rd_gl; | 411 | gl = rgd->rd_gl; |
389 | 412 | ||
390 | list_del(&rgd->rd_list); | 413 | rb_erase(n, &sdp->sd_rindex_tree); |
391 | list_del(&rgd->rd_list_mru); | ||
392 | 414 | ||
393 | if (gl) { | 415 | if (gl) { |
394 | gl->gl_object = NULL; | 416 | gl->gl_object = NULL; |
@@ -535,6 +557,29 @@ static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf) | |||
535 | rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes); | 557 | rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes); |
536 | } | 558 | } |
537 | 559 | ||
560 | static void rgd_insert(struct gfs2_rgrpd *rgd) | ||
561 | { | ||
562 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
563 | struct rb_node **newn = &sdp->sd_rindex_tree.rb_node, *parent = NULL; | ||
564 | |||
565 | /* Figure out where to put new node */ | ||
566 | while (*newn) { | ||
567 | struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd, | ||
568 | rd_node); | ||
569 | |||
570 | parent = *newn; | ||
571 | if (rgd->rd_addr < cur->rd_addr) | ||
572 | newn = &((*newn)->rb_left); | ||
573 | else if (rgd->rd_addr > cur->rd_addr) | ||
574 | newn = &((*newn)->rb_right); | ||
575 | else | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | rb_link_node(&rgd->rd_node, parent, newn); | ||
580 | rb_insert_color(&rgd->rd_node, &sdp->sd_rindex_tree); | ||
581 | } | ||
582 | |||
538 | /** | 583 | /** |
539 | * read_rindex_entry - Pull in a new resource index entry from the disk | 584 | * read_rindex_entry - Pull in a new resource index entry from the disk |
540 | * @gl: The glock covering the rindex inode | 585 | * @gl: The glock covering the rindex inode |
@@ -566,14 +611,11 @@ static int read_rindex_entry(struct gfs2_inode *ip, | |||
566 | if (!rgd) | 611 | if (!rgd) |
567 | return error; | 612 | return error; |
568 | 613 | ||
569 | mutex_init(&rgd->rd_mutex); | ||
570 | lops_init_le(&rgd->rd_le, &gfs2_rg_lops); | ||
571 | rgd->rd_sbd = sdp; | 614 | rgd->rd_sbd = sdp; |
572 | 615 | ||
573 | list_add_tail(&rgd->rd_list, &sdp->sd_rindex_list); | ||
574 | list_add_tail(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
575 | |||
576 | gfs2_rindex_in(rgd, buf); | 616 | gfs2_rindex_in(rgd, buf); |
617 | rgd_insert(rgd); | ||
618 | |||
577 | error = compute_bitstructs(rgd); | 619 | error = compute_bitstructs(rgd); |
578 | if (error) | 620 | if (error) |
579 | return error; | 621 | return error; |
@@ -585,6 +627,8 @@ static int read_rindex_entry(struct gfs2_inode *ip, | |||
585 | 627 | ||
586 | rgd->rd_gl->gl_object = rgd; | 628 | rgd->rd_gl->gl_object = rgd; |
587 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; | 629 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
630 | if (rgd->rd_data > sdp->sd_max_rg_data) | ||
631 | sdp->sd_max_rg_data = rgd->rd_data; | ||
588 | return error; | 632 | return error; |
589 | } | 633 | } |
590 | 634 | ||
@@ -601,8 +645,6 @@ int gfs2_ri_update(struct gfs2_inode *ip) | |||
601 | struct inode *inode = &ip->i_inode; | 645 | struct inode *inode = &ip->i_inode; |
602 | struct file_ra_state ra_state; | 646 | struct file_ra_state ra_state; |
603 | u64 rgrp_count = i_size_read(inode); | 647 | u64 rgrp_count = i_size_read(inode); |
604 | struct gfs2_rgrpd *rgd; | ||
605 | unsigned int max_data = 0; | ||
606 | int error; | 648 | int error; |
607 | 649 | ||
608 | do_div(rgrp_count, sizeof(struct gfs2_rindex)); | 650 | do_div(rgrp_count, sizeof(struct gfs2_rindex)); |
@@ -617,10 +659,6 @@ int gfs2_ri_update(struct gfs2_inode *ip) | |||
617 | } | 659 | } |
618 | } | 660 | } |
619 | 661 | ||
620 | list_for_each_entry(rgd, &sdp->sd_rindex_list, rd_list) | ||
621 | if (rgd->rd_data > max_data) | ||
622 | max_data = rgd->rd_data; | ||
623 | sdp->sd_max_rg_data = max_data; | ||
624 | sdp->sd_rindex_uptodate = 1; | 662 | sdp->sd_rindex_uptodate = 1; |
625 | return 0; | 663 | return 0; |
626 | } | 664 | } |
@@ -694,7 +732,7 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | |||
694 | } | 732 | } |
695 | 733 | ||
696 | /** | 734 | /** |
697 | * gfs2_rgrp_bh_get - Read in a RG's header and bitmaps | 735 | * gfs2_rgrp_go_lock - Read in a RG's header and bitmaps |
698 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | 736 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
699 | * | 737 | * |
700 | * Read in all of a Resource Group's header and bitmap blocks. | 738 | * Read in all of a Resource Group's header and bitmap blocks. |
@@ -703,8 +741,9 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | |||
703 | * Returns: errno | 741 | * Returns: errno |
704 | */ | 742 | */ |
705 | 743 | ||
706 | int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | 744 | int gfs2_rgrp_go_lock(struct gfs2_holder *gh) |
707 | { | 745 | { |
746 | struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; | ||
708 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 747 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
709 | struct gfs2_glock *gl = rgd->rd_gl; | 748 | struct gfs2_glock *gl = rgd->rd_gl; |
710 | unsigned int length = rgd->rd_length; | 749 | unsigned int length = rgd->rd_length; |
@@ -712,17 +751,6 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
712 | unsigned int x, y; | 751 | unsigned int x, y; |
713 | int error; | 752 | int error; |
714 | 753 | ||
715 | mutex_lock(&rgd->rd_mutex); | ||
716 | |||
717 | spin_lock(&sdp->sd_rindex_spin); | ||
718 | if (rgd->rd_bh_count) { | ||
719 | rgd->rd_bh_count++; | ||
720 | spin_unlock(&sdp->sd_rindex_spin); | ||
721 | mutex_unlock(&rgd->rd_mutex); | ||
722 | return 0; | ||
723 | } | ||
724 | spin_unlock(&sdp->sd_rindex_spin); | ||
725 | |||
726 | for (x = 0; x < length; x++) { | 754 | for (x = 0; x < length; x++) { |
727 | bi = rgd->rd_bits + x; | 755 | bi = rgd->rd_bits + x; |
728 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); | 756 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); |
@@ -747,15 +775,9 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
747 | clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); | 775 | clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); |
748 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); | 776 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); |
749 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); | 777 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); |
778 | rgd->rd_free_clone = rgd->rd_free; | ||
750 | } | 779 | } |
751 | 780 | ||
752 | spin_lock(&sdp->sd_rindex_spin); | ||
753 | rgd->rd_free_clone = rgd->rd_free; | ||
754 | rgd->rd_bh_count++; | ||
755 | spin_unlock(&sdp->sd_rindex_spin); | ||
756 | |||
757 | mutex_unlock(&rgd->rd_mutex); | ||
758 | |||
759 | return 0; | 781 | return 0; |
760 | 782 | ||
761 | fail: | 783 | fail: |
@@ -765,52 +787,32 @@ fail: | |||
765 | bi->bi_bh = NULL; | 787 | bi->bi_bh = NULL; |
766 | gfs2_assert_warn(sdp, !bi->bi_clone); | 788 | gfs2_assert_warn(sdp, !bi->bi_clone); |
767 | } | 789 | } |
768 | mutex_unlock(&rgd->rd_mutex); | ||
769 | 790 | ||
770 | return error; | 791 | return error; |
771 | } | 792 | } |
772 | 793 | ||
773 | void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd) | ||
774 | { | ||
775 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
776 | |||
777 | spin_lock(&sdp->sd_rindex_spin); | ||
778 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); | ||
779 | rgd->rd_bh_count++; | ||
780 | spin_unlock(&sdp->sd_rindex_spin); | ||
781 | } | ||
782 | |||
783 | /** | 794 | /** |
784 | * gfs2_rgrp_bh_put - Release RG bitmaps read in with gfs2_rgrp_bh_get() | 795 | * gfs2_rgrp_go_unlock - Release RG bitmaps read in with gfs2_rgrp_bh_get() |
785 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | 796 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
786 | * | 797 | * |
787 | */ | 798 | */ |
788 | 799 | ||
789 | void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd) | 800 | void gfs2_rgrp_go_unlock(struct gfs2_holder *gh) |
790 | { | 801 | { |
791 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 802 | struct gfs2_rgrpd *rgd = gh->gh_gl->gl_object; |
792 | int x, length = rgd->rd_length; | 803 | int x, length = rgd->rd_length; |
793 | 804 | ||
794 | spin_lock(&sdp->sd_rindex_spin); | ||
795 | gfs2_assert_warn(rgd->rd_sbd, rgd->rd_bh_count); | ||
796 | if (--rgd->rd_bh_count) { | ||
797 | spin_unlock(&sdp->sd_rindex_spin); | ||
798 | return; | ||
799 | } | ||
800 | |||
801 | for (x = 0; x < length; x++) { | 805 | for (x = 0; x < length; x++) { |
802 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | 806 | struct gfs2_bitmap *bi = rgd->rd_bits + x; |
803 | kfree(bi->bi_clone); | ||
804 | bi->bi_clone = NULL; | ||
805 | brelse(bi->bi_bh); | 807 | brelse(bi->bi_bh); |
806 | bi->bi_bh = NULL; | 808 | bi->bi_bh = NULL; |
807 | } | 809 | } |
808 | 810 | ||
809 | spin_unlock(&sdp->sd_rindex_spin); | ||
810 | } | 811 | } |
811 | 812 | ||
812 | static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | 813 | void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, |
813 | const struct gfs2_bitmap *bi) | 814 | struct buffer_head *bh, |
815 | const struct gfs2_bitmap *bi) | ||
814 | { | 816 | { |
815 | struct super_block *sb = sdp->sd_vfs; | 817 | struct super_block *sb = sdp->sd_vfs; |
816 | struct block_device *bdev = sb->s_bdev; | 818 | struct block_device *bdev = sb->s_bdev; |
@@ -823,7 +825,7 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
823 | unsigned int x; | 825 | unsigned int x; |
824 | 826 | ||
825 | for (x = 0; x < bi->bi_len; x++) { | 827 | for (x = 0; x < bi->bi_len; x++) { |
826 | const u8 *orig = bi->bi_bh->b_data + bi->bi_offset + x; | 828 | const u8 *orig = bh->b_data + bi->bi_offset + x; |
827 | const u8 *clone = bi->bi_clone + bi->bi_offset + x; | 829 | const u8 *clone = bi->bi_clone + bi->bi_offset + x; |
828 | u8 diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1)); | 830 | u8 diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1)); |
829 | diff &= 0x55; | 831 | diff &= 0x55; |
@@ -862,28 +864,6 @@ fail: | |||
862 | sdp->sd_args.ar_discard = 0; | 864 | sdp->sd_args.ar_discard = 0; |
863 | } | 865 | } |
864 | 866 | ||
865 | void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | ||
866 | { | ||
867 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
868 | unsigned int length = rgd->rd_length; | ||
869 | unsigned int x; | ||
870 | |||
871 | for (x = 0; x < length; x++) { | ||
872 | struct gfs2_bitmap *bi = rgd->rd_bits + x; | ||
873 | if (!bi->bi_clone) | ||
874 | continue; | ||
875 | if (sdp->sd_args.ar_discard) | ||
876 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi); | ||
877 | clear_bit(GBF_FULL, &bi->bi_flags); | ||
878 | memcpy(bi->bi_clone + bi->bi_offset, | ||
879 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); | ||
880 | } | ||
881 | |||
882 | spin_lock(&sdp->sd_rindex_spin); | ||
883 | rgd->rd_free_clone = rgd->rd_free; | ||
884 | spin_unlock(&sdp->sd_rindex_spin); | ||
885 | } | ||
886 | |||
887 | /** | 867 | /** |
888 | * gfs2_alloc_get - get the struct gfs2_alloc structure for an inode | 868 | * gfs2_alloc_get - get the struct gfs2_alloc structure for an inode |
889 | * @ip: the incore GFS2 inode structure | 869 | * @ip: the incore GFS2 inode structure |
@@ -911,20 +891,15 @@ struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) | |||
911 | 891 | ||
912 | static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | 892 | static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) |
913 | { | 893 | { |
914 | struct gfs2_sbd *sdp = rgd->rd_sbd; | ||
915 | int ret = 0; | ||
916 | |||
917 | if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) | 894 | if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) |
918 | return 0; | 895 | return 0; |
919 | 896 | ||
920 | spin_lock(&sdp->sd_rindex_spin); | ||
921 | if (rgd->rd_free_clone >= al->al_requested) { | 897 | if (rgd->rd_free_clone >= al->al_requested) { |
922 | al->al_rgd = rgd; | 898 | al->al_rgd = rgd; |
923 | ret = 1; | 899 | return 1; |
924 | } | 900 | } |
925 | spin_unlock(&sdp->sd_rindex_spin); | ||
926 | 901 | ||
927 | return ret; | 902 | return 0; |
928 | } | 903 | } |
929 | 904 | ||
930 | /** | 905 | /** |
@@ -992,76 +967,6 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip | |||
992 | } | 967 | } |
993 | 968 | ||
994 | /** | 969 | /** |
995 | * recent_rgrp_next - get next RG from "recent" list | ||
996 | * @cur_rgd: current rgrp | ||
997 | * | ||
998 | * Returns: The next rgrp in the recent list | ||
999 | */ | ||
1000 | |||
1001 | static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd) | ||
1002 | { | ||
1003 | struct gfs2_sbd *sdp = cur_rgd->rd_sbd; | ||
1004 | struct list_head *head; | ||
1005 | struct gfs2_rgrpd *rgd; | ||
1006 | |||
1007 | spin_lock(&sdp->sd_rindex_spin); | ||
1008 | head = &sdp->sd_rindex_mru_list; | ||
1009 | if (unlikely(cur_rgd->rd_list_mru.next == head)) { | ||
1010 | spin_unlock(&sdp->sd_rindex_spin); | ||
1011 | return NULL; | ||
1012 | } | ||
1013 | rgd = list_entry(cur_rgd->rd_list_mru.next, struct gfs2_rgrpd, rd_list_mru); | ||
1014 | spin_unlock(&sdp->sd_rindex_spin); | ||
1015 | return rgd; | ||
1016 | } | ||
1017 | |||
1018 | /** | ||
1019 | * forward_rgrp_get - get an rgrp to try next from full list | ||
1020 | * @sdp: The GFS2 superblock | ||
1021 | * | ||
1022 | * Returns: The rgrp to try next | ||
1023 | */ | ||
1024 | |||
1025 | static struct gfs2_rgrpd *forward_rgrp_get(struct gfs2_sbd *sdp) | ||
1026 | { | ||
1027 | struct gfs2_rgrpd *rgd; | ||
1028 | unsigned int journals = gfs2_jindex_size(sdp); | ||
1029 | unsigned int rg = 0, x; | ||
1030 | |||
1031 | spin_lock(&sdp->sd_rindex_spin); | ||
1032 | |||
1033 | rgd = sdp->sd_rindex_forward; | ||
1034 | if (!rgd) { | ||
1035 | if (sdp->sd_rgrps >= journals) | ||
1036 | rg = sdp->sd_rgrps * sdp->sd_jdesc->jd_jid / journals; | ||
1037 | |||
1038 | for (x = 0, rgd = gfs2_rgrpd_get_first(sdp); x < rg; | ||
1039 | x++, rgd = gfs2_rgrpd_get_next(rgd)) | ||
1040 | /* Do Nothing */; | ||
1041 | |||
1042 | sdp->sd_rindex_forward = rgd; | ||
1043 | } | ||
1044 | |||
1045 | spin_unlock(&sdp->sd_rindex_spin); | ||
1046 | |||
1047 | return rgd; | ||
1048 | } | ||
1049 | |||
1050 | /** | ||
1051 | * forward_rgrp_set - set the forward rgrp pointer | ||
1052 | * @sdp: the filesystem | ||
1053 | * @rgd: The new forward rgrp | ||
1054 | * | ||
1055 | */ | ||
1056 | |||
1057 | static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) | ||
1058 | { | ||
1059 | spin_lock(&sdp->sd_rindex_spin); | ||
1060 | sdp->sd_rindex_forward = rgd; | ||
1061 | spin_unlock(&sdp->sd_rindex_spin); | ||
1062 | } | ||
1063 | |||
1064 | /** | ||
1065 | * get_local_rgrp - Choose and lock a rgrp for allocation | 970 | * get_local_rgrp - Choose and lock a rgrp for allocation |
1066 | * @ip: the inode to reserve space for | 971 | * @ip: the inode to reserve space for |
1067 | * @rgp: the chosen and locked rgrp | 972 | * @rgp: the chosen and locked rgrp |
@@ -1076,14 +981,15 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1076 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 981 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1077 | struct gfs2_rgrpd *rgd, *begin = NULL; | 982 | struct gfs2_rgrpd *rgd, *begin = NULL; |
1078 | struct gfs2_alloc *al = ip->i_alloc; | 983 | struct gfs2_alloc *al = ip->i_alloc; |
1079 | int flags = LM_FLAG_TRY; | ||
1080 | int skipped = 0; | ||
1081 | int loops = 0; | ||
1082 | int error, rg_locked; | 984 | int error, rg_locked; |
985 | int loops = 0; | ||
1083 | 986 | ||
1084 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); | 987 | rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal); |
1085 | 988 | ||
1086 | while (rgd) { | 989 | if (rgd == NULL) |
990 | return -EBADSLT; | ||
991 | |||
992 | while (loops < 3) { | ||
1087 | rg_locked = 0; | 993 | rg_locked = 0; |
1088 | 994 | ||
1089 | if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { | 995 | if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { |
@@ -1096,80 +1002,24 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1096 | switch (error) { | 1002 | switch (error) { |
1097 | case 0: | 1003 | case 0: |
1098 | if (try_rgrp_fit(rgd, al)) | 1004 | if (try_rgrp_fit(rgd, al)) |
1099 | goto out; | 1005 | return 0; |
1100 | if (rgd->rd_flags & GFS2_RDF_CHECK) | 1006 | if (rgd->rd_flags & GFS2_RDF_CHECK) |
1101 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1007 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); |
1102 | if (!rg_locked) | 1008 | if (!rg_locked) |
1103 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1009 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1104 | /* fall through */ | 1010 | /* fall through */ |
1105 | case GLR_TRYFAILED: | 1011 | case GLR_TRYFAILED: |
1106 | rgd = recent_rgrp_next(rgd); | 1012 | rgd = gfs2_rgrpd_get_next(rgd); |
1107 | break; | 1013 | if (rgd == begin) |
1108 | 1014 | loops++; | |
1109 | default: | ||
1110 | return error; | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | /* Go through full list of rgrps */ | ||
1115 | |||
1116 | begin = rgd = forward_rgrp_get(sdp); | ||
1117 | |||
1118 | for (;;) { | ||
1119 | rg_locked = 0; | ||
1120 | |||
1121 | if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) { | ||
1122 | rg_locked = 1; | ||
1123 | error = 0; | ||
1124 | } else { | ||
1125 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, | ||
1126 | &al->al_rgd_gh); | ||
1127 | } | ||
1128 | switch (error) { | ||
1129 | case 0: | ||
1130 | if (try_rgrp_fit(rgd, al)) | ||
1131 | goto out; | ||
1132 | if (rgd->rd_flags & GFS2_RDF_CHECK) | ||
1133 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | ||
1134 | if (!rg_locked) | ||
1135 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
1136 | break; | ||
1137 | |||
1138 | case GLR_TRYFAILED: | ||
1139 | skipped++; | ||
1140 | break; | 1015 | break; |
1141 | 1016 | ||
1142 | default: | 1017 | default: |
1143 | return error; | 1018 | return error; |
1144 | } | 1019 | } |
1145 | |||
1146 | rgd = gfs2_rgrpd_get_next(rgd); | ||
1147 | if (!rgd) | ||
1148 | rgd = gfs2_rgrpd_get_first(sdp); | ||
1149 | |||
1150 | if (rgd == begin) { | ||
1151 | if (++loops >= 3) | ||
1152 | return -ENOSPC; | ||
1153 | if (!skipped) | ||
1154 | loops++; | ||
1155 | flags = 0; | ||
1156 | if (loops == 2) | ||
1157 | gfs2_log_flush(sdp, NULL); | ||
1158 | } | ||
1159 | } | ||
1160 | |||
1161 | out: | ||
1162 | if (begin) { | ||
1163 | spin_lock(&sdp->sd_rindex_spin); | ||
1164 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
1165 | spin_unlock(&sdp->sd_rindex_spin); | ||
1166 | rgd = gfs2_rgrpd_get_next(rgd); | ||
1167 | if (!rgd) | ||
1168 | rgd = gfs2_rgrpd_get_first(sdp); | ||
1169 | forward_rgrp_set(sdp, rgd); | ||
1170 | } | 1020 | } |
1171 | 1021 | ||
1172 | return 0; | 1022 | return -ENOSPC; |
1173 | } | 1023 | } |
1174 | 1024 | ||
1175 | /** | 1025 | /** |
@@ -1352,6 +1202,7 @@ do_search: | |||
1352 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | 1202 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone |
1353 | bitmaps, so we must search the originals for that. */ | 1203 | bitmaps, so we must search the originals for that. */ |
1354 | buffer = bi->bi_bh->b_data + bi->bi_offset; | 1204 | buffer = bi->bi_bh->b_data + bi->bi_offset; |
1205 | WARN_ON(!buffer_uptodate(bi->bi_bh)); | ||
1355 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) | 1206 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) |
1356 | buffer = bi->bi_clone + bi->bi_offset; | 1207 | buffer = bi->bi_clone + bi->bi_offset; |
1357 | 1208 | ||
@@ -1371,6 +1222,7 @@ skip: | |||
1371 | 1222 | ||
1372 | if (blk == BFITNOENT) | 1223 | if (blk == BFITNOENT) |
1373 | return blk; | 1224 | return blk; |
1225 | |||
1374 | *n = 1; | 1226 | *n = 1; |
1375 | if (old_state == new_state) | 1227 | if (old_state == new_state) |
1376 | goto out; | 1228 | goto out; |
@@ -1539,9 +1391,7 @@ int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n) | |||
1539 | gfs2_statfs_change(sdp, 0, -(s64)*n, 0); | 1391 | gfs2_statfs_change(sdp, 0, -(s64)*n, 0); |
1540 | gfs2_quota_change(ip, *n, ip->i_inode.i_uid, ip->i_inode.i_gid); | 1392 | gfs2_quota_change(ip, *n, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1541 | 1393 | ||
1542 | spin_lock(&sdp->sd_rindex_spin); | ||
1543 | rgd->rd_free_clone -= *n; | 1394 | rgd->rd_free_clone -= *n; |
1544 | spin_unlock(&sdp->sd_rindex_spin); | ||
1545 | trace_gfs2_block_alloc(ip, block, *n, GFS2_BLKST_USED); | 1395 | trace_gfs2_block_alloc(ip, block, *n, GFS2_BLKST_USED); |
1546 | *bn = block; | 1396 | *bn = block; |
1547 | return 0; | 1397 | return 0; |
@@ -1594,9 +1444,7 @@ int gfs2_alloc_di(struct gfs2_inode *dip, u64 *bn, u64 *generation) | |||
1594 | gfs2_statfs_change(sdp, 0, -1, +1); | 1444 | gfs2_statfs_change(sdp, 0, -1, +1); |
1595 | gfs2_trans_add_unrevoke(sdp, block, 1); | 1445 | gfs2_trans_add_unrevoke(sdp, block, 1); |
1596 | 1446 | ||
1597 | spin_lock(&sdp->sd_rindex_spin); | ||
1598 | rgd->rd_free_clone--; | 1447 | rgd->rd_free_clone--; |
1599 | spin_unlock(&sdp->sd_rindex_spin); | ||
1600 | trace_gfs2_block_alloc(dip, block, 1, GFS2_BLKST_DINODE); | 1448 | trace_gfs2_block_alloc(dip, block, 1, GFS2_BLKST_DINODE); |
1601 | *bn = block; | 1449 | *bn = block; |
1602 | return 0; | 1450 | return 0; |
@@ -1629,8 +1477,6 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta) | |||
1629 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1477 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1630 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1478 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1631 | 1479 | ||
1632 | gfs2_trans_add_rg(rgd); | ||
1633 | |||
1634 | /* Directories keep their data in the metadata address space */ | 1480 | /* Directories keep their data in the metadata address space */ |
1635 | if (meta || ip->i_depth) | 1481 | if (meta || ip->i_depth) |
1636 | gfs2_meta_wipe(ip, bstart, blen); | 1482 | gfs2_meta_wipe(ip, bstart, blen); |
@@ -1666,7 +1512,6 @@ void gfs2_unlink_di(struct inode *inode) | |||
1666 | trace_gfs2_block_alloc(ip, blkno, 1, GFS2_BLKST_UNLINKED); | 1512 | trace_gfs2_block_alloc(ip, blkno, 1, GFS2_BLKST_UNLINKED); |
1667 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1513 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1668 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1514 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1669 | gfs2_trans_add_rg(rgd); | ||
1670 | } | 1515 | } |
1671 | 1516 | ||
1672 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | 1517 | static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) |
@@ -1688,7 +1533,6 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1688 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1533 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1689 | 1534 | ||
1690 | gfs2_statfs_change(sdp, 0, +1, -1); | 1535 | gfs2_statfs_change(sdp, 0, +1, -1); |
1691 | gfs2_trans_add_rg(rgd); | ||
1692 | } | 1536 | } |
1693 | 1537 | ||
1694 | 1538 | ||