diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-24 11:37:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-24 11:37:40 -0400 |
commit | a4277bf122e907e4fec509fc0bd9bf5fde30b14e (patch) | |
tree | b359e8b0f7895acda1d6331332e69ea5b14d5f0d /fs | |
parent | 6ae85d6db4871d8dbcb5cc0e9056f97f1ca07061 (diff) | |
parent | b5451f7b2694b04d9f912f6cf09db1729f291996 (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: Fix potential inode allocation soft lockup in Orlov allocator
ext4: Make the extent validity check more paranoid
jbd: use SWRITE_SYNC_PLUG when writing synchronous revoke records
jbd2: use SWRITE_SYNC_PLUG when writing synchronous revoke records
ext4: really print the find_group_flex fallback warning only once
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/extents.c | 18 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 6 | ||||
-rw-r--r-- | fs/jbd/commit.c | 2 | ||||
-rw-r--r-- | fs/jbd/revoke.c | 20 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 3 | ||||
-rw-r--r-- | fs/jbd2/revoke.c | 21 |
6 files changed, 42 insertions, 28 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 2a1cb0979768..e40332158340 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -326,11 +326,14 @@ ext4_ext_max_entries(struct inode *inode, int depth) | |||
326 | 326 | ||
327 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) | 327 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) |
328 | { | 328 | { |
329 | ext4_fsblk_t block = ext_pblock(ext); | 329 | ext4_fsblk_t block = ext_pblock(ext), valid_block; |
330 | int len = ext4_ext_get_actual_len(ext); | 330 | int len = ext4_ext_get_actual_len(ext); |
331 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | 331 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; |
332 | if (unlikely(block < le32_to_cpu(es->s_first_data_block) || | 332 | |
333 | ((block + len) > ext4_blocks_count(es)))) | 333 | valid_block = le32_to_cpu(es->s_first_data_block) + |
334 | EXT4_SB(inode->i_sb)->s_gdb_count; | ||
335 | if (unlikely(block <= valid_block || | ||
336 | ((block + len) > ext4_blocks_count(es)))) | ||
334 | return 0; | 337 | return 0; |
335 | else | 338 | else |
336 | return 1; | 339 | return 1; |
@@ -339,10 +342,13 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) | |||
339 | static int ext4_valid_extent_idx(struct inode *inode, | 342 | static int ext4_valid_extent_idx(struct inode *inode, |
340 | struct ext4_extent_idx *ext_idx) | 343 | struct ext4_extent_idx *ext_idx) |
341 | { | 344 | { |
342 | ext4_fsblk_t block = idx_pblock(ext_idx); | 345 | ext4_fsblk_t block = idx_pblock(ext_idx), valid_block; |
343 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | 346 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; |
344 | if (unlikely(block < le32_to_cpu(es->s_first_data_block) || | 347 | |
345 | (block >= ext4_blocks_count(es)))) | 348 | valid_block = le32_to_cpu(es->s_first_data_block) + |
349 | EXT4_SB(inode->i_sb)->s_gdb_count; | ||
350 | if (unlikely(block <= valid_block || | ||
351 | (block >= ext4_blocks_count(es)))) | ||
346 | return 0; | 352 | return 0; |
347 | else | 353 | else |
348 | return 1; | 354 | return 1; |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 47b84e8df568..f18e0a08a6b5 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -585,6 +585,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
585 | fallback: | 585 | fallback: |
586 | ngroups = sbi->s_groups_count; | 586 | ngroups = sbi->s_groups_count; |
587 | avefreei = freei / ngroups; | 587 | avefreei = freei / ngroups; |
588 | fallback_retry: | ||
588 | parent_group = EXT4_I(parent)->i_block_group; | 589 | parent_group = EXT4_I(parent)->i_block_group; |
589 | for (i = 0; i < ngroups; i++) { | 590 | for (i = 0; i < ngroups; i++) { |
590 | grp = (parent_group + i) % ngroups; | 591 | grp = (parent_group + i) % ngroups; |
@@ -602,7 +603,7 @@ fallback: | |||
602 | * filesystems the above test can fail to find any blockgroups | 603 | * filesystems the above test can fail to find any blockgroups |
603 | */ | 604 | */ |
604 | avefreei = 0; | 605 | avefreei = 0; |
605 | goto fallback; | 606 | goto fallback_retry; |
606 | } | 607 | } |
607 | 608 | ||
608 | return -1; | 609 | return -1; |
@@ -831,11 +832,12 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
831 | ret2 = find_group_flex(sb, dir, &group); | 832 | ret2 = find_group_flex(sb, dir, &group); |
832 | if (ret2 == -1) { | 833 | if (ret2 == -1) { |
833 | ret2 = find_group_other(sb, dir, &group, mode); | 834 | ret2 = find_group_other(sb, dir, &group, mode); |
834 | if (ret2 == 0 && once) | 835 | if (ret2 == 0 && once) { |
835 | once = 0; | 836 | once = 0; |
836 | printk(KERN_NOTICE "ext4: find_group_flex " | 837 | printk(KERN_NOTICE "ext4: find_group_flex " |
837 | "failed, fallback succeeded dir %lu\n", | 838 | "failed, fallback succeeded dir %lu\n", |
838 | dir->i_ino); | 839 | dir->i_ino); |
840 | } | ||
839 | } | 841 | } |
840 | goto got_group; | 842 | goto got_group; |
841 | } | 843 | } |
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index a8e8513a78a9..06560c520f49 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -502,7 +502,7 @@ void journal_commit_transaction(journal_t *journal) | |||
502 | err = 0; | 502 | err = 0; |
503 | } | 503 | } |
504 | 504 | ||
505 | journal_write_revoke_records(journal, commit_transaction); | 505 | journal_write_revoke_records(journal, commit_transaction, write_op); |
506 | 506 | ||
507 | /* | 507 | /* |
508 | * If we found any dirty or locked buffers, then we should have | 508 | * If we found any dirty or locked buffers, then we should have |
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index 3e9afc2a91d2..da6cd9bdaabc 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/slab.h> | 86 | #include <linux/slab.h> |
87 | #include <linux/list.h> | 87 | #include <linux/list.h> |
88 | #include <linux/init.h> | 88 | #include <linux/init.h> |
89 | #include <linux/bio.h> | ||
89 | #endif | 90 | #endif |
90 | #include <linux/log2.h> | 91 | #include <linux/log2.h> |
91 | 92 | ||
@@ -118,8 +119,8 @@ struct jbd_revoke_table_s | |||
118 | #ifdef __KERNEL__ | 119 | #ifdef __KERNEL__ |
119 | static void write_one_revoke_record(journal_t *, transaction_t *, | 120 | static void write_one_revoke_record(journal_t *, transaction_t *, |
120 | struct journal_head **, int *, | 121 | struct journal_head **, int *, |
121 | struct jbd_revoke_record_s *); | 122 | struct jbd_revoke_record_s *, int); |
122 | static void flush_descriptor(journal_t *, struct journal_head *, int); | 123 | static void flush_descriptor(journal_t *, struct journal_head *, int, int); |
123 | #endif | 124 | #endif |
124 | 125 | ||
125 | /* Utility functions to maintain the revoke table */ | 126 | /* Utility functions to maintain the revoke table */ |
@@ -500,7 +501,7 @@ void journal_switch_revoke_table(journal_t *journal) | |||
500 | * revoke hash, deleting the entries as we go. | 501 | * revoke hash, deleting the entries as we go. |
501 | */ | 502 | */ |
502 | void journal_write_revoke_records(journal_t *journal, | 503 | void journal_write_revoke_records(journal_t *journal, |
503 | transaction_t *transaction) | 504 | transaction_t *transaction, int write_op) |
504 | { | 505 | { |
505 | struct journal_head *descriptor; | 506 | struct journal_head *descriptor; |
506 | struct jbd_revoke_record_s *record; | 507 | struct jbd_revoke_record_s *record; |
@@ -524,14 +525,14 @@ void journal_write_revoke_records(journal_t *journal, | |||
524 | hash_list->next; | 525 | hash_list->next; |
525 | write_one_revoke_record(journal, transaction, | 526 | write_one_revoke_record(journal, transaction, |
526 | &descriptor, &offset, | 527 | &descriptor, &offset, |
527 | record); | 528 | record, write_op); |
528 | count++; | 529 | count++; |
529 | list_del(&record->hash); | 530 | list_del(&record->hash); |
530 | kmem_cache_free(revoke_record_cache, record); | 531 | kmem_cache_free(revoke_record_cache, record); |
531 | } | 532 | } |
532 | } | 533 | } |
533 | if (descriptor) | 534 | if (descriptor) |
534 | flush_descriptor(journal, descriptor, offset); | 535 | flush_descriptor(journal, descriptor, offset, write_op); |
535 | jbd_debug(1, "Wrote %d revoke records\n", count); | 536 | jbd_debug(1, "Wrote %d revoke records\n", count); |
536 | } | 537 | } |
537 | 538 | ||
@@ -544,7 +545,8 @@ static void write_one_revoke_record(journal_t *journal, | |||
544 | transaction_t *transaction, | 545 | transaction_t *transaction, |
545 | struct journal_head **descriptorp, | 546 | struct journal_head **descriptorp, |
546 | int *offsetp, | 547 | int *offsetp, |
547 | struct jbd_revoke_record_s *record) | 548 | struct jbd_revoke_record_s *record, |
549 | int write_op) | ||
548 | { | 550 | { |
549 | struct journal_head *descriptor; | 551 | struct journal_head *descriptor; |
550 | int offset; | 552 | int offset; |
@@ -563,7 +565,7 @@ static void write_one_revoke_record(journal_t *journal, | |||
563 | /* Make sure we have a descriptor with space left for the record */ | 565 | /* Make sure we have a descriptor with space left for the record */ |
564 | if (descriptor) { | 566 | if (descriptor) { |
565 | if (offset == journal->j_blocksize) { | 567 | if (offset == journal->j_blocksize) { |
566 | flush_descriptor(journal, descriptor, offset); | 568 | flush_descriptor(journal, descriptor, offset, write_op); |
567 | descriptor = NULL; | 569 | descriptor = NULL; |
568 | } | 570 | } |
569 | } | 571 | } |
@@ -600,7 +602,7 @@ static void write_one_revoke_record(journal_t *journal, | |||
600 | 602 | ||
601 | static void flush_descriptor(journal_t *journal, | 603 | static void flush_descriptor(journal_t *journal, |
602 | struct journal_head *descriptor, | 604 | struct journal_head *descriptor, |
603 | int offset) | 605 | int offset, int write_op) |
604 | { | 606 | { |
605 | journal_revoke_header_t *header; | 607 | journal_revoke_header_t *header; |
606 | struct buffer_head *bh = jh2bh(descriptor); | 608 | struct buffer_head *bh = jh2bh(descriptor); |
@@ -615,7 +617,7 @@ static void flush_descriptor(journal_t *journal, | |||
615 | set_buffer_jwrite(bh); | 617 | set_buffer_jwrite(bh); |
616 | BUFFER_TRACE(bh, "write"); | 618 | BUFFER_TRACE(bh, "write"); |
617 | set_buffer_dirty(bh); | 619 | set_buffer_dirty(bh); |
618 | ll_rw_block(SWRITE, 1, &bh); | 620 | ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh); |
619 | } | 621 | } |
620 | #endif | 622 | #endif |
621 | 623 | ||
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 073c8c3df7cd..0b7d3b8226fd 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -506,7 +506,8 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
506 | if (err) | 506 | if (err) |
507 | jbd2_journal_abort(journal, err); | 507 | jbd2_journal_abort(journal, err); |
508 | 508 | ||
509 | jbd2_journal_write_revoke_records(journal, commit_transaction); | 509 | jbd2_journal_write_revoke_records(journal, commit_transaction, |
510 | write_op); | ||
510 | 511 | ||
511 | jbd_debug(3, "JBD: commit phase 2\n"); | 512 | jbd_debug(3, "JBD: commit phase 2\n"); |
512 | 513 | ||
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index bbe6d592d8b3..a360b06af2e3 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/slab.h> | 86 | #include <linux/slab.h> |
87 | #include <linux/list.h> | 87 | #include <linux/list.h> |
88 | #include <linux/init.h> | 88 | #include <linux/init.h> |
89 | #include <linux/bio.h> | ||
89 | #endif | 90 | #endif |
90 | #include <linux/log2.h> | 91 | #include <linux/log2.h> |
91 | 92 | ||
@@ -118,8 +119,8 @@ struct jbd2_revoke_table_s | |||
118 | #ifdef __KERNEL__ | 119 | #ifdef __KERNEL__ |
119 | static void write_one_revoke_record(journal_t *, transaction_t *, | 120 | static void write_one_revoke_record(journal_t *, transaction_t *, |
120 | struct journal_head **, int *, | 121 | struct journal_head **, int *, |
121 | struct jbd2_revoke_record_s *); | 122 | struct jbd2_revoke_record_s *, int); |
122 | static void flush_descriptor(journal_t *, struct journal_head *, int); | 123 | static void flush_descriptor(journal_t *, struct journal_head *, int, int); |
123 | #endif | 124 | #endif |
124 | 125 | ||
125 | /* Utility functions to maintain the revoke table */ | 126 | /* Utility functions to maintain the revoke table */ |
@@ -499,7 +500,8 @@ void jbd2_journal_switch_revoke_table(journal_t *journal) | |||
499 | * revoke hash, deleting the entries as we go. | 500 | * revoke hash, deleting the entries as we go. |
500 | */ | 501 | */ |
501 | void jbd2_journal_write_revoke_records(journal_t *journal, | 502 | void jbd2_journal_write_revoke_records(journal_t *journal, |
502 | transaction_t *transaction) | 503 | transaction_t *transaction, |
504 | int write_op) | ||
503 | { | 505 | { |
504 | struct journal_head *descriptor; | 506 | struct journal_head *descriptor; |
505 | struct jbd2_revoke_record_s *record; | 507 | struct jbd2_revoke_record_s *record; |
@@ -523,14 +525,14 @@ void jbd2_journal_write_revoke_records(journal_t *journal, | |||
523 | hash_list->next; | 525 | hash_list->next; |
524 | write_one_revoke_record(journal, transaction, | 526 | write_one_revoke_record(journal, transaction, |
525 | &descriptor, &offset, | 527 | &descriptor, &offset, |
526 | record); | 528 | record, write_op); |
527 | count++; | 529 | count++; |
528 | list_del(&record->hash); | 530 | list_del(&record->hash); |
529 | kmem_cache_free(jbd2_revoke_record_cache, record); | 531 | kmem_cache_free(jbd2_revoke_record_cache, record); |
530 | } | 532 | } |
531 | } | 533 | } |
532 | if (descriptor) | 534 | if (descriptor) |
533 | flush_descriptor(journal, descriptor, offset); | 535 | flush_descriptor(journal, descriptor, offset, write_op); |
534 | jbd_debug(1, "Wrote %d revoke records\n", count); | 536 | jbd_debug(1, "Wrote %d revoke records\n", count); |
535 | } | 537 | } |
536 | 538 | ||
@@ -543,7 +545,8 @@ static void write_one_revoke_record(journal_t *journal, | |||
543 | transaction_t *transaction, | 545 | transaction_t *transaction, |
544 | struct journal_head **descriptorp, | 546 | struct journal_head **descriptorp, |
545 | int *offsetp, | 547 | int *offsetp, |
546 | struct jbd2_revoke_record_s *record) | 548 | struct jbd2_revoke_record_s *record, |
549 | int write_op) | ||
547 | { | 550 | { |
548 | struct journal_head *descriptor; | 551 | struct journal_head *descriptor; |
549 | int offset; | 552 | int offset; |
@@ -562,7 +565,7 @@ static void write_one_revoke_record(journal_t *journal, | |||
562 | /* Make sure we have a descriptor with space left for the record */ | 565 | /* Make sure we have a descriptor with space left for the record */ |
563 | if (descriptor) { | 566 | if (descriptor) { |
564 | if (offset == journal->j_blocksize) { | 567 | if (offset == journal->j_blocksize) { |
565 | flush_descriptor(journal, descriptor, offset); | 568 | flush_descriptor(journal, descriptor, offset, write_op); |
566 | descriptor = NULL; | 569 | descriptor = NULL; |
567 | } | 570 | } |
568 | } | 571 | } |
@@ -607,7 +610,7 @@ static void write_one_revoke_record(journal_t *journal, | |||
607 | 610 | ||
608 | static void flush_descriptor(journal_t *journal, | 611 | static void flush_descriptor(journal_t *journal, |
609 | struct journal_head *descriptor, | 612 | struct journal_head *descriptor, |
610 | int offset) | 613 | int offset, int write_op) |
611 | { | 614 | { |
612 | jbd2_journal_revoke_header_t *header; | 615 | jbd2_journal_revoke_header_t *header; |
613 | struct buffer_head *bh = jh2bh(descriptor); | 616 | struct buffer_head *bh = jh2bh(descriptor); |
@@ -622,7 +625,7 @@ static void flush_descriptor(journal_t *journal, | |||
622 | set_buffer_jwrite(bh); | 625 | set_buffer_jwrite(bh); |
623 | BUFFER_TRACE(bh, "write"); | 626 | BUFFER_TRACE(bh, "write"); |
624 | set_buffer_dirty(bh); | 627 | set_buffer_dirty(bh); |
625 | ll_rw_block(SWRITE, 1, &bh); | 628 | ll_rw_block((write_op == WRITE) ? SWRITE : SWRITE_SYNC_PLUG, 1, &bh); |
626 | } | 629 | } |
627 | #endif | 630 | #endif |
628 | 631 | ||