diff options
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r-- | fs/ocfs2/suballoc.c | 300 |
1 files changed, 213 insertions, 87 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index c30b644d9572..19ba00f28547 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #define ALLOC_NEW_GROUP 0x1 | 51 | #define ALLOC_NEW_GROUP 0x1 |
52 | #define ALLOC_GROUPS_FROM_GLOBAL 0x2 | 52 | #define ALLOC_GROUPS_FROM_GLOBAL 0x2 |
53 | 53 | ||
54 | #define OCFS2_MAX_INODES_TO_STEAL 1024 | 54 | #define OCFS2_MAX_TO_STEAL 1024 |
55 | 55 | ||
56 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); | 56 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); |
57 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); | 57 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); |
@@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, | |||
95 | struct buffer_head *group_bh, | 95 | struct buffer_head *group_bh, |
96 | unsigned int bit_off, | 96 | unsigned int bit_off, |
97 | unsigned int num_bits); | 97 | unsigned int num_bits); |
98 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, | ||
99 | struct inode *alloc_inode, | ||
100 | struct ocfs2_group_desc *bg, | ||
101 | struct buffer_head *group_bh, | ||
102 | unsigned int bit_off, | ||
103 | unsigned int num_bits); | ||
104 | |||
105 | static int ocfs2_relink_block_group(handle_t *handle, | 98 | static int ocfs2_relink_block_group(handle_t *handle, |
106 | struct inode *alloc_inode, | 99 | struct inode *alloc_inode, |
107 | struct buffer_head *fe_bh, | 100 | struct buffer_head *fe_bh, |
@@ -152,7 +145,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) | |||
152 | 145 | ||
153 | #define do_error(fmt, ...) \ | 146 | #define do_error(fmt, ...) \ |
154 | do{ \ | 147 | do{ \ |
155 | if (clean_error) \ | 148 | if (resize) \ |
156 | mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__); \ | 149 | mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__); \ |
157 | else \ | 150 | else \ |
158 | ocfs2_error(sb, fmt, ##__VA_ARGS__); \ | 151 | ocfs2_error(sb, fmt, ##__VA_ARGS__); \ |
@@ -160,7 +153,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) | |||
160 | 153 | ||
161 | static int ocfs2_validate_gd_self(struct super_block *sb, | 154 | static int ocfs2_validate_gd_self(struct super_block *sb, |
162 | struct buffer_head *bh, | 155 | struct buffer_head *bh, |
163 | int clean_error) | 156 | int resize) |
164 | { | 157 | { |
165 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | 158 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; |
166 | 159 | ||
@@ -211,7 +204,7 @@ static int ocfs2_validate_gd_self(struct super_block *sb, | |||
211 | static int ocfs2_validate_gd_parent(struct super_block *sb, | 204 | static int ocfs2_validate_gd_parent(struct super_block *sb, |
212 | struct ocfs2_dinode *di, | 205 | struct ocfs2_dinode *di, |
213 | struct buffer_head *bh, | 206 | struct buffer_head *bh, |
214 | int clean_error) | 207 | int resize) |
215 | { | 208 | { |
216 | unsigned int max_bits; | 209 | unsigned int max_bits; |
217 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | 210 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; |
@@ -233,8 +226,11 @@ static int ocfs2_validate_gd_parent(struct super_block *sb, | |||
233 | return -EINVAL; | 226 | return -EINVAL; |
234 | } | 227 | } |
235 | 228 | ||
236 | if (le16_to_cpu(gd->bg_chain) >= | 229 | /* In resize, we may meet the case bg_chain == cl_next_free_rec. */ |
237 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { | 230 | if ((le16_to_cpu(gd->bg_chain) > |
231 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) || | ||
232 | ((le16_to_cpu(gd->bg_chain) == | ||
233 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) && !resize)) { | ||
238 | do_error("Group descriptor #%llu has bad chain %u", | 234 | do_error("Group descriptor #%llu has bad chain %u", |
239 | (unsigned long long)bh->b_blocknr, | 235 | (unsigned long long)bh->b_blocknr, |
240 | le16_to_cpu(gd->bg_chain)); | 236 | le16_to_cpu(gd->bg_chain)); |
@@ -637,12 +633,113 @@ bail: | |||
637 | return status; | 633 | return status; |
638 | } | 634 | } |
639 | 635 | ||
636 | static void ocfs2_init_inode_steal_slot(struct ocfs2_super *osb) | ||
637 | { | ||
638 | spin_lock(&osb->osb_lock); | ||
639 | osb->s_inode_steal_slot = OCFS2_INVALID_SLOT; | ||
640 | spin_unlock(&osb->osb_lock); | ||
641 | atomic_set(&osb->s_num_inodes_stolen, 0); | ||
642 | } | ||
643 | |||
644 | static void ocfs2_init_meta_steal_slot(struct ocfs2_super *osb) | ||
645 | { | ||
646 | spin_lock(&osb->osb_lock); | ||
647 | osb->s_meta_steal_slot = OCFS2_INVALID_SLOT; | ||
648 | spin_unlock(&osb->osb_lock); | ||
649 | atomic_set(&osb->s_num_meta_stolen, 0); | ||
650 | } | ||
651 | |||
652 | void ocfs2_init_steal_slots(struct ocfs2_super *osb) | ||
653 | { | ||
654 | ocfs2_init_inode_steal_slot(osb); | ||
655 | ocfs2_init_meta_steal_slot(osb); | ||
656 | } | ||
657 | |||
658 | static void __ocfs2_set_steal_slot(struct ocfs2_super *osb, int slot, int type) | ||
659 | { | ||
660 | spin_lock(&osb->osb_lock); | ||
661 | if (type == INODE_ALLOC_SYSTEM_INODE) | ||
662 | osb->s_inode_steal_slot = slot; | ||
663 | else if (type == EXTENT_ALLOC_SYSTEM_INODE) | ||
664 | osb->s_meta_steal_slot = slot; | ||
665 | spin_unlock(&osb->osb_lock); | ||
666 | } | ||
667 | |||
668 | static int __ocfs2_get_steal_slot(struct ocfs2_super *osb, int type) | ||
669 | { | ||
670 | int slot = OCFS2_INVALID_SLOT; | ||
671 | |||
672 | spin_lock(&osb->osb_lock); | ||
673 | if (type == INODE_ALLOC_SYSTEM_INODE) | ||
674 | slot = osb->s_inode_steal_slot; | ||
675 | else if (type == EXTENT_ALLOC_SYSTEM_INODE) | ||
676 | slot = osb->s_meta_steal_slot; | ||
677 | spin_unlock(&osb->osb_lock); | ||
678 | |||
679 | return slot; | ||
680 | } | ||
681 | |||
682 | static int ocfs2_get_inode_steal_slot(struct ocfs2_super *osb) | ||
683 | { | ||
684 | return __ocfs2_get_steal_slot(osb, INODE_ALLOC_SYSTEM_INODE); | ||
685 | } | ||
686 | |||
687 | static int ocfs2_get_meta_steal_slot(struct ocfs2_super *osb) | ||
688 | { | ||
689 | return __ocfs2_get_steal_slot(osb, EXTENT_ALLOC_SYSTEM_INODE); | ||
690 | } | ||
691 | |||
692 | static int ocfs2_steal_resource(struct ocfs2_super *osb, | ||
693 | struct ocfs2_alloc_context *ac, | ||
694 | int type) | ||
695 | { | ||
696 | int i, status = -ENOSPC; | ||
697 | int slot = __ocfs2_get_steal_slot(osb, type); | ||
698 | |||
699 | /* Start to steal resource from the first slot after ours. */ | ||
700 | if (slot == OCFS2_INVALID_SLOT) | ||
701 | slot = osb->slot_num + 1; | ||
702 | |||
703 | for (i = 0; i < osb->max_slots; i++, slot++) { | ||
704 | if (slot == osb->max_slots) | ||
705 | slot = 0; | ||
706 | |||
707 | if (slot == osb->slot_num) | ||
708 | continue; | ||
709 | |||
710 | status = ocfs2_reserve_suballoc_bits(osb, ac, | ||
711 | type, | ||
712 | (u32)slot, NULL, | ||
713 | NOT_ALLOC_NEW_GROUP); | ||
714 | if (status >= 0) { | ||
715 | __ocfs2_set_steal_slot(osb, slot, type); | ||
716 | break; | ||
717 | } | ||
718 | |||
719 | ocfs2_free_ac_resource(ac); | ||
720 | } | ||
721 | |||
722 | return status; | ||
723 | } | ||
724 | |||
725 | static int ocfs2_steal_inode(struct ocfs2_super *osb, | ||
726 | struct ocfs2_alloc_context *ac) | ||
727 | { | ||
728 | return ocfs2_steal_resource(osb, ac, INODE_ALLOC_SYSTEM_INODE); | ||
729 | } | ||
730 | |||
731 | static int ocfs2_steal_meta(struct ocfs2_super *osb, | ||
732 | struct ocfs2_alloc_context *ac) | ||
733 | { | ||
734 | return ocfs2_steal_resource(osb, ac, EXTENT_ALLOC_SYSTEM_INODE); | ||
735 | } | ||
736 | |||
640 | int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb, | 737 | int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb, |
641 | int blocks, | 738 | int blocks, |
642 | struct ocfs2_alloc_context **ac) | 739 | struct ocfs2_alloc_context **ac) |
643 | { | 740 | { |
644 | int status; | 741 | int status; |
645 | u32 slot; | 742 | int slot = ocfs2_get_meta_steal_slot(osb); |
646 | 743 | ||
647 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 744 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
648 | if (!(*ac)) { | 745 | if (!(*ac)) { |
@@ -653,12 +750,34 @@ int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb, | |||
653 | 750 | ||
654 | (*ac)->ac_bits_wanted = blocks; | 751 | (*ac)->ac_bits_wanted = blocks; |
655 | (*ac)->ac_which = OCFS2_AC_USE_META; | 752 | (*ac)->ac_which = OCFS2_AC_USE_META; |
656 | slot = osb->slot_num; | ||
657 | (*ac)->ac_group_search = ocfs2_block_group_search; | 753 | (*ac)->ac_group_search = ocfs2_block_group_search; |
658 | 754 | ||
755 | if (slot != OCFS2_INVALID_SLOT && | ||
756 | atomic_read(&osb->s_num_meta_stolen) < OCFS2_MAX_TO_STEAL) | ||
757 | goto extent_steal; | ||
758 | |||
759 | atomic_set(&osb->s_num_meta_stolen, 0); | ||
659 | status = ocfs2_reserve_suballoc_bits(osb, (*ac), | 760 | status = ocfs2_reserve_suballoc_bits(osb, (*ac), |
660 | EXTENT_ALLOC_SYSTEM_INODE, | 761 | EXTENT_ALLOC_SYSTEM_INODE, |
661 | slot, NULL, ALLOC_NEW_GROUP); | 762 | (u32)osb->slot_num, NULL, |
763 | ALLOC_NEW_GROUP); | ||
764 | |||
765 | |||
766 | if (status >= 0) { | ||
767 | status = 0; | ||
768 | if (slot != OCFS2_INVALID_SLOT) | ||
769 | ocfs2_init_meta_steal_slot(osb); | ||
770 | goto bail; | ||
771 | } else if (status < 0 && status != -ENOSPC) { | ||
772 | mlog_errno(status); | ||
773 | goto bail; | ||
774 | } | ||
775 | |||
776 | ocfs2_free_ac_resource(*ac); | ||
777 | |||
778 | extent_steal: | ||
779 | status = ocfs2_steal_meta(osb, *ac); | ||
780 | atomic_inc(&osb->s_num_meta_stolen); | ||
662 | if (status < 0) { | 781 | if (status < 0) { |
663 | if (status != -ENOSPC) | 782 | if (status != -ENOSPC) |
664 | mlog_errno(status); | 783 | mlog_errno(status); |
@@ -685,43 +804,11 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | |||
685 | ac); | 804 | ac); |
686 | } | 805 | } |
687 | 806 | ||
688 | static int ocfs2_steal_inode_from_other_nodes(struct ocfs2_super *osb, | ||
689 | struct ocfs2_alloc_context *ac) | ||
690 | { | ||
691 | int i, status = -ENOSPC; | ||
692 | s16 slot = ocfs2_get_inode_steal_slot(osb); | ||
693 | |||
694 | /* Start to steal inodes from the first slot after ours. */ | ||
695 | if (slot == OCFS2_INVALID_SLOT) | ||
696 | slot = osb->slot_num + 1; | ||
697 | |||
698 | for (i = 0; i < osb->max_slots; i++, slot++) { | ||
699 | if (slot == osb->max_slots) | ||
700 | slot = 0; | ||
701 | |||
702 | if (slot == osb->slot_num) | ||
703 | continue; | ||
704 | |||
705 | status = ocfs2_reserve_suballoc_bits(osb, ac, | ||
706 | INODE_ALLOC_SYSTEM_INODE, | ||
707 | slot, NULL, | ||
708 | NOT_ALLOC_NEW_GROUP); | ||
709 | if (status >= 0) { | ||
710 | ocfs2_set_inode_steal_slot(osb, slot); | ||
711 | break; | ||
712 | } | ||
713 | |||
714 | ocfs2_free_ac_resource(ac); | ||
715 | } | ||
716 | |||
717 | return status; | ||
718 | } | ||
719 | |||
720 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | 807 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, |
721 | struct ocfs2_alloc_context **ac) | 808 | struct ocfs2_alloc_context **ac) |
722 | { | 809 | { |
723 | int status; | 810 | int status; |
724 | s16 slot = ocfs2_get_inode_steal_slot(osb); | 811 | int slot = ocfs2_get_inode_steal_slot(osb); |
725 | u64 alloc_group; | 812 | u64 alloc_group; |
726 | 813 | ||
727 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 814 | *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
@@ -754,14 +841,14 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | |||
754 | * need to check our slots to see whether there is some space for us. | 841 | * need to check our slots to see whether there is some space for us. |
755 | */ | 842 | */ |
756 | if (slot != OCFS2_INVALID_SLOT && | 843 | if (slot != OCFS2_INVALID_SLOT && |
757 | atomic_read(&osb->s_num_inodes_stolen) < OCFS2_MAX_INODES_TO_STEAL) | 844 | atomic_read(&osb->s_num_inodes_stolen) < OCFS2_MAX_TO_STEAL) |
758 | goto inode_steal; | 845 | goto inode_steal; |
759 | 846 | ||
760 | atomic_set(&osb->s_num_inodes_stolen, 0); | 847 | atomic_set(&osb->s_num_inodes_stolen, 0); |
761 | alloc_group = osb->osb_inode_alloc_group; | 848 | alloc_group = osb->osb_inode_alloc_group; |
762 | status = ocfs2_reserve_suballoc_bits(osb, *ac, | 849 | status = ocfs2_reserve_suballoc_bits(osb, *ac, |
763 | INODE_ALLOC_SYSTEM_INODE, | 850 | INODE_ALLOC_SYSTEM_INODE, |
764 | osb->slot_num, | 851 | (u32)osb->slot_num, |
765 | &alloc_group, | 852 | &alloc_group, |
766 | ALLOC_NEW_GROUP | | 853 | ALLOC_NEW_GROUP | |
767 | ALLOC_GROUPS_FROM_GLOBAL); | 854 | ALLOC_GROUPS_FROM_GLOBAL); |
@@ -789,7 +876,7 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | |||
789 | ocfs2_free_ac_resource(*ac); | 876 | ocfs2_free_ac_resource(*ac); |
790 | 877 | ||
791 | inode_steal: | 878 | inode_steal: |
792 | status = ocfs2_steal_inode_from_other_nodes(osb, *ac); | 879 | status = ocfs2_steal_inode(osb, *ac); |
793 | atomic_inc(&osb->s_num_inodes_stolen); | 880 | atomic_inc(&osb->s_num_inodes_stolen); |
794 | if (status < 0) { | 881 | if (status < 0) { |
795 | if (status != -ENOSPC) | 882 | if (status != -ENOSPC) |
@@ -1884,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
1884 | bits_wanted, cluster_start, num_clusters); | 1971 | bits_wanted, cluster_start, num_clusters); |
1885 | } | 1972 | } |
1886 | 1973 | ||
1887 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, | 1974 | static int ocfs2_block_group_clear_bits(handle_t *handle, |
1888 | struct inode *alloc_inode, | 1975 | struct inode *alloc_inode, |
1889 | struct ocfs2_group_desc *bg, | 1976 | struct ocfs2_group_desc *bg, |
1890 | struct buffer_head *group_bh, | 1977 | struct buffer_head *group_bh, |
1891 | unsigned int bit_off, | 1978 | unsigned int bit_off, |
1892 | unsigned int num_bits) | 1979 | unsigned int num_bits, |
1980 | void (*undo_fn)(unsigned int bit, | ||
1981 | unsigned long *bmap)) | ||
1893 | { | 1982 | { |
1894 | int status; | 1983 | int status; |
1895 | unsigned int tmp; | 1984 | unsigned int tmp; |
1896 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; | ||
1897 | struct ocfs2_group_desc *undo_bg = NULL; | 1985 | struct ocfs2_group_desc *undo_bg = NULL; |
1898 | int cluster_bitmap = 0; | ||
1899 | 1986 | ||
1900 | mlog_entry_void(); | 1987 | mlog_entry_void(); |
1901 | 1988 | ||
@@ -1905,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
1905 | 1992 | ||
1906 | mlog(0, "off = %u, num = %u\n", bit_off, num_bits); | 1993 | mlog(0, "off = %u, num = %u\n", bit_off, num_bits); |
1907 | 1994 | ||
1908 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 1995 | BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode)); |
1909 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; | ||
1910 | |||
1911 | status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), | 1996 | status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), |
1912 | group_bh, journal_type); | 1997 | group_bh, |
1998 | undo_fn ? | ||
1999 | OCFS2_JOURNAL_ACCESS_UNDO : | ||
2000 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
1913 | if (status < 0) { | 2001 | if (status < 0) { |
1914 | mlog_errno(status); | 2002 | mlog_errno(status); |
1915 | goto bail; | 2003 | goto bail; |
1916 | } | 2004 | } |
1917 | 2005 | ||
1918 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 2006 | if (undo_fn) { |
1919 | cluster_bitmap = 1; | ||
1920 | |||
1921 | if (cluster_bitmap) { | ||
1922 | jbd_lock_bh_state(group_bh); | 2007 | jbd_lock_bh_state(group_bh); |
1923 | undo_bg = (struct ocfs2_group_desc *) | 2008 | undo_bg = (struct ocfs2_group_desc *) |
1924 | bh2jh(group_bh)->b_committed_data; | 2009 | bh2jh(group_bh)->b_committed_data; |
@@ -1929,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
1929 | while(tmp--) { | 2014 | while(tmp--) { |
1930 | ocfs2_clear_bit((bit_off + tmp), | 2015 | ocfs2_clear_bit((bit_off + tmp), |
1931 | (unsigned long *) bg->bg_bitmap); | 2016 | (unsigned long *) bg->bg_bitmap); |
1932 | if (cluster_bitmap) | 2017 | if (undo_fn) |
1933 | ocfs2_set_bit(bit_off + tmp, | 2018 | undo_fn(bit_off + tmp, |
1934 | (unsigned long *) undo_bg->bg_bitmap); | 2019 | (unsigned long *) undo_bg->bg_bitmap); |
1935 | } | 2020 | } |
1936 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); | 2021 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); |
1937 | 2022 | ||
1938 | if (cluster_bitmap) | 2023 | if (undo_fn) |
1939 | jbd_unlock_bh_state(group_bh); | 2024 | jbd_unlock_bh_state(group_bh); |
1940 | 2025 | ||
1941 | status = ocfs2_journal_dirty(handle, group_bh); | 2026 | status = ocfs2_journal_dirty(handle, group_bh); |
@@ -1948,12 +2033,14 @@ bail: | |||
1948 | /* | 2033 | /* |
1949 | * expects the suballoc inode to already be locked. | 2034 | * expects the suballoc inode to already be locked. |
1950 | */ | 2035 | */ |
1951 | int ocfs2_free_suballoc_bits(handle_t *handle, | 2036 | static int _ocfs2_free_suballoc_bits(handle_t *handle, |
1952 | struct inode *alloc_inode, | 2037 | struct inode *alloc_inode, |
1953 | struct buffer_head *alloc_bh, | 2038 | struct buffer_head *alloc_bh, |
1954 | unsigned int start_bit, | 2039 | unsigned int start_bit, |
1955 | u64 bg_blkno, | 2040 | u64 bg_blkno, |
1956 | unsigned int count) | 2041 | unsigned int count, |
2042 | void (*undo_fn)(unsigned int bit, | ||
2043 | unsigned long *bitmap)) | ||
1957 | { | 2044 | { |
1958 | int status = 0; | 2045 | int status = 0; |
1959 | u32 tmp_used; | 2046 | u32 tmp_used; |
@@ -1988,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
1988 | 2075 | ||
1989 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 2076 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, |
1990 | group, group_bh, | 2077 | group, group_bh, |
1991 | start_bit, count); | 2078 | start_bit, count, undo_fn); |
1992 | if (status < 0) { | 2079 | if (status < 0) { |
1993 | mlog_errno(status); | 2080 | mlog_errno(status); |
1994 | goto bail; | 2081 | goto bail; |
@@ -2019,6 +2106,17 @@ bail: | |||
2019 | return status; | 2106 | return status; |
2020 | } | 2107 | } |
2021 | 2108 | ||
2109 | int ocfs2_free_suballoc_bits(handle_t *handle, | ||
2110 | struct inode *alloc_inode, | ||
2111 | struct buffer_head *alloc_bh, | ||
2112 | unsigned int start_bit, | ||
2113 | u64 bg_blkno, | ||
2114 | unsigned int count) | ||
2115 | { | ||
2116 | return _ocfs2_free_suballoc_bits(handle, alloc_inode, alloc_bh, | ||
2117 | start_bit, bg_blkno, count, NULL); | ||
2118 | } | ||
2119 | |||
2022 | int ocfs2_free_dinode(handle_t *handle, | 2120 | int ocfs2_free_dinode(handle_t *handle, |
2023 | struct inode *inode_alloc_inode, | 2121 | struct inode *inode_alloc_inode, |
2024 | struct buffer_head *inode_alloc_bh, | 2122 | struct buffer_head *inode_alloc_bh, |
@@ -2032,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle, | |||
2032 | inode_alloc_bh, bit, bg_blkno, 1); | 2130 | inode_alloc_bh, bit, bg_blkno, 1); |
2033 | } | 2131 | } |
2034 | 2132 | ||
2035 | int ocfs2_free_clusters(handle_t *handle, | 2133 | static int _ocfs2_free_clusters(handle_t *handle, |
2036 | struct inode *bitmap_inode, | 2134 | struct inode *bitmap_inode, |
2037 | struct buffer_head *bitmap_bh, | 2135 | struct buffer_head *bitmap_bh, |
2038 | u64 start_blk, | 2136 | u64 start_blk, |
2039 | unsigned int num_clusters) | 2137 | unsigned int num_clusters, |
2138 | void (*undo_fn)(unsigned int bit, | ||
2139 | unsigned long *bitmap)) | ||
2040 | { | 2140 | { |
2041 | int status; | 2141 | int status; |
2042 | u16 bg_start_bit; | 2142 | u16 bg_start_bit; |
@@ -2063,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle, | |||
2063 | mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", | 2163 | mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", |
2064 | (unsigned long long)bg_blkno, bg_start_bit); | 2164 | (unsigned long long)bg_blkno, bg_start_bit); |
2065 | 2165 | ||
2066 | status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, | 2166 | status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, |
2067 | bg_start_bit, bg_blkno, | 2167 | bg_start_bit, bg_blkno, |
2068 | num_clusters); | 2168 | num_clusters, undo_fn); |
2069 | if (status < 0) { | 2169 | if (status < 0) { |
2070 | mlog_errno(status); | 2170 | mlog_errno(status); |
2071 | goto out; | 2171 | goto out; |
@@ -2079,6 +2179,32 @@ out: | |||
2079 | return status; | 2179 | return status; |
2080 | } | 2180 | } |
2081 | 2181 | ||
2182 | int ocfs2_free_clusters(handle_t *handle, | ||
2183 | struct inode *bitmap_inode, | ||
2184 | struct buffer_head *bitmap_bh, | ||
2185 | u64 start_blk, | ||
2186 | unsigned int num_clusters) | ||
2187 | { | ||
2188 | return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh, | ||
2189 | start_blk, num_clusters, | ||
2190 | _ocfs2_set_bit); | ||
2191 | } | ||
2192 | |||
2193 | /* | ||
2194 | * Give never-used clusters back to the global bitmap. We don't need | ||
2195 | * to protect these bits in the undo buffer. | ||
2196 | */ | ||
2197 | int ocfs2_release_clusters(handle_t *handle, | ||
2198 | struct inode *bitmap_inode, | ||
2199 | struct buffer_head *bitmap_bh, | ||
2200 | u64 start_blk, | ||
2201 | unsigned int num_clusters) | ||
2202 | { | ||
2203 | return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh, | ||
2204 | start_blk, num_clusters, | ||
2205 | _ocfs2_clear_bit); | ||
2206 | } | ||
2207 | |||
2082 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) | 2208 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) |
2083 | { | 2209 | { |
2084 | printk("Block Group:\n"); | 2210 | printk("Block Group:\n"); |