diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-18 13:32:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-18 13:32:00 -0400 |
commit | d756d10e246a01515d07f8161181b8a14afba7cc (patch) | |
tree | de7336f2b4b596881468bf65cb2f2f88cedcde86 /fs | |
parent | cdf4a6482dd4c739f8c1132c5a9356912911fec5 (diff) | |
parent | e9f410b1c035b6e63f0b4c3d6cfe4298d6a04492 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: extent macros cleanup
Fix compilation with EXT_DEBUG, also fix leXX_to_cpu conversions.
ext4: remove extra IS_RDONLY() check
ext4: Use is_power_of_2()
Use zero_user_page() in ext4 where possible
ext4: Remove 65000 subdirectory limit
ext4: Expand extra_inodes space per the s_{want,min}_extra_isize fields
ext4: Add nanosecond timestamps
jbd2: Move jbd2-debug file to debugfs
jbd2: Fix CONFIG_JBD_DEBUG ifdef to be CONFIG_JBD2_DEBUG
ext4: Set the journal JBD2_FEATURE_INCOMPAT_64BIT on large devices
ext4: Make extents code sanely handle on-disk corruption
ext4: copy i_flags to inode flags on write
ext4: Enable extents by default
Change on-disk format to support 2^15 uninitialized extents
write support for preallocated blocks
fallocate support in ext4
sys_fallocate() implementation on i386, x86_64 and powerpc
Diffstat (limited to 'fs')
-rw-r--r-- | fs/Kconfig | 10 | ||||
-rw-r--r-- | fs/ext4/balloc.c | 4 | ||||
-rw-r--r-- | fs/ext4/extents.c | 682 | ||||
-rw-r--r-- | fs/ext4/file.c | 1 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 8 | ||||
-rw-r--r-- | fs/ext4/inode.c | 118 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 9 | ||||
-rw-r--r-- | fs/ext4/namei.c | 76 | ||||
-rw-r--r-- | fs/ext4/super.c | 50 | ||||
-rw-r--r-- | fs/ext4/xattr.c | 276 | ||||
-rw-r--r-- | fs/ext4/xattr.h | 17 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 79 | ||||
-rw-r--r-- | fs/jbd2/recovery.c | 2 | ||||
-rw-r--r-- | fs/open.c | 59 |
14 files changed, 1143 insertions, 248 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 613df554728d..6a649902c5ac 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -251,7 +251,7 @@ config JBD2 | |||
251 | 251 | ||
252 | config JBD2_DEBUG | 252 | config JBD2_DEBUG |
253 | bool "JBD2 (ext4dev/ext4) debugging support" | 253 | bool "JBD2 (ext4dev/ext4) debugging support" |
254 | depends on JBD2 | 254 | depends on JBD2 && DEBUG_FS |
255 | help | 255 | help |
256 | If you are using the ext4dev/ext4 journaled file system (or | 256 | If you are using the ext4dev/ext4 journaled file system (or |
257 | potentially any other filesystem/device using JBD2), this option | 257 | potentially any other filesystem/device using JBD2), this option |
@@ -260,10 +260,10 @@ config JBD2_DEBUG | |||
260 | By default, the debugging output will be turned off. | 260 | By default, the debugging output will be turned off. |
261 | 261 | ||
262 | If you select Y here, then you will be able to turn on debugging | 262 | If you select Y here, then you will be able to turn on debugging |
263 | with "echo N > /proc/sys/fs/jbd2-debug", where N is a number between | 263 | with "echo N > /sys/kernel/debug/jbd2/jbd2-debug", where N is a |
264 | 1 and 5. The higher the number, the more debugging output is | 264 | number between 1 and 5. The higher the number, the more debugging |
265 | generated. To turn debugging off again, do | 265 | output is generated. To turn debugging off again, do |
266 | "echo 0 > /proc/sys/fs/jbd2-debug". | 266 | "echo 0 > /sys/kernel/debug/jbd2/jbd2-debug". |
267 | 267 | ||
268 | config FS_MBCACHE | 268 | config FS_MBCACHE |
269 | # Meta block cache for Extended Attributes (ext2/ext3/ext4) | 269 | # Meta block cache for Extended Attributes (ext2/ext3/ext4) |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 9de54ae48dee..e53b4af52f11 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -517,7 +517,7 @@ do_more: | |||
517 | /* | 517 | /* |
518 | * An HJ special. This is expensive... | 518 | * An HJ special. This is expensive... |
519 | */ | 519 | */ |
520 | #ifdef CONFIG_JBD_DEBUG | 520 | #ifdef CONFIG_JBD2_DEBUG |
521 | jbd_unlock_bh_state(bitmap_bh); | 521 | jbd_unlock_bh_state(bitmap_bh); |
522 | { | 522 | { |
523 | struct buffer_head *debug_bh; | 523 | struct buffer_head *debug_bh; |
@@ -1597,7 +1597,7 @@ allocated: | |||
1597 | 1597 | ||
1598 | performed_allocation = 1; | 1598 | performed_allocation = 1; |
1599 | 1599 | ||
1600 | #ifdef CONFIG_JBD_DEBUG | 1600 | #ifdef CONFIG_JBD2_DEBUG |
1601 | { | 1601 | { |
1602 | struct buffer_head *debug_bh; | 1602 | struct buffer_head *debug_bh; |
1603 | 1603 | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b9ce24129070..750c46f7d893 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/quotaops.h> | 39 | #include <linux/quotaops.h> |
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/falloc.h> | ||
42 | #include <linux/ext4_fs_extents.h> | 43 | #include <linux/ext4_fs_extents.h> |
43 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
44 | 45 | ||
@@ -91,36 +92,6 @@ static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) | |||
91 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
92 | } | 93 | } |
93 | 94 | ||
94 | static int ext4_ext_check_header(const char *function, struct inode *inode, | ||
95 | struct ext4_extent_header *eh) | ||
96 | { | ||
97 | const char *error_msg = NULL; | ||
98 | |||
99 | if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) { | ||
100 | error_msg = "invalid magic"; | ||
101 | goto corrupted; | ||
102 | } | ||
103 | if (unlikely(eh->eh_max == 0)) { | ||
104 | error_msg = "invalid eh_max"; | ||
105 | goto corrupted; | ||
106 | } | ||
107 | if (unlikely(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max))) { | ||
108 | error_msg = "invalid eh_entries"; | ||
109 | goto corrupted; | ||
110 | } | ||
111 | return 0; | ||
112 | |||
113 | corrupted: | ||
114 | ext4_error(inode->i_sb, function, | ||
115 | "bad header in inode #%lu: %s - magic %x, " | ||
116 | "entries %u, max %u, depth %u", | ||
117 | inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic), | ||
118 | le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), | ||
119 | le16_to_cpu(eh->eh_depth)); | ||
120 | |||
121 | return -EIO; | ||
122 | } | ||
123 | |||
124 | static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed) | 95 | static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed) |
125 | { | 96 | { |
126 | int err; | 97 | int err; |
@@ -269,6 +240,70 @@ static int ext4_ext_space_root_idx(struct inode *inode) | |||
269 | return size; | 240 | return size; |
270 | } | 241 | } |
271 | 242 | ||
243 | static int | ||
244 | ext4_ext_max_entries(struct inode *inode, int depth) | ||
245 | { | ||
246 | int max; | ||
247 | |||
248 | if (depth == ext_depth(inode)) { | ||
249 | if (depth == 0) | ||
250 | max = ext4_ext_space_root(inode); | ||
251 | else | ||
252 | max = ext4_ext_space_root_idx(inode); | ||
253 | } else { | ||
254 | if (depth == 0) | ||
255 | max = ext4_ext_space_block(inode); | ||
256 | else | ||
257 | max = ext4_ext_space_block_idx(inode); | ||
258 | } | ||
259 | |||
260 | return max; | ||
261 | } | ||
262 | |||
263 | static int __ext4_ext_check_header(const char *function, struct inode *inode, | ||
264 | struct ext4_extent_header *eh, | ||
265 | int depth) | ||
266 | { | ||
267 | const char *error_msg; | ||
268 | int max = 0; | ||
269 | |||
270 | if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) { | ||
271 | error_msg = "invalid magic"; | ||
272 | goto corrupted; | ||
273 | } | ||
274 | if (unlikely(le16_to_cpu(eh->eh_depth) != depth)) { | ||
275 | error_msg = "unexpected eh_depth"; | ||
276 | goto corrupted; | ||
277 | } | ||
278 | if (unlikely(eh->eh_max == 0)) { | ||
279 | error_msg = "invalid eh_max"; | ||
280 | goto corrupted; | ||
281 | } | ||
282 | max = ext4_ext_max_entries(inode, depth); | ||
283 | if (unlikely(le16_to_cpu(eh->eh_max) > max)) { | ||
284 | error_msg = "too large eh_max"; | ||
285 | goto corrupted; | ||
286 | } | ||
287 | if (unlikely(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max))) { | ||
288 | error_msg = "invalid eh_entries"; | ||
289 | goto corrupted; | ||
290 | } | ||
291 | return 0; | ||
292 | |||
293 | corrupted: | ||
294 | ext4_error(inode->i_sb, function, | ||
295 | "bad header in inode #%lu: %s - magic %x, " | ||
296 | "entries %u, max %u(%u), depth %u(%u)", | ||
297 | inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic), | ||
298 | le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), | ||
299 | max, le16_to_cpu(eh->eh_depth), depth); | ||
300 | |||
301 | return -EIO; | ||
302 | } | ||
303 | |||
304 | #define ext4_ext_check_header(inode, eh, depth) \ | ||
305 | __ext4_ext_check_header(__FUNCTION__, inode, eh, depth) | ||
306 | |||
272 | #ifdef EXT_DEBUG | 307 | #ifdef EXT_DEBUG |
273 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | 308 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) |
274 | { | 309 | { |
@@ -282,7 +317,7 @@ static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | |||
282 | } else if (path->p_ext) { | 317 | } else if (path->p_ext) { |
283 | ext_debug(" %d:%d:%llu ", | 318 | ext_debug(" %d:%d:%llu ", |
284 | le32_to_cpu(path->p_ext->ee_block), | 319 | le32_to_cpu(path->p_ext->ee_block), |
285 | le16_to_cpu(path->p_ext->ee_len), | 320 | ext4_ext_get_actual_len(path->p_ext), |
286 | ext_pblock(path->p_ext)); | 321 | ext_pblock(path->p_ext)); |
287 | } else | 322 | } else |
288 | ext_debug(" []"); | 323 | ext_debug(" []"); |
@@ -305,7 +340,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) | |||
305 | 340 | ||
306 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { | 341 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { |
307 | ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block), | 342 | ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block), |
308 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); | 343 | ext4_ext_get_actual_len(ex), ext_pblock(ex)); |
309 | } | 344 | } |
310 | ext_debug("\n"); | 345 | ext_debug("\n"); |
311 | } | 346 | } |
@@ -329,6 +364,7 @@ static void ext4_ext_drop_refs(struct ext4_ext_path *path) | |||
329 | /* | 364 | /* |
330 | * ext4_ext_binsearch_idx: | 365 | * ext4_ext_binsearch_idx: |
331 | * binary search for the closest index of the given block | 366 | * binary search for the closest index of the given block |
367 | * the header must be checked before calling this | ||
332 | */ | 368 | */ |
333 | static void | 369 | static void |
334 | ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block) | 370 | ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block) |
@@ -336,27 +372,25 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc | |||
336 | struct ext4_extent_header *eh = path->p_hdr; | 372 | struct ext4_extent_header *eh = path->p_hdr; |
337 | struct ext4_extent_idx *r, *l, *m; | 373 | struct ext4_extent_idx *r, *l, *m; |
338 | 374 | ||
339 | BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); | ||
340 | BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); | ||
341 | BUG_ON(le16_to_cpu(eh->eh_entries) <= 0); | ||
342 | 375 | ||
343 | ext_debug("binsearch for %d(idx): ", block); | 376 | ext_debug("binsearch for %d(idx): ", block); |
344 | 377 | ||
345 | l = EXT_FIRST_INDEX(eh) + 1; | 378 | l = EXT_FIRST_INDEX(eh) + 1; |
346 | r = EXT_FIRST_INDEX(eh) + le16_to_cpu(eh->eh_entries) - 1; | 379 | r = EXT_LAST_INDEX(eh); |
347 | while (l <= r) { | 380 | while (l <= r) { |
348 | m = l + (r - l) / 2; | 381 | m = l + (r - l) / 2; |
349 | if (block < le32_to_cpu(m->ei_block)) | 382 | if (block < le32_to_cpu(m->ei_block)) |
350 | r = m - 1; | 383 | r = m - 1; |
351 | else | 384 | else |
352 | l = m + 1; | 385 | l = m + 1; |
353 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ei_block, | 386 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, le32_to_cpu(l->ei_block), |
354 | m, m->ei_block, r, r->ei_block); | 387 | m, le32_to_cpu(m->ei_block), |
388 | r, le32_to_cpu(r->ei_block)); | ||
355 | } | 389 | } |
356 | 390 | ||
357 | path->p_idx = l - 1; | 391 | path->p_idx = l - 1; |
358 | ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), | 392 | ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), |
359 | idx_block(path->p_idx)); | 393 | idx_pblock(path->p_idx)); |
360 | 394 | ||
361 | #ifdef CHECK_BINSEARCH | 395 | #ifdef CHECK_BINSEARCH |
362 | { | 396 | { |
@@ -388,6 +422,7 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc | |||
388 | /* | 422 | /* |
389 | * ext4_ext_binsearch: | 423 | * ext4_ext_binsearch: |
390 | * binary search for closest extent of the given block | 424 | * binary search for closest extent of the given block |
425 | * the header must be checked before calling this | ||
391 | */ | 426 | */ |
392 | static void | 427 | static void |
393 | ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | 428 | ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) |
@@ -395,9 +430,6 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | |||
395 | struct ext4_extent_header *eh = path->p_hdr; | 430 | struct ext4_extent_header *eh = path->p_hdr; |
396 | struct ext4_extent *r, *l, *m; | 431 | struct ext4_extent *r, *l, *m; |
397 | 432 | ||
398 | BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); | ||
399 | BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); | ||
400 | |||
401 | if (eh->eh_entries == 0) { | 433 | if (eh->eh_entries == 0) { |
402 | /* | 434 | /* |
403 | * this leaf is empty: | 435 | * this leaf is empty: |
@@ -409,7 +441,7 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | |||
409 | ext_debug("binsearch for %d: ", block); | 441 | ext_debug("binsearch for %d: ", block); |
410 | 442 | ||
411 | l = EXT_FIRST_EXTENT(eh) + 1; | 443 | l = EXT_FIRST_EXTENT(eh) + 1; |
412 | r = EXT_FIRST_EXTENT(eh) + le16_to_cpu(eh->eh_entries) - 1; | 444 | r = EXT_LAST_EXTENT(eh); |
413 | 445 | ||
414 | while (l <= r) { | 446 | while (l <= r) { |
415 | m = l + (r - l) / 2; | 447 | m = l + (r - l) / 2; |
@@ -417,15 +449,16 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | |||
417 | r = m - 1; | 449 | r = m - 1; |
418 | else | 450 | else |
419 | l = m + 1; | 451 | l = m + 1; |
420 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ee_block, | 452 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, le32_to_cpu(l->ee_block), |
421 | m, m->ee_block, r, r->ee_block); | 453 | m, le32_to_cpu(m->ee_block), |
454 | r, le32_to_cpu(r->ee_block)); | ||
422 | } | 455 | } |
423 | 456 | ||
424 | path->p_ext = l - 1; | 457 | path->p_ext = l - 1; |
425 | ext_debug(" -> %d:%llu:%d ", | 458 | ext_debug(" -> %d:%llu:%d ", |
426 | le32_to_cpu(path->p_ext->ee_block), | 459 | le32_to_cpu(path->p_ext->ee_block), |
427 | ext_pblock(path->p_ext), | 460 | ext_pblock(path->p_ext), |
428 | le16_to_cpu(path->p_ext->ee_len)); | 461 | ext4_ext_get_actual_len(path->p_ext)); |
429 | 462 | ||
430 | #ifdef CHECK_BINSEARCH | 463 | #ifdef CHECK_BINSEARCH |
431 | { | 464 | { |
@@ -468,11 +501,10 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
468 | short int depth, i, ppos = 0, alloc = 0; | 501 | short int depth, i, ppos = 0, alloc = 0; |
469 | 502 | ||
470 | eh = ext_inode_hdr(inode); | 503 | eh = ext_inode_hdr(inode); |
471 | BUG_ON(eh == NULL); | 504 | depth = ext_depth(inode); |
472 | if (ext4_ext_check_header(__FUNCTION__, inode, eh)) | 505 | if (ext4_ext_check_header(inode, eh, depth)) |
473 | return ERR_PTR(-EIO); | 506 | return ERR_PTR(-EIO); |
474 | 507 | ||
475 | i = depth = ext_depth(inode); | ||
476 | 508 | ||
477 | /* account possible depth increase */ | 509 | /* account possible depth increase */ |
478 | if (!path) { | 510 | if (!path) { |
@@ -484,10 +516,12 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
484 | } | 516 | } |
485 | path[0].p_hdr = eh; | 517 | path[0].p_hdr = eh; |
486 | 518 | ||
519 | i = depth; | ||
487 | /* walk through the tree */ | 520 | /* walk through the tree */ |
488 | while (i) { | 521 | while (i) { |
489 | ext_debug("depth %d: num %d, max %d\n", | 522 | ext_debug("depth %d: num %d, max %d\n", |
490 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); | 523 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); |
524 | |||
491 | ext4_ext_binsearch_idx(inode, path + ppos, block); | 525 | ext4_ext_binsearch_idx(inode, path + ppos, block); |
492 | path[ppos].p_block = idx_pblock(path[ppos].p_idx); | 526 | path[ppos].p_block = idx_pblock(path[ppos].p_idx); |
493 | path[ppos].p_depth = i; | 527 | path[ppos].p_depth = i; |
@@ -504,7 +538,7 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
504 | path[ppos].p_hdr = eh; | 538 | path[ppos].p_hdr = eh; |
505 | i--; | 539 | i--; |
506 | 540 | ||
507 | if (ext4_ext_check_header(__FUNCTION__, inode, eh)) | 541 | if (ext4_ext_check_header(inode, eh, i)) |
508 | goto err; | 542 | goto err; |
509 | } | 543 | } |
510 | 544 | ||
@@ -513,9 +547,6 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
513 | path[ppos].p_ext = NULL; | 547 | path[ppos].p_ext = NULL; |
514 | path[ppos].p_idx = NULL; | 548 | path[ppos].p_idx = NULL; |
515 | 549 | ||
516 | if (ext4_ext_check_header(__FUNCTION__, inode, eh)) | ||
517 | goto err; | ||
518 | |||
519 | /* find extent */ | 550 | /* find extent */ |
520 | ext4_ext_binsearch(inode, path + ppos, block); | 551 | ext4_ext_binsearch(inode, path + ppos, block); |
521 | 552 | ||
@@ -553,7 +584,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
553 | if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { | 584 | if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { |
554 | len = (len - 1) * sizeof(struct ext4_extent_idx); | 585 | len = (len - 1) * sizeof(struct ext4_extent_idx); |
555 | len = len < 0 ? 0 : len; | 586 | len = len < 0 ? 0 : len; |
556 | ext_debug("insert new index %d after: %d. " | 587 | ext_debug("insert new index %d after: %llu. " |
557 | "move %d from 0x%p to 0x%p\n", | 588 | "move %d from 0x%p to 0x%p\n", |
558 | logical, ptr, len, | 589 | logical, ptr, len, |
559 | (curp->p_idx + 1), (curp->p_idx + 2)); | 590 | (curp->p_idx + 1), (curp->p_idx + 2)); |
@@ -564,7 +595,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
564 | /* insert before */ | 595 | /* insert before */ |
565 | len = len * sizeof(struct ext4_extent_idx); | 596 | len = len * sizeof(struct ext4_extent_idx); |
566 | len = len < 0 ? 0 : len; | 597 | len = len < 0 ? 0 : len; |
567 | ext_debug("insert new index %d before: %d. " | 598 | ext_debug("insert new index %d before: %llu. " |
568 | "move %d from 0x%p to 0x%p\n", | 599 | "move %d from 0x%p to 0x%p\n", |
569 | logical, ptr, len, | 600 | logical, ptr, len, |
570 | curp->p_idx, (curp->p_idx + 1)); | 601 | curp->p_idx, (curp->p_idx + 1)); |
@@ -686,7 +717,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
686 | ext_debug("move %d:%llu:%d in new leaf %llu\n", | 717 | ext_debug("move %d:%llu:%d in new leaf %llu\n", |
687 | le32_to_cpu(path[depth].p_ext->ee_block), | 718 | le32_to_cpu(path[depth].p_ext->ee_block), |
688 | ext_pblock(path[depth].p_ext), | 719 | ext_pblock(path[depth].p_ext), |
689 | le16_to_cpu(path[depth].p_ext->ee_len), | 720 | ext4_ext_get_actual_len(path[depth].p_ext), |
690 | newblock); | 721 | newblock); |
691 | /*memmove(ex++, path[depth].p_ext++, | 722 | /*memmove(ex++, path[depth].p_ext++, |
692 | sizeof(struct ext4_extent)); | 723 | sizeof(struct ext4_extent)); |
@@ -764,7 +795,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
764 | BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) != | 795 | BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) != |
765 | EXT_LAST_INDEX(path[i].p_hdr)); | 796 | EXT_LAST_INDEX(path[i].p_hdr)); |
766 | while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { | 797 | while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { |
767 | ext_debug("%d: move %d:%d in new index %llu\n", i, | 798 | ext_debug("%d: move %d:%llu in new index %llu\n", i, |
768 | le32_to_cpu(path[i].p_idx->ei_block), | 799 | le32_to_cpu(path[i].p_idx->ei_block), |
769 | idx_pblock(path[i].p_idx), | 800 | idx_pblock(path[i].p_idx), |
770 | newblock); | 801 | newblock); |
@@ -893,8 +924,13 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
893 | curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode)); | 924 | curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode)); |
894 | curp->p_hdr->eh_entries = cpu_to_le16(1); | 925 | curp->p_hdr->eh_entries = cpu_to_le16(1); |
895 | curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); | 926 | curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); |
896 | /* FIXME: it works, but actually path[0] can be index */ | 927 | |
897 | curp->p_idx->ei_block = EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; | 928 | if (path[0].p_hdr->eh_depth) |
929 | curp->p_idx->ei_block = | ||
930 | EXT_FIRST_INDEX(path[0].p_hdr)->ei_block; | ||
931 | else | ||
932 | curp->p_idx->ei_block = | ||
933 | EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; | ||
898 | ext4_idx_store_pblock(curp->p_idx, newblock); | 934 | ext4_idx_store_pblock(curp->p_idx, newblock); |
899 | 935 | ||
900 | neh = ext_inode_hdr(inode); | 936 | neh = ext_inode_hdr(inode); |
@@ -1106,7 +1142,24 @@ static int | |||
1106 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | 1142 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, |
1107 | struct ext4_extent *ex2) | 1143 | struct ext4_extent *ex2) |
1108 | { | 1144 | { |
1109 | if (le32_to_cpu(ex1->ee_block) + le16_to_cpu(ex1->ee_len) != | 1145 | unsigned short ext1_ee_len, ext2_ee_len, max_len; |
1146 | |||
1147 | /* | ||
1148 | * Make sure that either both extents are uninitialized, or | ||
1149 | * both are _not_. | ||
1150 | */ | ||
1151 | if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2)) | ||
1152 | return 0; | ||
1153 | |||
1154 | if (ext4_ext_is_uninitialized(ex1)) | ||
1155 | max_len = EXT_UNINIT_MAX_LEN; | ||
1156 | else | ||
1157 | max_len = EXT_INIT_MAX_LEN; | ||
1158 | |||
1159 | ext1_ee_len = ext4_ext_get_actual_len(ex1); | ||
1160 | ext2_ee_len = ext4_ext_get_actual_len(ex2); | ||
1161 | |||
1162 | if (le32_to_cpu(ex1->ee_block) + ext1_ee_len != | ||
1110 | le32_to_cpu(ex2->ee_block)) | 1163 | le32_to_cpu(ex2->ee_block)) |
1111 | return 0; | 1164 | return 0; |
1112 | 1165 | ||
@@ -1115,19 +1168,66 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | |||
1115 | * as an RO_COMPAT feature, refuse to merge to extents if | 1168 | * as an RO_COMPAT feature, refuse to merge to extents if |
1116 | * this can result in the top bit of ee_len being set. | 1169 | * this can result in the top bit of ee_len being set. |
1117 | */ | 1170 | */ |
1118 | if (le16_to_cpu(ex1->ee_len) + le16_to_cpu(ex2->ee_len) > EXT_MAX_LEN) | 1171 | if (ext1_ee_len + ext2_ee_len > max_len) |
1119 | return 0; | 1172 | return 0; |
1120 | #ifdef AGGRESSIVE_TEST | 1173 | #ifdef AGGRESSIVE_TEST |
1121 | if (le16_to_cpu(ex1->ee_len) >= 4) | 1174 | if (le16_to_cpu(ex1->ee_len) >= 4) |
1122 | return 0; | 1175 | return 0; |
1123 | #endif | 1176 | #endif |
1124 | 1177 | ||
1125 | if (ext_pblock(ex1) + le16_to_cpu(ex1->ee_len) == ext_pblock(ex2)) | 1178 | if (ext_pblock(ex1) + ext1_ee_len == ext_pblock(ex2)) |
1126 | return 1; | 1179 | return 1; |
1127 | return 0; | 1180 | return 0; |
1128 | } | 1181 | } |
1129 | 1182 | ||
1130 | /* | 1183 | /* |
1184 | * This function tries to merge the "ex" extent to the next extent in the tree. | ||
1185 | * It always tries to merge towards right. If you want to merge towards | ||
1186 | * left, pass "ex - 1" as argument instead of "ex". | ||
1187 | * Returns 0 if the extents (ex and ex+1) were _not_ merged and returns | ||
1188 | * 1 if they got merged. | ||
1189 | */ | ||
1190 | int ext4_ext_try_to_merge(struct inode *inode, | ||
1191 | struct ext4_ext_path *path, | ||
1192 | struct ext4_extent *ex) | ||
1193 | { | ||
1194 | struct ext4_extent_header *eh; | ||
1195 | unsigned int depth, len; | ||
1196 | int merge_done = 0; | ||
1197 | int uninitialized = 0; | ||
1198 | |||
1199 | depth = ext_depth(inode); | ||
1200 | BUG_ON(path[depth].p_hdr == NULL); | ||
1201 | eh = path[depth].p_hdr; | ||
1202 | |||
1203 | while (ex < EXT_LAST_EXTENT(eh)) { | ||
1204 | if (!ext4_can_extents_be_merged(inode, ex, ex + 1)) | ||
1205 | break; | ||
1206 | /* merge with next extent! */ | ||
1207 | if (ext4_ext_is_uninitialized(ex)) | ||
1208 | uninitialized = 1; | ||
1209 | ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex) | ||
1210 | + ext4_ext_get_actual_len(ex + 1)); | ||
1211 | if (uninitialized) | ||
1212 | ext4_ext_mark_uninitialized(ex); | ||
1213 | |||
1214 | if (ex + 1 < EXT_LAST_EXTENT(eh)) { | ||
1215 | len = (EXT_LAST_EXTENT(eh) - ex - 1) | ||
1216 | * sizeof(struct ext4_extent); | ||
1217 | memmove(ex + 1, ex + 2, len); | ||
1218 | } | ||
1219 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries) - 1); | ||
1220 | merge_done = 1; | ||
1221 | WARN_ON(eh->eh_entries == 0); | ||
1222 | if (!eh->eh_entries) | ||
1223 | ext4_error(inode->i_sb, "ext4_ext_try_to_merge", | ||
1224 | "inode#%lu, eh->eh_entries = 0!", inode->i_ino); | ||
1225 | } | ||
1226 | |||
1227 | return merge_done; | ||
1228 | } | ||
1229 | |||
1230 | /* | ||
1131 | * check if a portion of the "newext" extent overlaps with an | 1231 | * check if a portion of the "newext" extent overlaps with an |
1132 | * existing extent. | 1232 | * existing extent. |
1133 | * | 1233 | * |
@@ -1144,7 +1244,7 @@ unsigned int ext4_ext_check_overlap(struct inode *inode, | |||
1144 | unsigned int ret = 0; | 1244 | unsigned int ret = 0; |
1145 | 1245 | ||
1146 | b1 = le32_to_cpu(newext->ee_block); | 1246 | b1 = le32_to_cpu(newext->ee_block); |
1147 | len1 = le16_to_cpu(newext->ee_len); | 1247 | len1 = ext4_ext_get_actual_len(newext); |
1148 | depth = ext_depth(inode); | 1248 | depth = ext_depth(inode); |
1149 | if (!path[depth].p_ext) | 1249 | if (!path[depth].p_ext) |
1150 | goto out; | 1250 | goto out; |
@@ -1191,8 +1291,9 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
1191 | struct ext4_extent *nearex; /* nearest extent */ | 1291 | struct ext4_extent *nearex; /* nearest extent */ |
1192 | struct ext4_ext_path *npath = NULL; | 1292 | struct ext4_ext_path *npath = NULL; |
1193 | int depth, len, err, next; | 1293 | int depth, len, err, next; |
1294 | unsigned uninitialized = 0; | ||
1194 | 1295 | ||
1195 | BUG_ON(newext->ee_len == 0); | 1296 | BUG_ON(ext4_ext_get_actual_len(newext) == 0); |
1196 | depth = ext_depth(inode); | 1297 | depth = ext_depth(inode); |
1197 | ex = path[depth].p_ext; | 1298 | ex = path[depth].p_ext; |
1198 | BUG_ON(path[depth].p_hdr == NULL); | 1299 | BUG_ON(path[depth].p_hdr == NULL); |
@@ -1200,14 +1301,24 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
1200 | /* try to insert block into found extent and return */ | 1301 | /* try to insert block into found extent and return */ |
1201 | if (ex && ext4_can_extents_be_merged(inode, ex, newext)) { | 1302 | if (ex && ext4_can_extents_be_merged(inode, ex, newext)) { |
1202 | ext_debug("append %d block to %d:%d (from %llu)\n", | 1303 | ext_debug("append %d block to %d:%d (from %llu)\n", |
1203 | le16_to_cpu(newext->ee_len), | 1304 | ext4_ext_get_actual_len(newext), |
1204 | le32_to_cpu(ex->ee_block), | 1305 | le32_to_cpu(ex->ee_block), |
1205 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); | 1306 | ext4_ext_get_actual_len(ex), ext_pblock(ex)); |
1206 | err = ext4_ext_get_access(handle, inode, path + depth); | 1307 | err = ext4_ext_get_access(handle, inode, path + depth); |
1207 | if (err) | 1308 | if (err) |
1208 | return err; | 1309 | return err; |
1209 | ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) | 1310 | |
1210 | + le16_to_cpu(newext->ee_len)); | 1311 | /* |
1312 | * ext4_can_extents_be_merged should have checked that either | ||
1313 | * both extents are uninitialized, or both aren't. Thus we | ||
1314 | * need to check only one of them here. | ||
1315 | */ | ||
1316 | if (ext4_ext_is_uninitialized(ex)) | ||
1317 | uninitialized = 1; | ||
1318 | ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex) | ||
1319 | + ext4_ext_get_actual_len(newext)); | ||
1320 | if (uninitialized) | ||
1321 | ext4_ext_mark_uninitialized(ex); | ||
1211 | eh = path[depth].p_hdr; | 1322 | eh = path[depth].p_hdr; |
1212 | nearex = ex; | 1323 | nearex = ex; |
1213 | goto merge; | 1324 | goto merge; |
@@ -1263,7 +1374,7 @@ has_space: | |||
1263 | ext_debug("first extent in the leaf: %d:%llu:%d\n", | 1374 | ext_debug("first extent in the leaf: %d:%llu:%d\n", |
1264 | le32_to_cpu(newext->ee_block), | 1375 | le32_to_cpu(newext->ee_block), |
1265 | ext_pblock(newext), | 1376 | ext_pblock(newext), |
1266 | le16_to_cpu(newext->ee_len)); | 1377 | ext4_ext_get_actual_len(newext)); |
1267 | path[depth].p_ext = EXT_FIRST_EXTENT(eh); | 1378 | path[depth].p_ext = EXT_FIRST_EXTENT(eh); |
1268 | } else if (le32_to_cpu(newext->ee_block) | 1379 | } else if (le32_to_cpu(newext->ee_block) |
1269 | > le32_to_cpu(nearex->ee_block)) { | 1380 | > le32_to_cpu(nearex->ee_block)) { |
@@ -1276,7 +1387,7 @@ has_space: | |||
1276 | "move %d from 0x%p to 0x%p\n", | 1387 | "move %d from 0x%p to 0x%p\n", |
1277 | le32_to_cpu(newext->ee_block), | 1388 | le32_to_cpu(newext->ee_block), |
1278 | ext_pblock(newext), | 1389 | ext_pblock(newext), |
1279 | le16_to_cpu(newext->ee_len), | 1390 | ext4_ext_get_actual_len(newext), |
1280 | nearex, len, nearex + 1, nearex + 2); | 1391 | nearex, len, nearex + 1, nearex + 2); |
1281 | memmove(nearex + 2, nearex + 1, len); | 1392 | memmove(nearex + 2, nearex + 1, len); |
1282 | } | 1393 | } |
@@ -1289,7 +1400,7 @@ has_space: | |||
1289 | "move %d from 0x%p to 0x%p\n", | 1400 | "move %d from 0x%p to 0x%p\n", |
1290 | le32_to_cpu(newext->ee_block), | 1401 | le32_to_cpu(newext->ee_block), |
1291 | ext_pblock(newext), | 1402 | ext_pblock(newext), |
1292 | le16_to_cpu(newext->ee_len), | 1403 | ext4_ext_get_actual_len(newext), |
1293 | nearex, len, nearex + 1, nearex + 2); | 1404 | nearex, len, nearex + 1, nearex + 2); |
1294 | memmove(nearex + 1, nearex, len); | 1405 | memmove(nearex + 1, nearex, len); |
1295 | path[depth].p_ext = nearex; | 1406 | path[depth].p_ext = nearex; |
@@ -1304,20 +1415,7 @@ has_space: | |||
1304 | 1415 | ||
1305 | merge: | 1416 | merge: |
1306 | /* try to merge extents to the right */ | 1417 | /* try to merge extents to the right */ |
1307 | while (nearex < EXT_LAST_EXTENT(eh)) { | 1418 | ext4_ext_try_to_merge(inode, path, nearex); |
1308 | if (!ext4_can_extents_be_merged(inode, nearex, nearex + 1)) | ||
1309 | break; | ||
1310 | /* merge with next extent! */ | ||
1311 | nearex->ee_len = cpu_to_le16(le16_to_cpu(nearex->ee_len) | ||
1312 | + le16_to_cpu(nearex[1].ee_len)); | ||
1313 | if (nearex + 1 < EXT_LAST_EXTENT(eh)) { | ||
1314 | len = (EXT_LAST_EXTENT(eh) - nearex - 1) | ||
1315 | * sizeof(struct ext4_extent); | ||
1316 | memmove(nearex + 1, nearex + 2, len); | ||
1317 | } | ||
1318 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1); | ||
1319 | BUG_ON(eh->eh_entries == 0); | ||
1320 | } | ||
1321 | 1419 | ||
1322 | /* try to merge extents to the left */ | 1420 | /* try to merge extents to the left */ |
1323 | 1421 | ||
@@ -1379,8 +1477,8 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
1379 | end = le32_to_cpu(ex->ee_block); | 1477 | end = le32_to_cpu(ex->ee_block); |
1380 | if (block + num < end) | 1478 | if (block + num < end) |
1381 | end = block + num; | 1479 | end = block + num; |
1382 | } else if (block >= | 1480 | } else if (block >= le32_to_cpu(ex->ee_block) |
1383 | le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len)) { | 1481 | + ext4_ext_get_actual_len(ex)) { |
1384 | /* need to allocate space after found extent */ | 1482 | /* need to allocate space after found extent */ |
1385 | start = block; | 1483 | start = block; |
1386 | end = block + num; | 1484 | end = block + num; |
@@ -1392,7 +1490,8 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
1392 | * by found extent | 1490 | * by found extent |
1393 | */ | 1491 | */ |
1394 | start = block; | 1492 | start = block; |
1395 | end = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len); | 1493 | end = le32_to_cpu(ex->ee_block) |
1494 | + ext4_ext_get_actual_len(ex); | ||
1396 | if (block + num < end) | 1495 | if (block + num < end) |
1397 | end = block + num; | 1496 | end = block + num; |
1398 | exists = 1; | 1497 | exists = 1; |
@@ -1408,7 +1507,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
1408 | cbex.ec_type = EXT4_EXT_CACHE_GAP; | 1507 | cbex.ec_type = EXT4_EXT_CACHE_GAP; |
1409 | } else { | 1508 | } else { |
1410 | cbex.ec_block = le32_to_cpu(ex->ee_block); | 1509 | cbex.ec_block = le32_to_cpu(ex->ee_block); |
1411 | cbex.ec_len = le16_to_cpu(ex->ee_len); | 1510 | cbex.ec_len = ext4_ext_get_actual_len(ex); |
1412 | cbex.ec_start = ext_pblock(ex); | 1511 | cbex.ec_start = ext_pblock(ex); |
1413 | cbex.ec_type = EXT4_EXT_CACHE_EXTENT; | 1512 | cbex.ec_type = EXT4_EXT_CACHE_EXTENT; |
1414 | } | 1513 | } |
@@ -1481,15 +1580,15 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
1481 | ext_debug("cache gap(before): %lu [%lu:%lu]", | 1580 | ext_debug("cache gap(before): %lu [%lu:%lu]", |
1482 | (unsigned long) block, | 1581 | (unsigned long) block, |
1483 | (unsigned long) le32_to_cpu(ex->ee_block), | 1582 | (unsigned long) le32_to_cpu(ex->ee_block), |
1484 | (unsigned long) le16_to_cpu(ex->ee_len)); | 1583 | (unsigned long) ext4_ext_get_actual_len(ex)); |
1485 | } else if (block >= le32_to_cpu(ex->ee_block) | 1584 | } else if (block >= le32_to_cpu(ex->ee_block) |
1486 | + le16_to_cpu(ex->ee_len)) { | 1585 | + ext4_ext_get_actual_len(ex)) { |
1487 | lblock = le32_to_cpu(ex->ee_block) | 1586 | lblock = le32_to_cpu(ex->ee_block) |
1488 | + le16_to_cpu(ex->ee_len); | 1587 | + ext4_ext_get_actual_len(ex); |
1489 | len = ext4_ext_next_allocated_block(path); | 1588 | len = ext4_ext_next_allocated_block(path); |
1490 | ext_debug("cache gap(after): [%lu:%lu] %lu", | 1589 | ext_debug("cache gap(after): [%lu:%lu] %lu", |
1491 | (unsigned long) le32_to_cpu(ex->ee_block), | 1590 | (unsigned long) le32_to_cpu(ex->ee_block), |
1492 | (unsigned long) le16_to_cpu(ex->ee_len), | 1591 | (unsigned long) ext4_ext_get_actual_len(ex), |
1493 | (unsigned long) block); | 1592 | (unsigned long) block); |
1494 | BUG_ON(len == lblock); | 1593 | BUG_ON(len == lblock); |
1495 | len = len - lblock; | 1594 | len = len - lblock; |
@@ -1619,12 +1718,12 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
1619 | unsigned long from, unsigned long to) | 1718 | unsigned long from, unsigned long to) |
1620 | { | 1719 | { |
1621 | struct buffer_head *bh; | 1720 | struct buffer_head *bh; |
1721 | unsigned short ee_len = ext4_ext_get_actual_len(ex); | ||
1622 | int i; | 1722 | int i; |
1623 | 1723 | ||
1624 | #ifdef EXTENTS_STATS | 1724 | #ifdef EXTENTS_STATS |
1625 | { | 1725 | { |
1626 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1726 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
1627 | unsigned short ee_len = le16_to_cpu(ex->ee_len); | ||
1628 | spin_lock(&sbi->s_ext_stats_lock); | 1727 | spin_lock(&sbi->s_ext_stats_lock); |
1629 | sbi->s_ext_blocks += ee_len; | 1728 | sbi->s_ext_blocks += ee_len; |
1630 | sbi->s_ext_extents++; | 1729 | sbi->s_ext_extents++; |
@@ -1638,12 +1737,12 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
1638 | } | 1737 | } |
1639 | #endif | 1738 | #endif |
1640 | if (from >= le32_to_cpu(ex->ee_block) | 1739 | if (from >= le32_to_cpu(ex->ee_block) |
1641 | && to == le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) { | 1740 | && to == le32_to_cpu(ex->ee_block) + ee_len - 1) { |
1642 | /* tail removal */ | 1741 | /* tail removal */ |
1643 | unsigned long num; | 1742 | unsigned long num; |
1644 | ext4_fsblk_t start; | 1743 | ext4_fsblk_t start; |
1645 | num = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - from; | 1744 | num = le32_to_cpu(ex->ee_block) + ee_len - from; |
1646 | start = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - num; | 1745 | start = ext_pblock(ex) + ee_len - num; |
1647 | ext_debug("free last %lu blocks starting %llu\n", num, start); | 1746 | ext_debug("free last %lu blocks starting %llu\n", num, start); |
1648 | for (i = 0; i < num; i++) { | 1747 | for (i = 0; i < num; i++) { |
1649 | bh = sb_find_get_block(inode->i_sb, start + i); | 1748 | bh = sb_find_get_block(inode->i_sb, start + i); |
@@ -1651,12 +1750,12 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
1651 | } | 1750 | } |
1652 | ext4_free_blocks(handle, inode, start, num); | 1751 | ext4_free_blocks(handle, inode, start, num); |
1653 | } else if (from == le32_to_cpu(ex->ee_block) | 1752 | } else if (from == le32_to_cpu(ex->ee_block) |
1654 | && to <= le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) { | 1753 | && to <= le32_to_cpu(ex->ee_block) + ee_len - 1) { |
1655 | printk("strange request: removal %lu-%lu from %u:%u\n", | 1754 | printk("strange request: removal %lu-%lu from %u:%u\n", |
1656 | from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len)); | 1755 | from, to, le32_to_cpu(ex->ee_block), ee_len); |
1657 | } else { | 1756 | } else { |
1658 | printk("strange request: removal(2) %lu-%lu from %u:%u\n", | 1757 | printk("strange request: removal(2) %lu-%lu from %u:%u\n", |
1659 | from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len)); | 1758 | from, to, le32_to_cpu(ex->ee_block), ee_len); |
1660 | } | 1759 | } |
1661 | return 0; | 1760 | return 0; |
1662 | } | 1761 | } |
@@ -1671,21 +1770,23 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
1671 | unsigned a, b, block, num; | 1770 | unsigned a, b, block, num; |
1672 | unsigned long ex_ee_block; | 1771 | unsigned long ex_ee_block; |
1673 | unsigned short ex_ee_len; | 1772 | unsigned short ex_ee_len; |
1773 | unsigned uninitialized = 0; | ||
1674 | struct ext4_extent *ex; | 1774 | struct ext4_extent *ex; |
1675 | 1775 | ||
1776 | /* the header must be checked already in ext4_ext_remove_space() */ | ||
1676 | ext_debug("truncate since %lu in leaf\n", start); | 1777 | ext_debug("truncate since %lu in leaf\n", start); |
1677 | if (!path[depth].p_hdr) | 1778 | if (!path[depth].p_hdr) |
1678 | path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); | 1779 | path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); |
1679 | eh = path[depth].p_hdr; | 1780 | eh = path[depth].p_hdr; |
1680 | BUG_ON(eh == NULL); | 1781 | BUG_ON(eh == NULL); |
1681 | BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); | ||
1682 | BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); | ||
1683 | 1782 | ||
1684 | /* find where to start removing */ | 1783 | /* find where to start removing */ |
1685 | ex = EXT_LAST_EXTENT(eh); | 1784 | ex = EXT_LAST_EXTENT(eh); |
1686 | 1785 | ||
1687 | ex_ee_block = le32_to_cpu(ex->ee_block); | 1786 | ex_ee_block = le32_to_cpu(ex->ee_block); |
1688 | ex_ee_len = le16_to_cpu(ex->ee_len); | 1787 | if (ext4_ext_is_uninitialized(ex)) |
1788 | uninitialized = 1; | ||
1789 | ex_ee_len = ext4_ext_get_actual_len(ex); | ||
1689 | 1790 | ||
1690 | while (ex >= EXT_FIRST_EXTENT(eh) && | 1791 | while (ex >= EXT_FIRST_EXTENT(eh) && |
1691 | ex_ee_block + ex_ee_len > start) { | 1792 | ex_ee_block + ex_ee_len > start) { |
@@ -1753,6 +1854,12 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
1753 | 1854 | ||
1754 | ex->ee_block = cpu_to_le32(block); | 1855 | ex->ee_block = cpu_to_le32(block); |
1755 | ex->ee_len = cpu_to_le16(num); | 1856 | ex->ee_len = cpu_to_le16(num); |
1857 | /* | ||
1858 | * Do not mark uninitialized if all the blocks in the | ||
1859 | * extent have been removed. | ||
1860 | */ | ||
1861 | if (uninitialized && num) | ||
1862 | ext4_ext_mark_uninitialized(ex); | ||
1756 | 1863 | ||
1757 | err = ext4_ext_dirty(handle, inode, path + depth); | 1864 | err = ext4_ext_dirty(handle, inode, path + depth); |
1758 | if (err) | 1865 | if (err) |
@@ -1762,7 +1869,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
1762 | ext_pblock(ex)); | 1869 | ext_pblock(ex)); |
1763 | ex--; | 1870 | ex--; |
1764 | ex_ee_block = le32_to_cpu(ex->ee_block); | 1871 | ex_ee_block = le32_to_cpu(ex->ee_block); |
1765 | ex_ee_len = le16_to_cpu(ex->ee_len); | 1872 | ex_ee_len = ext4_ext_get_actual_len(ex); |
1766 | } | 1873 | } |
1767 | 1874 | ||
1768 | if (correct_index && eh->eh_entries) | 1875 | if (correct_index && eh->eh_entries) |
@@ -1825,7 +1932,7 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
1825 | return -ENOMEM; | 1932 | return -ENOMEM; |
1826 | } | 1933 | } |
1827 | path[0].p_hdr = ext_inode_hdr(inode); | 1934 | path[0].p_hdr = ext_inode_hdr(inode); |
1828 | if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { | 1935 | if (ext4_ext_check_header(inode, path[0].p_hdr, depth)) { |
1829 | err = -EIO; | 1936 | err = -EIO; |
1830 | goto out; | 1937 | goto out; |
1831 | } | 1938 | } |
@@ -1846,17 +1953,8 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
1846 | if (!path[i].p_hdr) { | 1953 | if (!path[i].p_hdr) { |
1847 | ext_debug("initialize header\n"); | 1954 | ext_debug("initialize header\n"); |
1848 | path[i].p_hdr = ext_block_hdr(path[i].p_bh); | 1955 | path[i].p_hdr = ext_block_hdr(path[i].p_bh); |
1849 | if (ext4_ext_check_header(__FUNCTION__, inode, | ||
1850 | path[i].p_hdr)) { | ||
1851 | err = -EIO; | ||
1852 | goto out; | ||
1853 | } | ||
1854 | } | 1956 | } |
1855 | 1957 | ||
1856 | BUG_ON(le16_to_cpu(path[i].p_hdr->eh_entries) | ||
1857 | > le16_to_cpu(path[i].p_hdr->eh_max)); | ||
1858 | BUG_ON(path[i].p_hdr->eh_magic != EXT4_EXT_MAGIC); | ||
1859 | |||
1860 | if (!path[i].p_idx) { | 1958 | if (!path[i].p_idx) { |
1861 | /* this level hasn't been touched yet */ | 1959 | /* this level hasn't been touched yet */ |
1862 | path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr); | 1960 | path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr); |
@@ -1873,17 +1971,27 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
1873 | i, EXT_FIRST_INDEX(path[i].p_hdr), | 1971 | i, EXT_FIRST_INDEX(path[i].p_hdr), |
1874 | path[i].p_idx); | 1972 | path[i].p_idx); |
1875 | if (ext4_ext_more_to_rm(path + i)) { | 1973 | if (ext4_ext_more_to_rm(path + i)) { |
1974 | struct buffer_head *bh; | ||
1876 | /* go to the next level */ | 1975 | /* go to the next level */ |
1877 | ext_debug("move to level %d (block %llu)\n", | 1976 | ext_debug("move to level %d (block %llu)\n", |
1878 | i + 1, idx_pblock(path[i].p_idx)); | 1977 | i + 1, idx_pblock(path[i].p_idx)); |
1879 | memset(path + i + 1, 0, sizeof(*path)); | 1978 | memset(path + i + 1, 0, sizeof(*path)); |
1880 | path[i+1].p_bh = | 1979 | bh = sb_bread(sb, idx_pblock(path[i].p_idx)); |
1881 | sb_bread(sb, idx_pblock(path[i].p_idx)); | 1980 | if (!bh) { |
1882 | if (!path[i+1].p_bh) { | ||
1883 | /* should we reset i_size? */ | 1981 | /* should we reset i_size? */ |
1884 | err = -EIO; | 1982 | err = -EIO; |
1885 | break; | 1983 | break; |
1886 | } | 1984 | } |
1985 | if (WARN_ON(i + 1 > depth)) { | ||
1986 | err = -EIO; | ||
1987 | break; | ||
1988 | } | ||
1989 | if (ext4_ext_check_header(inode, ext_block_hdr(bh), | ||
1990 | depth - i - 1)) { | ||
1991 | err = -EIO; | ||
1992 | break; | ||
1993 | } | ||
1994 | path[i + 1].p_bh = bh; | ||
1887 | 1995 | ||
1888 | /* save actual number of indexes since this | 1996 | /* save actual number of indexes since this |
1889 | * number is changed at the next iteration */ | 1997 | * number is changed at the next iteration */ |
@@ -1977,15 +2085,158 @@ void ext4_ext_release(struct super_block *sb) | |||
1977 | #endif | 2085 | #endif |
1978 | } | 2086 | } |
1979 | 2087 | ||
2088 | /* | ||
2089 | * This function is called by ext4_ext_get_blocks() if someone tries to write | ||
2090 | * to an uninitialized extent. It may result in splitting the uninitialized | ||
2091 | * extent into multiple extents (upto three - one initialized and two | ||
2092 | * uninitialized). | ||
2093 | * There are three possibilities: | ||
2094 | * a> There is no split required: Entire extent should be initialized | ||
2095 | * b> Splits in two extents: Write is happening at either end of the extent | ||
2096 | * c> Splits in three extents: Somone is writing in middle of the extent | ||
2097 | */ | ||
2098 | int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode, | ||
2099 | struct ext4_ext_path *path, | ||
2100 | ext4_fsblk_t iblock, | ||
2101 | unsigned long max_blocks) | ||
2102 | { | ||
2103 | struct ext4_extent *ex, newex; | ||
2104 | struct ext4_extent *ex1 = NULL; | ||
2105 | struct ext4_extent *ex2 = NULL; | ||
2106 | struct ext4_extent *ex3 = NULL; | ||
2107 | struct ext4_extent_header *eh; | ||
2108 | unsigned int allocated, ee_block, ee_len, depth; | ||
2109 | ext4_fsblk_t newblock; | ||
2110 | int err = 0; | ||
2111 | int ret = 0; | ||
2112 | |||
2113 | depth = ext_depth(inode); | ||
2114 | eh = path[depth].p_hdr; | ||
2115 | ex = path[depth].p_ext; | ||
2116 | ee_block = le32_to_cpu(ex->ee_block); | ||
2117 | ee_len = ext4_ext_get_actual_len(ex); | ||
2118 | allocated = ee_len - (iblock - ee_block); | ||
2119 | newblock = iblock - ee_block + ext_pblock(ex); | ||
2120 | ex2 = ex; | ||
2121 | |||
2122 | /* ex1: ee_block to iblock - 1 : uninitialized */ | ||
2123 | if (iblock > ee_block) { | ||
2124 | ex1 = ex; | ||
2125 | ex1->ee_len = cpu_to_le16(iblock - ee_block); | ||
2126 | ext4_ext_mark_uninitialized(ex1); | ||
2127 | ex2 = &newex; | ||
2128 | } | ||
2129 | /* | ||
2130 | * for sanity, update the length of the ex2 extent before | ||
2131 | * we insert ex3, if ex1 is NULL. This is to avoid temporary | ||
2132 | * overlap of blocks. | ||
2133 | */ | ||
2134 | if (!ex1 && allocated > max_blocks) | ||
2135 | ex2->ee_len = cpu_to_le16(max_blocks); | ||
2136 | /* ex3: to ee_block + ee_len : uninitialised */ | ||
2137 | if (allocated > max_blocks) { | ||
2138 | unsigned int newdepth; | ||
2139 | ex3 = &newex; | ||
2140 | ex3->ee_block = cpu_to_le32(iblock + max_blocks); | ||
2141 | ext4_ext_store_pblock(ex3, newblock + max_blocks); | ||
2142 | ex3->ee_len = cpu_to_le16(allocated - max_blocks); | ||
2143 | ext4_ext_mark_uninitialized(ex3); | ||
2144 | err = ext4_ext_insert_extent(handle, inode, path, ex3); | ||
2145 | if (err) | ||
2146 | goto out; | ||
2147 | /* | ||
2148 | * The depth, and hence eh & ex might change | ||
2149 | * as part of the insert above. | ||
2150 | */ | ||
2151 | newdepth = ext_depth(inode); | ||
2152 | if (newdepth != depth) { | ||
2153 | depth = newdepth; | ||
2154 | path = ext4_ext_find_extent(inode, iblock, NULL); | ||
2155 | if (IS_ERR(path)) { | ||
2156 | err = PTR_ERR(path); | ||
2157 | path = NULL; | ||
2158 | goto out; | ||
2159 | } | ||
2160 | eh = path[depth].p_hdr; | ||
2161 | ex = path[depth].p_ext; | ||
2162 | if (ex2 != &newex) | ||
2163 | ex2 = ex; | ||
2164 | } | ||
2165 | allocated = max_blocks; | ||
2166 | } | ||
2167 | /* | ||
2168 | * If there was a change of depth as part of the | ||
2169 | * insertion of ex3 above, we need to update the length | ||
2170 | * of the ex1 extent again here | ||
2171 | */ | ||
2172 | if (ex1 && ex1 != ex) { | ||
2173 | ex1 = ex; | ||
2174 | ex1->ee_len = cpu_to_le16(iblock - ee_block); | ||
2175 | ext4_ext_mark_uninitialized(ex1); | ||
2176 | ex2 = &newex; | ||
2177 | } | ||
2178 | /* ex2: iblock to iblock + maxblocks-1 : initialised */ | ||
2179 | ex2->ee_block = cpu_to_le32(iblock); | ||
2180 | ex2->ee_start = cpu_to_le32(newblock); | ||
2181 | ext4_ext_store_pblock(ex2, newblock); | ||
2182 | ex2->ee_len = cpu_to_le16(allocated); | ||
2183 | if (ex2 != ex) | ||
2184 | goto insert; | ||
2185 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
2186 | if (err) | ||
2187 | goto out; | ||
2188 | /* | ||
2189 | * New (initialized) extent starts from the first block | ||
2190 | * in the current extent. i.e., ex2 == ex | ||
2191 | * We have to see if it can be merged with the extent | ||
2192 | * on the left. | ||
2193 | */ | ||
2194 | if (ex2 > EXT_FIRST_EXTENT(eh)) { | ||
2195 | /* | ||
2196 | * To merge left, pass "ex2 - 1" to try_to_merge(), | ||
2197 | * since it merges towards right _only_. | ||
2198 | */ | ||
2199 | ret = ext4_ext_try_to_merge(inode, path, ex2 - 1); | ||
2200 | if (ret) { | ||
2201 | err = ext4_ext_correct_indexes(handle, inode, path); | ||
2202 | if (err) | ||
2203 | goto out; | ||
2204 | depth = ext_depth(inode); | ||
2205 | ex2--; | ||
2206 | } | ||
2207 | } | ||
2208 | /* | ||
2209 | * Try to Merge towards right. This might be required | ||
2210 | * only when the whole extent is being written to. | ||
2211 | * i.e. ex2 == ex and ex3 == NULL. | ||
2212 | */ | ||
2213 | if (!ex3) { | ||
2214 | ret = ext4_ext_try_to_merge(inode, path, ex2); | ||
2215 | if (ret) { | ||
2216 | err = ext4_ext_correct_indexes(handle, inode, path); | ||
2217 | if (err) | ||
2218 | goto out; | ||
2219 | } | ||
2220 | } | ||
2221 | /* Mark modified extent as dirty */ | ||
2222 | err = ext4_ext_dirty(handle, inode, path + depth); | ||
2223 | goto out; | ||
2224 | insert: | ||
2225 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | ||
2226 | out: | ||
2227 | return err ? err : allocated; | ||
2228 | } | ||
2229 | |||
1980 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2230 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
1981 | ext4_fsblk_t iblock, | 2231 | ext4_fsblk_t iblock, |
1982 | unsigned long max_blocks, struct buffer_head *bh_result, | 2232 | unsigned long max_blocks, struct buffer_head *bh_result, |
1983 | int create, int extend_disksize) | 2233 | int create, int extend_disksize) |
1984 | { | 2234 | { |
1985 | struct ext4_ext_path *path = NULL; | 2235 | struct ext4_ext_path *path = NULL; |
2236 | struct ext4_extent_header *eh; | ||
1986 | struct ext4_extent newex, *ex; | 2237 | struct ext4_extent newex, *ex; |
1987 | ext4_fsblk_t goal, newblock; | 2238 | ext4_fsblk_t goal, newblock; |
1988 | int err = 0, depth; | 2239 | int err = 0, depth, ret; |
1989 | unsigned long allocated = 0; | 2240 | unsigned long allocated = 0; |
1990 | 2241 | ||
1991 | __clear_bit(BH_New, &bh_result->b_state); | 2242 | __clear_bit(BH_New, &bh_result->b_state); |
@@ -1998,8 +2249,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
1998 | if (goal) { | 2249 | if (goal) { |
1999 | if (goal == EXT4_EXT_CACHE_GAP) { | 2250 | if (goal == EXT4_EXT_CACHE_GAP) { |
2000 | if (!create) { | 2251 | if (!create) { |
2001 | /* block isn't allocated yet and | 2252 | /* |
2002 | * user doesn't want to allocate it */ | 2253 | * block isn't allocated yet and |
2254 | * user doesn't want to allocate it | ||
2255 | */ | ||
2003 | goto out2; | 2256 | goto out2; |
2004 | } | 2257 | } |
2005 | /* we should allocate requested block */ | 2258 | /* we should allocate requested block */ |
@@ -2033,21 +2286,19 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2033 | * this is why assert can't be put in ext4_ext_find_extent() | 2286 | * this is why assert can't be put in ext4_ext_find_extent() |
2034 | */ | 2287 | */ |
2035 | BUG_ON(path[depth].p_ext == NULL && depth != 0); | 2288 | BUG_ON(path[depth].p_ext == NULL && depth != 0); |
2289 | eh = path[depth].p_hdr; | ||
2036 | 2290 | ||
2037 | ex = path[depth].p_ext; | 2291 | ex = path[depth].p_ext; |
2038 | if (ex) { | 2292 | if (ex) { |
2039 | unsigned long ee_block = le32_to_cpu(ex->ee_block); | 2293 | unsigned long ee_block = le32_to_cpu(ex->ee_block); |
2040 | ext4_fsblk_t ee_start = ext_pblock(ex); | 2294 | ext4_fsblk_t ee_start = ext_pblock(ex); |
2041 | unsigned short ee_len = le16_to_cpu(ex->ee_len); | 2295 | unsigned short ee_len; |
2042 | 2296 | ||
2043 | /* | 2297 | /* |
2044 | * Allow future support for preallocated extents to be added | ||
2045 | * as an RO_COMPAT feature: | ||
2046 | * Uninitialized extents are treated as holes, except that | 2298 | * Uninitialized extents are treated as holes, except that |
2047 | * we avoid (fail) allocating new blocks during a write. | 2299 | * we split out initialized portions during a write. |
2048 | */ | 2300 | */ |
2049 | if (ee_len > EXT_MAX_LEN) | 2301 | ee_len = ext4_ext_get_actual_len(ex); |
2050 | goto out2; | ||
2051 | /* if found extent covers block, simply return it */ | 2302 | /* if found extent covers block, simply return it */ |
2052 | if (iblock >= ee_block && iblock < ee_block + ee_len) { | 2303 | if (iblock >= ee_block && iblock < ee_block + ee_len) { |
2053 | newblock = iblock - ee_block + ee_start; | 2304 | newblock = iblock - ee_block + ee_start; |
@@ -2055,9 +2306,27 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2055 | allocated = ee_len - (iblock - ee_block); | 2306 | allocated = ee_len - (iblock - ee_block); |
2056 | ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock, | 2307 | ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock, |
2057 | ee_block, ee_len, newblock); | 2308 | ee_block, ee_len, newblock); |
2058 | ext4_ext_put_in_cache(inode, ee_block, ee_len, | 2309 | |
2059 | ee_start, EXT4_EXT_CACHE_EXTENT); | 2310 | /* Do not put uninitialized extent in the cache */ |
2060 | goto out; | 2311 | if (!ext4_ext_is_uninitialized(ex)) { |
2312 | ext4_ext_put_in_cache(inode, ee_block, | ||
2313 | ee_len, ee_start, | ||
2314 | EXT4_EXT_CACHE_EXTENT); | ||
2315 | goto out; | ||
2316 | } | ||
2317 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) | ||
2318 | goto out; | ||
2319 | if (!create) | ||
2320 | goto out2; | ||
2321 | |||
2322 | ret = ext4_ext_convert_to_initialized(handle, inode, | ||
2323 | path, iblock, | ||
2324 | max_blocks); | ||
2325 | if (ret <= 0) | ||
2326 | goto out2; | ||
2327 | else | ||
2328 | allocated = ret; | ||
2329 | goto outnew; | ||
2061 | } | 2330 | } |
2062 | } | 2331 | } |
2063 | 2332 | ||
@@ -2066,8 +2335,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2066 | * we couldn't try to create block if create flag is zero | 2335 | * we couldn't try to create block if create flag is zero |
2067 | */ | 2336 | */ |
2068 | if (!create) { | 2337 | if (!create) { |
2069 | /* put just found gap into cache to speed up | 2338 | /* |
2070 | * subsequent requests */ | 2339 | * put just found gap into cache to speed up |
2340 | * subsequent requests | ||
2341 | */ | ||
2071 | ext4_ext_put_gap_in_cache(inode, path, iblock); | 2342 | ext4_ext_put_gap_in_cache(inode, path, iblock); |
2072 | goto out2; | 2343 | goto out2; |
2073 | } | 2344 | } |
@@ -2081,6 +2352,19 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2081 | /* allocate new block */ | 2352 | /* allocate new block */ |
2082 | goal = ext4_ext_find_goal(inode, path, iblock); | 2353 | goal = ext4_ext_find_goal(inode, path, iblock); |
2083 | 2354 | ||
2355 | /* | ||
2356 | * See if request is beyond maximum number of blocks we can have in | ||
2357 | * a single extent. For an initialized extent this limit is | ||
2358 | * EXT_INIT_MAX_LEN and for an uninitialized extent this limit is | ||
2359 | * EXT_UNINIT_MAX_LEN. | ||
2360 | */ | ||
2361 | if (max_blocks > EXT_INIT_MAX_LEN && | ||
2362 | create != EXT4_CREATE_UNINITIALIZED_EXT) | ||
2363 | max_blocks = EXT_INIT_MAX_LEN; | ||
2364 | else if (max_blocks > EXT_UNINIT_MAX_LEN && | ||
2365 | create == EXT4_CREATE_UNINITIALIZED_EXT) | ||
2366 | max_blocks = EXT_UNINIT_MAX_LEN; | ||
2367 | |||
2084 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ | 2368 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ |
2085 | newex.ee_block = cpu_to_le32(iblock); | 2369 | newex.ee_block = cpu_to_le32(iblock); |
2086 | newex.ee_len = cpu_to_le16(max_blocks); | 2370 | newex.ee_len = cpu_to_le16(max_blocks); |
@@ -2098,6 +2382,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2098 | /* try to insert new extent into found leaf and return */ | 2382 | /* try to insert new extent into found leaf and return */ |
2099 | ext4_ext_store_pblock(&newex, newblock); | 2383 | ext4_ext_store_pblock(&newex, newblock); |
2100 | newex.ee_len = cpu_to_le16(allocated); | 2384 | newex.ee_len = cpu_to_le16(allocated); |
2385 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */ | ||
2386 | ext4_ext_mark_uninitialized(&newex); | ||
2101 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | 2387 | err = ext4_ext_insert_extent(handle, inode, path, &newex); |
2102 | if (err) { | 2388 | if (err) { |
2103 | /* free data blocks we just allocated */ | 2389 | /* free data blocks we just allocated */ |
@@ -2111,10 +2397,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2111 | 2397 | ||
2112 | /* previous routine could use block we allocated */ | 2398 | /* previous routine could use block we allocated */ |
2113 | newblock = ext_pblock(&newex); | 2399 | newblock = ext_pblock(&newex); |
2400 | outnew: | ||
2114 | __set_bit(BH_New, &bh_result->b_state); | 2401 | __set_bit(BH_New, &bh_result->b_state); |
2115 | 2402 | ||
2116 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, | 2403 | /* Cache only when it is _not_ an uninitialized extent */ |
2117 | EXT4_EXT_CACHE_EXTENT); | 2404 | if (create != EXT4_CREATE_UNINITIALIZED_EXT) |
2405 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, | ||
2406 | EXT4_EXT_CACHE_EXTENT); | ||
2118 | out: | 2407 | out: |
2119 | if (allocated > max_blocks) | 2408 | if (allocated > max_blocks) |
2120 | allocated = max_blocks; | 2409 | allocated = max_blocks; |
@@ -2178,7 +2467,8 @@ void ext4_ext_truncate(struct inode * inode, struct page *page) | |||
2178 | err = ext4_ext_remove_space(inode, last_block); | 2467 | err = ext4_ext_remove_space(inode, last_block); |
2179 | 2468 | ||
2180 | /* In a multi-transaction truncate, we only make the final | 2469 | /* In a multi-transaction truncate, we only make the final |
2181 | * transaction synchronous. */ | 2470 | * transaction synchronous. |
2471 | */ | ||
2182 | if (IS_SYNC(inode)) | 2472 | if (IS_SYNC(inode)) |
2183 | handle->h_sync = 1; | 2473 | handle->h_sync = 1; |
2184 | 2474 | ||
@@ -2217,3 +2507,127 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num) | |||
2217 | 2507 | ||
2218 | return needed; | 2508 | return needed; |
2219 | } | 2509 | } |
2510 | |||
2511 | /* | ||
2512 | * preallocate space for a file. This implements ext4's fallocate inode | ||
2513 | * operation, which gets called from sys_fallocate system call. | ||
2514 | * For block-mapped files, posix_fallocate should fall back to the method | ||
2515 | * of writing zeroes to the required new blocks (the same behavior which is | ||
2516 | * expected for file systems which do not support fallocate() system call). | ||
2517 | */ | ||
2518 | long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | ||
2519 | { | ||
2520 | handle_t *handle; | ||
2521 | ext4_fsblk_t block, max_blocks; | ||
2522 | ext4_fsblk_t nblocks = 0; | ||
2523 | int ret = 0; | ||
2524 | int ret2 = 0; | ||
2525 | int retries = 0; | ||
2526 | struct buffer_head map_bh; | ||
2527 | unsigned int credits, blkbits = inode->i_blkbits; | ||
2528 | |||
2529 | /* | ||
2530 | * currently supporting (pre)allocate mode for extent-based | ||
2531 | * files _only_ | ||
2532 | */ | ||
2533 | if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) | ||
2534 | return -EOPNOTSUPP; | ||
2535 | |||
2536 | /* preallocation to directories is currently not supported */ | ||
2537 | if (S_ISDIR(inode->i_mode)) | ||
2538 | return -ENODEV; | ||
2539 | |||
2540 | block = offset >> blkbits; | ||
2541 | max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) | ||
2542 | - block; | ||
2543 | |||
2544 | /* | ||
2545 | * credits to insert 1 extent into extent tree + buffers to be able to | ||
2546 | * modify 1 super block, 1 block bitmap and 1 group descriptor. | ||
2547 | */ | ||
2548 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; | ||
2549 | retry: | ||
2550 | while (ret >= 0 && ret < max_blocks) { | ||
2551 | block = block + ret; | ||
2552 | max_blocks = max_blocks - ret; | ||
2553 | handle = ext4_journal_start(inode, credits); | ||
2554 | if (IS_ERR(handle)) { | ||
2555 | ret = PTR_ERR(handle); | ||
2556 | break; | ||
2557 | } | ||
2558 | |||
2559 | ret = ext4_ext_get_blocks(handle, inode, block, | ||
2560 | max_blocks, &map_bh, | ||
2561 | EXT4_CREATE_UNINITIALIZED_EXT, 0); | ||
2562 | WARN_ON(!ret); | ||
2563 | if (!ret) { | ||
2564 | ext4_error(inode->i_sb, "ext4_fallocate", | ||
2565 | "ext4_ext_get_blocks returned 0! inode#%lu" | ||
2566 | ", block=%llu, max_blocks=%llu", | ||
2567 | inode->i_ino, block, max_blocks); | ||
2568 | ret = -EIO; | ||
2569 | ext4_mark_inode_dirty(handle, inode); | ||
2570 | ret2 = ext4_journal_stop(handle); | ||
2571 | break; | ||
2572 | } | ||
2573 | if (ret > 0) { | ||
2574 | /* check wrap through sign-bit/zero here */ | ||
2575 | if ((block + ret) < 0 || (block + ret) < block) { | ||
2576 | ret = -EIO; | ||
2577 | ext4_mark_inode_dirty(handle, inode); | ||
2578 | ret2 = ext4_journal_stop(handle); | ||
2579 | break; | ||
2580 | } | ||
2581 | if (buffer_new(&map_bh) && ((block + ret) > | ||
2582 | (EXT4_BLOCK_ALIGN(i_size_read(inode), blkbits) | ||
2583 | >> blkbits))) | ||
2584 | nblocks = nblocks + ret; | ||
2585 | } | ||
2586 | |||
2587 | /* Update ctime if new blocks get allocated */ | ||
2588 | if (nblocks) { | ||
2589 | struct timespec now; | ||
2590 | |||
2591 | now = current_fs_time(inode->i_sb); | ||
2592 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
2593 | inode->i_ctime = now; | ||
2594 | } | ||
2595 | |||
2596 | ext4_mark_inode_dirty(handle, inode); | ||
2597 | ret2 = ext4_journal_stop(handle); | ||
2598 | if (ret2) | ||
2599 | break; | ||
2600 | } | ||
2601 | |||
2602 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | ||
2603 | goto retry; | ||
2604 | |||
2605 | /* | ||
2606 | * Time to update the file size. | ||
2607 | * Update only when preallocation was requested beyond the file size. | ||
2608 | */ | ||
2609 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
2610 | (offset + len) > i_size_read(inode)) { | ||
2611 | if (ret > 0) { | ||
2612 | /* | ||
2613 | * if no error, we assume preallocation succeeded | ||
2614 | * completely | ||
2615 | */ | ||
2616 | mutex_lock(&inode->i_mutex); | ||
2617 | i_size_write(inode, offset + len); | ||
2618 | EXT4_I(inode)->i_disksize = i_size_read(inode); | ||
2619 | mutex_unlock(&inode->i_mutex); | ||
2620 | } else if (ret < 0 && nblocks) { | ||
2621 | /* Handle partial allocation scenario */ | ||
2622 | loff_t newsize; | ||
2623 | |||
2624 | mutex_lock(&inode->i_mutex); | ||
2625 | newsize = (nblocks << blkbits) + i_size_read(inode); | ||
2626 | i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); | ||
2627 | EXT4_I(inode)->i_disksize = i_size_read(inode); | ||
2628 | mutex_unlock(&inode->i_mutex); | ||
2629 | } | ||
2630 | } | ||
2631 | |||
2632 | return ret > 0 ? ret2 : ret; | ||
2633 | } | ||
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index d4c8186aed64..1a81cd66d63b 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -134,5 +134,6 @@ const struct inode_operations ext4_file_inode_operations = { | |||
134 | .removexattr = generic_removexattr, | 134 | .removexattr = generic_removexattr, |
135 | #endif | 135 | #endif |
136 | .permission = ext4_permission, | 136 | .permission = ext4_permission, |
137 | .fallocate = ext4_fallocate, | ||
137 | }; | 138 | }; |
138 | 139 | ||
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index c88b439ba5cd..427f83066a0d 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -563,7 +563,8 @@ got: | |||
563 | inode->i_ino = ino; | 563 | inode->i_ino = ino; |
564 | /* This is the optimal IO size (for stat), not the fs block size */ | 564 | /* This is the optimal IO size (for stat), not the fs block size */ |
565 | inode->i_blocks = 0; | 565 | inode->i_blocks = 0; |
566 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 566 | inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime = |
567 | ext4_current_time(inode); | ||
567 | 568 | ||
568 | memset(ei->i_data, 0, sizeof(ei->i_data)); | 569 | memset(ei->i_data, 0, sizeof(ei->i_data)); |
569 | ei->i_dir_start_lookup = 0; | 570 | ei->i_dir_start_lookup = 0; |
@@ -595,9 +596,8 @@ got: | |||
595 | spin_unlock(&sbi->s_next_gen_lock); | 596 | spin_unlock(&sbi->s_next_gen_lock); |
596 | 597 | ||
597 | ei->i_state = EXT4_STATE_NEW; | 598 | ei->i_state = EXT4_STATE_NEW; |
598 | ei->i_extra_isize = | 599 | |
599 | (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) ? | 600 | ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize; |
600 | sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE : 0; | ||
601 | 601 | ||
602 | ret = inode; | 602 | ret = inode; |
603 | if(DQUOT_ALLOC_INODE(inode)) { | 603 | if(DQUOT_ALLOC_INODE(inode)) { |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8416fa28c422..de26c25d6a18 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -726,7 +726,7 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode, | |||
726 | 726 | ||
727 | /* We are done with atomic stuff, now do the rest of housekeeping */ | 727 | /* We are done with atomic stuff, now do the rest of housekeeping */ |
728 | 728 | ||
729 | inode->i_ctime = CURRENT_TIME_SEC; | 729 | inode->i_ctime = ext4_current_time(inode); |
730 | ext4_mark_inode_dirty(handle, inode); | 730 | ext4_mark_inode_dirty(handle, inode); |
731 | 731 | ||
732 | /* had we spliced it onto indirect block? */ | 732 | /* had we spliced it onto indirect block? */ |
@@ -1766,7 +1766,6 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, | |||
1766 | struct inode *inode = mapping->host; | 1766 | struct inode *inode = mapping->host; |
1767 | struct buffer_head *bh; | 1767 | struct buffer_head *bh; |
1768 | int err = 0; | 1768 | int err = 0; |
1769 | void *kaddr; | ||
1770 | 1769 | ||
1771 | blocksize = inode->i_sb->s_blocksize; | 1770 | blocksize = inode->i_sb->s_blocksize; |
1772 | length = blocksize - (offset & (blocksize - 1)); | 1771 | length = blocksize - (offset & (blocksize - 1)); |
@@ -1778,10 +1777,7 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, | |||
1778 | */ | 1777 | */ |
1779 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && | 1778 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && |
1780 | ext4_should_writeback_data(inode) && PageUptodate(page)) { | 1779 | ext4_should_writeback_data(inode) && PageUptodate(page)) { |
1781 | kaddr = kmap_atomic(page, KM_USER0); | 1780 | zero_user_page(page, offset, length, KM_USER0); |
1782 | memset(kaddr + offset, 0, length); | ||
1783 | flush_dcache_page(page); | ||
1784 | kunmap_atomic(kaddr, KM_USER0); | ||
1785 | set_page_dirty(page); | 1781 | set_page_dirty(page); |
1786 | goto unlock; | 1782 | goto unlock; |
1787 | } | 1783 | } |
@@ -1834,10 +1830,7 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page, | |||
1834 | goto unlock; | 1830 | goto unlock; |
1835 | } | 1831 | } |
1836 | 1832 | ||
1837 | kaddr = kmap_atomic(page, KM_USER0); | 1833 | zero_user_page(page, offset, length, KM_USER0); |
1838 | memset(kaddr + offset, 0, length); | ||
1839 | flush_dcache_page(page); | ||
1840 | kunmap_atomic(kaddr, KM_USER0); | ||
1841 | 1834 | ||
1842 | BUFFER_TRACE(bh, "zeroed end of block"); | 1835 | BUFFER_TRACE(bh, "zeroed end of block"); |
1843 | 1836 | ||
@@ -2375,7 +2368,7 @@ do_indirects: | |||
2375 | ext4_discard_reservation(inode); | 2368 | ext4_discard_reservation(inode); |
2376 | 2369 | ||
2377 | mutex_unlock(&ei->truncate_mutex); | 2370 | mutex_unlock(&ei->truncate_mutex); |
2378 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 2371 | inode->i_mtime = inode->i_ctime = ext4_current_time(inode); |
2379 | ext4_mark_inode_dirty(handle, inode); | 2372 | ext4_mark_inode_dirty(handle, inode); |
2380 | 2373 | ||
2381 | /* | 2374 | /* |
@@ -2583,6 +2576,25 @@ void ext4_set_inode_flags(struct inode *inode) | |||
2583 | inode->i_flags |= S_DIRSYNC; | 2576 | inode->i_flags |= S_DIRSYNC; |
2584 | } | 2577 | } |
2585 | 2578 | ||
2579 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ | ||
2580 | void ext4_get_inode_flags(struct ext4_inode_info *ei) | ||
2581 | { | ||
2582 | unsigned int flags = ei->vfs_inode.i_flags; | ||
2583 | |||
2584 | ei->i_flags &= ~(EXT4_SYNC_FL|EXT4_APPEND_FL| | ||
2585 | EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|EXT4_DIRSYNC_FL); | ||
2586 | if (flags & S_SYNC) | ||
2587 | ei->i_flags |= EXT4_SYNC_FL; | ||
2588 | if (flags & S_APPEND) | ||
2589 | ei->i_flags |= EXT4_APPEND_FL; | ||
2590 | if (flags & S_IMMUTABLE) | ||
2591 | ei->i_flags |= EXT4_IMMUTABLE_FL; | ||
2592 | if (flags & S_NOATIME) | ||
2593 | ei->i_flags |= EXT4_NOATIME_FL; | ||
2594 | if (flags & S_DIRSYNC) | ||
2595 | ei->i_flags |= EXT4_DIRSYNC_FL; | ||
2596 | } | ||
2597 | |||
2586 | void ext4_read_inode(struct inode * inode) | 2598 | void ext4_read_inode(struct inode * inode) |
2587 | { | 2599 | { |
2588 | struct ext4_iloc iloc; | 2600 | struct ext4_iloc iloc; |
@@ -2610,10 +2622,6 @@ void ext4_read_inode(struct inode * inode) | |||
2610 | } | 2622 | } |
2611 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); | 2623 | inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
2612 | inode->i_size = le32_to_cpu(raw_inode->i_size); | 2624 | inode->i_size = le32_to_cpu(raw_inode->i_size); |
2613 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); | ||
2614 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime); | ||
2615 | inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime); | ||
2616 | inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; | ||
2617 | 2625 | ||
2618 | ei->i_state = 0; | 2626 | ei->i_state = 0; |
2619 | ei->i_dir_start_lookup = 0; | 2627 | ei->i_dir_start_lookup = 0; |
@@ -2691,6 +2699,11 @@ void ext4_read_inode(struct inode * inode) | |||
2691 | } else | 2699 | } else |
2692 | ei->i_extra_isize = 0; | 2700 | ei->i_extra_isize = 0; |
2693 | 2701 | ||
2702 | EXT4_INODE_GET_XTIME(i_ctime, inode, raw_inode); | ||
2703 | EXT4_INODE_GET_XTIME(i_mtime, inode, raw_inode); | ||
2704 | EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); | ||
2705 | EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); | ||
2706 | |||
2694 | if (S_ISREG(inode->i_mode)) { | 2707 | if (S_ISREG(inode->i_mode)) { |
2695 | inode->i_op = &ext4_file_inode_operations; | 2708 | inode->i_op = &ext4_file_inode_operations; |
2696 | inode->i_fop = &ext4_file_operations; | 2709 | inode->i_fop = &ext4_file_operations; |
@@ -2744,6 +2757,7 @@ static int ext4_do_update_inode(handle_t *handle, | |||
2744 | if (ei->i_state & EXT4_STATE_NEW) | 2757 | if (ei->i_state & EXT4_STATE_NEW) |
2745 | memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size); | 2758 | memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size); |
2746 | 2759 | ||
2760 | ext4_get_inode_flags(ei); | ||
2747 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 2761 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
2748 | if(!(test_opt(inode->i_sb, NO_UID32))) { | 2762 | if(!(test_opt(inode->i_sb, NO_UID32))) { |
2749 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); | 2763 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); |
@@ -2771,9 +2785,12 @@ static int ext4_do_update_inode(handle_t *handle, | |||
2771 | } | 2785 | } |
2772 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); | 2786 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
2773 | raw_inode->i_size = cpu_to_le32(ei->i_disksize); | 2787 | raw_inode->i_size = cpu_to_le32(ei->i_disksize); |
2774 | raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); | 2788 | |
2775 | raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); | 2789 | EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode); |
2776 | raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); | 2790 | EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); |
2791 | EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); | ||
2792 | EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode); | ||
2793 | |||
2777 | raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); | 2794 | raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); |
2778 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); | 2795 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); |
2779 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); | 2796 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); |
@@ -3082,6 +3099,39 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode, | |||
3082 | } | 3099 | } |
3083 | 3100 | ||
3084 | /* | 3101 | /* |
3102 | * Expand an inode by new_extra_isize bytes. | ||
3103 | * Returns 0 on success or negative error number on failure. | ||
3104 | */ | ||
3105 | int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize, | ||
3106 | struct ext4_iloc iloc, handle_t *handle) | ||
3107 | { | ||
3108 | struct ext4_inode *raw_inode; | ||
3109 | struct ext4_xattr_ibody_header *header; | ||
3110 | struct ext4_xattr_entry *entry; | ||
3111 | |||
3112 | if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) | ||
3113 | return 0; | ||
3114 | |||
3115 | raw_inode = ext4_raw_inode(&iloc); | ||
3116 | |||
3117 | header = IHDR(inode, raw_inode); | ||
3118 | entry = IFIRST(header); | ||
3119 | |||
3120 | /* No extended attributes present */ | ||
3121 | if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR) || | ||
3122 | header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) { | ||
3123 | memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0, | ||
3124 | new_extra_isize); | ||
3125 | EXT4_I(inode)->i_extra_isize = new_extra_isize; | ||
3126 | return 0; | ||
3127 | } | ||
3128 | |||
3129 | /* try to expand with EAs present */ | ||
3130 | return ext4_expand_extra_isize_ea(inode, new_extra_isize, | ||
3131 | raw_inode, handle); | ||
3132 | } | ||
3133 | |||
3134 | /* | ||
3085 | * What we do here is to mark the in-core inode as clean with respect to inode | 3135 | * What we do here is to mark the in-core inode as clean with respect to inode |
3086 | * dirtiness (it may still be data-dirty). | 3136 | * dirtiness (it may still be data-dirty). |
3087 | * This means that the in-core inode may be reaped by prune_icache | 3137 | * This means that the in-core inode may be reaped by prune_icache |
@@ -3105,10 +3155,38 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode, | |||
3105 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | 3155 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) |
3106 | { | 3156 | { |
3107 | struct ext4_iloc iloc; | 3157 | struct ext4_iloc iloc; |
3108 | int err; | 3158 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
3159 | static unsigned int mnt_count; | ||
3160 | int err, ret; | ||
3109 | 3161 | ||
3110 | might_sleep(); | 3162 | might_sleep(); |
3111 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 3163 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
3164 | if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && | ||
3165 | !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) { | ||
3166 | /* | ||
3167 | * We need extra buffer credits since we may write into EA block | ||
3168 | * with this same handle. If journal_extend fails, then it will | ||
3169 | * only result in a minor loss of functionality for that inode. | ||
3170 | * If this is felt to be critical, then e2fsck should be run to | ||
3171 | * force a large enough s_min_extra_isize. | ||
3172 | */ | ||
3173 | if ((jbd2_journal_extend(handle, | ||
3174 | EXT4_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) { | ||
3175 | ret = ext4_expand_extra_isize(inode, | ||
3176 | sbi->s_want_extra_isize, | ||
3177 | iloc, handle); | ||
3178 | if (ret) { | ||
3179 | EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; | ||
3180 | if (mnt_count != sbi->s_es->s_mnt_count) { | ||
3181 | ext4_warning(inode->i_sb, __FUNCTION__, | ||
3182 | "Unable to expand inode %lu. Delete" | ||
3183 | " some EAs or run e2fsck.", | ||
3184 | inode->i_ino); | ||
3185 | mnt_count = sbi->s_es->s_mnt_count; | ||
3186 | } | ||
3187 | } | ||
3188 | } | ||
3189 | } | ||
3112 | if (!err) | 3190 | if (!err) |
3113 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 3191 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
3114 | return err; | 3192 | return err; |
@@ -3197,7 +3275,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val) | |||
3197 | */ | 3275 | */ |
3198 | 3276 | ||
3199 | journal = EXT4_JOURNAL(inode); | 3277 | journal = EXT4_JOURNAL(inode); |
3200 | if (is_journal_aborted(journal) || IS_RDONLY(inode)) | 3278 | if (is_journal_aborted(journal)) |
3201 | return -EROFS; | 3279 | return -EROFS; |
3202 | 3280 | ||
3203 | jbd2_journal_lock_updates(journal); | 3281 | jbd2_journal_lock_updates(journal); |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 7b4aa4543c83..c04c7ccba9e3 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -28,6 +28,7 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
28 | 28 | ||
29 | switch (cmd) { | 29 | switch (cmd) { |
30 | case EXT4_IOC_GETFLAGS: | 30 | case EXT4_IOC_GETFLAGS: |
31 | ext4_get_inode_flags(ei); | ||
31 | flags = ei->i_flags & EXT4_FL_USER_VISIBLE; | 32 | flags = ei->i_flags & EXT4_FL_USER_VISIBLE; |
32 | return put_user(flags, (int __user *) arg); | 33 | return put_user(flags, (int __user *) arg); |
33 | case EXT4_IOC_SETFLAGS: { | 34 | case EXT4_IOC_SETFLAGS: { |
@@ -96,7 +97,7 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
96 | ei->i_flags = flags; | 97 | ei->i_flags = flags; |
97 | 98 | ||
98 | ext4_set_inode_flags(inode); | 99 | ext4_set_inode_flags(inode); |
99 | inode->i_ctime = CURRENT_TIME_SEC; | 100 | inode->i_ctime = ext4_current_time(inode); |
100 | 101 | ||
101 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 102 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
102 | flags_err: | 103 | flags_err: |
@@ -133,14 +134,14 @@ flags_err: | |||
133 | return PTR_ERR(handle); | 134 | return PTR_ERR(handle); |
134 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 135 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
135 | if (err == 0) { | 136 | if (err == 0) { |
136 | inode->i_ctime = CURRENT_TIME_SEC; | 137 | inode->i_ctime = ext4_current_time(inode); |
137 | inode->i_generation = generation; | 138 | inode->i_generation = generation; |
138 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 139 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
139 | } | 140 | } |
140 | ext4_journal_stop(handle); | 141 | ext4_journal_stop(handle); |
141 | return err; | 142 | return err; |
142 | } | 143 | } |
143 | #ifdef CONFIG_JBD_DEBUG | 144 | #ifdef CONFIG_JBD2_DEBUG |
144 | case EXT4_IOC_WAIT_FOR_READONLY: | 145 | case EXT4_IOC_WAIT_FOR_READONLY: |
145 | /* | 146 | /* |
146 | * This is racy - by the time we're woken up and running, | 147 | * This is racy - by the time we're woken up and running, |
@@ -282,7 +283,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
282 | case EXT4_IOC32_SETVERSION_OLD: | 283 | case EXT4_IOC32_SETVERSION_OLD: |
283 | cmd = EXT4_IOC_SETVERSION_OLD; | 284 | cmd = EXT4_IOC_SETVERSION_OLD; |
284 | break; | 285 | break; |
285 | #ifdef CONFIG_JBD_DEBUG | 286 | #ifdef CONFIG_JBD2_DEBUG |
286 | case EXT4_IOC32_WAIT_FOR_READONLY: | 287 | case EXT4_IOC32_WAIT_FOR_READONLY: |
287 | cmd = EXT4_IOC_WAIT_FOR_READONLY; | 288 | cmd = EXT4_IOC_WAIT_FOR_READONLY; |
288 | break; | 289 | break; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 2de339dd7554..da224974af78 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1295,7 +1295,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, | |||
1295 | * happen is that the times are slightly out of date | 1295 | * happen is that the times are slightly out of date |
1296 | * and/or different from the directory change time. | 1296 | * and/or different from the directory change time. |
1297 | */ | 1297 | */ |
1298 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 1298 | dir->i_mtime = dir->i_ctime = ext4_current_time(dir); |
1299 | ext4_update_dx_flag(dir); | 1299 | ext4_update_dx_flag(dir); |
1300 | dir->i_version++; | 1300 | dir->i_version++; |
1301 | ext4_mark_inode_dirty(handle, dir); | 1301 | ext4_mark_inode_dirty(handle, dir); |
@@ -1629,6 +1629,35 @@ static int ext4_delete_entry (handle_t *handle, | |||
1629 | return -ENOENT; | 1629 | return -ENOENT; |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | /* | ||
1633 | * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2, | ||
1634 | * since this indicates that nlinks count was previously 1. | ||
1635 | */ | ||
1636 | static void ext4_inc_count(handle_t *handle, struct inode *inode) | ||
1637 | { | ||
1638 | inc_nlink(inode); | ||
1639 | if (is_dx(inode) && inode->i_nlink > 1) { | ||
1640 | /* limit is 16-bit i_links_count */ | ||
1641 | if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) { | ||
1642 | inode->i_nlink = 1; | ||
1643 | EXT4_SET_RO_COMPAT_FEATURE(inode->i_sb, | ||
1644 | EXT4_FEATURE_RO_COMPAT_DIR_NLINK); | ||
1645 | } | ||
1646 | } | ||
1647 | } | ||
1648 | |||
1649 | /* | ||
1650 | * If a directory had nlink == 1, then we should let it be 1. This indicates | ||
1651 | * directory has >EXT4_LINK_MAX subdirs. | ||
1652 | */ | ||
1653 | static void ext4_dec_count(handle_t *handle, struct inode *inode) | ||
1654 | { | ||
1655 | drop_nlink(inode); | ||
1656 | if (S_ISDIR(inode->i_mode) && inode->i_nlink == 0) | ||
1657 | inc_nlink(inode); | ||
1658 | } | ||
1659 | |||
1660 | |||
1632 | static int ext4_add_nondir(handle_t *handle, | 1661 | static int ext4_add_nondir(handle_t *handle, |
1633 | struct dentry *dentry, struct inode *inode) | 1662 | struct dentry *dentry, struct inode *inode) |
1634 | { | 1663 | { |
@@ -1725,7 +1754,7 @@ static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
1725 | struct ext4_dir_entry_2 * de; | 1754 | struct ext4_dir_entry_2 * de; |
1726 | int err, retries = 0; | 1755 | int err, retries = 0; |
1727 | 1756 | ||
1728 | if (dir->i_nlink >= EXT4_LINK_MAX) | 1757 | if (EXT4_DIR_LINK_MAX(dir)) |
1729 | return -EMLINK; | 1758 | return -EMLINK; |
1730 | 1759 | ||
1731 | retry: | 1760 | retry: |
@@ -1748,7 +1777,7 @@ retry: | |||
1748 | inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; | 1777 | inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; |
1749 | dir_block = ext4_bread (handle, inode, 0, 1, &err); | 1778 | dir_block = ext4_bread (handle, inode, 0, 1, &err); |
1750 | if (!dir_block) { | 1779 | if (!dir_block) { |
1751 | drop_nlink(inode); /* is this nlink == 0? */ | 1780 | ext4_dec_count(handle, inode); /* is this nlink == 0? */ |
1752 | ext4_mark_inode_dirty(handle, inode); | 1781 | ext4_mark_inode_dirty(handle, inode); |
1753 | iput (inode); | 1782 | iput (inode); |
1754 | goto out_stop; | 1783 | goto out_stop; |
@@ -1780,7 +1809,7 @@ retry: | |||
1780 | iput (inode); | 1809 | iput (inode); |
1781 | goto out_stop; | 1810 | goto out_stop; |
1782 | } | 1811 | } |
1783 | inc_nlink(dir); | 1812 | ext4_inc_count(handle, dir); |
1784 | ext4_update_dx_flag(dir); | 1813 | ext4_update_dx_flag(dir); |
1785 | ext4_mark_inode_dirty(handle, dir); | 1814 | ext4_mark_inode_dirty(handle, dir); |
1786 | d_instantiate(dentry, inode); | 1815 | d_instantiate(dentry, inode); |
@@ -2045,9 +2074,9 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry) | |||
2045 | retval = ext4_delete_entry(handle, dir, de, bh); | 2074 | retval = ext4_delete_entry(handle, dir, de, bh); |
2046 | if (retval) | 2075 | if (retval) |
2047 | goto end_rmdir; | 2076 | goto end_rmdir; |
2048 | if (inode->i_nlink != 2) | 2077 | if (!EXT4_DIR_LINK_EMPTY(inode)) |
2049 | ext4_warning (inode->i_sb, "ext4_rmdir", | 2078 | ext4_warning (inode->i_sb, "ext4_rmdir", |
2050 | "empty directory has nlink!=2 (%d)", | 2079 | "empty directory has too many links (%d)", |
2051 | inode->i_nlink); | 2080 | inode->i_nlink); |
2052 | inode->i_version++; | 2081 | inode->i_version++; |
2053 | clear_nlink(inode); | 2082 | clear_nlink(inode); |
@@ -2056,9 +2085,9 @@ static int ext4_rmdir (struct inode * dir, struct dentry *dentry) | |||
2056 | * recovery. */ | 2085 | * recovery. */ |
2057 | inode->i_size = 0; | 2086 | inode->i_size = 0; |
2058 | ext4_orphan_add(handle, inode); | 2087 | ext4_orphan_add(handle, inode); |
2059 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 2088 | inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode); |
2060 | ext4_mark_inode_dirty(handle, inode); | 2089 | ext4_mark_inode_dirty(handle, inode); |
2061 | drop_nlink(dir); | 2090 | ext4_dec_count(handle, dir); |
2062 | ext4_update_dx_flag(dir); | 2091 | ext4_update_dx_flag(dir); |
2063 | ext4_mark_inode_dirty(handle, dir); | 2092 | ext4_mark_inode_dirty(handle, dir); |
2064 | 2093 | ||
@@ -2106,13 +2135,13 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry) | |||
2106 | retval = ext4_delete_entry(handle, dir, de, bh); | 2135 | retval = ext4_delete_entry(handle, dir, de, bh); |
2107 | if (retval) | 2136 | if (retval) |
2108 | goto end_unlink; | 2137 | goto end_unlink; |
2109 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 2138 | dir->i_ctime = dir->i_mtime = ext4_current_time(dir); |
2110 | ext4_update_dx_flag(dir); | 2139 | ext4_update_dx_flag(dir); |
2111 | ext4_mark_inode_dirty(handle, dir); | 2140 | ext4_mark_inode_dirty(handle, dir); |
2112 | drop_nlink(inode); | 2141 | ext4_dec_count(handle, inode); |
2113 | if (!inode->i_nlink) | 2142 | if (!inode->i_nlink) |
2114 | ext4_orphan_add(handle, inode); | 2143 | ext4_orphan_add(handle, inode); |
2115 | inode->i_ctime = dir->i_ctime; | 2144 | inode->i_ctime = ext4_current_time(inode); |
2116 | ext4_mark_inode_dirty(handle, inode); | 2145 | ext4_mark_inode_dirty(handle, inode); |
2117 | retval = 0; | 2146 | retval = 0; |
2118 | 2147 | ||
@@ -2159,7 +2188,7 @@ retry: | |||
2159 | err = __page_symlink(inode, symname, l, | 2188 | err = __page_symlink(inode, symname, l, |
2160 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 2189 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
2161 | if (err) { | 2190 | if (err) { |
2162 | drop_nlink(inode); | 2191 | ext4_dec_count(handle, inode); |
2163 | ext4_mark_inode_dirty(handle, inode); | 2192 | ext4_mark_inode_dirty(handle, inode); |
2164 | iput (inode); | 2193 | iput (inode); |
2165 | goto out_stop; | 2194 | goto out_stop; |
@@ -2185,8 +2214,9 @@ static int ext4_link (struct dentry * old_dentry, | |||
2185 | struct inode *inode = old_dentry->d_inode; | 2214 | struct inode *inode = old_dentry->d_inode; |
2186 | int err, retries = 0; | 2215 | int err, retries = 0; |
2187 | 2216 | ||
2188 | if (inode->i_nlink >= EXT4_LINK_MAX) | 2217 | if (EXT4_DIR_LINK_MAX(inode)) |
2189 | return -EMLINK; | 2218 | return -EMLINK; |
2219 | |||
2190 | /* | 2220 | /* |
2191 | * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing | 2221 | * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing |
2192 | * otherwise has the potential to corrupt the orphan inode list. | 2222 | * otherwise has the potential to corrupt the orphan inode list. |
@@ -2203,8 +2233,8 @@ retry: | |||
2203 | if (IS_DIRSYNC(dir)) | 2233 | if (IS_DIRSYNC(dir)) |
2204 | handle->h_sync = 1; | 2234 | handle->h_sync = 1; |
2205 | 2235 | ||
2206 | inode->i_ctime = CURRENT_TIME_SEC; | 2236 | inode->i_ctime = ext4_current_time(inode); |
2207 | inc_nlink(inode); | 2237 | ext4_inc_count(handle, inode); |
2208 | atomic_inc(&inode->i_count); | 2238 | atomic_inc(&inode->i_count); |
2209 | 2239 | ||
2210 | err = ext4_add_nondir(handle, dentry, inode); | 2240 | err = ext4_add_nondir(handle, dentry, inode); |
@@ -2305,7 +2335,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2305 | * Like most other Unix systems, set the ctime for inodes on a | 2335 | * Like most other Unix systems, set the ctime for inodes on a |
2306 | * rename. | 2336 | * rename. |
2307 | */ | 2337 | */ |
2308 | old_inode->i_ctime = CURRENT_TIME_SEC; | 2338 | old_inode->i_ctime = ext4_current_time(old_inode); |
2309 | ext4_mark_inode_dirty(handle, old_inode); | 2339 | ext4_mark_inode_dirty(handle, old_inode); |
2310 | 2340 | ||
2311 | /* | 2341 | /* |
@@ -2337,10 +2367,10 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2337 | } | 2367 | } |
2338 | 2368 | ||
2339 | if (new_inode) { | 2369 | if (new_inode) { |
2340 | drop_nlink(new_inode); | 2370 | ext4_dec_count(handle, new_inode); |
2341 | new_inode->i_ctime = CURRENT_TIME_SEC; | 2371 | new_inode->i_ctime = ext4_current_time(new_inode); |
2342 | } | 2372 | } |
2343 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; | 2373 | old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir); |
2344 | ext4_update_dx_flag(old_dir); | 2374 | ext4_update_dx_flag(old_dir); |
2345 | if (dir_bh) { | 2375 | if (dir_bh) { |
2346 | BUFFER_TRACE(dir_bh, "get_write_access"); | 2376 | BUFFER_TRACE(dir_bh, "get_write_access"); |
@@ -2348,11 +2378,13 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2348 | PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); | 2378 | PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); |
2349 | BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata"); | 2379 | BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata"); |
2350 | ext4_journal_dirty_metadata(handle, dir_bh); | 2380 | ext4_journal_dirty_metadata(handle, dir_bh); |
2351 | drop_nlink(old_dir); | 2381 | ext4_dec_count(handle, old_dir); |
2352 | if (new_inode) { | 2382 | if (new_inode) { |
2353 | drop_nlink(new_inode); | 2383 | /* checked empty_dir above, can't have another parent, |
2384 | * ext3_dec_count() won't work for many-linked dirs */ | ||
2385 | new_inode->i_nlink = 0; | ||
2354 | } else { | 2386 | } else { |
2355 | inc_nlink(new_dir); | 2387 | ext4_inc_count(handle, new_dir); |
2356 | ext4_update_dx_flag(new_dir); | 2388 | ext4_update_dx_flag(new_dir); |
2357 | ext4_mark_inode_dirty(handle, new_dir); | 2389 | ext4_mark_inode_dirty(handle, new_dir); |
2358 | } | 2390 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b806e689c4aa..6dcbb28dc06d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/namei.h> | 36 | #include <linux/namei.h> |
37 | #include <linux/quotaops.h> | 37 | #include <linux/quotaops.h> |
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/log2.h> | ||
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | 42 | ||
@@ -734,7 +735,7 @@ enum { | |||
734 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 735 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
735 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 736 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
736 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 737 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
737 | Opt_grpquota, Opt_extents, | 738 | Opt_grpquota, Opt_extents, Opt_noextents, |
738 | }; | 739 | }; |
739 | 740 | ||
740 | static match_table_t tokens = { | 741 | static match_table_t tokens = { |
@@ -785,6 +786,7 @@ static match_table_t tokens = { | |||
785 | {Opt_usrquota, "usrquota"}, | 786 | {Opt_usrquota, "usrquota"}, |
786 | {Opt_barrier, "barrier=%u"}, | 787 | {Opt_barrier, "barrier=%u"}, |
787 | {Opt_extents, "extents"}, | 788 | {Opt_extents, "extents"}, |
789 | {Opt_noextents, "noextents"}, | ||
788 | {Opt_err, NULL}, | 790 | {Opt_err, NULL}, |
789 | {Opt_resize, "resize"}, | 791 | {Opt_resize, "resize"}, |
790 | }; | 792 | }; |
@@ -1120,6 +1122,9 @@ clear_qf_name: | |||
1120 | case Opt_extents: | 1122 | case Opt_extents: |
1121 | set_opt (sbi->s_mount_opt, EXTENTS); | 1123 | set_opt (sbi->s_mount_opt, EXTENTS); |
1122 | break; | 1124 | break; |
1125 | case Opt_noextents: | ||
1126 | clear_opt (sbi->s_mount_opt, EXTENTS); | ||
1127 | break; | ||
1123 | default: | 1128 | default: |
1124 | printk (KERN_ERR | 1129 | printk (KERN_ERR |
1125 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1130 | "EXT4-fs: Unrecognized mount option \"%s\" " |
@@ -1551,6 +1556,12 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1551 | 1556 | ||
1552 | set_opt(sbi->s_mount_opt, RESERVATION); | 1557 | set_opt(sbi->s_mount_opt, RESERVATION); |
1553 | 1558 | ||
1559 | /* | ||
1560 | * turn on extents feature by default in ext4 filesystem | ||
1561 | * User -o noextents to turn it off | ||
1562 | */ | ||
1563 | set_opt(sbi->s_mount_opt, EXTENTS); | ||
1564 | |||
1554 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, | 1565 | if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, |
1555 | NULL, 0)) | 1566 | NULL, 0)) |
1556 | goto failed_mount; | 1567 | goto failed_mount; |
@@ -1634,13 +1645,15 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1634 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); | 1645 | sbi->s_inode_size = le16_to_cpu(es->s_inode_size); |
1635 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); | 1646 | sbi->s_first_ino = le32_to_cpu(es->s_first_ino); |
1636 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || | 1647 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || |
1637 | (sbi->s_inode_size & (sbi->s_inode_size - 1)) || | 1648 | (!is_power_of_2(sbi->s_inode_size)) || |
1638 | (sbi->s_inode_size > blocksize)) { | 1649 | (sbi->s_inode_size > blocksize)) { |
1639 | printk (KERN_ERR | 1650 | printk (KERN_ERR |
1640 | "EXT4-fs: unsupported inode size: %d\n", | 1651 | "EXT4-fs: unsupported inode size: %d\n", |
1641 | sbi->s_inode_size); | 1652 | sbi->s_inode_size); |
1642 | goto failed_mount; | 1653 | goto failed_mount; |
1643 | } | 1654 | } |
1655 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) | ||
1656 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); | ||
1644 | } | 1657 | } |
1645 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << | 1658 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << |
1646 | le32_to_cpu(es->s_log_frag_size); | 1659 | le32_to_cpu(es->s_log_frag_size); |
@@ -1803,6 +1816,13 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1803 | goto failed_mount3; | 1816 | goto failed_mount3; |
1804 | } | 1817 | } |
1805 | 1818 | ||
1819 | if (ext4_blocks_count(es) > 0xffffffffULL && | ||
1820 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | ||
1821 | JBD2_FEATURE_INCOMPAT_64BIT)) { | ||
1822 | printk(KERN_ERR "ext4: Failed to set 64-bit journal feature\n"); | ||
1823 | goto failed_mount4; | ||
1824 | } | ||
1825 | |||
1806 | /* We have now updated the journal if required, so we can | 1826 | /* We have now updated the journal if required, so we can |
1807 | * validate the data journaling mode. */ | 1827 | * validate the data journaling mode. */ |
1808 | switch (test_opt(sb, DATA_FLAGS)) { | 1828 | switch (test_opt(sb, DATA_FLAGS)) { |
@@ -1857,6 +1877,32 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1857 | } | 1877 | } |
1858 | 1878 | ||
1859 | ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 1879 | ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
1880 | |||
1881 | /* determine the minimum size of new large inodes, if present */ | ||
1882 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) { | ||
1883 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | ||
1884 | EXT4_GOOD_OLD_INODE_SIZE; | ||
1885 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, | ||
1886 | EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) { | ||
1887 | if (sbi->s_want_extra_isize < | ||
1888 | le16_to_cpu(es->s_want_extra_isize)) | ||
1889 | sbi->s_want_extra_isize = | ||
1890 | le16_to_cpu(es->s_want_extra_isize); | ||
1891 | if (sbi->s_want_extra_isize < | ||
1892 | le16_to_cpu(es->s_min_extra_isize)) | ||
1893 | sbi->s_want_extra_isize = | ||
1894 | le16_to_cpu(es->s_min_extra_isize); | ||
1895 | } | ||
1896 | } | ||
1897 | /* Check if enough inode space is available */ | ||
1898 | if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > | ||
1899 | sbi->s_inode_size) { | ||
1900 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | ||
1901 | EXT4_GOOD_OLD_INODE_SIZE; | ||
1902 | printk(KERN_INFO "EXT4-fs: required extra inode space not" | ||
1903 | "available.\n"); | ||
1904 | } | ||
1905 | |||
1860 | /* | 1906 | /* |
1861 | * akpm: core read_super() calls in here with the superblock locked. | 1907 | * akpm: core read_super() calls in here with the superblock locked. |
1862 | * That deadlocks, because orphan cleanup needs to lock the superblock | 1908 | * That deadlocks, because orphan cleanup needs to lock the superblock |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index e832e96095b3..b10d68fffb55 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -66,13 +66,6 @@ | |||
66 | #define BFIRST(bh) ENTRY(BHDR(bh)+1) | 66 | #define BFIRST(bh) ENTRY(BHDR(bh)+1) |
67 | #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) | 67 | #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) |
68 | 68 | ||
69 | #define IHDR(inode, raw_inode) \ | ||
70 | ((struct ext4_xattr_ibody_header *) \ | ||
71 | ((void *)raw_inode + \ | ||
72 | EXT4_GOOD_OLD_INODE_SIZE + \ | ||
73 | EXT4_I(inode)->i_extra_isize)) | ||
74 | #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) | ||
75 | |||
76 | #ifdef EXT4_XATTR_DEBUG | 69 | #ifdef EXT4_XATTR_DEBUG |
77 | # define ea_idebug(inode, f...) do { \ | 70 | # define ea_idebug(inode, f...) do { \ |
78 | printk(KERN_DEBUG "inode %s:%lu: ", \ | 71 | printk(KERN_DEBUG "inode %s:%lu: ", \ |
@@ -508,6 +501,24 @@ out: | |||
508 | return; | 501 | return; |
509 | } | 502 | } |
510 | 503 | ||
504 | /* | ||
505 | * Find the available free space for EAs. This also returns the total number of | ||
506 | * bytes used by EA entries. | ||
507 | */ | ||
508 | static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last, | ||
509 | size_t *min_offs, void *base, int *total) | ||
510 | { | ||
511 | for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { | ||
512 | *total += EXT4_XATTR_LEN(last->e_name_len); | ||
513 | if (!last->e_value_block && last->e_value_size) { | ||
514 | size_t offs = le16_to_cpu(last->e_value_offs); | ||
515 | if (offs < *min_offs) | ||
516 | *min_offs = offs; | ||
517 | } | ||
518 | } | ||
519 | return (*min_offs - ((void *)last - base) - sizeof(__u32)); | ||
520 | } | ||
521 | |||
511 | struct ext4_xattr_info { | 522 | struct ext4_xattr_info { |
512 | int name_index; | 523 | int name_index; |
513 | const char *name; | 524 | const char *name; |
@@ -1013,7 +1024,9 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, | |||
1013 | } | 1024 | } |
1014 | if (!error) { | 1025 | if (!error) { |
1015 | ext4_xattr_update_super_block(handle, inode->i_sb); | 1026 | ext4_xattr_update_super_block(handle, inode->i_sb); |
1016 | inode->i_ctime = CURRENT_TIME_SEC; | 1027 | inode->i_ctime = ext4_current_time(inode); |
1028 | if (!value) | ||
1029 | EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND; | ||
1017 | error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); | 1030 | error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); |
1018 | /* | 1031 | /* |
1019 | * The bh is consumed by ext4_mark_iloc_dirty, even with | 1032 | * The bh is consumed by ext4_mark_iloc_dirty, even with |
@@ -1067,6 +1080,253 @@ retry: | |||
1067 | } | 1080 | } |
1068 | 1081 | ||
1069 | /* | 1082 | /* |
1083 | * Shift the EA entries in the inode to create space for the increased | ||
1084 | * i_extra_isize. | ||
1085 | */ | ||
1086 | static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry, | ||
1087 | int value_offs_shift, void *to, | ||
1088 | void *from, size_t n, int blocksize) | ||
1089 | { | ||
1090 | struct ext4_xattr_entry *last = entry; | ||
1091 | int new_offs; | ||
1092 | |||
1093 | /* Adjust the value offsets of the entries */ | ||
1094 | for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { | ||
1095 | if (!last->e_value_block && last->e_value_size) { | ||
1096 | new_offs = le16_to_cpu(last->e_value_offs) + | ||
1097 | value_offs_shift; | ||
1098 | BUG_ON(new_offs + le32_to_cpu(last->e_value_size) | ||
1099 | > blocksize); | ||
1100 | last->e_value_offs = cpu_to_le16(new_offs); | ||
1101 | } | ||
1102 | } | ||
1103 | /* Shift the entries by n bytes */ | ||
1104 | memmove(to, from, n); | ||
1105 | } | ||
1106 | |||
1107 | /* | ||
1108 | * Expand an inode by new_extra_isize bytes when EAs are present. | ||
1109 | * Returns 0 on success or negative error number on failure. | ||
1110 | */ | ||
1111 | int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | ||
1112 | struct ext4_inode *raw_inode, handle_t *handle) | ||
1113 | { | ||
1114 | struct ext4_xattr_ibody_header *header; | ||
1115 | struct ext4_xattr_entry *entry, *last, *first; | ||
1116 | struct buffer_head *bh = NULL; | ||
1117 | struct ext4_xattr_ibody_find *is = NULL; | ||
1118 | struct ext4_xattr_block_find *bs = NULL; | ||
1119 | char *buffer = NULL, *b_entry_name = NULL; | ||
1120 | size_t min_offs, free; | ||
1121 | int total_ino, total_blk; | ||
1122 | void *base, *start, *end; | ||
1123 | int extra_isize = 0, error = 0, tried_min_extra_isize = 0; | ||
1124 | int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize; | ||
1125 | |||
1126 | down_write(&EXT4_I(inode)->xattr_sem); | ||
1127 | retry: | ||
1128 | if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) { | ||
1129 | up_write(&EXT4_I(inode)->xattr_sem); | ||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | header = IHDR(inode, raw_inode); | ||
1134 | entry = IFIRST(header); | ||
1135 | |||
1136 | /* | ||
1137 | * Check if enough free space is available in the inode to shift the | ||
1138 | * entries ahead by new_extra_isize. | ||
1139 | */ | ||
1140 | |||
1141 | base = start = entry; | ||
1142 | end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size; | ||
1143 | min_offs = end - base; | ||
1144 | last = entry; | ||
1145 | total_ino = sizeof(struct ext4_xattr_ibody_header); | ||
1146 | |||
1147 | free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); | ||
1148 | if (free >= new_extra_isize) { | ||
1149 | entry = IFIRST(header); | ||
1150 | ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize | ||
1151 | - new_extra_isize, (void *)raw_inode + | ||
1152 | EXT4_GOOD_OLD_INODE_SIZE + new_extra_isize, | ||
1153 | (void *)header, total_ino, | ||
1154 | inode->i_sb->s_blocksize); | ||
1155 | EXT4_I(inode)->i_extra_isize = new_extra_isize; | ||
1156 | error = 0; | ||
1157 | goto cleanup; | ||
1158 | } | ||
1159 | |||
1160 | /* | ||
1161 | * Enough free space isn't available in the inode, check if | ||
1162 | * EA block can hold new_extra_isize bytes. | ||
1163 | */ | ||
1164 | if (EXT4_I(inode)->i_file_acl) { | ||
1165 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | ||
1166 | error = -EIO; | ||
1167 | if (!bh) | ||
1168 | goto cleanup; | ||
1169 | if (ext4_xattr_check_block(bh)) { | ||
1170 | ext4_error(inode->i_sb, __FUNCTION__, | ||
1171 | "inode %lu: bad block %llu", inode->i_ino, | ||
1172 | EXT4_I(inode)->i_file_acl); | ||
1173 | error = -EIO; | ||
1174 | goto cleanup; | ||
1175 | } | ||
1176 | base = BHDR(bh); | ||
1177 | first = BFIRST(bh); | ||
1178 | end = bh->b_data + bh->b_size; | ||
1179 | min_offs = end - base; | ||
1180 | free = ext4_xattr_free_space(first, &min_offs, base, | ||
1181 | &total_blk); | ||
1182 | if (free < new_extra_isize) { | ||
1183 | if (!tried_min_extra_isize && s_min_extra_isize) { | ||
1184 | tried_min_extra_isize++; | ||
1185 | new_extra_isize = s_min_extra_isize; | ||
1186 | brelse(bh); | ||
1187 | goto retry; | ||
1188 | } | ||
1189 | error = -1; | ||
1190 | goto cleanup; | ||
1191 | } | ||
1192 | } else { | ||
1193 | free = inode->i_sb->s_blocksize; | ||
1194 | } | ||
1195 | |||
1196 | while (new_extra_isize > 0) { | ||
1197 | size_t offs, size, entry_size; | ||
1198 | struct ext4_xattr_entry *small_entry = NULL; | ||
1199 | struct ext4_xattr_info i = { | ||
1200 | .value = NULL, | ||
1201 | .value_len = 0, | ||
1202 | }; | ||
1203 | unsigned int total_size; /* EA entry size + value size */ | ||
1204 | unsigned int shift_bytes; /* No. of bytes to shift EAs by? */ | ||
1205 | unsigned int min_total_size = ~0U; | ||
1206 | |||
1207 | is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); | ||
1208 | bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS); | ||
1209 | if (!is || !bs) { | ||
1210 | error = -ENOMEM; | ||
1211 | goto cleanup; | ||
1212 | } | ||
1213 | |||
1214 | is->s.not_found = -ENODATA; | ||
1215 | bs->s.not_found = -ENODATA; | ||
1216 | is->iloc.bh = NULL; | ||
1217 | bs->bh = NULL; | ||
1218 | |||
1219 | last = IFIRST(header); | ||
1220 | /* Find the entry best suited to be pushed into EA block */ | ||
1221 | entry = NULL; | ||
1222 | for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { | ||
1223 | total_size = | ||
1224 | EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) + | ||
1225 | EXT4_XATTR_LEN(last->e_name_len); | ||
1226 | if (total_size <= free && total_size < min_total_size) { | ||
1227 | if (total_size < new_extra_isize) { | ||
1228 | small_entry = last; | ||
1229 | } else { | ||
1230 | entry = last; | ||
1231 | min_total_size = total_size; | ||
1232 | } | ||
1233 | } | ||
1234 | } | ||
1235 | |||
1236 | if (entry == NULL) { | ||
1237 | if (small_entry) { | ||
1238 | entry = small_entry; | ||
1239 | } else { | ||
1240 | if (!tried_min_extra_isize && | ||
1241 | s_min_extra_isize) { | ||
1242 | tried_min_extra_isize++; | ||
1243 | new_extra_isize = s_min_extra_isize; | ||
1244 | goto retry; | ||
1245 | } | ||
1246 | error = -1; | ||
1247 | goto cleanup; | ||
1248 | } | ||
1249 | } | ||
1250 | offs = le16_to_cpu(entry->e_value_offs); | ||
1251 | size = le32_to_cpu(entry->e_value_size); | ||
1252 | entry_size = EXT4_XATTR_LEN(entry->e_name_len); | ||
1253 | i.name_index = entry->e_name_index, | ||
1254 | buffer = kmalloc(EXT4_XATTR_SIZE(size), GFP_NOFS); | ||
1255 | b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS); | ||
1256 | if (!buffer || !b_entry_name) { | ||
1257 | error = -ENOMEM; | ||
1258 | goto cleanup; | ||
1259 | } | ||
1260 | /* Save the entry name and the entry value */ | ||
1261 | memcpy(buffer, (void *)IFIRST(header) + offs, | ||
1262 | EXT4_XATTR_SIZE(size)); | ||
1263 | memcpy(b_entry_name, entry->e_name, entry->e_name_len); | ||
1264 | b_entry_name[entry->e_name_len] = '\0'; | ||
1265 | i.name = b_entry_name; | ||
1266 | |||
1267 | error = ext4_get_inode_loc(inode, &is->iloc); | ||
1268 | if (error) | ||
1269 | goto cleanup; | ||
1270 | |||
1271 | error = ext4_xattr_ibody_find(inode, &i, is); | ||
1272 | if (error) | ||
1273 | goto cleanup; | ||
1274 | |||
1275 | /* Remove the chosen entry from the inode */ | ||
1276 | error = ext4_xattr_ibody_set(handle, inode, &i, is); | ||
1277 | |||
1278 | entry = IFIRST(header); | ||
1279 | if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize) | ||
1280 | shift_bytes = new_extra_isize; | ||
1281 | else | ||
1282 | shift_bytes = entry_size + size; | ||
1283 | /* Adjust the offsets and shift the remaining entries ahead */ | ||
1284 | ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize - | ||
1285 | shift_bytes, (void *)raw_inode + | ||
1286 | EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes, | ||
1287 | (void *)header, total_ino - entry_size, | ||
1288 | inode->i_sb->s_blocksize); | ||
1289 | |||
1290 | extra_isize += shift_bytes; | ||
1291 | new_extra_isize -= shift_bytes; | ||
1292 | EXT4_I(inode)->i_extra_isize = extra_isize; | ||
1293 | |||
1294 | i.name = b_entry_name; | ||
1295 | i.value = buffer; | ||
1296 | i.value_len = cpu_to_le32(size); | ||
1297 | error = ext4_xattr_block_find(inode, &i, bs); | ||
1298 | if (error) | ||
1299 | goto cleanup; | ||
1300 | |||
1301 | /* Add entry which was removed from the inode into the block */ | ||
1302 | error = ext4_xattr_block_set(handle, inode, &i, bs); | ||
1303 | if (error) | ||
1304 | goto cleanup; | ||
1305 | kfree(b_entry_name); | ||
1306 | kfree(buffer); | ||
1307 | brelse(is->iloc.bh); | ||
1308 | kfree(is); | ||
1309 | kfree(bs); | ||
1310 | } | ||
1311 | brelse(bh); | ||
1312 | up_write(&EXT4_I(inode)->xattr_sem); | ||
1313 | return 0; | ||
1314 | |||
1315 | cleanup: | ||
1316 | kfree(b_entry_name); | ||
1317 | kfree(buffer); | ||
1318 | if (is) | ||
1319 | brelse(is->iloc.bh); | ||
1320 | kfree(is); | ||
1321 | kfree(bs); | ||
1322 | brelse(bh); | ||
1323 | up_write(&EXT4_I(inode)->xattr_sem); | ||
1324 | return error; | ||
1325 | } | ||
1326 | |||
1327 | |||
1328 | |||
1329 | /* | ||
1070 | * ext4_xattr_delete_inode() | 1330 | * ext4_xattr_delete_inode() |
1071 | * | 1331 | * |
1072 | * Free extended attribute resources associated with this inode. This | 1332 | * Free extended attribute resources associated with this inode. This |
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 79432b35398f..d7f5d6a12651 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h | |||
@@ -56,6 +56,13 @@ struct ext4_xattr_entry { | |||
56 | #define EXT4_XATTR_SIZE(size) \ | 56 | #define EXT4_XATTR_SIZE(size) \ |
57 | (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND) | 57 | (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND) |
58 | 58 | ||
59 | #define IHDR(inode, raw_inode) \ | ||
60 | ((struct ext4_xattr_ibody_header *) \ | ||
61 | ((void *)raw_inode + \ | ||
62 | EXT4_GOOD_OLD_INODE_SIZE + \ | ||
63 | EXT4_I(inode)->i_extra_isize)) | ||
64 | #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1)) | ||
65 | |||
59 | # ifdef CONFIG_EXT4DEV_FS_XATTR | 66 | # ifdef CONFIG_EXT4DEV_FS_XATTR |
60 | 67 | ||
61 | extern struct xattr_handler ext4_xattr_user_handler; | 68 | extern struct xattr_handler ext4_xattr_user_handler; |
@@ -74,6 +81,9 @@ extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, | |||
74 | extern void ext4_xattr_delete_inode(handle_t *, struct inode *); | 81 | extern void ext4_xattr_delete_inode(handle_t *, struct inode *); |
75 | extern void ext4_xattr_put_super(struct super_block *); | 82 | extern void ext4_xattr_put_super(struct super_block *); |
76 | 83 | ||
84 | extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | ||
85 | struct ext4_inode *raw_inode, handle_t *handle); | ||
86 | |||
77 | extern int init_ext4_xattr(void); | 87 | extern int init_ext4_xattr(void); |
78 | extern void exit_ext4_xattr(void); | 88 | extern void exit_ext4_xattr(void); |
79 | 89 | ||
@@ -129,6 +139,13 @@ exit_ext4_xattr(void) | |||
129 | { | 139 | { |
130 | } | 140 | } |
131 | 141 | ||
142 | static inline int | ||
143 | ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | ||
144 | struct ext4_inode *raw_inode, handle_t *handle) | ||
145 | { | ||
146 | return -EOPNOTSUPP; | ||
147 | } | ||
148 | |||
132 | #define ext4_xattr_handlers NULL | 149 | #define ext4_xattr_handlers NULL |
133 | 150 | ||
134 | # endif /* CONFIG_EXT4DEV_FS_XATTR */ | 151 | # endif /* CONFIG_EXT4DEV_FS_XATTR */ |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 78d63b818f0b..f290cb7cb834 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/kthread.h> | 35 | #include <linux/kthread.h> |
36 | #include <linux/poison.h> | 36 | #include <linux/poison.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/debugfs.h> | ||
38 | 39 | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
40 | #include <asm/page.h> | 41 | #include <asm/page.h> |
@@ -528,7 +529,7 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid) | |||
528 | { | 529 | { |
529 | int err = 0; | 530 | int err = 0; |
530 | 531 | ||
531 | #ifdef CONFIG_JBD_DEBUG | 532 | #ifdef CONFIG_JBD2_DEBUG |
532 | spin_lock(&journal->j_state_lock); | 533 | spin_lock(&journal->j_state_lock); |
533 | if (!tid_geq(journal->j_commit_request, tid)) { | 534 | if (!tid_geq(journal->j_commit_request, tid)) { |
534 | printk(KERN_EMERG | 535 | printk(KERN_EMERG |
@@ -1709,7 +1710,7 @@ void jbd2_slab_free(void *ptr, size_t size) | |||
1709 | * Journal_head storage management | 1710 | * Journal_head storage management |
1710 | */ | 1711 | */ |
1711 | static struct kmem_cache *jbd2_journal_head_cache; | 1712 | static struct kmem_cache *jbd2_journal_head_cache; |
1712 | #ifdef CONFIG_JBD_DEBUG | 1713 | #ifdef CONFIG_JBD2_DEBUG |
1713 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); | 1714 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); |
1714 | #endif | 1715 | #endif |
1715 | 1716 | ||
@@ -1747,7 +1748,7 @@ static struct journal_head *journal_alloc_journal_head(void) | |||
1747 | struct journal_head *ret; | 1748 | struct journal_head *ret; |
1748 | static unsigned long last_warning; | 1749 | static unsigned long last_warning; |
1749 | 1750 | ||
1750 | #ifdef CONFIG_JBD_DEBUG | 1751 | #ifdef CONFIG_JBD2_DEBUG |
1751 | atomic_inc(&nr_journal_heads); | 1752 | atomic_inc(&nr_journal_heads); |
1752 | #endif | 1753 | #endif |
1753 | ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); | 1754 | ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); |
@@ -1768,7 +1769,7 @@ static struct journal_head *journal_alloc_journal_head(void) | |||
1768 | 1769 | ||
1769 | static void journal_free_journal_head(struct journal_head *jh) | 1770 | static void journal_free_journal_head(struct journal_head *jh) |
1770 | { | 1771 | { |
1771 | #ifdef CONFIG_JBD_DEBUG | 1772 | #ifdef CONFIG_JBD2_DEBUG |
1772 | atomic_dec(&nr_journal_heads); | 1773 | atomic_dec(&nr_journal_heads); |
1773 | memset(jh, JBD_POISON_FREE, sizeof(*jh)); | 1774 | memset(jh, JBD_POISON_FREE, sizeof(*jh)); |
1774 | #endif | 1775 | #endif |
@@ -1951,64 +1952,50 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) | |||
1951 | } | 1952 | } |
1952 | 1953 | ||
1953 | /* | 1954 | /* |
1954 | * /proc tunables | 1955 | * debugfs tunables |
1955 | */ | 1956 | */ |
1956 | #if defined(CONFIG_JBD_DEBUG) | 1957 | #if defined(CONFIG_JBD2_DEBUG) |
1957 | int jbd2_journal_enable_debug; | 1958 | u8 jbd2_journal_enable_debug; |
1958 | EXPORT_SYMBOL(jbd2_journal_enable_debug); | 1959 | EXPORT_SYMBOL(jbd2_journal_enable_debug); |
1959 | #endif | 1960 | #endif |
1960 | 1961 | ||
1961 | #if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS) | 1962 | #if defined(CONFIG_JBD2_DEBUG) && defined(CONFIG_DEBUG_FS) |
1962 | 1963 | ||
1963 | static struct proc_dir_entry *proc_jbd_debug; | 1964 | #define JBD2_DEBUG_NAME "jbd2-debug" |
1964 | 1965 | ||
1965 | static int read_jbd_debug(char *page, char **start, off_t off, | 1966 | struct dentry *jbd2_debugfs_dir, *jbd2_debug; |
1966 | int count, int *eof, void *data) | ||
1967 | { | ||
1968 | int ret; | ||
1969 | 1967 | ||
1970 | ret = sprintf(page + off, "%d\n", jbd2_journal_enable_debug); | 1968 | static void __init jbd2_create_debugfs_entry(void) |
1971 | *eof = 1; | 1969 | { |
1972 | return ret; | 1970 | jbd2_debugfs_dir = debugfs_create_dir("jbd2", NULL); |
1971 | if (jbd2_debugfs_dir) | ||
1972 | jbd2_debug = debugfs_create_u8(JBD2_DEBUG_NAME, S_IRUGO, | ||
1973 | jbd2_debugfs_dir, | ||
1974 | &jbd2_journal_enable_debug); | ||
1973 | } | 1975 | } |
1974 | 1976 | ||
1975 | static int write_jbd_debug(struct file *file, const char __user *buffer, | 1977 | static void __exit jbd2_remove_debugfs_entry(void) |
1976 | unsigned long count, void *data) | ||
1977 | { | 1978 | { |
1978 | char buf[32]; | 1979 | if (jbd2_debug) |
1979 | 1980 | debugfs_remove(jbd2_debug); | |
1980 | if (count > ARRAY_SIZE(buf) - 1) | 1981 | if (jbd2_debugfs_dir) |
1981 | count = ARRAY_SIZE(buf) - 1; | 1982 | debugfs_remove(jbd2_debugfs_dir); |
1982 | if (copy_from_user(buf, buffer, count)) | ||
1983 | return -EFAULT; | ||
1984 | buf[ARRAY_SIZE(buf) - 1] = '\0'; | ||
1985 | jbd2_journal_enable_debug = simple_strtoul(buf, NULL, 10); | ||
1986 | return count; | ||
1987 | } | 1983 | } |
1988 | 1984 | ||
1989 | #define JBD_PROC_NAME "sys/fs/jbd2-debug" | 1985 | #else |
1990 | 1986 | ||
1991 | static void __init create_jbd_proc_entry(void) | 1987 | static void __init jbd2_create_debugfs_entry(void) |
1992 | { | 1988 | { |
1993 | proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL); | 1989 | do { |
1994 | if (proc_jbd_debug) { | 1990 | } while (0); |
1995 | /* Why is this so hard? */ | ||
1996 | proc_jbd_debug->read_proc = read_jbd_debug; | ||
1997 | proc_jbd_debug->write_proc = write_jbd_debug; | ||
1998 | } | ||
1999 | } | 1991 | } |
2000 | 1992 | ||
2001 | static void __exit jbd2_remove_jbd_proc_entry(void) | 1993 | static void __exit jbd2_remove_debugfs_entry(void) |
2002 | { | 1994 | { |
2003 | if (proc_jbd_debug) | 1995 | do { |
2004 | remove_proc_entry(JBD_PROC_NAME, NULL); | 1996 | } while (0); |
2005 | } | 1997 | } |
2006 | 1998 | ||
2007 | #else | ||
2008 | |||
2009 | #define create_jbd_proc_entry() do {} while (0) | ||
2010 | #define jbd2_remove_jbd_proc_entry() do {} while (0) | ||
2011 | |||
2012 | #endif | 1999 | #endif |
2013 | 2000 | ||
2014 | struct kmem_cache *jbd2_handle_cache; | 2001 | struct kmem_cache *jbd2_handle_cache; |
@@ -2067,18 +2054,18 @@ static int __init journal_init(void) | |||
2067 | ret = journal_init_caches(); | 2054 | ret = journal_init_caches(); |
2068 | if (ret != 0) | 2055 | if (ret != 0) |
2069 | jbd2_journal_destroy_caches(); | 2056 | jbd2_journal_destroy_caches(); |
2070 | create_jbd_proc_entry(); | 2057 | jbd2_create_debugfs_entry(); |
2071 | return ret; | 2058 | return ret; |
2072 | } | 2059 | } |
2073 | 2060 | ||
2074 | static void __exit journal_exit(void) | 2061 | static void __exit journal_exit(void) |
2075 | { | 2062 | { |
2076 | #ifdef CONFIG_JBD_DEBUG | 2063 | #ifdef CONFIG_JBD2_DEBUG |
2077 | int n = atomic_read(&nr_journal_heads); | 2064 | int n = atomic_read(&nr_journal_heads); |
2078 | if (n) | 2065 | if (n) |
2079 | printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); | 2066 | printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); |
2080 | #endif | 2067 | #endif |
2081 | jbd2_remove_jbd_proc_entry(); | 2068 | jbd2_remove_debugfs_entry(); |
2082 | jbd2_journal_destroy_caches(); | 2069 | jbd2_journal_destroy_caches(); |
2083 | } | 2070 | } |
2084 | 2071 | ||
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 395c92a04ac9..e7730a045b93 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c | |||
@@ -295,7 +295,7 @@ int jbd2_journal_skip_recovery(journal_t *journal) | |||
295 | printk(KERN_ERR "JBD: error %d scanning journal\n", err); | 295 | printk(KERN_ERR "JBD: error %d scanning journal\n", err); |
296 | ++journal->j_transaction_sequence; | 296 | ++journal->j_transaction_sequence; |
297 | } else { | 297 | } else { |
298 | #ifdef CONFIG_JBD_DEBUG | 298 | #ifdef CONFIG_JBD2_DEBUG |
299 | int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); | 299 | int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); |
300 | #endif | 300 | #endif |
301 | jbd_debug(0, | 301 | jbd_debug(0, |
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/syscalls.h> | 26 | #include <linux/syscalls.h> |
27 | #include <linux/rcupdate.h> | 27 | #include <linux/rcupdate.h> |
28 | #include <linux/audit.h> | 28 | #include <linux/audit.h> |
29 | #include <linux/falloc.h> | ||
29 | 30 | ||
30 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 31 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
31 | { | 32 | { |
@@ -352,6 +353,64 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) | |||
352 | } | 353 | } |
353 | #endif | 354 | #endif |
354 | 355 | ||
356 | asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len) | ||
357 | { | ||
358 | struct file *file; | ||
359 | struct inode *inode; | ||
360 | long ret = -EINVAL; | ||
361 | |||
362 | if (offset < 0 || len <= 0) | ||
363 | goto out; | ||
364 | |||
365 | /* Return error if mode is not supported */ | ||
366 | ret = -EOPNOTSUPP; | ||
367 | if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) | ||
368 | goto out; | ||
369 | |||
370 | ret = -EBADF; | ||
371 | file = fget(fd); | ||
372 | if (!file) | ||
373 | goto out; | ||
374 | if (!(file->f_mode & FMODE_WRITE)) | ||
375 | goto out_fput; | ||
376 | /* | ||
377 | * Revalidate the write permissions, in case security policy has | ||
378 | * changed since the files were opened. | ||
379 | */ | ||
380 | ret = security_file_permission(file, MAY_WRITE); | ||
381 | if (ret) | ||
382 | goto out_fput; | ||
383 | |||
384 | inode = file->f_path.dentry->d_inode; | ||
385 | |||
386 | ret = -ESPIPE; | ||
387 | if (S_ISFIFO(inode->i_mode)) | ||
388 | goto out_fput; | ||
389 | |||
390 | ret = -ENODEV; | ||
391 | /* | ||
392 | * Let individual file system decide if it supports preallocation | ||
393 | * for directories or not. | ||
394 | */ | ||
395 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) | ||
396 | goto out_fput; | ||
397 | |||
398 | ret = -EFBIG; | ||
399 | /* Check for wrap through zero too */ | ||
400 | if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) | ||
401 | goto out_fput; | ||
402 | |||
403 | if (inode->i_op && inode->i_op->fallocate) | ||
404 | ret = inode->i_op->fallocate(inode, mode, offset, len); | ||
405 | else | ||
406 | ret = -ENOSYS; | ||
407 | |||
408 | out_fput: | ||
409 | fput(file); | ||
410 | out: | ||
411 | return ret; | ||
412 | } | ||
413 | |||
355 | /* | 414 | /* |
356 | * access() needs to use the real uid/gid, not the effective uid/gid. | 415 | * access() needs to use the real uid/gid, not the effective uid/gid. |
357 | * We do this by temporarily clearing all FS-related capabilities and | 416 | * We do this by temporarily clearing all FS-related capabilities and |