diff options
Diffstat (limited to 'fs/ocfs2/suballoc.c')
| -rw-r--r-- | fs/ocfs2/suballoc.c | 129 | 
1 files changed, 82 insertions, 47 deletions
| diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index c3c60bc3e072..19ba00f28547 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
| @@ -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)); | 
| @@ -1975,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
| 1975 | bits_wanted, cluster_start, num_clusters); | 1971 | bits_wanted, cluster_start, num_clusters); | 
| 1976 | } | 1972 | } | 
| 1977 | 1973 | ||
| 1978 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, | 1974 | static int ocfs2_block_group_clear_bits(handle_t *handle, | 
| 1979 | struct inode *alloc_inode, | 1975 | struct inode *alloc_inode, | 
| 1980 | struct ocfs2_group_desc *bg, | 1976 | struct ocfs2_group_desc *bg, | 
| 1981 | struct buffer_head *group_bh, | 1977 | struct buffer_head *group_bh, | 
| 1982 | unsigned int bit_off, | 1978 | unsigned int bit_off, | 
| 1983 | unsigned int num_bits) | 1979 | unsigned int num_bits, | 
| 1980 | void (*undo_fn)(unsigned int bit, | ||
| 1981 | unsigned long *bmap)) | ||
| 1984 | { | 1982 | { | 
| 1985 | int status; | 1983 | int status; | 
| 1986 | unsigned int tmp; | 1984 | unsigned int tmp; | 
| 1987 | int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; | ||
| 1988 | struct ocfs2_group_desc *undo_bg = NULL; | 1985 | struct ocfs2_group_desc *undo_bg = NULL; | 
| 1989 | int cluster_bitmap = 0; | ||
| 1990 | 1986 | ||
| 1991 | mlog_entry_void(); | 1987 | mlog_entry_void(); | 
| 1992 | 1988 | ||
| @@ -1996,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
| 1996 | 1992 | ||
| 1997 | mlog(0, "off = %u, num = %u\n", bit_off, num_bits); | 1993 | mlog(0, "off = %u, num = %u\n", bit_off, num_bits); | 
| 1998 | 1994 | ||
| 1999 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 1995 | BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode)); | 
| 2000 | journal_type = OCFS2_JOURNAL_ACCESS_UNDO; | ||
| 2001 | |||
| 2002 | status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), | 1996 | status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), | 
| 2003 | group_bh, journal_type); | 1997 | group_bh, | 
| 1998 | undo_fn ? | ||
| 1999 | OCFS2_JOURNAL_ACCESS_UNDO : | ||
| 2000 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 2004 | if (status < 0) { | 2001 | if (status < 0) { | 
| 2005 | mlog_errno(status); | 2002 | mlog_errno(status); | 
| 2006 | goto bail; | 2003 | goto bail; | 
| 2007 | } | 2004 | } | 
| 2008 | 2005 | ||
| 2009 | if (ocfs2_is_cluster_bitmap(alloc_inode)) | 2006 | if (undo_fn) { | 
| 2010 | cluster_bitmap = 1; | ||
| 2011 | |||
| 2012 | if (cluster_bitmap) { | ||
| 2013 | jbd_lock_bh_state(group_bh); | 2007 | jbd_lock_bh_state(group_bh); | 
| 2014 | undo_bg = (struct ocfs2_group_desc *) | 2008 | undo_bg = (struct ocfs2_group_desc *) | 
| 2015 | bh2jh(group_bh)->b_committed_data; | 2009 | bh2jh(group_bh)->b_committed_data; | 
| @@ -2020,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, | |||
| 2020 | while(tmp--) { | 2014 | while(tmp--) { | 
| 2021 | ocfs2_clear_bit((bit_off + tmp), | 2015 | ocfs2_clear_bit((bit_off + tmp), | 
| 2022 | (unsigned long *) bg->bg_bitmap); | 2016 | (unsigned long *) bg->bg_bitmap); | 
| 2023 | if (cluster_bitmap) | 2017 | if (undo_fn) | 
| 2024 | ocfs2_set_bit(bit_off + tmp, | 2018 | undo_fn(bit_off + tmp, | 
| 2025 | (unsigned long *) undo_bg->bg_bitmap); | 2019 | (unsigned long *) undo_bg->bg_bitmap); | 
| 2026 | } | 2020 | } | 
| 2027 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); | 2021 | le16_add_cpu(&bg->bg_free_bits_count, num_bits); | 
| 2028 | 2022 | ||
| 2029 | if (cluster_bitmap) | 2023 | if (undo_fn) | 
| 2030 | jbd_unlock_bh_state(group_bh); | 2024 | jbd_unlock_bh_state(group_bh); | 
| 2031 | 2025 | ||
| 2032 | status = ocfs2_journal_dirty(handle, group_bh); | 2026 | status = ocfs2_journal_dirty(handle, group_bh); | 
| @@ -2039,12 +2033,14 @@ bail: | |||
| 2039 | /* | 2033 | /* | 
| 2040 | * expects the suballoc inode to already be locked. | 2034 | * expects the suballoc inode to already be locked. | 
| 2041 | */ | 2035 | */ | 
| 2042 | int ocfs2_free_suballoc_bits(handle_t *handle, | 2036 | static int _ocfs2_free_suballoc_bits(handle_t *handle, | 
| 2043 | struct inode *alloc_inode, | 2037 | struct inode *alloc_inode, | 
| 2044 | struct buffer_head *alloc_bh, | 2038 | struct buffer_head *alloc_bh, | 
| 2045 | unsigned int start_bit, | 2039 | unsigned int start_bit, | 
| 2046 | u64 bg_blkno, | 2040 | u64 bg_blkno, | 
| 2047 | unsigned int count) | 2041 | unsigned int count, | 
| 2042 | void (*undo_fn)(unsigned int bit, | ||
| 2043 | unsigned long *bitmap)) | ||
| 2048 | { | 2044 | { | 
| 2049 | int status = 0; | 2045 | int status = 0; | 
| 2050 | u32 tmp_used; | 2046 | u32 tmp_used; | 
| @@ -2079,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
| 2079 | 2075 | ||
| 2080 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 2076 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 
| 2081 | group, group_bh, | 2077 | group, group_bh, | 
| 2082 | start_bit, count); | 2078 | start_bit, count, undo_fn); | 
| 2083 | if (status < 0) { | 2079 | if (status < 0) { | 
| 2084 | mlog_errno(status); | 2080 | mlog_errno(status); | 
| 2085 | goto bail; | 2081 | goto bail; | 
| @@ -2110,6 +2106,17 @@ bail: | |||
| 2110 | return status; | 2106 | return status; | 
| 2111 | } | 2107 | } | 
| 2112 | 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 | |||
| 2113 | int ocfs2_free_dinode(handle_t *handle, | 2120 | int ocfs2_free_dinode(handle_t *handle, | 
| 2114 | struct inode *inode_alloc_inode, | 2121 | struct inode *inode_alloc_inode, | 
| 2115 | struct buffer_head *inode_alloc_bh, | 2122 | struct buffer_head *inode_alloc_bh, | 
| @@ -2123,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle, | |||
| 2123 | inode_alloc_bh, bit, bg_blkno, 1); | 2130 | inode_alloc_bh, bit, bg_blkno, 1); | 
| 2124 | } | 2131 | } | 
| 2125 | 2132 | ||
| 2126 | int ocfs2_free_clusters(handle_t *handle, | 2133 | static int _ocfs2_free_clusters(handle_t *handle, | 
| 2127 | struct inode *bitmap_inode, | 2134 | struct inode *bitmap_inode, | 
| 2128 | struct buffer_head *bitmap_bh, | 2135 | struct buffer_head *bitmap_bh, | 
| 2129 | u64 start_blk, | 2136 | u64 start_blk, | 
| 2130 | unsigned int num_clusters) | 2137 | unsigned int num_clusters, | 
| 2138 | void (*undo_fn)(unsigned int bit, | ||
| 2139 | unsigned long *bitmap)) | ||
| 2131 | { | 2140 | { | 
| 2132 | int status; | 2141 | int status; | 
| 2133 | u16 bg_start_bit; | 2142 | u16 bg_start_bit; | 
| @@ -2154,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle, | |||
| 2154 | mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", | 2163 | mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", | 
| 2155 | (unsigned long long)bg_blkno, bg_start_bit); | 2164 | (unsigned long long)bg_blkno, bg_start_bit); | 
| 2156 | 2165 | ||
| 2157 | status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, | 2166 | status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, | 
| 2158 | bg_start_bit, bg_blkno, | 2167 | bg_start_bit, bg_blkno, | 
| 2159 | num_clusters); | 2168 | num_clusters, undo_fn); | 
| 2160 | if (status < 0) { | 2169 | if (status < 0) { | 
| 2161 | mlog_errno(status); | 2170 | mlog_errno(status); | 
| 2162 | goto out; | 2171 | goto out; | 
| @@ -2170,6 +2179,32 @@ out: | |||
| 2170 | return status; | 2179 | return status; | 
| 2171 | } | 2180 | } | 
| 2172 | 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 | |||
| 2173 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) | 2208 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) | 
| 2174 | { | 2209 | { | 
| 2175 | printk("Block Group:\n"); | 2210 | printk("Block Group:\n"); | 
