Blame view
fs/ext4/balloc.c
21.5 KB
ac27a0ec1 [PATCH] ext4: ini... |
1 |
/* |
617ba13b3 [PATCH] ext4: ren... |
2 |
* linux/fs/ext4/balloc.c |
ac27a0ec1 [PATCH] ext4: ini... |
3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
* * 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> |
dab291af8 [PATCH] jbd2: ena... |
17 |
#include <linux/jbd2.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 */ /* |
3212a80a5 ext4: convert blo... |
32 33 |
* Calculate the block group number and offset into the block/cluster * allocation bitmap, given a block number |
72b64b594 [PATCH] ext4 unin... |
34 35 |
*/ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, |
fd2d42912 ext4: add ext4_gr... |
36 |
ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp) |
72b64b594 [PATCH] ext4 unin... |
37 |
{ |
8c55e2041 EXT4: Fix whitespace |
38 |
struct ext4_super_block *es = EXT4_SB(sb)->s_es; |
72b64b594 [PATCH] ext4 unin... |
39 |
ext4_grpblk_t offset; |
8c55e2041 EXT4: Fix whitespace |
40 |
blocknr = blocknr - le32_to_cpu(es->s_first_data_block); |
3212a80a5 ext4: convert blo... |
41 42 |
offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb)) >> EXT4_SB(sb)->s_cluster_bits; |
72b64b594 [PATCH] ext4 unin... |
43 44 45 |
if (offsetp) *offsetp = offset; if (blockgrpp) |
8c55e2041 EXT4: Fix whitespace |
46 |
*blockgrpp = blocknr; |
72b64b594 [PATCH] ext4 unin... |
47 48 |
} |
0bf7e8379 ext4: Fix uninit ... |
49 50 51 52 |
static int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block, ext4_group_t block_group) { ext4_group_t actual_group; |
7477827f6 ext4: Fix sparse ... |
53 |
ext4_get_group_no_and_offset(sb, block, &actual_group, NULL); |
0bf7e8379 ext4: Fix uninit ... |
54 55 56 57 |
if (actual_group == block_group) return 1; return 0; } |
d5b8f3100 ext4: bigalloc ch... |
58 59 60 61 62 63 |
/* Return the number of clusters used for file system metadata; this * represents the overhead needed by the file system. */ unsigned ext4_num_overhead_clusters(struct super_block *sb, ext4_group_t block_group, struct ext4_group_desc *gdp) |
0bf7e8379 ext4: Fix uninit ... |
64 |
{ |
d5b8f3100 ext4: bigalloc ch... |
65 66 67 68 |
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 ... |
69 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
0bf7e8379 ext4: Fix uninit ... |
70 |
|
d5b8f3100 ext4: bigalloc ch... |
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
/* 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)) { block_cluster = EXT4_B2C(sbi, (start - ext4_block_bitmap(sb, gdp))); 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, start - ext4_inode_bitmap(sb, gdp)); 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)) { c = EXT4_B2C(sbi, start - itbl_blk + i); 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 ... |
123 124 |
} } |
d5b8f3100 ext4: bigalloc ch... |
125 126 127 128 129 130 131 |
if (block_cluster != -1) num_clusters++; if (inode_cluster != -1) num_clusters++; return num_clusters; |
0bf7e8379 ext4: Fix uninit ... |
132 |
} |
c2ea3fde6 ext4: Remove old ... |
133 |
|
d5b8f3100 ext4: bigalloc ch... |
134 135 |
static unsigned int num_clusters_in_group(struct super_block *sb, ext4_group_t block_group) |
49f7f9af4 ext4: factor out ... |
136 |
{ |
d5b8f3100 ext4: bigalloc ch... |
137 |
unsigned int blocks; |
49f7f9af4 ext4: factor out ... |
138 139 140 141 142 143 144 |
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... |
145 |
blocks = ext4_blocks_count(EXT4_SB(sb)->s_es) - |
49f7f9af4 ext4: factor out ... |
146 147 |
ext4_group_first_block_no(sb, block_group); } else |
d5b8f3100 ext4: bigalloc ch... |
148 149 |
blocks = EXT4_BLOCKS_PER_GROUP(sb); return EXT4_NUM_B2C(EXT4_SB(sb), blocks); |
49f7f9af4 ext4: factor out ... |
150 |
} |
fd034a84e ext4: split out e... |
151 152 153 154 |
/* Initializes an uninitialized block bitmap */ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp) |
717d50e49 Ext4: Uninitializ... |
155 |
{ |
d5b8f3100 ext4: bigalloc ch... |
156 |
unsigned int bit, bit_max; |
717d50e49 Ext4: Uninitializ... |
157 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
fd034a84e ext4: split out e... |
158 159 160 161 162 163 164 165 166 |
ext4_fsblk_t start, tmp; int flex_bg = 0; 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. */ if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { ext4_error(sb, "Checksum bad for group %u", block_group); |
021b65bb1 ext4: Rename ext4... |
167 |
ext4_free_group_clusters_set(sb, gdp, 0); |
fd034a84e ext4: split out e... |
168 169 170 171 |
ext4_free_inodes_set(sb, gdp, 0); ext4_itable_unused_set(sb, gdp, 0); memset(bh->b_data, 0xff, sb->s_blocksize); return; |
717d50e49 Ext4: Uninitializ... |
172 |
} |
fd034a84e ext4: split out e... |
173 |
memset(bh->b_data, 0, sb->s_blocksize); |
717d50e49 Ext4: Uninitializ... |
174 |
|
d5b8f3100 ext4: bigalloc ch... |
175 |
bit_max = ext4_num_base_meta_clusters(sb, block_group); |
fd034a84e ext4: split out e... |
176 177 |
for (bit = 0; bit < bit_max; bit++) ext4_set_bit(bit, bh->b_data); |
d00a6d7b4 ext4: use ext4_gr... |
178 |
|
fd034a84e ext4: split out e... |
179 |
start = ext4_group_first_block_no(sb, block_group); |
717d50e49 Ext4: Uninitializ... |
180 |
|
fd034a84e ext4: split out e... |
181 182 |
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) flex_bg = 1; |
717d50e49 Ext4: Uninitializ... |
183 |
|
fd034a84e ext4: split out e... |
184 185 186 |
/* Set bits for block and inode bitmaps, and inode table */ tmp = ext4_block_bitmap(sb, gdp); if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) |
d5b8f3100 ext4: bigalloc ch... |
187 |
ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
717d50e49 Ext4: Uninitializ... |
188 |
|
fd034a84e ext4: split out e... |
189 190 |
tmp = ext4_inode_bitmap(sb, gdp); if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) |
d5b8f3100 ext4: bigalloc ch... |
191 |
ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
0bf7e8379 ext4: Fix uninit ... |
192 |
|
fd034a84e ext4: split out e... |
193 194 195 |
tmp = ext4_inode_table(sb, gdp); for (; tmp < ext4_inode_table(sb, gdp) + sbi->s_itb_per_group; tmp++) { |
0bf7e8379 ext4: Fix uninit ... |
196 |
if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) |
d5b8f3100 ext4: bigalloc ch... |
197 |
ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); |
717d50e49 Ext4: Uninitializ... |
198 |
} |
d5b8f3100 ext4: bigalloc ch... |
199 |
|
fd034a84e ext4: split out e... |
200 201 202 203 204 |
/* * 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... |
205 |
ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), |
fd034a84e ext4: split out e... |
206 |
sb->s_blocksize * 8, bh->b_data); |
717d50e49 Ext4: Uninitializ... |
207 |
} |
fd034a84e ext4: split out e... |
208 209 210 |
/* 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... |
211 212 213 |
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... |
214 |
{ |
d5b8f3100 ext4: bigalloc ch... |
215 216 |
return num_clusters_in_group(sb, block_group) - ext4_num_overhead_clusters(sb, block_group, gdp); |
fd034a84e ext4: split out e... |
217 |
} |
717d50e49 Ext4: Uninitializ... |
218 |
|
72b64b594 [PATCH] ext4 unin... |
219 |
/* |
ac27a0ec1 [PATCH] ext4: ini... |
220 221 222 223 224 225 226 |
* 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]:... |
227 |
* when a file system is mounted (see ext4_fill_super). |
ac27a0ec1 [PATCH] ext4: ini... |
228 |
*/ |
ac27a0ec1 [PATCH] ext4: ini... |
229 |
/** |
617ba13b3 [PATCH] ext4: ren... |
230 |
* ext4_get_group_desc() -- load group descriptor from disk |
ac27a0ec1 [PATCH] ext4: ini... |
231 232 233 234 235 |
* @sb: super block * @block_group: given block group * @bh: pointer to the buffer head to store the block * group descriptor */ |
af5bc92dd ext4: Fix whitesp... |
236 |
struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, |
fd2d42912 ext4: add ext4_gr... |
237 |
ext4_group_t block_group, |
af5bc92dd ext4: Fix whitesp... |
238 |
struct buffer_head **bh) |
ac27a0ec1 [PATCH] ext4: ini... |
239 |
{ |
498e5f241 ext4: Change unsi... |
240 241 |
unsigned int group_desc; unsigned int offset; |
8df9675f8 ext4: Avoid races... |
242 |
ext4_group_t ngroups = ext4_get_groups_count(sb); |
af5bc92dd ext4: Fix whitesp... |
243 |
struct ext4_group_desc *desc; |
617ba13b3 [PATCH] ext4: ren... |
244 |
struct ext4_sb_info *sbi = EXT4_SB(sb); |
ac27a0ec1 [PATCH] ext4: ini... |
245 |
|
8df9675f8 ext4: Avoid races... |
246 |
if (block_group >= ngroups) { |
12062dddd ext4: move __func... |
247 248 |
ext4_error(sb, "block_group >= groups_count - block_group = %u," " groups_count = %u", block_group, ngroups); |
ac27a0ec1 [PATCH] ext4: ini... |
249 250 251 |
return NULL; } |
ac27a0ec1 [PATCH] ext4: ini... |
252 |
|
617ba13b3 [PATCH] ext4: ren... |
253 254 |
group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); |
ac27a0ec1 [PATCH] ext4: ini... |
255 |
if (!sbi->s_group_desc[group_desc]) { |
12062dddd ext4: move __func... |
256 |
ext4_error(sb, "Group descriptor not loaded - " |
498e5f241 ext4: Change unsi... |
257 |
"block_group = %u, group_desc = %u, desc = %u", |
af5bc92dd ext4: Fix whitesp... |
258 |
block_group, group_desc, offset); |
ac27a0ec1 [PATCH] ext4: ini... |
259 260 |
return NULL; } |
0d1ee42f2 [PATCH] ext4: all... |
261 262 263 |
desc = (struct ext4_group_desc *)( (__u8 *)sbi->s_group_desc[group_desc]->b_data + offset * EXT4_DESC_SIZE(sb)); |
ac27a0ec1 [PATCH] ext4: ini... |
264 265 |
if (bh) *bh = sbi->s_group_desc[group_desc]; |
0d1ee42f2 [PATCH] ext4: all... |
266 |
return desc; |
ac27a0ec1 [PATCH] ext4: ini... |
267 |
} |
abcb2947c ext4: add block b... |
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
static int ext4_valid_block_bitmap(struct super_block *sb, struct ext4_group_desc *desc, unsigned int block_group, struct buffer_head *bh) { ext4_grpblk_t offset; ext4_grpblk_t next_zero_bit; ext4_fsblk_t bitmap_blk; ext4_fsblk_t group_first_block; if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { /* 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. */ return 1; } group_first_block = ext4_group_first_block_no(sb, block_group); /* check whether block bitmap block number is set */ bitmap_blk = ext4_block_bitmap(sb, desc); offset = bitmap_blk - group_first_block; if (!ext4_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode bitmap block number is set */ bitmap_blk = ext4_inode_bitmap(sb, desc); offset = bitmap_blk - group_first_block; if (!ext4_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode table block number is set */ bitmap_blk = ext4_inode_table(sb, desc); offset = bitmap_blk - group_first_block; next_zero_bit = ext4_find_next_zero_bit(bh->b_data, offset + EXT4_SB(sb)->s_itb_per_group, offset); if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group) /* good bitmap for inode tables */ return 1; err_out: |
12062dddd ext4: move __func... |
314 |
ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu", |
abcb2947c ext4: add block b... |
315 316 317 |
block_group, bitmap_blk); return 0; } |
ac27a0ec1 [PATCH] ext4: ini... |
318 |
/** |
574ca174c ext4: Rename read... |
319 |
* ext4_read_block_bitmap() |
ac27a0ec1 [PATCH] ext4: ini... |
320 321 322 |
* @sb: super block * @block_group: given block group * |
abcb2947c ext4: add block b... |
323 324 |
* 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... |
325 326 327 |
* * Return buffer_head on success or NULL in case of failure. */ |
717d50e49 Ext4: Uninitializ... |
328 |
struct buffer_head * |
574ca174c ext4: Rename read... |
329 |
ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) |
ac27a0ec1 [PATCH] ext4: ini... |
330 |
{ |
af5bc92dd ext4: Fix whitesp... |
331 332 |
struct ext4_group_desc *desc; struct buffer_head *bh = NULL; |
7c9e69faa ext2/ext3/ext4: a... |
333 |
ext4_fsblk_t bitmap_blk; |
ac27a0ec1 [PATCH] ext4: ini... |
334 |
|
717d50e49 Ext4: Uninitializ... |
335 |
desc = ext4_get_group_desc(sb, block_group, NULL); |
ac27a0ec1 [PATCH] ext4: ini... |
336 |
if (!desc) |
7c9e69faa ext2/ext3/ext4: a... |
337 338 |
return NULL; bitmap_blk = ext4_block_bitmap(sb, desc); |
abcb2947c ext4: add block b... |
339 340 |
bh = sb_getblk(sb, bitmap_blk); if (unlikely(!bh)) { |
12062dddd ext4: move __func... |
341 |
ext4_error(sb, "Cannot read block bitmap - " |
a9df9a491 ext4: Make ext4_g... |
342 |
"block_group = %u, block_bitmap = %llu", |
e29d1cde6 ext4: sync up blo... |
343 |
block_group, bitmap_blk); |
abcb2947c ext4: add block b... |
344 345 |
return NULL; } |
2ccb5fb9f ext4: Use new buf... |
346 347 |
if (bitmap_uptodate(bh)) |
abcb2947c ext4: add block b... |
348 |
return bh; |
c806e68f5 ext4: fix initial... |
349 |
lock_buffer(bh); |
2ccb5fb9f ext4: Use new buf... |
350 351 352 353 |
if (bitmap_uptodate(bh)) { unlock_buffer(bh); return bh; } |
955ce5f5b ext4: Convert ext... |
354 |
ext4_lock_group(sb, block_group); |
717d50e49 Ext4: Uninitializ... |
355 |
if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
abcb2947c ext4: add block b... |
356 |
ext4_init_block_bitmap(sb, bh, block_group, desc); |
2ccb5fb9f ext4: Use new buf... |
357 |
set_bitmap_uptodate(bh); |
abcb2947c ext4: add block b... |
358 |
set_buffer_uptodate(bh); |
955ce5f5b ext4: Convert ext... |
359 |
ext4_unlock_group(sb, block_group); |
3300beda5 ext4: code cleanup |
360 |
unlock_buffer(bh); |
abcb2947c ext4: add block b... |
361 |
return bh; |
717d50e49 Ext4: Uninitializ... |
362 |
} |
955ce5f5b ext4: Convert ext... |
363 |
ext4_unlock_group(sb, block_group); |
2ccb5fb9f ext4: Use new buf... |
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
if (buffer_uptodate(bh)) { /* * if not uninit if bh is uptodate, * bitmap is also uptodate */ set_bitmap_uptodate(bh); unlock_buffer(bh); return bh; } /* * submit the buffer_head for read. We can * safely mark the bitmap as uptodate now. * We do it here so the bitmap uptodate bit * get set with buffer lock held. */ |
0562e0bad ext4: add more tr... |
379 |
trace_ext4_read_block_bitmap_load(sb, block_group); |
2ccb5fb9f ext4: Use new buf... |
380 |
set_bitmap_uptodate(bh); |
abcb2947c ext4: add block b... |
381 382 |
if (bh_submit_read(bh) < 0) { put_bh(bh); |
12062dddd ext4: move __func... |
383 |
ext4_error(sb, "Cannot read block bitmap - " |
a9df9a491 ext4: Make ext4_g... |
384 |
"block_group = %u, block_bitmap = %llu", |
e29d1cde6 ext4: sync up blo... |
385 |
block_group, bitmap_blk); |
abcb2947c ext4: add block b... |
386 387 |
return NULL; } |
519deca04 ext4: Retry block... |
388 389 390 391 392 |
ext4_valid_block_bitmap(sb, desc, block_group, bh); /* * file system mounted not to panic on error, * continue with corrupt bitmap */ |
ac27a0ec1 [PATCH] ext4: ini... |
393 394 |
return bh; } |
ac27a0ec1 [PATCH] ext4: ini... |
395 396 |
/** |
df55c99dc ext4: rename ext4... |
397 |
* ext4_has_free_clusters() |
8c3bf8a01 merge ext4_claim_... |
398 |
* @sbi: in-core super block structure. |
df55c99dc ext4: rename ext4... |
399 400 |
* @nclusters: number of needed blocks * @flags: flags from ext4_mb_new_blocks() |
8c3bf8a01 merge ext4_claim_... |
401 |
* |
df55c99dc ext4: rename ext4... |
402 |
* Check if filesystem has nclusters free & available for allocation. |
8c3bf8a01 merge ext4_claim_... |
403 404 |
* On success return 1, return 0 on failure. */ |
df55c99dc ext4: rename ext4... |
405 406 |
static int ext4_has_free_clusters(struct ext4_sb_info *sbi, s64 nclusters, unsigned int flags) |
a30d542a0 ext4: Make sure a... |
407 |
{ |
df55c99dc ext4: rename ext4... |
408 |
s64 free_clusters, dirty_clusters, root_clusters; |
570426518 ext4: convert s_{... |
409 |
struct percpu_counter *fcc = &sbi->s_freeclusters_counter; |
df55c99dc ext4: rename ext4... |
410 |
struct percpu_counter *dcc = &sbi->s_dirtyclusters_counter; |
a30d542a0 ext4: Make sure a... |
411 |
|
df55c99dc ext4: rename ext4... |
412 413 414 |
free_clusters = percpu_counter_read_positive(fcc); dirty_clusters = percpu_counter_read_positive(dcc); root_clusters = EXT4_B2C(sbi, ext4_r_blocks_count(sbi->s_es)); |
a30d542a0 ext4: Make sure a... |
415 |
|
df55c99dc ext4: rename ext4... |
416 417 418 419 |
if (free_clusters - (nclusters + root_clusters + dirty_clusters) < EXT4_FREECLUSTERS_WATERMARK) { free_clusters = EXT4_C2B(sbi, percpu_counter_sum_positive(fcc)); dirty_clusters = percpu_counter_sum_positive(dcc); |
6bc6e63fc ext4: Add percpu ... |
420 |
} |
df55c99dc ext4: rename ext4... |
421 422 |
/* Check whether we have space after accounting for current * dirty clusters & root reserved clusters. |
6bc6e63fc ext4: Add percpu ... |
423 |
*/ |
df55c99dc ext4: rename ext4... |
424 |
if (free_clusters >= ((root_clusters + nclusters) + dirty_clusters)) |
a996031c8 delay capable() c... |
425 |
return 1; |
a30d542a0 ext4: Make sure a... |
426 |
|
df55c99dc ext4: rename ext4... |
427 |
/* Hm, nope. Are (enough) root reserved clusters available? */ |
4c9c544e4 CRED: Wrap task c... |
428 |
if (sbi->s_resuid == current_fsuid() || |
a996031c8 delay capable() c... |
429 |
((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || |
55f020db6 ext4: add flag to... |
430 431 |
capable(CAP_SYS_RESOURCE) || (flags & EXT4_MB_USE_ROOT_BLOCKS)) { |
df55c99dc ext4: rename ext4... |
432 |
if (free_clusters >= (nclusters + dirty_clusters)) |
a996031c8 delay capable() c... |
433 434 435 436 |
return 1; } return 0; |
a30d542a0 ext4: Make sure a... |
437 |
} |
e7d5f3156 ext4: rename ext4... |
438 439 |
int ext4_claim_free_clusters(struct ext4_sb_info *sbi, s64 nclusters, unsigned int flags) |
ac27a0ec1 [PATCH] ext4: ini... |
440 |
{ |
df55c99dc ext4: rename ext4... |
441 |
if (ext4_has_free_clusters(sbi, nclusters, flags)) { |
e7d5f3156 ext4: rename ext4... |
442 |
percpu_counter_add(&sbi->s_dirtyclusters_counter, nclusters); |
16eb72956 ext4: make sure e... |
443 |
return 0; |
8c3bf8a01 merge ext4_claim_... |
444 445 |
} else return -ENOSPC; |
a30d542a0 ext4: Make sure a... |
446 |
} |
070314310 ext4: mballoc avo... |
447 |
|
ac27a0ec1 [PATCH] ext4: ini... |
448 |
/** |
617ba13b3 [PATCH] ext4: ren... |
449 |
* ext4_should_retry_alloc() |
ac27a0ec1 [PATCH] ext4: ini... |
450 451 452 |
* @sb: super block * @retries number of attemps has been made * |
617ba13b3 [PATCH] ext4: ren... |
453 |
* ext4_should_retry_alloc() is called when ENOSPC is returned, and if |
ac27a0ec1 [PATCH] ext4: ini... |
454 |
* it is profitable to retry the operation, this function will wait |
25985edce Fix common misspe... |
455 |
* for the current or committing transaction to complete, and then |
ac27a0ec1 [PATCH] ext4: ini... |
456 457 458 459 |
* return TRUE. * * if the total number of retries exceed three times, return FALSE. */ |
617ba13b3 [PATCH] ext4: ren... |
460 |
int ext4_should_retry_alloc(struct super_block *sb, int *retries) |
ac27a0ec1 [PATCH] ext4: ini... |
461 |
{ |
df55c99dc ext4: rename ext4... |
462 |
if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) || |
8f64b32eb ext4: don't call ... |
463 464 |
(*retries)++ > 3 || !EXT4_SB(sb)->s_journal) |
ac27a0ec1 [PATCH] ext4: ini... |
465 466 467 468 |
return 0; jbd_debug(1, "%s: retrying operation after ENOSPC ", sb->s_id); |
dab291af8 [PATCH] jbd2: ena... |
469 |
return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); |
ac27a0ec1 [PATCH] ext4: ini... |
470 |
} |
654b4908b ext4: cleanup blo... |
471 |
/* |
d2a176379 ext4: delayed all... |
472 |
* ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks |
654b4908b ext4: cleanup blo... |
473 474 475 476 |
* * @handle: handle to this transaction * @inode: file inode * @goal: given target block(filesystem wide) |
7b415bf60 ext4: Fix bigallo... |
477 |
* @count: pointer to total number of clusters needed |
654b4908b ext4: cleanup blo... |
478 479 |
* @errp: error code * |
97df5d155 ext4: remove do_b... |
480 |
* Return 1st allocated block number on success, *count stores total account |
d2a176379 ext4: delayed all... |
481 |
* error stores in errp pointer |
654b4908b ext4: cleanup blo... |
482 |
*/ |
d2a176379 ext4: delayed all... |
483 |
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, |
55f020db6 ext4: add flag to... |
484 485 |
ext4_fsblk_t goal, unsigned int flags, unsigned long *count, int *errp) |
654b4908b ext4: cleanup blo... |
486 |
{ |
97df5d155 ext4: remove do_b... |
487 |
struct ext4_allocation_request ar; |
d2a176379 ext4: delayed all... |
488 |
ext4_fsblk_t ret; |
97df5d155 ext4: remove do_b... |
489 490 491 492 493 494 |
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... |
495 |
ar.flags = flags; |
97df5d155 ext4: remove do_b... |
496 497 498 499 |
ret = ext4_mb_new_blocks(handle, &ar, errp); if (count) *count = ar.len; |
d2a176379 ext4: delayed all... |
500 |
/* |
72b8ab9dd ext4: don't use q... |
501 502 |
* Account for the allocated meta blocks. We will never * fail EDQUOT for metdata, but we do account for it. |
d2a176379 ext4: delayed all... |
503 |
*/ |
f23210977 ext4: replace i_d... |
504 505 |
if (!(*errp) && ext4_test_inode_state(inode, EXT4_STATE_DELALLOC_RESERVED)) { |
d2a176379 ext4: delayed all... |
506 |
spin_lock(&EXT4_I(inode)->i_block_reservation_lock); |
97df5d155 ext4: remove do_b... |
507 |
EXT4_I(inode)->i_allocated_meta_blocks += ar.len; |
d2a176379 ext4: delayed all... |
508 |
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); |
7b415bf60 ext4: Fix bigallo... |
509 510 |
dquot_alloc_block_nofail(inode, EXT4_C2B(EXT4_SB(inode->i_sb), ar.len)); |
d2a176379 ext4: delayed all... |
511 512 |
} return ret; |
654b4908b ext4: cleanup blo... |
513 |
} |
ac27a0ec1 [PATCH] ext4: ini... |
514 |
/** |
5dee54372 ext4: rename ext4... |
515 |
* ext4_count_free_clusters() -- count filesystem free clusters |
ac27a0ec1 [PATCH] ext4: ini... |
516 517 |
* @sb: superblock * |
5dee54372 ext4: rename ext4... |
518 |
* Adds up the number of free clusters from each block group. |
ac27a0ec1 [PATCH] ext4: ini... |
519 |
*/ |
5dee54372 ext4: rename ext4... |
520 |
ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb) |
ac27a0ec1 [PATCH] ext4: ini... |
521 |
{ |
617ba13b3 [PATCH] ext4: ren... |
522 523 |
ext4_fsblk_t desc_count; struct ext4_group_desc *gdp; |
fd2d42912 ext4: add ext4_gr... |
524 |
ext4_group_t i; |
8df9675f8 ext4: Avoid races... |
525 |
ext4_group_t ngroups = ext4_get_groups_count(sb); |
617ba13b3 [PATCH] ext4: ren... |
526 527 528 |
#ifdef EXT4FS_DEBUG struct ext4_super_block *es; ext4_fsblk_t bitmap_count; |
498e5f241 ext4: Change unsi... |
529 |
unsigned int x; |
ac27a0ec1 [PATCH] ext4: ini... |
530 |
struct buffer_head *bitmap_bh = NULL; |
617ba13b3 [PATCH] ext4: ren... |
531 |
es = EXT4_SB(sb)->s_es; |
ac27a0ec1 [PATCH] ext4: ini... |
532 533 534 |
desc_count = 0; bitmap_count = 0; gdp = NULL; |
ac27a0ec1 [PATCH] ext4: ini... |
535 |
for (i = 0; i < ngroups; i++) { |
617ba13b3 [PATCH] ext4: ren... |
536 |
gdp = ext4_get_group_desc(sb, i, NULL); |
ac27a0ec1 [PATCH] ext4: ini... |
537 538 |
if (!gdp) continue; |
021b65bb1 ext4: Rename ext4... |
539 |
desc_count += ext4_free_group_clusters(sb, gdp); |
ac27a0ec1 [PATCH] ext4: ini... |
540 |
brelse(bitmap_bh); |
574ca174c ext4: Rename read... |
541 |
bitmap_bh = ext4_read_block_bitmap(sb, i); |
ac27a0ec1 [PATCH] ext4: ini... |
542 543 |
if (bitmap_bh == NULL) continue; |
617ba13b3 [PATCH] ext4: ren... |
544 |
x = ext4_count_free(bitmap_bh, sb->s_blocksize); |
9fd9784c9 ext4: Fix buildin... |
545 546 |
printk(KERN_DEBUG "group %u: stored = %d, counted = %u ", |
021b65bb1 ext4: Rename ext4... |
547 |
i, ext4_free_group_clusters(sb, gdp), x); |
ac27a0ec1 [PATCH] ext4: ini... |
548 549 550 |
bitmap_count += x; } brelse(bitmap_bh); |
5dee54372 ext4: rename ext4... |
551 552 553 |
printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu" ", computed = %llu, %llu ", |
6e58ad69e ext4: fix up a un... |
554 |
EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), |
4776004f5 ext4: Add printk ... |
555 |
desc_count, bitmap_count); |
ac27a0ec1 [PATCH] ext4: ini... |
556 557 558 |
return bitmap_count; #else desc_count = 0; |
ac27a0ec1 [PATCH] ext4: ini... |
559 |
for (i = 0; i < ngroups; i++) { |
617ba13b3 [PATCH] ext4: ren... |
560 |
gdp = ext4_get_group_desc(sb, i, NULL); |
ac27a0ec1 [PATCH] ext4: ini... |
561 562 |
if (!gdp) continue; |
021b65bb1 ext4: Rename ext4... |
563 |
desc_count += ext4_free_group_clusters(sb, gdp); |
ac27a0ec1 [PATCH] ext4: ini... |
564 565 566 567 568 |
} return desc_count; #endif } |
fd2d42912 ext4: add ext4_gr... |
569 |
static inline int test_root(ext4_group_t a, int b) |
ac27a0ec1 [PATCH] ext4: ini... |
570 571 572 573 574 575 576 |
{ int num = b; while (a > num) num *= b; return num == a; } |
fd2d42912 ext4: add ext4_gr... |
577 |
static int ext4_group_sparse(ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
578 579 580 581 582 583 584 585 586 587 |
{ if (group <= 1) return 1; if (!(group & 1)) return 0; return (test_root(group, 7) || test_root(group, 5) || test_root(group, 3)); } /** |
617ba13b3 [PATCH] ext4: ren... |
588 |
* ext4_bg_has_super - number of blocks used by the superblock in group |
ac27a0ec1 [PATCH] ext4: ini... |
589 590 591 592 593 594 |
* @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... |
595 |
int ext4_bg_has_super(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
596 |
{ |
617ba13b3 [PATCH] ext4: ren... |
597 598 599 |
if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && !ext4_group_sparse(group)) |
ac27a0ec1 [PATCH] ext4: ini... |
600 601 602 |
return 0; return 1; } |
fd2d42912 ext4: add ext4_gr... |
603 604 |
static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
605 |
{ |
617ba13b3 [PATCH] ext4: ren... |
606 |
unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb); |
fd2d42912 ext4: add ext4_gr... |
607 608 |
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... |
609 610 611 612 613 |
if (group == first || group == first + 1 || group == last) return 1; return 0; } |
fd2d42912 ext4: add ext4_gr... |
614 615 |
static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
616 |
{ |
8dadb198c ext4: fix uninit ... |
617 618 619 620 621 622 623 |
if (!ext4_bg_has_super(sb, group)) return 0; if (EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG)) 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... |
624 625 626 |
} /** |
617ba13b3 [PATCH] ext4: ren... |
627 |
* ext4_bg_num_gdb - number of blocks used by the group table in group |
ac27a0ec1 [PATCH] ext4: ini... |
628 629 630 631 632 633 634 |
* @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... |
635 |
unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group) |
ac27a0ec1 [PATCH] ext4: ini... |
636 637 |
{ unsigned long first_meta_bg = |
617ba13b3 [PATCH] ext4: ren... |
638 639 |
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... |
640 |
|
617ba13b3 [PATCH] ext4: ren... |
641 |
if (!EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG) || |
ac27a0ec1 [PATCH] ext4: ini... |
642 |
metagroup < first_meta_bg) |
af5bc92dd ext4: Fix whitesp... |
643 |
return ext4_bg_num_gdb_nometa(sb, group); |
ac27a0ec1 [PATCH] ext4: ini... |
644 |
|
617ba13b3 [PATCH] ext4: ren... |
645 |
return ext4_bg_num_gdb_meta(sb,group); |
ac27a0ec1 [PATCH] ext4: ini... |
646 647 |
} |
c2ea3fde6 ext4: Remove old ... |
648 |
|
49f7f9af4 ext4: factor out ... |
649 |
/* |
d5b8f3100 ext4: bigalloc ch... |
650 |
* This function returns the number of file system metadata clusters at |
49f7f9af4 ext4: factor out ... |
651 652 |
* the beginning of a block group, including the reserved gdt blocks. */ |
5f163cc75 ext4: make more s... |
653 |
static unsigned ext4_num_base_meta_clusters(struct super_block *sb, |
d5b8f3100 ext4: bigalloc ch... |
654 |
ext4_group_t block_group) |
49f7f9af4 ext4: factor out ... |
655 656 |
{ struct ext4_sb_info *sbi = EXT4_SB(sb); |
d5b8f3100 ext4: bigalloc ch... |
657 |
unsigned num; |
49f7f9af4 ext4: factor out ... |
658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
/* Check for superblock and gdt backups in this group */ num = ext4_bg_has_super(sb, block_group); if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) || 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... |
672 |
return EXT4_NUM_B2C(sbi, num); |
49f7f9af4 ext4: factor out ... |
673 |
} |
f86186b44 ext4: refactor du... |
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 |
/** * 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) colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); else colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour; } |