diff options
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 01c235bc2054..5d047a030a73 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -683,6 +683,26 @@ static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
683 | ext3_nfs_get_inode); | 683 | ext3_nfs_get_inode); |
684 | } | 684 | } |
685 | 685 | ||
686 | /* | ||
687 | * Try to release metadata pages (indirect blocks, directories) which are | ||
688 | * mapped via the block device. Since these pages could have journal heads | ||
689 | * which would prevent try_to_free_buffers() from freeing them, we must use | ||
690 | * jbd layer's try_to_free_buffers() function to release them. | ||
691 | */ | ||
692 | static int bdev_try_to_free_page(struct super_block *sb, struct page *page, | ||
693 | gfp_t wait) | ||
694 | { | ||
695 | journal_t *journal = EXT3_SB(sb)->s_journal; | ||
696 | |||
697 | WARN_ON(PageChecked(page)); | ||
698 | if (!page_has_buffers(page)) | ||
699 | return 0; | ||
700 | if (journal) | ||
701 | return journal_try_to_free_buffers(journal, page, | ||
702 | wait & ~__GFP_WAIT); | ||
703 | return try_to_free_buffers(page); | ||
704 | } | ||
705 | |||
686 | #ifdef CONFIG_QUOTA | 706 | #ifdef CONFIG_QUOTA |
687 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") | 707 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") |
688 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) | 708 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) |
@@ -749,6 +769,7 @@ static const struct super_operations ext3_sops = { | |||
749 | .quota_read = ext3_quota_read, | 769 | .quota_read = ext3_quota_read, |
750 | .quota_write = ext3_quota_write, | 770 | .quota_write = ext3_quota_write, |
751 | #endif | 771 | #endif |
772 | .bdev_try_to_free_page = bdev_try_to_free_page, | ||
752 | }; | 773 | }; |
753 | 774 | ||
754 | static const struct export_operations ext3_export_ops = { | 775 | static const struct export_operations ext3_export_ops = { |
@@ -1750,6 +1771,18 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1750 | for (i=0; i < 4; i++) | 1771 | for (i=0; i < 4; i++) |
1751 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); | 1772 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); |
1752 | sbi->s_def_hash_version = es->s_def_hash_version; | 1773 | sbi->s_def_hash_version = es->s_def_hash_version; |
1774 | i = le32_to_cpu(es->s_flags); | ||
1775 | if (i & EXT2_FLAGS_UNSIGNED_HASH) | ||
1776 | sbi->s_hash_unsigned = 3; | ||
1777 | else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { | ||
1778 | #ifdef __CHAR_UNSIGNED__ | ||
1779 | es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); | ||
1780 | sbi->s_hash_unsigned = 3; | ||
1781 | #else | ||
1782 | es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); | ||
1783 | #endif | ||
1784 | sb->s_dirt = 1; | ||
1785 | } | ||
1753 | 1786 | ||
1754 | if (sbi->s_blocks_per_group > blocksize * 8) { | 1787 | if (sbi->s_blocks_per_group > blocksize * 8) { |
1755 | printk (KERN_ERR | 1788 | printk (KERN_ERR |