diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-02-26 14:04:15 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-02-26 14:06:24 -0500 |
commit | a7790532f5b7358c33a6b1834dc2b318de209f31 (patch) | |
tree | 0ceb9e24b3f54cb5c8453fb5a218e2a94a0f1cce /fs/ext4/extents.c | |
parent | 2764fb4244cc1bc08df3667924ca4a972e90ac70 (diff) | |
parent | 60b341b778cc2929df16c0a504c91621b3c6a4ad (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
The SmartMedia FTL code depends on new kfifo bits from 2.6.33
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 98 |
1 files changed, 80 insertions, 18 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3a7928f825e4..765a4826b118 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -296,29 +296,44 @@ static inline int ext4_ext_space_root_idx(struct inode *inode, int check) | |||
296 | * to allocate @blocks | 296 | * to allocate @blocks |
297 | * Worse case is one block per extent | 297 | * Worse case is one block per extent |
298 | */ | 298 | */ |
299 | int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks) | 299 | int ext4_ext_calc_metadata_amount(struct inode *inode, sector_t lblock) |
300 | { | 300 | { |
301 | int lcap, icap, rcap, leafs, idxs, num; | 301 | struct ext4_inode_info *ei = EXT4_I(inode); |
302 | int newextents = blocks; | 302 | int idxs, num = 0; |
303 | |||
304 | rcap = ext4_ext_space_root_idx(inode, 0); | ||
305 | lcap = ext4_ext_space_block(inode, 0); | ||
306 | icap = ext4_ext_space_block_idx(inode, 0); | ||
307 | 303 | ||
308 | /* number of new leaf blocks needed */ | 304 | idxs = ((inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header)) |
309 | num = leafs = (newextents + lcap - 1) / lcap; | 305 | / sizeof(struct ext4_extent_idx)); |
310 | 306 | ||
311 | /* | 307 | /* |
312 | * Worse case, we need separate index block(s) | 308 | * If the new delayed allocation block is contiguous with the |
313 | * to link all new leaf blocks | 309 | * previous da block, it can share index blocks with the |
310 | * previous block, so we only need to allocate a new index | ||
311 | * block every idxs leaf blocks. At ldxs**2 blocks, we need | ||
312 | * an additional index block, and at ldxs**3 blocks, yet | ||
313 | * another index blocks. | ||
314 | */ | 314 | */ |
315 | idxs = (leafs + icap - 1) / icap; | 315 | if (ei->i_da_metadata_calc_len && |
316 | do { | 316 | ei->i_da_metadata_calc_last_lblock+1 == lblock) { |
317 | num += idxs; | 317 | if ((ei->i_da_metadata_calc_len % idxs) == 0) |
318 | idxs = (idxs + icap - 1) / icap; | 318 | num++; |
319 | } while (idxs > rcap); | 319 | if ((ei->i_da_metadata_calc_len % (idxs*idxs)) == 0) |
320 | num++; | ||
321 | if ((ei->i_da_metadata_calc_len % (idxs*idxs*idxs)) == 0) { | ||
322 | num++; | ||
323 | ei->i_da_metadata_calc_len = 0; | ||
324 | } else | ||
325 | ei->i_da_metadata_calc_len++; | ||
326 | ei->i_da_metadata_calc_last_lblock++; | ||
327 | return num; | ||
328 | } | ||
320 | 329 | ||
321 | return num; | 330 | /* |
331 | * In the worst case we need a new set of index blocks at | ||
332 | * every level of the inode's extent tree. | ||
333 | */ | ||
334 | ei->i_da_metadata_calc_len = 1; | ||
335 | ei->i_da_metadata_calc_last_lblock = lblock; | ||
336 | return ext_depth(inode) + 1; | ||
322 | } | 337 | } |
323 | 338 | ||
324 | static int | 339 | static int |
@@ -3023,6 +3038,14 @@ out: | |||
3023 | return err; | 3038 | return err; |
3024 | } | 3039 | } |
3025 | 3040 | ||
3041 | static void unmap_underlying_metadata_blocks(struct block_device *bdev, | ||
3042 | sector_t block, int count) | ||
3043 | { | ||
3044 | int i; | ||
3045 | for (i = 0; i < count; i++) | ||
3046 | unmap_underlying_metadata(bdev, block + i); | ||
3047 | } | ||
3048 | |||
3026 | static int | 3049 | static int |
3027 | ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | 3050 | ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, |
3028 | ext4_lblk_t iblock, unsigned int max_blocks, | 3051 | ext4_lblk_t iblock, unsigned int max_blocks, |
@@ -3098,6 +3121,30 @@ out: | |||
3098 | } else | 3121 | } else |
3099 | allocated = ret; | 3122 | allocated = ret; |
3100 | set_buffer_new(bh_result); | 3123 | set_buffer_new(bh_result); |
3124 | /* | ||
3125 | * if we allocated more blocks than requested | ||
3126 | * we need to make sure we unmap the extra block | ||
3127 | * allocated. The actual needed block will get | ||
3128 | * unmapped later when we find the buffer_head marked | ||
3129 | * new. | ||
3130 | */ | ||
3131 | if (allocated > max_blocks) { | ||
3132 | unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, | ||
3133 | newblock + max_blocks, | ||
3134 | allocated - max_blocks); | ||
3135 | allocated = max_blocks; | ||
3136 | } | ||
3137 | |||
3138 | /* | ||
3139 | * If we have done fallocate with the offset that is already | ||
3140 | * delayed allocated, we would have block reservation | ||
3141 | * and quota reservation done in the delayed write path. | ||
3142 | * But fallocate would have already updated quota and block | ||
3143 | * count for this offset. So cancel these reservation | ||
3144 | */ | ||
3145 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) | ||
3146 | ext4_da_update_reserve_space(inode, allocated, 0); | ||
3147 | |||
3101 | map_out: | 3148 | map_out: |
3102 | set_buffer_mapped(bh_result); | 3149 | set_buffer_mapped(bh_result); |
3103 | out1: | 3150 | out1: |
@@ -3190,7 +3237,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
3190 | * this situation is possible, though, _during_ tree modification; | 3237 | * this situation is possible, though, _during_ tree modification; |
3191 | * this is why assert can't be put in ext4_ext_find_extent() | 3238 | * this is why assert can't be put in ext4_ext_find_extent() |
3192 | */ | 3239 | */ |
3193 | BUG_ON(path[depth].p_ext == NULL && depth != 0); | 3240 | if (path[depth].p_ext == NULL && depth != 0) { |
3241 | ext4_error(inode->i_sb, __func__, "bad extent address " | ||
3242 | "inode: %lu, iblock: %d, depth: %d", | ||
3243 | inode->i_ino, iblock, depth); | ||
3244 | err = -EIO; | ||
3245 | goto out2; | ||
3246 | } | ||
3194 | eh = path[depth].p_hdr; | 3247 | eh = path[depth].p_hdr; |
3195 | 3248 | ||
3196 | ex = path[depth].p_ext; | 3249 | ex = path[depth].p_ext; |
@@ -3327,9 +3380,18 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
3327 | /* previous routine could use block we allocated */ | 3380 | /* previous routine could use block we allocated */ |
3328 | newblock = ext_pblock(&newex); | 3381 | newblock = ext_pblock(&newex); |
3329 | allocated = ext4_ext_get_actual_len(&newex); | 3382 | allocated = ext4_ext_get_actual_len(&newex); |
3383 | if (allocated > max_blocks) | ||
3384 | allocated = max_blocks; | ||
3330 | set_buffer_new(bh_result); | 3385 | set_buffer_new(bh_result); |
3331 | 3386 | ||
3332 | /* | 3387 | /* |
3388 | * Update reserved blocks/metadata blocks after successful | ||
3389 | * block allocation which had been deferred till now. | ||
3390 | */ | ||
3391 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) | ||
3392 | ext4_da_update_reserve_space(inode, allocated, 1); | ||
3393 | |||
3394 | /* | ||
3333 | * Cache the extent and update transaction to commit on fdatasync only | 3395 | * Cache the extent and update transaction to commit on fdatasync only |
3334 | * when it is _not_ an uninitialized extent. | 3396 | * when it is _not_ an uninitialized extent. |
3335 | */ | 3397 | */ |