diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 354 |
1 files changed, 284 insertions, 70 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 9ae6e67090cd..47929c4e3dae 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
34 | #include <linux/time.h> | 34 | #include <linux/time.h> |
35 | #include <linux/ext4_jbd2.h> | ||
36 | #include <linux/jbd2.h> | 35 | #include <linux/jbd2.h> |
37 | #include <linux/highuid.h> | 36 | #include <linux/highuid.h> |
38 | #include <linux/pagemap.h> | 37 | #include <linux/pagemap.h> |
@@ -40,8 +39,9 @@ | |||
40 | #include <linux/string.h> | 39 | #include <linux/string.h> |
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/falloc.h> | 41 | #include <linux/falloc.h> |
43 | #include <linux/ext4_fs_extents.h> | ||
44 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include "ext4_jbd2.h" | ||
44 | #include "ext4_extents.h" | ||
45 | 45 | ||
46 | 46 | ||
47 | /* | 47 | /* |
@@ -308,7 +308,7 @@ corrupted: | |||
308 | } | 308 | } |
309 | 309 | ||
310 | #define ext4_ext_check_header(inode, eh, depth) \ | 310 | #define ext4_ext_check_header(inode, eh, depth) \ |
311 | __ext4_ext_check_header(__FUNCTION__, inode, eh, depth) | 311 | __ext4_ext_check_header(__func__, inode, eh, depth) |
312 | 312 | ||
313 | #ifdef EXT_DEBUG | 313 | #ifdef EXT_DEBUG |
314 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | 314 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) |
@@ -614,7 +614,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
614 | 614 | ||
615 | ix->ei_block = cpu_to_le32(logical); | 615 | ix->ei_block = cpu_to_le32(logical); |
616 | ext4_idx_store_pblock(ix, ptr); | 616 | ext4_idx_store_pblock(ix, ptr); |
617 | curp->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(curp->p_hdr->eh_entries)+1); | 617 | le16_add_cpu(&curp->p_hdr->eh_entries, 1); |
618 | 618 | ||
619 | BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries) | 619 | BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries) |
620 | > le16_to_cpu(curp->p_hdr->eh_max)); | 620 | > le16_to_cpu(curp->p_hdr->eh_max)); |
@@ -736,7 +736,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
736 | } | 736 | } |
737 | if (m) { | 737 | if (m) { |
738 | memmove(ex, path[depth].p_ext-m, sizeof(struct ext4_extent)*m); | 738 | memmove(ex, path[depth].p_ext-m, sizeof(struct ext4_extent)*m); |
739 | neh->eh_entries = cpu_to_le16(le16_to_cpu(neh->eh_entries)+m); | 739 | le16_add_cpu(&neh->eh_entries, m); |
740 | } | 740 | } |
741 | 741 | ||
742 | set_buffer_uptodate(bh); | 742 | set_buffer_uptodate(bh); |
@@ -753,8 +753,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
753 | err = ext4_ext_get_access(handle, inode, path + depth); | 753 | err = ext4_ext_get_access(handle, inode, path + depth); |
754 | if (err) | 754 | if (err) |
755 | goto cleanup; | 755 | goto cleanup; |
756 | path[depth].p_hdr->eh_entries = | 756 | le16_add_cpu(&path[depth].p_hdr->eh_entries, -m); |
757 | cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m); | ||
758 | err = ext4_ext_dirty(handle, inode, path + depth); | 757 | err = ext4_ext_dirty(handle, inode, path + depth); |
759 | if (err) | 758 | if (err) |
760 | goto cleanup; | 759 | goto cleanup; |
@@ -817,8 +816,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
817 | if (m) { | 816 | if (m) { |
818 | memmove(++fidx, path[i].p_idx - m, | 817 | memmove(++fidx, path[i].p_idx - m, |
819 | sizeof(struct ext4_extent_idx) * m); | 818 | sizeof(struct ext4_extent_idx) * m); |
820 | neh->eh_entries = | 819 | le16_add_cpu(&neh->eh_entries, m); |
821 | cpu_to_le16(le16_to_cpu(neh->eh_entries) + m); | ||
822 | } | 820 | } |
823 | set_buffer_uptodate(bh); | 821 | set_buffer_uptodate(bh); |
824 | unlock_buffer(bh); | 822 | unlock_buffer(bh); |
@@ -834,7 +832,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
834 | err = ext4_ext_get_access(handle, inode, path + i); | 832 | err = ext4_ext_get_access(handle, inode, path + i); |
835 | if (err) | 833 | if (err) |
836 | goto cleanup; | 834 | goto cleanup; |
837 | path[i].p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path[i].p_hdr->eh_entries)-m); | 835 | le16_add_cpu(&path[i].p_hdr->eh_entries, -m); |
838 | err = ext4_ext_dirty(handle, inode, path + i); | 836 | err = ext4_ext_dirty(handle, inode, path + i); |
839 | if (err) | 837 | if (err) |
840 | goto cleanup; | 838 | goto cleanup; |
@@ -1369,7 +1367,7 @@ int ext4_ext_try_to_merge(struct inode *inode, | |||
1369 | * sizeof(struct ext4_extent); | 1367 | * sizeof(struct ext4_extent); |
1370 | memmove(ex + 1, ex + 2, len); | 1368 | memmove(ex + 1, ex + 2, len); |
1371 | } | 1369 | } |
1372 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries) - 1); | 1370 | le16_add_cpu(&eh->eh_entries, -1); |
1373 | merge_done = 1; | 1371 | merge_done = 1; |
1374 | WARN_ON(eh->eh_entries == 0); | 1372 | WARN_ON(eh->eh_entries == 0); |
1375 | if (!eh->eh_entries) | 1373 | if (!eh->eh_entries) |
@@ -1560,7 +1558,7 @@ has_space: | |||
1560 | path[depth].p_ext = nearex; | 1558 | path[depth].p_ext = nearex; |
1561 | } | 1559 | } |
1562 | 1560 | ||
1563 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1); | 1561 | le16_add_cpu(&eh->eh_entries, 1); |
1564 | nearex = path[depth].p_ext; | 1562 | nearex = path[depth].p_ext; |
1565 | nearex->ee_block = newext->ee_block; | 1563 | nearex->ee_block = newext->ee_block; |
1566 | ext4_ext_store_pblock(nearex, ext_pblock(newext)); | 1564 | ext4_ext_store_pblock(nearex, ext_pblock(newext)); |
@@ -1699,7 +1697,7 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
1699 | err = ext4_ext_get_access(handle, inode, path); | 1697 | err = ext4_ext_get_access(handle, inode, path); |
1700 | if (err) | 1698 | if (err) |
1701 | return err; | 1699 | return err; |
1702 | path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1); | 1700 | le16_add_cpu(&path->p_hdr->eh_entries, -1); |
1703 | err = ext4_ext_dirty(handle, inode, path); | 1701 | err = ext4_ext_dirty(handle, inode, path); |
1704 | if (err) | 1702 | if (err) |
1705 | return err; | 1703 | return err; |
@@ -1902,7 +1900,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
1902 | if (num == 0) { | 1900 | if (num == 0) { |
1903 | /* this extent is removed; mark slot entirely unused */ | 1901 | /* this extent is removed; mark slot entirely unused */ |
1904 | ext4_ext_store_pblock(ex, 0); | 1902 | ext4_ext_store_pblock(ex, 0); |
1905 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1); | 1903 | le16_add_cpu(&eh->eh_entries, -1); |
1906 | } | 1904 | } |
1907 | 1905 | ||
1908 | ex->ee_block = cpu_to_le32(block); | 1906 | ex->ee_block = cpu_to_le32(block); |
@@ -1979,7 +1977,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start) | |||
1979 | * We start scanning from right side, freeing all the blocks | 1977 | * We start scanning from right side, freeing all the blocks |
1980 | * after i_size and walking into the tree depth-wise. | 1978 | * after i_size and walking into the tree depth-wise. |
1981 | */ | 1979 | */ |
1982 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); | 1980 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_NOFS); |
1983 | if (path == NULL) { | 1981 | if (path == NULL) { |
1984 | ext4_journal_stop(handle); | 1982 | ext4_journal_stop(handle); |
1985 | return -ENOMEM; | 1983 | return -ENOMEM; |
@@ -2138,6 +2136,82 @@ void ext4_ext_release(struct super_block *sb) | |||
2138 | #endif | 2136 | #endif |
2139 | } | 2137 | } |
2140 | 2138 | ||
2139 | static void bi_complete(struct bio *bio, int error) | ||
2140 | { | ||
2141 | complete((struct completion *)bio->bi_private); | ||
2142 | } | ||
2143 | |||
2144 | /* FIXME!! we need to try to merge to left or right after zero-out */ | ||
2145 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | ||
2146 | { | ||
2147 | int ret = -EIO; | ||
2148 | struct bio *bio; | ||
2149 | int blkbits, blocksize; | ||
2150 | sector_t ee_pblock; | ||
2151 | struct completion event; | ||
2152 | unsigned int ee_len, len, done, offset; | ||
2153 | |||
2154 | |||
2155 | blkbits = inode->i_blkbits; | ||
2156 | blocksize = inode->i_sb->s_blocksize; | ||
2157 | ee_len = ext4_ext_get_actual_len(ex); | ||
2158 | ee_pblock = ext_pblock(ex); | ||
2159 | |||
2160 | /* convert ee_pblock to 512 byte sectors */ | ||
2161 | ee_pblock = ee_pblock << (blkbits - 9); | ||
2162 | |||
2163 | while (ee_len > 0) { | ||
2164 | |||
2165 | if (ee_len > BIO_MAX_PAGES) | ||
2166 | len = BIO_MAX_PAGES; | ||
2167 | else | ||
2168 | len = ee_len; | ||
2169 | |||
2170 | bio = bio_alloc(GFP_NOIO, len); | ||
2171 | if (!bio) | ||
2172 | return -ENOMEM; | ||
2173 | bio->bi_sector = ee_pblock; | ||
2174 | bio->bi_bdev = inode->i_sb->s_bdev; | ||
2175 | |||
2176 | done = 0; | ||
2177 | offset = 0; | ||
2178 | while (done < len) { | ||
2179 | ret = bio_add_page(bio, ZERO_PAGE(0), | ||
2180 | blocksize, offset); | ||
2181 | if (ret != blocksize) { | ||
2182 | /* | ||
2183 | * We can't add any more pages because of | ||
2184 | * hardware limitations. Start a new bio. | ||
2185 | */ | ||
2186 | break; | ||
2187 | } | ||
2188 | done++; | ||
2189 | offset += blocksize; | ||
2190 | if (offset >= PAGE_CACHE_SIZE) | ||
2191 | offset = 0; | ||
2192 | } | ||
2193 | |||
2194 | init_completion(&event); | ||
2195 | bio->bi_private = &event; | ||
2196 | bio->bi_end_io = bi_complete; | ||
2197 | submit_bio(WRITE, bio); | ||
2198 | wait_for_completion(&event); | ||
2199 | |||
2200 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) | ||
2201 | ret = 0; | ||
2202 | else { | ||
2203 | ret = -EIO; | ||
2204 | break; | ||
2205 | } | ||
2206 | bio_put(bio); | ||
2207 | ee_len -= done; | ||
2208 | ee_pblock += done << (blkbits - 9); | ||
2209 | } | ||
2210 | return ret; | ||
2211 | } | ||
2212 | |||
2213 | #define EXT4_EXT_ZERO_LEN 7 | ||
2214 | |||
2141 | /* | 2215 | /* |
2142 | * This function is called by ext4_ext_get_blocks() if someone tries to write | 2216 | * This function is called by ext4_ext_get_blocks() if someone tries to write |
2143 | * to an uninitialized extent. It may result in splitting the uninitialized | 2217 | * to an uninitialized extent. It may result in splitting the uninitialized |
@@ -2154,7 +2228,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2154 | ext4_lblk_t iblock, | 2228 | ext4_lblk_t iblock, |
2155 | unsigned long max_blocks) | 2229 | unsigned long max_blocks) |
2156 | { | 2230 | { |
2157 | struct ext4_extent *ex, newex; | 2231 | struct ext4_extent *ex, newex, orig_ex; |
2158 | struct ext4_extent *ex1 = NULL; | 2232 | struct ext4_extent *ex1 = NULL; |
2159 | struct ext4_extent *ex2 = NULL; | 2233 | struct ext4_extent *ex2 = NULL; |
2160 | struct ext4_extent *ex3 = NULL; | 2234 | struct ext4_extent *ex3 = NULL; |
@@ -2173,10 +2247,26 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2173 | allocated = ee_len - (iblock - ee_block); | 2247 | allocated = ee_len - (iblock - ee_block); |
2174 | newblock = iblock - ee_block + ext_pblock(ex); | 2248 | newblock = iblock - ee_block + ext_pblock(ex); |
2175 | ex2 = ex; | 2249 | ex2 = ex; |
2250 | orig_ex.ee_block = ex->ee_block; | ||
2251 | orig_ex.ee_len = cpu_to_le16(ee_len); | ||
2252 | ext4_ext_store_pblock(&orig_ex, ext_pblock(ex)); | ||
2176 | 2253 | ||
2177 | err = ext4_ext_get_access(handle, inode, path + depth); | 2254 | err = ext4_ext_get_access(handle, inode, path + depth); |
2178 | if (err) | 2255 | if (err) |
2179 | goto out; | 2256 | goto out; |
2257 | /* If extent has less than 2*EXT4_EXT_ZERO_LEN zerout directly */ | ||
2258 | if (ee_len <= 2*EXT4_EXT_ZERO_LEN) { | ||
2259 | err = ext4_ext_zeroout(inode, &orig_ex); | ||
2260 | if (err) | ||
2261 | goto fix_extent_len; | ||
2262 | /* update the extent length and mark as initialized */ | ||
2263 | ex->ee_block = orig_ex.ee_block; | ||
2264 | ex->ee_len = orig_ex.ee_len; | ||
2265 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2266 | ext4_ext_dirty(handle, inode, path + depth); | ||
2267 | /* zeroed the full extent */ | ||
2268 | return allocated; | ||
2269 | } | ||
2180 | 2270 | ||
2181 | /* ex1: ee_block to iblock - 1 : uninitialized */ | 2271 | /* ex1: ee_block to iblock - 1 : uninitialized */ |
2182 | if (iblock > ee_block) { | 2272 | if (iblock > ee_block) { |
@@ -2195,19 +2285,103 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2195 | /* ex3: to ee_block + ee_len : uninitialised */ | 2285 | /* ex3: to ee_block + ee_len : uninitialised */ |
2196 | if (allocated > max_blocks) { | 2286 | if (allocated > max_blocks) { |
2197 | unsigned int newdepth; | 2287 | unsigned int newdepth; |
2288 | /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */ | ||
2289 | if (allocated <= EXT4_EXT_ZERO_LEN) { | ||
2290 | /* Mark first half uninitialized. | ||
2291 | * Mark second half initialized and zero out the | ||
2292 | * initialized extent | ||
2293 | */ | ||
2294 | ex->ee_block = orig_ex.ee_block; | ||
2295 | ex->ee_len = cpu_to_le16(ee_len - allocated); | ||
2296 | ext4_ext_mark_uninitialized(ex); | ||
2297 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2298 | ext4_ext_dirty(handle, inode, path + depth); | ||
2299 | |||
2300 | ex3 = &newex; | ||
2301 | ex3->ee_block = cpu_to_le32(iblock); | ||
2302 | ext4_ext_store_pblock(ex3, newblock); | ||
2303 | ex3->ee_len = cpu_to_le16(allocated); | ||
2304 | err = ext4_ext_insert_extent(handle, inode, path, ex3); | ||
2305 | if (err == -ENOSPC) { | ||
2306 | err = ext4_ext_zeroout(inode, &orig_ex); | ||
2307 | if (err) | ||
2308 | goto fix_extent_len; | ||
2309 | ex->ee_block = orig_ex.ee_block; | ||
2310 | ex->ee_len = orig_ex.ee_len; | ||
2311 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2312 | ext4_ext_dirty(handle, inode, path + depth); | ||
2313 | /* zeroed the full extent */ | ||
2314 | return allocated; | ||
2315 | |||
2316 | } else if (err) | ||
2317 | goto fix_extent_len; | ||
2318 | |||
2319 | /* | ||
2320 | * We need to zero out the second half because | ||
2321 | * an fallocate request can update file size and | ||
2322 | * converting the second half to initialized extent | ||
2323 | * implies that we can leak some junk data to user | ||
2324 | * space. | ||
2325 | */ | ||
2326 | err = ext4_ext_zeroout(inode, ex3); | ||
2327 | if (err) { | ||
2328 | /* | ||
2329 | * We should actually mark the | ||
2330 | * second half as uninit and return error | ||
2331 | * Insert would have changed the extent | ||
2332 | */ | ||
2333 | depth = ext_depth(inode); | ||
2334 | ext4_ext_drop_refs(path); | ||
2335 | path = ext4_ext_find_extent(inode, | ||
2336 | iblock, path); | ||
2337 | if (IS_ERR(path)) { | ||
2338 | err = PTR_ERR(path); | ||
2339 | return err; | ||
2340 | } | ||
2341 | ex = path[depth].p_ext; | ||
2342 | err = ext4_ext_get_access(handle, inode, | ||
2343 | path + depth); | ||
2344 | if (err) | ||
2345 | return err; | ||
2346 | ext4_ext_mark_uninitialized(ex); | ||
2347 | ext4_ext_dirty(handle, inode, path + depth); | ||
2348 | return err; | ||
2349 | } | ||
2350 | |||
2351 | /* zeroed the second half */ | ||
2352 | return allocated; | ||
2353 | } | ||
2198 | ex3 = &newex; | 2354 | ex3 = &newex; |
2199 | ex3->ee_block = cpu_to_le32(iblock + max_blocks); | 2355 | ex3->ee_block = cpu_to_le32(iblock + max_blocks); |
2200 | ext4_ext_store_pblock(ex3, newblock + max_blocks); | 2356 | ext4_ext_store_pblock(ex3, newblock + max_blocks); |
2201 | ex3->ee_len = cpu_to_le16(allocated - max_blocks); | 2357 | ex3->ee_len = cpu_to_le16(allocated - max_blocks); |
2202 | ext4_ext_mark_uninitialized(ex3); | 2358 | ext4_ext_mark_uninitialized(ex3); |
2203 | err = ext4_ext_insert_extent(handle, inode, path, ex3); | 2359 | err = ext4_ext_insert_extent(handle, inode, path, ex3); |
2204 | if (err) | 2360 | if (err == -ENOSPC) { |
2205 | goto out; | 2361 | err = ext4_ext_zeroout(inode, &orig_ex); |
2362 | if (err) | ||
2363 | goto fix_extent_len; | ||
2364 | /* update the extent length and mark as initialized */ | ||
2365 | ex->ee_block = orig_ex.ee_block; | ||
2366 | ex->ee_len = orig_ex.ee_len; | ||
2367 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2368 | ext4_ext_dirty(handle, inode, path + depth); | ||
2369 | /* zeroed the full extent */ | ||
2370 | return allocated; | ||
2371 | |||
2372 | } else if (err) | ||
2373 | goto fix_extent_len; | ||
2206 | /* | 2374 | /* |
2207 | * The depth, and hence eh & ex might change | 2375 | * The depth, and hence eh & ex might change |
2208 | * as part of the insert above. | 2376 | * as part of the insert above. |
2209 | */ | 2377 | */ |
2210 | newdepth = ext_depth(inode); | 2378 | newdepth = ext_depth(inode); |
2379 | /* | ||
2380 | * update the extent length after successfull insert of the | ||
2381 | * split extent | ||
2382 | */ | ||
2383 | orig_ex.ee_len = cpu_to_le16(ee_len - | ||
2384 | ext4_ext_get_actual_len(ex3)); | ||
2211 | if (newdepth != depth) { | 2385 | if (newdepth != depth) { |
2212 | depth = newdepth; | 2386 | depth = newdepth; |
2213 | ext4_ext_drop_refs(path); | 2387 | ext4_ext_drop_refs(path); |
@@ -2226,6 +2400,24 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2226 | goto out; | 2400 | goto out; |
2227 | } | 2401 | } |
2228 | allocated = max_blocks; | 2402 | allocated = max_blocks; |
2403 | |||
2404 | /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying | ||
2405 | * to insert a extent in the middle zerout directly | ||
2406 | * otherwise give the extent a chance to merge to left | ||
2407 | */ | ||
2408 | if (le16_to_cpu(orig_ex.ee_len) <= EXT4_EXT_ZERO_LEN && | ||
2409 | iblock != ee_block) { | ||
2410 | err = ext4_ext_zeroout(inode, &orig_ex); | ||
2411 | if (err) | ||
2412 | goto fix_extent_len; | ||
2413 | /* update the extent length and mark as initialized */ | ||
2414 | ex->ee_block = orig_ex.ee_block; | ||
2415 | ex->ee_len = orig_ex.ee_len; | ||
2416 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2417 | ext4_ext_dirty(handle, inode, path + depth); | ||
2418 | /* zero out the first half */ | ||
2419 | return allocated; | ||
2420 | } | ||
2229 | } | 2421 | } |
2230 | /* | 2422 | /* |
2231 | * If there was a change of depth as part of the | 2423 | * If there was a change of depth as part of the |
@@ -2282,8 +2474,29 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
2282 | goto out; | 2474 | goto out; |
2283 | insert: | 2475 | insert: |
2284 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | 2476 | err = ext4_ext_insert_extent(handle, inode, path, &newex); |
2477 | if (err == -ENOSPC) { | ||
2478 | err = ext4_ext_zeroout(inode, &orig_ex); | ||
2479 | if (err) | ||
2480 | goto fix_extent_len; | ||
2481 | /* update the extent length and mark as initialized */ | ||
2482 | ex->ee_block = orig_ex.ee_block; | ||
2483 | ex->ee_len = orig_ex.ee_len; | ||
2484 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2485 | ext4_ext_dirty(handle, inode, path + depth); | ||
2486 | /* zero out the first half */ | ||
2487 | return allocated; | ||
2488 | } else if (err) | ||
2489 | goto fix_extent_len; | ||
2285 | out: | 2490 | out: |
2286 | return err ? err : allocated; | 2491 | return err ? err : allocated; |
2492 | |||
2493 | fix_extent_len: | ||
2494 | ex->ee_block = orig_ex.ee_block; | ||
2495 | ex->ee_len = orig_ex.ee_len; | ||
2496 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | ||
2497 | ext4_ext_mark_uninitialized(ex); | ||
2498 | ext4_ext_dirty(handle, inode, path + depth); | ||
2499 | return err; | ||
2287 | } | 2500 | } |
2288 | 2501 | ||
2289 | /* | 2502 | /* |
@@ -2393,8 +2606,20 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2393 | } | 2606 | } |
2394 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) | 2607 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) |
2395 | goto out; | 2608 | goto out; |
2396 | if (!create) | 2609 | if (!create) { |
2610 | /* | ||
2611 | * We have blocks reserved already. We | ||
2612 | * return allocated blocks so that delalloc | ||
2613 | * won't do block reservation for us. But | ||
2614 | * the buffer head will be unmapped so that | ||
2615 | * a read from the block returns 0s. | ||
2616 | */ | ||
2617 | if (allocated > max_blocks) | ||
2618 | allocated = max_blocks; | ||
2619 | /* mark the buffer unwritten */ | ||
2620 | __set_bit(BH_Unwritten, &bh_result->b_state); | ||
2397 | goto out2; | 2621 | goto out2; |
2622 | } | ||
2398 | 2623 | ||
2399 | ret = ext4_ext_convert_to_initialized(handle, inode, | 2624 | ret = ext4_ext_convert_to_initialized(handle, inode, |
2400 | path, iblock, | 2625 | path, iblock, |
@@ -2584,6 +2809,8 @@ out_stop: | |||
2584 | ext4_orphan_del(handle, inode); | 2809 | ext4_orphan_del(handle, inode); |
2585 | 2810 | ||
2586 | up_write(&EXT4_I(inode)->i_data_sem); | 2811 | up_write(&EXT4_I(inode)->i_data_sem); |
2812 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); | ||
2813 | ext4_mark_inode_dirty(handle, inode); | ||
2587 | ext4_journal_stop(handle); | 2814 | ext4_journal_stop(handle); |
2588 | } | 2815 | } |
2589 | 2816 | ||
@@ -2608,6 +2835,28 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num) | |||
2608 | return needed; | 2835 | return needed; |
2609 | } | 2836 | } |
2610 | 2837 | ||
2838 | static void ext4_falloc_update_inode(struct inode *inode, | ||
2839 | int mode, loff_t new_size, int update_ctime) | ||
2840 | { | ||
2841 | struct timespec now; | ||
2842 | |||
2843 | if (update_ctime) { | ||
2844 | now = current_fs_time(inode->i_sb); | ||
2845 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
2846 | inode->i_ctime = now; | ||
2847 | } | ||
2848 | /* | ||
2849 | * Update only when preallocation was requested beyond | ||
2850 | * the file size. | ||
2851 | */ | ||
2852 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
2853 | new_size > i_size_read(inode)) { | ||
2854 | i_size_write(inode, new_size); | ||
2855 | EXT4_I(inode)->i_disksize = new_size; | ||
2856 | } | ||
2857 | |||
2858 | } | ||
2859 | |||
2611 | /* | 2860 | /* |
2612 | * preallocate space for a file. This implements ext4's fallocate inode | 2861 | * preallocate space for a file. This implements ext4's fallocate inode |
2613 | * operation, which gets called from sys_fallocate system call. | 2862 | * operation, which gets called from sys_fallocate system call. |
@@ -2619,8 +2868,8 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | |||
2619 | { | 2868 | { |
2620 | handle_t *handle; | 2869 | handle_t *handle; |
2621 | ext4_lblk_t block; | 2870 | ext4_lblk_t block; |
2871 | loff_t new_size; | ||
2622 | unsigned long max_blocks; | 2872 | unsigned long max_blocks; |
2623 | ext4_fsblk_t nblocks = 0; | ||
2624 | int ret = 0; | 2873 | int ret = 0; |
2625 | int ret2 = 0; | 2874 | int ret2 = 0; |
2626 | int retries = 0; | 2875 | int retries = 0; |
@@ -2639,9 +2888,12 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | |||
2639 | return -ENODEV; | 2888 | return -ENODEV; |
2640 | 2889 | ||
2641 | block = offset >> blkbits; | 2890 | block = offset >> blkbits; |
2891 | /* | ||
2892 | * We can't just convert len to max_blocks because | ||
2893 | * If blocksize = 4096 offset = 3072 and len = 2048 | ||
2894 | */ | ||
2642 | max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) | 2895 | max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) |
2643 | - block; | 2896 | - block; |
2644 | |||
2645 | /* | 2897 | /* |
2646 | * credits to insert 1 extent into extent tree + buffers to be able to | 2898 | * credits to insert 1 extent into extent tree + buffers to be able to |
2647 | * modify 1 super block, 1 block bitmap and 1 group descriptor. | 2899 | * modify 1 super block, 1 block bitmap and 1 group descriptor. |
@@ -2657,7 +2909,6 @@ retry: | |||
2657 | ret = PTR_ERR(handle); | 2909 | ret = PTR_ERR(handle); |
2658 | break; | 2910 | break; |
2659 | } | 2911 | } |
2660 | |||
2661 | ret = ext4_get_blocks_wrap(handle, inode, block, | 2912 | ret = ext4_get_blocks_wrap(handle, inode, block, |
2662 | max_blocks, &map_bh, | 2913 | max_blocks, &map_bh, |
2663 | EXT4_CREATE_UNINITIALIZED_EXT, 0); | 2914 | EXT4_CREATE_UNINITIALIZED_EXT, 0); |
@@ -2673,61 +2924,24 @@ retry: | |||
2673 | ret2 = ext4_journal_stop(handle); | 2924 | ret2 = ext4_journal_stop(handle); |
2674 | break; | 2925 | break; |
2675 | } | 2926 | } |
2676 | if (ret > 0) { | 2927 | if ((block + ret) >= (EXT4_BLOCK_ALIGN(offset + len, |
2677 | /* check wrap through sign-bit/zero here */ | 2928 | blkbits) >> blkbits)) |
2678 | if ((block + ret) < 0 || (block + ret) < block) { | 2929 | new_size = offset + len; |
2679 | ret = -EIO; | 2930 | else |
2680 | ext4_mark_inode_dirty(handle, inode); | 2931 | new_size = (block + ret) << blkbits; |
2681 | ret2 = ext4_journal_stop(handle); | ||
2682 | break; | ||
2683 | } | ||
2684 | if (buffer_new(&map_bh) && ((block + ret) > | ||
2685 | (EXT4_BLOCK_ALIGN(i_size_read(inode), blkbits) | ||
2686 | >> blkbits))) | ||
2687 | nblocks = nblocks + ret; | ||
2688 | } | ||
2689 | |||
2690 | /* Update ctime if new blocks get allocated */ | ||
2691 | if (nblocks) { | ||
2692 | struct timespec now; | ||
2693 | |||
2694 | now = current_fs_time(inode->i_sb); | ||
2695 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
2696 | inode->i_ctime = now; | ||
2697 | } | ||
2698 | 2932 | ||
2933 | ext4_falloc_update_inode(inode, mode, new_size, | ||
2934 | buffer_new(&map_bh)); | ||
2699 | ext4_mark_inode_dirty(handle, inode); | 2935 | ext4_mark_inode_dirty(handle, inode); |
2700 | ret2 = ext4_journal_stop(handle); | 2936 | ret2 = ext4_journal_stop(handle); |
2701 | if (ret2) | 2937 | if (ret2) |
2702 | break; | 2938 | break; |
2703 | } | 2939 | } |
2704 | 2940 | if (ret == -ENOSPC && | |
2705 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 2941 | ext4_should_retry_alloc(inode->i_sb, &retries)) { |
2942 | ret = 0; | ||
2706 | goto retry; | 2943 | goto retry; |
2707 | |||
2708 | /* | ||
2709 | * Time to update the file size. | ||
2710 | * Update only when preallocation was requested beyond the file size. | ||
2711 | */ | ||
2712 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
2713 | (offset + len) > i_size_read(inode)) { | ||
2714 | if (ret > 0) { | ||
2715 | /* | ||
2716 | * if no error, we assume preallocation succeeded | ||
2717 | * completely | ||
2718 | */ | ||
2719 | i_size_write(inode, offset + len); | ||
2720 | EXT4_I(inode)->i_disksize = i_size_read(inode); | ||
2721 | } else if (ret < 0 && nblocks) { | ||
2722 | /* Handle partial allocation scenario */ | ||
2723 | loff_t newsize; | ||
2724 | |||
2725 | newsize = (nblocks << blkbits) + i_size_read(inode); | ||
2726 | i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); | ||
2727 | EXT4_I(inode)->i_disksize = i_size_read(inode); | ||
2728 | } | ||
2729 | } | 2944 | } |
2730 | |||
2731 | mutex_unlock(&inode->i_mutex); | 2945 | mutex_unlock(&inode->i_mutex); |
2732 | return ret > 0 ? ret2 : ret; | 2946 | return ret > 0 ? ret2 : ret; |
2733 | } | 2947 | } |