Blame view
fs/ext4/balloc.c
26.2 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
ac27a0ec1 [PATCH] ext4: ini... |
2 |
/* |
617ba13b3 [PATCH] ext4: ren... |
3 |
* linux/fs/ext4/balloc.c |
ac27a0ec1 [PATCH] ext4: ini... |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
* * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * Enhanced block allocation by Stephen Tweedie (sct@redhat.com), 1993 * Big-endian to little-endian byte-swapping/bitmaps by * David S. Miller (davem@caip.rutgers.edu), 1995 */ #include <linux/time.h> #include <linux/capability.h> #include <linux/fs.h> |
ac27a0ec1 [PATCH] ext4: ini... |
18 19 |
#include <linux/quotaops.h> #include <linux/buffer_head.h> |
3dcf54515 ext4: move header... |
20 21 |
#include "ext4.h" #include "ext4_jbd2.h" |
e21675d4b ext4: Add blocks ... |
22 |
#include "mballoc.h" |
3dcf54515 ext4: move header... |
23 |
|
0562e0bad ext4: add more tr... |
24 |
#include <trace/events/ext4.h> |
5f163cc75 ext4: make more s... |
25 26 |
static unsigned ext4_num_base_meta_clusters(struct super_block *sb, ext4_group_t block_group); |
ac27a0ec1 [PATCH] ext4: ini... |
27 28 29 30 31 |
/* * balloc.c contains the blocks allocation and deallocation routines */ /* |
bd86298e6 ext4: introduce e... |
32 33 34 35 36 37 38 39 |
* Calculate block group number for a given block number */ ext4_group_t ext4_get_group_number(struct super_block *sb, ext4_fsblk_t block) { ext4_group_t group; if (test_opt2(sb, STD_GROUP_SIZE)) |
960fd856f ext4: fix ext4_ge... |
40 41 |
group = (block - le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) >> |
bd86298e6 ext4: introduce e... |
42 43 44 45 46 47 48 |
(EXT4_BLOCK_SIZE_BITS(sb) + EXT4_CLUSTER_BITS(sb) + 3); else ext4_get_group_no_and_offset(sb, block, &group, NULL); return group; } /* |
3212a80a5 ext4: convert blo... |
49 50 |
* Calculate the block group number and offset into the block/cluster * allocation bitmap, given a block number |
72b64b594 [PATCH] ext4 unin... |
51 52 |
*/ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, |
fd2d42912 ext4: add ext4_gr... |
53 |
ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp) |
72b64b594 [PATCH] ext4 unin... |
54 |
{ |
8c55e2041 EXT4: Fix whitespace |
55 |
struct ext4_super_block *es = EXT4_SB(sb)->s_es; |
72b64b594 [PATCH] ext4 unin... |
56 |
ext4_grpblk_t offset; |
8c55e2041 EXT4: Fix whitespace |
57 |
blocknr = blocknr - le32_to_cpu(es->s_first_data_block); |
3212a80a5 ext4: convert blo... |
58 59 |
offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)) >> EXT4_SB(sb)->s_cluster_bits; |
72b64b594 [PATCH] ext4 unin... |
60 61 62 |
if (offsetp) *offsetp = offset; if (blockgrpp) |
8c55e2041 EXT4: Fix whitespace |
63 |
*blockgrpp = blocknr; |
72b64b594 [PATCH] ext4 unin... |
64 65 |
} |
689110098 ext4: make ext4_b... |
66 67 68 69 70 71 72 |
/* * Check whether the 'block' lives within the 'block_group'. Returns 1 if so * and 0 otherwise. */ static inline int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block, ext4_group_t block_group) |
0bf7e8379 ext4: Fix uninit ... |
73 74 |
{ ext4_group_t actual_group; |
689110098 ext4: make ext4_b... |
75 |
|
bd86298e6 ext4: introduce e... |
76 |
actual_group = ext4_get_group_number(sb, block); |
689110098 ext4: make ext4_b... |
77 |
return (actual_group == block_group) ? 1 : 0; |
0bf7e8379 ext4: Fix uninit ... |
78 |
} |
d5b8f3100 ext4: bigalloc ch... |
79 80 81 |
/* Return the number of clusters used for file system metadata; this * represents the overhead needed by the file system. */ |
c197855ea ext4: make local ... |
82 83 84 |
static unsigned ext4_num_overhead_clusters(struct super_block *sb, ext4_group_t block_group, struct ext4_group_desc *gdp) |
0bf7e8379 ext4: Fix uninit ... |
85 |
{ |
d5b8f3100 ext4: bigalloc ch... |
86 87 88 89 |
unsigned num_clusters; int block_cluster = -1, inode_cluster = -1, itbl_cluster = -1, i, c; ext4_fsblk_t start = ext4_group_first_block_no(sb, block_group); ext4_fsblk_t itbl_blk; |
0bf7e8379 ext4: Fix uninit ... |
90 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
0bf7e8379 ext4: Fix uninit ... |
91 |
|
d5b8f3100 ext4: bigalloc ch... |
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
/* This is the number of clusters used by the superblock, * block group descriptors, and reserved block group * descriptor blocks */ num_clusters = ext4_num_base_meta_clusters(sb, block_group); /* * For the allocation bitmaps and inode table, we first need * to check to see if the block is in the block group. If it * is, then check to see if the cluster is already accounted * for in the clusters used for the base metadata cluster, or * if we can increment the base metadata cluster to include * that block. Otherwise, we will have to track the cluster * used for the allocation bitmap or inode table explicitly. * Normally all of these blocks are contiguous, so the special * case handling shouldn't be necessary except for *very* * unusual file system layouts. */ if (ext4_block_in_group(sb, ext4_block_bitmap(sb, gdp), block_group)) { |
b0dd6b70f ext4: fix the fre... |
110 111 |
block_cluster = EXT4_B2C(sbi, ext4_block_bitmap(sb, gdp) - start); |
d5b8f3100 ext4: bigalloc ch... |
112 113 114 115 116 117 118 119 120 121 |
if (block_cluster < num_clusters) block_cluster = -1; else if (block_cluster == num_clusters) { num_clusters++; block_cluster = -1; } } if (ext4_block_in_group(sb, ext4_inode_bitmap(sb, gdp), block_group)) { inode_cluster = EXT4_B2C(sbi, |
b0dd6b70f ext4: fix the fre... |
122 |
ext4_inode_bitmap(sb, gdp) - start); |
d5b8f3100 ext4: bigalloc ch... |
123 124 125 126 127 128 129 130 131 132 133 |
if (inode_cluster < num_clusters) inode_cluster = -1; else if (inode_cluster == num_clusters) { num_clusters++; inode_cluster = -1; } } itbl_blk = ext4_inode_table(sb, gdp); for (i = 0; i < sbi->s_itb_per_group; i++) { if (ext4_block_in_group(sb, itbl_blk + i, block_group)) { |
b0dd6b70f ext4: fix the fre... |
134 |
c = EXT4_B2C(sbi, itbl_blk + i - start); |
d5b8f3100 ext4: bigalloc ch... |
135 136 137 138 139 140 141 142 143 |
if ((c < num_clusters) || (c == inode_cluster) || (c == block_cluster) || (c == itbl_cluster)) continue; if (c == num_clusters) { num_clusters++; continue; } num_clusters++; itbl_cluster = c; |
0bf7e8379 ext4: Fix uninit ... |
144 145 |
} } |
d5b8f3100 ext4: bigalloc ch... |
146 147 148 149 150 151 152 |
if (block_cluster != -1) num_clusters++; if (inode_cluster != -1) num_clusters++; return num_clusters; |
0bf7e8379 ext4: Fix uninit ... |
153 |
} |
c2ea3fde6 ext4: Remove old ... |
154 |
|
d5b8f3100 ext4: bigalloc ch... |
155 156 |
static unsigned int num_clusters_in_group(struct super_block *sb, ext4_group_t block_group) |
49f7f9af4 ext4: factor out ... |
157 |
{ |
d5b8f3100 ext4: bigalloc ch... |
158 |
unsigned int blocks; |
49f7f9af4 ext4: factor out ... |
159 160 161 162 163 164 165 |
if (block_group == ext4_get_groups_count(sb) - 1) { /* * Even though mke2fs always initializes the first and * last group, just in case some other tool was used, * we need to make sure we calculate the right free * blocks. */ |
d5b8f3100 ext4: bigalloc ch... |
166 |
blocks = ext4_blocks_count(EXT4_SB(sb)->s_es) - |
49f7f9af4 ext4: factor out ... |
167 168 |
ext4_group_first_block_no(sb, block_group); } else |
d5b8f3100 ext4: bigalloc ch... |
169 170 |
blocks = EXT4_BLOCKS_PER_GROUP(sb); return EXT4_NUM_B2C(EXT4_SB(sb), blocks); |
49f7f9af4 ext4: factor out ... |
171 |
} |
fd034a84e ext4: split out e... |
172 |
/* Initializes an uninitialized block bitmap */ |
aef4885ae ext4: move error ... |
173 |
static int ext4_init_block_bitmap(struct super_block *sb, |
c197855ea ext4: make local ... |
174 175 176 |
struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp) |
717d50e49 Ext4: Uninitializ... |
177 |
{ |
d5b8f3100 ext4: bigalloc ch... |
178 |
unsigned int bit, bit_max; |
717d50e49 Ext4: Uninitializ... |
179 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
fd034a84e ext4: split out e... |
180 |
ext4_fsblk_t start, tmp; |
fd034a84e ext4: split out e... |
181 182 183 184 185 |
J_ASSERT_BH(bh, buffer_locked(bh)); /* If checksum is bad mark all blocks used to prevent allocation * essentially implementing a per-group read-only flag. */ |
feb0ab32a ext4: make block ... |
186 |
if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { |
db79e6d1f ext4: add new ext... |
187 188 189 |
ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT | EXT4_GROUP_INFO_IBITMAP_CORRUPT); |
6a797d273 ext4: call out CR... |
190 |
return -EFSBADCRC; |
717d50e49 Ext4: Uninitializ... |
191 |
} |
fd034a84e ext4: split out e... |
192 |
memset(bh->b_data, 0, sb->s_blocksize); |
717d50e49 Ext4: Uninitializ... |
193 |
|
d5b8f3100 ext4: bigalloc ch... |
194 |
bit_max = ext4_num_base_meta_clusters(sb, block_group); |
5b9554dc5 ext4: validate s_... |
195 196 |
if ((bit_max >> 3) >= bh->b_size) return -EFSCORRUPTED; |
fd034a84e ext4: split out e... |
197 198 |
for (bit = 0; bit < bit_max; bit++) ext4_set_bit(bit, bh->b_data); |
d00a6d7b4 ext4: use ext4_gr... |
199 |
|
fd034a84e ext4: split out e... |
200 |
start = ext4_group_first_block_no(sb, block_group); |
717d50e49 Ext4: Uninitializ... |
201 |
|
fd034a84e ext4: split out e... |
202 203 |
/* Set bits for block and inode bitmaps, and inode table */ tmp = ext4_block_bitmap(sb, gdp); |
819b23f1c ext4: always chec... |
204 |
if (ext4_block_in_group(sb, tmp, block_group)) |
d5b8f3100 ext4: bigalloc ch... |
205 |
ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
717d50e49 Ext4: Uninitializ... |
206 |
|
fd034a84e ext4: split out e... |
207 |
tmp = ext4_inode_bitmap(sb, gdp); |
819b23f1c ext4: always chec... |
208 |
if (ext4_block_in_group(sb, tmp, block_group)) |
d5b8f3100 ext4: bigalloc ch... |
209 |
ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
0bf7e8379 ext4: Fix uninit ... |
210 |
|
fd034a84e ext4: split out e... |
211 212 213 |
tmp = ext4_inode_table(sb, gdp); for (; tmp < ext4_inode_table(sb, gdp) + sbi->s_itb_per_group; tmp++) { |
819b23f1c ext4: always chec... |
214 |
if (ext4_block_in_group(sb, tmp, block_group)) |
d5b8f3100 ext4: bigalloc ch... |
215 |
ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
717d50e49 Ext4: Uninitializ... |
216 |
} |
d5b8f3100 ext4: bigalloc ch... |
217 |
|
fd034a84e ext4: split out e... |
218 219 220 221 222 |
/* * Also if the number of blocks within the group is less than * the blocksize * 8 ( which is the size of bitmap ), set rest * of the block bitmap to 1 */ |
d5b8f3100 ext4: bigalloc ch... |
223 |
ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), |
fd034a84e ext4: split out e... |
224 |
sb->s_blocksize * 8, bh->b_data); |
aef4885ae ext4: move error ... |
225 |
return 0; |
717d50e49 Ext4: Uninitializ... |
226 |
} |
fd034a84e ext4: split out e... |
227 228 229 |
/* Return the number of free blocks in a block group. It is used when * the block bitmap is uninitialized, so we can't just count the bits * in the bitmap. */ |
cff1dfd76 ext4: rename ext4... |
230 231 232 |
unsigned ext4_free_clusters_after_init(struct super_block *sb, ext4_group_t block_group, struct ext4_group_desc *gdp) |
fd034a84e ext4: split out e... |
233 |
{ |
d5b8f3100 ext4: bigalloc ch... |
234 235 |
return num_clusters_in_group(sb, block_group) - ext4_num_overhead_clusters(sb, block_group, gdp); |
fd034a84e ext4: split out e... |
236 |
} |
717d50e49 Ext4: Uninitializ... |
237 |
|
72b64b594 [PATCH] ext4 unin... |
238 |
/* |
ac27a0ec1 [PATCH] ext4: ini... |
239 240 241 242 243 244 245 |
* The free blocks are managed by bitmaps. A file system contains several * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap * block for inodes, N blocks for the inode table and data blocks. * * The file system contains group descriptors which are located after the * super block. Each descriptor contains the number of the bitmap block and * the free blocks count in the block. The descriptors are loaded in memory |
e627432c2 [PATCH] ext[234]:... |
246 |
* when a file system is mounted (see ext4_fill_super). |
ac27a0ec1 [PATCH] ext4: ini... |
247 |
*/ |
ac27a0ec1 [PATCH] ext4: ini... |
248 |
/** |
617ba13b3 [PATCH] ext4: ren... |
249 |
* ext4_get_group_desc() -- load group descriptor from disk |
ac27a0ec1 [PATCH] ext4: ini... |
250 251 252 253 254 |
* @sb: super block * @block_group: given block group * @bh: pointer to the buffer head to store the block * group descriptor */ |
af5bc92dd ext4: Fix whitesp... |
255 |
struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, |
fd2d42912 ext4: add ext4_gr... |
256 |
ext4_group_t block_group, |
af5bc92dd ext4: Fix whitesp... |
257 |
struct buffer_head **bh) |
ac27a0ec1 [PATCH] ext4: ini... |
258 |
{ |
498e5f241 ext4: Change unsi... |
259 260 |
unsigned int group_desc; unsigned int offset; |
8df9675f8 ext4: Avoid races... |
261 |
ext4_group_t ngroups = ext4_get_groups_count(sb); |
af5bc92dd ext4: Fix whitesp... |
262 |
struct ext4_group_desc *desc; |
617ba13b3 [PATCH] ext4: ren... |
263 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
1d0c3924a ext4: fix potenti... |
264 |
struct buffer_head *bh_p; |
ac27a0ec1 [PATCH] ext4: ini... |
265 |
|
8df9675f8 ext4: Avoid races... |
266 |
if (block_group >= ngroups) { |
12062dddd ext4: move __func... |
267 268 |
ext4_error(sb, "block_group >= groups_count - block_group = %u," " groups_count = %u", block_group, ngroups); |
ac27a0ec1 [PATCH] ext4: ini... |
269 270 271 |
return NULL; } |
ac27a0ec1 [PATCH] ext4: ini... |
272 |
|
617ba13b3 [PATCH] ext4: ren... |
273 274 |
group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); |
1d0c3924a ext4: fix potenti... |
275 276 277 278 279 280 281 282 |
bh_p = sbi_array_rcu_deref(sbi, s_group_desc, group_desc); /* * sbi_array_rcu_deref returns with rcu unlocked, this is ok since * the pointer being dereferenced won't be dereferenced again. By * looking at the usage in add_new_gdb() the value isn't modified, * just the pointer, and so it remains valid. */ if (!bh_p) { |
12062dddd ext4: move __func... |
283 |
ext4_error(sb, "Group descriptor not loaded - " |
498e5f241 ext4: Change unsi... |
284 |
"block_group = %u, group_desc = %u, desc = %u", |
af5bc92dd ext4: Fix whitesp... |
285 |
block_group, group_desc, offset); |
ac27a0ec1 [PATCH] ext4: ini... |
286 287 |
return NULL; } |
0d1ee42f2 [PATCH] ext4: all... |
288 |
desc = (struct ext4_group_desc *)( |
1d0c3924a ext4: fix potenti... |
289 |
(__u8 *)bh_p->b_data + |
0d1ee42f2 [PATCH] ext4: all... |
290 |
offset * EXT4_DESC_SIZE(sb)); |
ac27a0ec1 [PATCH] ext4: ini... |
291 |
if (bh) |
1d0c3924a ext4: fix potenti... |
292 |
*bh = bh_p; |
0d1ee42f2 [PATCH] ext4: all... |
293 |
return desc; |
ac27a0ec1 [PATCH] ext4: ini... |
294 |
} |
7a4c5de27 ext4: don't call ... |
295 296 297 298 299 300 |
/* * Return the block number which was discovered to be invalid, or 0 if * the block bitmap is valid. */ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, struct ext4_group_desc *desc, |
dbde0abed ext4: fix type de... |
301 |
ext4_group_t block_group, |
7a4c5de27 ext4: don't call ... |
302 |
struct buffer_head *bh) |
abcb2947c ext4: add block b... |
303 |
{ |
e674e5cbd ext4: fix block b... |
304 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
abcb2947c ext4: add block b... |
305 306 |
ext4_grpblk_t offset; ext4_grpblk_t next_zero_bit; |
22be37acc ext4: fix bitmap ... |
307 |
ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb); |
7a4c5de27 ext4: don't call ... |
308 |
ext4_fsblk_t blk; |
abcb2947c ext4: add block b... |
309 |
ext4_fsblk_t group_first_block; |
e2b911c53 ext4: clean up fe... |
310 |
if (ext4_has_feature_flex_bg(sb)) { |
abcb2947c ext4: add block b... |
311 312 313 314 315 316 |
/* with FLEX_BG, the inode/block bitmaps and itable * blocks may not be in the group at all * so the bitmap validation will be skipped for those groups * or it has to also read the block group where the bitmaps * are located to verify they are set. */ |
7a4c5de27 ext4: don't call ... |
317 |
return 0; |
abcb2947c ext4: add block b... |
318 319 320 321 |
} group_first_block = ext4_group_first_block_no(sb, block_group); /* check whether block bitmap block number is set */ |
7a4c5de27 ext4: don't call ... |
322 323 |
blk = ext4_block_bitmap(sb, desc); offset = blk - group_first_block; |
22be37acc ext4: fix bitmap ... |
324 |
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit || |
7dac4a172 ext4: add validit... |
325 |
!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) |
abcb2947c ext4: add block b... |
326 |
/* bad block bitmap */ |
7a4c5de27 ext4: don't call ... |
327 |
return blk; |
abcb2947c ext4: add block b... |
328 329 |
/* check whether the inode bitmap block number is set */ |
7a4c5de27 ext4: don't call ... |
330 331 |
blk = ext4_inode_bitmap(sb, desc); offset = blk - group_first_block; |
22be37acc ext4: fix bitmap ... |
332 |
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit || |
7dac4a172 ext4: add validit... |
333 |
!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) |
abcb2947c ext4: add block b... |
334 |
/* bad block bitmap */ |
7a4c5de27 ext4: don't call ... |
335 |
return blk; |
abcb2947c ext4: add block b... |
336 337 |
/* check whether the inode table block number is set */ |
7a4c5de27 ext4: don't call ... |
338 339 |
blk = ext4_inode_table(sb, desc); offset = blk - group_first_block; |
22be37acc ext4: fix bitmap ... |
340 341 |
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit || EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit) |
7dac4a172 ext4: add validit... |
342 |
return blk; |
abcb2947c ext4: add block b... |
343 |
next_zero_bit = ext4_find_next_zero_bit(bh->b_data, |
49598e04b ext4: use 'sbi' i... |
344 |
EXT4_B2C(sbi, offset + sbi->s_itb_per_group), |
e674e5cbd ext4: fix block b... |
345 346 |
EXT4_B2C(sbi, offset)); if (next_zero_bit < |
49598e04b ext4: use 'sbi' i... |
347 |
EXT4_B2C(sbi, offset + sbi->s_itb_per_group)) |
7a4c5de27 ext4: don't call ... |
348 349 |
/* bad bitmap for inode tables */ return blk; |
abcb2947c ext4: add block b... |
350 351 |
return 0; } |
fa77dcfaf ext4: calculate a... |
352 |
|
9008a58e5 ext4: make the bi... |
353 354 355 356 |
static int ext4_validate_block_bitmap(struct super_block *sb, struct ext4_group_desc *desc, ext4_group_t block_group, struct buffer_head *bh) |
fa77dcfaf ext4: calculate a... |
357 |
{ |
7a4c5de27 ext4: don't call ... |
358 |
ext4_fsblk_t blk; |
163a203dd ext4: mark block ... |
359 |
struct ext4_group_info *grp = ext4_get_group_info(sb, block_group); |
7a4c5de27 ext4: don't call ... |
360 |
|
9008a58e5 ext4: make the bi... |
361 362 363 364 |
if (buffer_verified(bh)) return 0; if (EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) return -EFSCORRUPTED; |
fa77dcfaf ext4: calculate a... |
365 366 |
ext4_lock_group(sb, block_group); |
8d5a803c6 ext4: check for a... |
367 368 |
if (buffer_verified(bh)) goto verified; |
9008a58e5 ext4: make the bi... |
369 |
if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, |
46f870d69 ext4: simulate va... |
370 371 |
desc, bh) || ext4_simulate_fail(sb, EXT4_SIM_BBITMAP_CRC))) { |
7a4c5de27 ext4: don't call ... |
372 |
ext4_unlock_group(sb, block_group); |
9008a58e5 ext4: make the bi... |
373 |
ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); |
db79e6d1f ext4: add new ext... |
374 375 |
ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); |
9008a58e5 ext4: make the bi... |
376 |
return -EFSBADCRC; |
7a4c5de27 ext4: don't call ... |
377 |
} |
9008a58e5 ext4: make the bi... |
378 379 |
blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); if (unlikely(blk != 0)) { |
7a4c5de27 ext4: don't call ... |
380 |
ext4_unlock_group(sb, block_group); |
9008a58e5 ext4: make the bi... |
381 382 |
ext4_error(sb, "bg %u: block %llu: invalid block bitmap", block_group, blk); |
db79e6d1f ext4: add new ext... |
383 384 |
ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); |
9008a58e5 ext4: make the bi... |
385 |
return -EFSCORRUPTED; |
7a4c5de27 ext4: don't call ... |
386 387 |
} set_buffer_verified(bh); |
8d5a803c6 ext4: check for a... |
388 |
verified: |
fa77dcfaf ext4: calculate a... |
389 |
ext4_unlock_group(sb, block_group); |
9008a58e5 ext4: make the bi... |
390 |
return 0; |
fa77dcfaf ext4: calculate a... |
391 |
} |
ac27a0ec1 [PATCH] ext4: ini... |
392 |
/** |
15b49132f ext4: check bh in... |
393 |
* ext4_read_block_bitmap_nowait() |
ac27a0ec1 [PATCH] ext4: ini... |
394 395 396 |
* @sb: super block * @block_group: given block group * |
abcb2947c ext4: add block b... |
397 398 |
* Read the bitmap for a given block_group,and validate the * bits for block/inode/inode tables are set in the bitmaps |
ac27a0ec1 [PATCH] ext4: ini... |
399 |
* |
9033783c8 ext4: fix return-... |
400 |
* Return buffer_head on success or an ERR_PTR in case of failure. |
ac27a0ec1 [PATCH] ext4: ini... |
401 |
*/ |
717d50e49 Ext4: Uninitializ... |
402 |
struct buffer_head * |
813e57276 ext4: fix race wh... |
403 |
ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) |
ac27a0ec1 [PATCH] ext4: ini... |
404 |
{ |
af5bc92dd ext4: Fix whitesp... |
405 |
struct ext4_group_desc *desc; |
7dac4a172 ext4: add validit... |
406 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
813e57276 ext4: fix race wh... |
407 |
struct buffer_head *bh; |
7c9e69faa ext2/ext3/ext4: a... |
408 |
ext4_fsblk_t bitmap_blk; |
9008a58e5 ext4: make the bi... |
409 |
int err; |
ac27a0ec1 [PATCH] ext4: ini... |
410 |
|
717d50e49 Ext4: Uninitializ... |
411 |
desc = ext4_get_group_desc(sb, block_group, NULL); |
ac27a0ec1 [PATCH] ext4: ini... |
412 |
if (!desc) |
9008a58e5 ext4: make the bi... |
413 |
return ERR_PTR(-EFSCORRUPTED); |
7c9e69faa ext2/ext3/ext4: a... |
414 |
bitmap_blk = ext4_block_bitmap(sb, desc); |
7dac4a172 ext4: add validit... |
415 416 417 418 |
if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { ext4_error(sb, "Invalid block bitmap block %llu in " "block_group %u", bitmap_blk, block_group); |
736dedbb1 ext4: mark block ... |
419 420 |
ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); |
7dac4a172 ext4: add validit... |
421 422 |
return ERR_PTR(-EFSCORRUPTED); } |
abcb2947c ext4: add block b... |
423 424 |
bh = sb_getblk(sb, bitmap_blk); if (unlikely(!bh)) { |
5ef2a6999 ext4: use ext4_wa... |
425 426 427 |
ext4_warning(sb, "Cannot get buffer for block bitmap - " "block_group = %u, block_bitmap = %llu", block_group, bitmap_blk); |
9008a58e5 ext4: make the bi... |
428 |
return ERR_PTR(-ENOMEM); |
abcb2947c ext4: add block b... |
429 |
} |
2ccb5fb9f ext4: Use new buf... |
430 431 |
if (bitmap_uptodate(bh)) |
fa77dcfaf ext4: calculate a... |
432 |
goto verify; |
abcb2947c ext4: add block b... |
433 |
|
c806e68f5 ext4: fix initial... |
434 |
lock_buffer(bh); |
2ccb5fb9f ext4: Use new buf... |
435 436 |
if (bitmap_uptodate(bh)) { unlock_buffer(bh); |
fa77dcfaf ext4: calculate a... |
437 |
goto verify; |
2ccb5fb9f ext4: Use new buf... |
438 |
} |
955ce5f5b ext4: Convert ext... |
439 |
ext4_lock_group(sb, block_group); |
8844618d8 ext4: only look a... |
440 441 442 443 444 445 446 447 448 449 |
if (ext4_has_group_desc_csum(sb) && (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { if (block_group == 0) { ext4_unlock_group(sb, block_group); unlock_buffer(bh); ext4_error(sb, "Block bitmap for bg 0 marked " "uninitialized"); err = -EFSCORRUPTED; goto out; } |
aef4885ae ext4: move error ... |
450 |
err = ext4_init_block_bitmap(sb, bh, block_group, desc); |
2ccb5fb9f ext4: Use new buf... |
451 |
set_bitmap_uptodate(bh); |
abcb2947c ext4: add block b... |
452 |
set_buffer_uptodate(bh); |
044e6e3d7 ext4: don't updat... |
453 |
set_buffer_verified(bh); |
955ce5f5b ext4: Convert ext... |
454 |
ext4_unlock_group(sb, block_group); |
3300beda5 ext4: code cleanup |
455 |
unlock_buffer(bh); |
05145bd79 ext4: fix schedul... |
456 457 458 |
if (err) { ext4_error(sb, "Failed to init block bitmap for group " "%u: %d", block_group, err); |
9008a58e5 ext4: make the bi... |
459 |
goto out; |
05145bd79 ext4: fix schedul... |
460 |
} |
41e5b7ed3 ext4: verify bloc... |
461 |
goto verify; |
717d50e49 Ext4: Uninitializ... |
462 |
} |
955ce5f5b ext4: Convert ext... |
463 |
ext4_unlock_group(sb, block_group); |
2ccb5fb9f ext4: Use new buf... |
464 465 466 467 468 469 470 |
if (buffer_uptodate(bh)) { /* * if not uninit if bh is uptodate, * bitmap is also uptodate */ set_bitmap_uptodate(bh); unlock_buffer(bh); |
fa77dcfaf ext4: calculate a... |
471 |
goto verify; |
2ccb5fb9f ext4: Use new buf... |
472 473 |
} /* |
813e57276 ext4: fix race wh... |
474 |
* submit the buffer_head for reading |
2ccb5fb9f ext4: Use new buf... |
475 |
*/ |
813e57276 ext4: fix race wh... |
476 |
set_buffer_new(bh); |
0562e0bad ext4: add more tr... |
477 |
trace_ext4_read_block_bitmap_load(sb, block_group); |
813e57276 ext4: fix race wh... |
478 479 |
bh->b_end_io = ext4_end_bitmap_read; get_bh(bh); |
2a222ca99 fs: have submit_b... |
480 |
submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, bh); |
813e57276 ext4: fix race wh... |
481 |
return bh; |
fa77dcfaf ext4: calculate a... |
482 |
verify: |
9008a58e5 ext4: make the bi... |
483 484 485 486 487 |
err = ext4_validate_block_bitmap(sb, desc, block_group, bh); if (err) goto out; return bh; out: |
48d9eb97d ext4: error out i... |
488 |
put_bh(bh); |
9008a58e5 ext4: make the bi... |
489 |
return ERR_PTR(err); |
813e57276 ext4: fix race wh... |
490 |
} |
9033783c8 ext4: fix return-... |
491 |
/* Returns 0 on success, -errno on error */ |
813e57276 ext4: fix race wh... |
492 493 494 495 496 497 498 499 500 |
int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group, struct buffer_head *bh) { struct ext4_group_desc *desc; if (!buffer_new(bh)) return 0; desc = ext4_get_group_desc(sb, block_group, NULL); if (!desc) |
9008a58e5 ext4: make the bi... |
501 |
return -EFSCORRUPTED; |
813e57276 ext4: fix race wh... |
502 |
wait_on_buffer(bh); |
46f870d69 ext4: simulate va... |
503 |
ext4_simulate_fail_bh(sb, bh, EXT4_SIM_BBITMAP_EIO); |
813e57276 ext4: fix race wh... |
504 |
if (!buffer_uptodate(bh)) { |
54d3adbc2 ext4: save all er... |
505 506 507 |
ext4_error_err(sb, EIO, "Cannot read block bitmap - " "block_group = %u, block_bitmap = %llu", block_group, (unsigned long long) bh->b_blocknr); |
736dedbb1 ext4: mark block ... |
508 509 |
ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); |
9008a58e5 ext4: make the bi... |
510 |
return -EIO; |
abcb2947c ext4: add block b... |
511 |
} |
813e57276 ext4: fix race wh... |
512 513 |
clear_buffer_new(bh); /* Panic or remount fs read-only if block bitmap is invalid */ |
9008a58e5 ext4: make the bi... |
514 |
return ext4_validate_block_bitmap(sb, desc, block_group, bh); |
813e57276 ext4: fix race wh... |
515 516 517 518 519 520 |
} struct buffer_head * ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) { struct buffer_head *bh; |
9008a58e5 ext4: make the bi... |
521 |
int err; |
813e57276 ext4: fix race wh... |
522 523 |
bh = ext4_read_block_bitmap_nowait(sb, block_group); |
9008a58e5 ext4: make the bi... |
524 525 526 527 |
if (IS_ERR(bh)) return bh; err = ext4_wait_block_bitmap(sb, block_group, bh); if (err) { |
813e57276 ext4: fix race wh... |
528 |
put_bh(bh); |
9008a58e5 ext4: make the bi... |
529 |
return ERR_PTR(err); |
813e57276 ext4: fix race wh... |
530 |
} |
ac27a0ec1 [PATCH] ext4: ini... |
531 532 |
return bh; } |
ac27a0ec1 [PATCH] ext4: ini... |
533 534 |
/** |
df55c99dc ext4: rename ext4... |
535 |
* ext4_has_free_clusters() |
8c3bf8a01 merge ext4_claim_... |
536 |
* @sbi: in-core super block structure. |
df55c99dc ext4: rename ext4... |
537 538 |
* @nclusters: number of needed blocks * @flags: flags from ext4_mb_new_blocks() |
8c3bf8a01 merge ext4_claim_... |
539 |
* |
df55c99dc ext4: rename ext4... |
540 |
* Check if filesystem has nclusters free & available for allocation. |
8c3bf8a01 merge ext4_claim_... |
541 542 |
* On success return 1, return 0 on failure. */ |
df55c99dc ext4: rename ext4... |
543 544 |
static int ext4_has_free_clusters(struct ext4_sb_info *sbi, s64 nclusters, unsigned int flags) |
a30d542a0 ext4: Make sure a... |
545 |
{ |
27dd43854 ext4: introduce r... |
546 |
s64 free_clusters, dirty_clusters, rsv, resv_clusters; |
570426518 ext4: convert s_{... |
547 |
struct percpu_counter *fcc = &sbi->s_freeclusters_counter; |
df55c99dc ext4: rename ext4... |
548 |
struct percpu_counter *dcc = &sbi->s_dirtyclusters_counter; |
a30d542a0 ext4: Make sure a... |
549 |
|
df55c99dc ext4: rename ext4... |
550 551 |
free_clusters = percpu_counter_read_positive(fcc); dirty_clusters = percpu_counter_read_positive(dcc); |
27dd43854 ext4: introduce r... |
552 |
resv_clusters = atomic64_read(&sbi->s_resv_clusters); |
304e220f0 ext4: fix free cl... |
553 554 555 556 557 |
/* * r_blocks_count should always be multiple of the cluster ratio so * we are safe to do a plane bit shift only. */ |
27dd43854 ext4: introduce r... |
558 559 |
rsv = (ext4_r_blocks_count(sbi->s_es) >> sbi->s_cluster_bits) + resv_clusters; |
a30d542a0 ext4: Make sure a... |
560 |
|
27dd43854 ext4: introduce r... |
561 |
if (free_clusters - (nclusters + rsv + dirty_clusters) < |
df55c99dc ext4: rename ext4... |
562 |
EXT4_FREECLUSTERS_WATERMARK) { |
304e220f0 ext4: fix free cl... |
563 |
free_clusters = percpu_counter_sum_positive(fcc); |
df55c99dc ext4: rename ext4... |
564 |
dirty_clusters = percpu_counter_sum_positive(dcc); |
6bc6e63fc ext4: Add percpu ... |
565 |
} |
df55c99dc ext4: rename ext4... |
566 567 |
/* Check whether we have space after accounting for current * dirty clusters & root reserved clusters. |
6bc6e63fc ext4: Add percpu ... |
568 |
*/ |
27dd43854 ext4: introduce r... |
569 |
if (free_clusters >= (rsv + nclusters + dirty_clusters)) |
a996031c8 delay capable() c... |
570 |
return 1; |
a30d542a0 ext4: Make sure a... |
571 |
|
df55c99dc ext4: rename ext4... |
572 |
/* Hm, nope. Are (enough) root reserved clusters available? */ |
08cefc7ab userns: Convert e... |
573 574 |
if (uid_eq(sbi->s_resuid, current_fsuid()) || (!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) && in_group_p(sbi->s_resgid)) || |
55f020db6 ext4: add flag to... |
575 |
capable(CAP_SYS_RESOURCE) || |
27dd43854 ext4: introduce r... |
576 |
(flags & EXT4_MB_USE_ROOT_BLOCKS)) { |
55f020db6 ext4: add flag to... |
577 |
|
27dd43854 ext4: introduce r... |
578 579 580 581 582 583 |
if (free_clusters >= (nclusters + dirty_clusters + resv_clusters)) return 1; } /* No free blocks. Let's see if we can dip into reserved pool */ if (flags & EXT4_MB_USE_RESERVED) { |
df55c99dc ext4: rename ext4... |
584 |
if (free_clusters >= (nclusters + dirty_clusters)) |
a996031c8 delay capable() c... |
585 586 587 588 |
return 1; } return 0; |
a30d542a0 ext4: Make sure a... |
589 |
} |
e7d5f3156 ext4: rename ext4... |
590 591 |
int ext4_claim_free_clusters(struct ext4_sb_info *sbi, s64 nclusters, unsigned int flags) |
ac27a0ec1 [PATCH] ext4: ini... |
592 |
{ |
df55c99dc ext4: rename ext4... |
593 |
if (ext4_has_free_clusters(sbi, nclusters, flags)) { |
e7d5f3156 ext4: rename ext4... |
594 |
percpu_counter_add(&sbi->s_dirtyclusters_counter, nclusters); |
16eb72956 ext4: make sure e... |
595 |
return 0; |
8c3bf8a01 merge ext4_claim_... |
596 597 |
} else return -ENOSPC; |
a30d542a0 ext4: Make sure a... |
598 |
} |
070314310 ext4: mballoc avo... |
599 |
|
ac27a0ec1 [PATCH] ext4: ini... |
600 |
/** |
c60990b36 ext4: clean up ke... |
601 |
* ext4_should_retry_alloc() - check if a block allocation should be retried |
ac27a0ec1 [PATCH] ext4: ini... |
602 |
* @sb: super block |
c60990b36 ext4: clean up ke... |
603 |
* @retries: number of attemps has been made |
ac27a0ec1 [PATCH] ext4: ini... |
604 |
* |
617ba13b3 [PATCH] ext4: ren... |
605 |
* ext4_should_retry_alloc() is called when ENOSPC is returned, and if |
ac27a0ec1 [PATCH] ext4: ini... |
606 |
* it is profitable to retry the operation, this function will wait |
25985edce Fix common misspe... |
607 |
* for the current or committing transaction to complete, and then |
68fd97504 ext4: retry alloc... |
608 |
* return TRUE. We will only retry once. |
ac27a0ec1 [PATCH] ext4: ini... |
609 |
*/ |
617ba13b3 [PATCH] ext4: ren... |
610 |
int ext4_should_retry_alloc(struct super_block *sb, int *retries) |
ac27a0ec1 [PATCH] ext4: ini... |
611 |
{ |
df55c99dc ext4: rename ext4... |
612 |
if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) || |
68fd97504 ext4: retry alloc... |
613 |
(*retries)++ > 1 || |
8f64b32eb ext4: don't call ... |
614 |
!EXT4_SB(sb)->s_journal) |
ac27a0ec1 [PATCH] ext4: ini... |
615 |
return 0; |
d08854f5b ext4: optimize ex... |
616 |
smp_mb(); |
68fd97504 ext4: retry alloc... |
617 618 619 620 621 622 |
if (EXT4_SB(sb)->s_mb_free_pending == 0) return 0; jbd_debug(1, "%s: retrying operation after ENOSPC ", sb->s_id); jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); |
dbc427ce4 ext4: fix race in... |
623 |
return 1; |
ac27a0ec1 [PATCH] ext4: ini... |
624 |
} |
654b4908b ext4: cleanup blo... |
625 |
/* |
d2a176379 ext4: delayed all... |
626 |
* ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks |
654b4908b ext4: cleanup blo... |
627 628 629 630 |
* * @handle: handle to this transaction * @inode: file inode * @goal: given target block(filesystem wide) |
7b415bf60 ext4: Fix bigallo... |
631 |
* @count: pointer to total number of clusters needed |
654b4908b ext4: cleanup blo... |
632 633 |
* @errp: error code * |
97df5d155 ext4: remove do_b... |
634 |
* Return 1st allocated block number on success, *count stores total account |
d2a176379 ext4: delayed all... |
635 |
* error stores in errp pointer |
654b4908b ext4: cleanup blo... |
636 |
*/ |
d2a176379 ext4: delayed all... |
637 |
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, |
55f020db6 ext4: add flag to... |
638 639 |
ext4_fsblk_t goal, unsigned int flags, unsigned long *count, int *errp) |
654b4908b ext4: cleanup blo... |
640 |
{ |
97df5d155 ext4: remove do_b... |
641 |
struct ext4_allocation_request ar; |
d2a176379 ext4: delayed all... |
642 |
ext4_fsblk_t ret; |
97df5d155 ext4: remove do_b... |
643 644 645 646 647 648 |
memset(&ar, 0, sizeof(ar)); /* Fill with neighbour allocated blocks */ ar.inode = inode; ar.goal = goal; ar.len = count ? *count : 1; |
55f020db6 ext4: add flag to... |
649 |
ar.flags = flags; |
97df5d155 ext4: remove do_b... |
650 651 652 653 |
ret = ext4_mb_new_blocks(handle, &ar, errp); if (count) *count = ar.len; |
d2a176379 ext4: delayed all... |
654 |
/* |
72b8ab9dd ext4: don't use q... |
655 656 |
* Account for the allocated meta blocks. We will never * fail EDQUOT for metdata, but we do account for it. |
d2a176379 ext4: delayed all... |
657 |
*/ |
e3cf5d5d9 ext4: prepare to ... |
658 |
if (!(*errp) && (flags & EXT4_MB_DELALLOC_RESERVED)) { |
7b415bf60 ext4: Fix bigallo... |
659 660 |
dquot_alloc_block_nofail(inode, EXT4_C2B(EXT4_SB(inode->i_sb), ar.len)); |
d2a176379 ext4: delayed all... |
661 662 |
} return ret; |
654b4908b ext4: cleanup blo... |
663 |
} |
ac27a0ec1 [PATCH] ext4: ini... |
664 |
/** |
5dee54372 ext4: rename ext4... |
665 |
* ext4_count_free_clusters() -- count filesystem free clusters |
ac27a0ec1 [PATCH] ext4: ini... |
666 667 |
* @sb: superblock * |
5dee54372 ext4: rename ext4... |
668 |
* Adds up the number of free clusters from each block group. |
ac27a0ec1 [PATCH] ext4: ini... |
669 |
*/ |
5dee54372 ext4: rename ext4... |
670 |
ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb) |
ac27a0ec1 [PATCH] ext4: ini... |
671 |
{ |
617ba13b3 [PATCH] ext4: ren... |
672 673 |
ext4_fsblk_t desc_count; struct ext4_group_desc *gdp; |
fd2d42912 ext4: add ext4_gr... |
674 |
ext4_group_t i; |
8df9675f8 ext4: Avoid races... |
675 |
ext4_group_t ngroups = ext4_get_groups_count(sb); |
2746f7a17 ext4: don't count... |
676 |
struct ext4_group_info *grp; |
617ba13b3 [PATCH] ext4: ren... |
677 678 679 |
#ifdef EXT4FS_DEBUG struct ext4_super_block *es; ext4_fsblk_t bitmap_count; |
498e5f241 ext4: Change unsi... |
680 |
unsigned int x; |
ac27a0ec1 [PATCH] ext4: ini... |
681 |
struct buffer_head *bitmap_bh = NULL; |
617ba13b3 [PATCH] ext4: ren... |
682 |
es = EXT4_SB(sb)->s_es; |
ac27a0ec1 [PATCH] ext4: ini... |
683 684 685 |
desc_count = 0; bitmap_count = 0; gdp = NULL; |
ac27a0ec1 [PATCH] ext4: ini... |
686 |
for (i = 0; i < ngroups; i++) { |
617ba13b3 [PATCH] ext4: ren... |
687 |
gdp = ext4_get_group_desc(sb, i, NULL); |
ac27a0ec1 [PATCH] ext4: ini... |
688 689 |
if (!gdp) continue; |
2746f7a17 ext4: don't count... |
690 691 692 693 694 |
grp = NULL; if (EXT4_SB(sb)->s_group_info) grp = ext4_get_group_info(sb, i); if (!grp || !EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) desc_count += ext4_free_group_clusters(sb, gdp); |
ac27a0ec1 [PATCH] ext4: ini... |
695 |
brelse(bitmap_bh); |
574ca174c ext4: Rename read... |
696 |
bitmap_bh = ext4_read_block_bitmap(sb, i); |
9008a58e5 ext4: make the bi... |
697 698 |
if (IS_ERR(bitmap_bh)) { bitmap_bh = NULL; |
ac27a0ec1 [PATCH] ext4: ini... |
699 |
continue; |
9008a58e5 ext4: make the bi... |
700 |
} |
ac27a0ec1 [PATCH] ext4: ini... |
701 |
|
f6fb99cad ext4: pass a char... |
702 |
x = ext4_count_free(bitmap_bh->b_data, |
036acea2c ext4: fix ext4_co... |
703 |
EXT4_CLUSTERS_PER_GROUP(sb) / 8); |
9fd9784c9 ext4: Fix buildin... |
704 705 |
printk(KERN_DEBUG "group %u: stored = %d, counted = %u ", |
021b65bb1 ext4: Rename ext4... |
706 |
i, ext4_free_group_clusters(sb, gdp), x); |
ac27a0ec1 [PATCH] ext4: ini... |
707 708 709 |
bitmap_count += x; } brelse(bitmap_bh); |
5dee54372 ext4: rename ext4... |
710 711 712 |
printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu" ", computed = %llu, %llu ", |
810da240f ext4: convert num... |
713 |
EXT4_NUM_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), |
4776004f5 ext4: Add printk ... |
714 |
desc_count, bitmap_count); |
ac27a0ec1 [PATCH] ext4: ini... |
715 716 717 |
return bitmap_count; #else desc_count = 0; |
ac27a0ec1 [PATCH] ext4: ini... |
718 |
for (i = 0; i < ngroups; i++) { |
617ba13b3 [PATCH] ext4: ren... |
719 |
gdp = ext4_get_group_desc(sb, i, NULL); |
ac27a0ec1 [PATCH] ext4: ini... |
720 721 |
if (!gdp) continue; |
2746f7a17 ext4: don't count... |
722 723 724 725 726 |
grp = NULL; if (EXT4_SB(sb)->s_group_info) grp = ext4_get_group_info(sb, i); if (!grp || !EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) desc_count += ext4_free_group_clusters(sb, gdp); |
ac27a0ec1 [PATCH] ext4: ini... |
727 728 729 730 731 |
} return desc_count; #endif } |
fd2d42912 ext4: add ext4_gr... |
732 |
static inline int test_root(ext4_group_t a, int b) |
ac27a0ec1 [PATCH] ext4: ini... |
733 |
{ |
f4afb4f4e ext4: optimize te... |
734 735 736 737 738 739 740 741 742 |
while (1) { if (a < b) return 0; if (a == b) return 1; if ((a % b) != 0) return 0; a = a / b; } |
ac27a0ec1 [PATCH] ext4: ini... |
743 |
} |
ac27a0ec1 [PATCH] ext4: ini... |
744 |
/** |
617ba13b3 [PATCH] ext4: ren... |
745 |
* ext4_bg_has_super - number of blocks used by the superblock in group |
ac27a0ec1 [PATCH] ext4: ini... |
746 747 748 749 750 751 |
* @sb: superblock for filesystem * @group: group number to check * * Return the number of blocks used by the superblock (primary or backup) * in this group. Currently this will be only 0 or 1. */ |
fd2d42912 ext4: add ext4_gr... |
752 |
int ext4_bg_has_super(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
753 |
{ |
1beeef1b5 ext4: fix block b... |
754 755 756 757 |
struct ext4_super_block *es = EXT4_SB(sb)->s_es; if (group == 0) return 1; |
e2b911c53 ext4: clean up fe... |
758 |
if (ext4_has_feature_sparse_super2(sb)) { |
1beeef1b5 ext4: fix block b... |
759 760 761 762 763 |
if (group == le32_to_cpu(es->s_backup_bgs[0]) || group == le32_to_cpu(es->s_backup_bgs[1])) return 1; return 0; } |
e2b911c53 ext4: clean up fe... |
764 |
if ((group <= 1) || !ext4_has_feature_sparse_super(sb)) |
1beeef1b5 ext4: fix block b... |
765 766 |
return 1; if (!(group & 1)) |
ac27a0ec1 [PATCH] ext4: ini... |
767 |
return 0; |
1beeef1b5 ext4: fix block b... |
768 769 770 771 772 |
if (test_root(group, 3) || (test_root(group, 5)) || test_root(group, 7)) return 1; return 0; |
ac27a0ec1 [PATCH] ext4: ini... |
773 |
} |
fd2d42912 ext4: add ext4_gr... |
774 775 |
static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
776 |
{ |
617ba13b3 [PATCH] ext4: ren... |
777 |
unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb); |
fd2d42912 ext4: add ext4_gr... |
778 779 |
ext4_group_t first = metagroup * EXT4_DESC_PER_BLOCK(sb); ext4_group_t last = first + EXT4_DESC_PER_BLOCK(sb) - 1; |
ac27a0ec1 [PATCH] ext4: ini... |
780 781 782 783 784 |
if (group == first || group == first + 1 || group == last) return 1; return 0; } |
fd2d42912 ext4: add ext4_gr... |
785 786 |
static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
787 |
{ |
8dadb198c ext4: fix uninit ... |
788 789 |
if (!ext4_bg_has_super(sb, group)) return 0; |
e2b911c53 ext4: clean up fe... |
790 |
if (ext4_has_feature_meta_bg(sb)) |
8dadb198c ext4: fix uninit ... |
791 792 793 |
return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg); else return EXT4_SB(sb)->s_gdb_count; |
ac27a0ec1 [PATCH] ext4: ini... |
794 795 796 |
} /** |
617ba13b3 [PATCH] ext4: ren... |
797 |
* ext4_bg_num_gdb - number of blocks used by the group table in group |
ac27a0ec1 [PATCH] ext4: ini... |
798 799 800 801 802 803 804 |
* @sb: superblock for filesystem * @group: group number to check * * Return the number of blocks used by the group descriptor table * (primary or backup) in this group. In the future there may be a * different number of descriptor blocks in each group. */ |
fd2d42912 ext4: add ext4_gr... |
805 |
unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
806 807 |
{ unsigned long first_meta_bg = |
617ba13b3 [PATCH] ext4: ren... |
808 809 |
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg); unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb); |
ac27a0ec1 [PATCH] ext4: ini... |
810 |
|
e2b911c53 ext4: clean up fe... |
811 |
if (!ext4_has_feature_meta_bg(sb) || metagroup < first_meta_bg) |
af5bc92dd ext4: Fix whitesp... |
812 |
return ext4_bg_num_gdb_nometa(sb, group); |
ac27a0ec1 [PATCH] ext4: ini... |
813 |
|
617ba13b3 [PATCH] ext4: ren... |
814 |
return ext4_bg_num_gdb_meta(sb,group); |
ac27a0ec1 [PATCH] ext4: ini... |
815 816 |
} |
c2ea3fde6 ext4: Remove old ... |
817 |
|
49f7f9af4 ext4: factor out ... |
818 |
/* |
d5b8f3100 ext4: bigalloc ch... |
819 |
* This function returns the number of file system metadata clusters at |
49f7f9af4 ext4: factor out ... |
820 821 |
* the beginning of a block group, including the reserved gdt blocks. */ |
5f163cc75 ext4: make more s... |
822 |
static unsigned ext4_num_base_meta_clusters(struct super_block *sb, |
d5b8f3100 ext4: bigalloc ch... |
823 |
ext4_group_t block_group) |
49f7f9af4 ext4: factor out ... |
824 825 |
{ struct ext4_sb_info *sbi = EXT4_SB(sb); |
d5b8f3100 ext4: bigalloc ch... |
826 |
unsigned num; |
49f7f9af4 ext4: factor out ... |
827 828 829 |
/* Check for superblock and gdt backups in this group */ num = ext4_bg_has_super(sb, block_group); |
e2b911c53 ext4: clean up fe... |
830 |
if (!ext4_has_feature_meta_bg(sb) || |
49f7f9af4 ext4: factor out ... |
831 832 833 834 835 836 837 838 839 |
block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) * sbi->s_desc_per_block) { if (num) { num += ext4_bg_num_gdb(sb, block_group); num += le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks); } } else { /* For META_BG_BLOCK_GROUPS */ num += ext4_bg_num_gdb(sb, block_group); } |
d5b8f3100 ext4: bigalloc ch... |
840 |
return EXT4_NUM_B2C(sbi, num); |
49f7f9af4 ext4: factor out ... |
841 |
} |
f86186b44 ext4: refactor du... |
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 |
/** * ext4_inode_to_goal_block - return a hint for block allocation * @inode: inode for block allocation * * Return the ideal location to start allocating blocks for a * newly created inode. */ ext4_fsblk_t ext4_inode_to_goal_block(struct inode *inode) { struct ext4_inode_info *ei = EXT4_I(inode); ext4_group_t block_group; ext4_grpblk_t colour; int flex_size = ext4_flex_bg_size(EXT4_SB(inode->i_sb)); ext4_fsblk_t bg_start; ext4_fsblk_t last_block; block_group = ei->i_block_group; if (flex_size >= EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME) { /* * If there are at least EXT4_FLEX_SIZE_DIR_ALLOC_SCHEME * block groups per flexgroup, reserve the first block * group for directories and special files. Regular * files will start at the second block group. This * tends to speed up directory access and improves * fsck times. */ block_group &= ~(flex_size-1); if (S_ISREG(inode->i_mode)) block_group++; } bg_start = ext4_group_first_block_no(inode->i_sb, block_group); last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; /* * If we are doing delayed allocation, we don't need take * colour into account. */ if (test_opt(inode->i_sb, DELALLOC)) return bg_start; if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) |
9bee5779e ext4: balloc: use... |
883 |
colour = (task_pid_nr(current) % 16) * |
f86186b44 ext4: refactor du... |
884 885 |
(EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); else |
9bee5779e ext4: balloc: use... |
886 887 |
colour = (task_pid_nr(current) % 16) * ((last_block - bg_start) / 16); |
f86186b44 ext4: refactor du... |
888 889 |
return bg_start + colour; } |