diff options
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r-- | fs/ext3/super.c | 104 |
1 files changed, 78 insertions, 26 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index f6c94f232ec1..b70d90e08a3c 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -48,8 +48,8 @@ static int ext3_load_journal(struct super_block *, struct ext3_super_block *, | |||
48 | unsigned long journal_devnum); | 48 | unsigned long journal_devnum); |
49 | static int ext3_create_journal(struct super_block *, struct ext3_super_block *, | 49 | static int ext3_create_journal(struct super_block *, struct ext3_super_block *, |
50 | unsigned int); | 50 | unsigned int); |
51 | static void ext3_commit_super (struct super_block * sb, | 51 | static int ext3_commit_super(struct super_block *sb, |
52 | struct ext3_super_block * es, | 52 | struct ext3_super_block *es, |
53 | int sync); | 53 | int sync); |
54 | static void ext3_mark_recovery_complete(struct super_block * sb, | 54 | static void ext3_mark_recovery_complete(struct super_block * sb, |
55 | struct ext3_super_block * es); | 55 | struct ext3_super_block * es); |
@@ -60,9 +60,9 @@ static const char *ext3_decode_error(struct super_block * sb, int errno, | |||
60 | char nbuf[16]); | 60 | char nbuf[16]); |
61 | static int ext3_remount (struct super_block * sb, int * flags, char * data); | 61 | static int ext3_remount (struct super_block * sb, int * flags, char * data); |
62 | static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf); | 62 | static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf); |
63 | static void ext3_unlockfs(struct super_block *sb); | 63 | static int ext3_unfreeze(struct super_block *sb); |
64 | static void ext3_write_super (struct super_block * sb); | 64 | static void ext3_write_super (struct super_block * sb); |
65 | static void ext3_write_super_lockfs(struct super_block *sb); | 65 | static int ext3_freeze(struct super_block *sb); |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * Wrappers for journal_start/end. | 68 | * Wrappers for journal_start/end. |
@@ -439,6 +439,7 @@ static void ext3_put_super (struct super_block * sb) | |||
439 | ext3_blkdev_remove(sbi); | 439 | ext3_blkdev_remove(sbi); |
440 | } | 440 | } |
441 | sb->s_fs_info = NULL; | 441 | sb->s_fs_info = NULL; |
442 | kfree(sbi->s_blockgroup_lock); | ||
442 | kfree(sbi); | 443 | kfree(sbi); |
443 | return; | 444 | return; |
444 | } | 445 | } |
@@ -682,6 +683,26 @@ static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
682 | ext3_nfs_get_inode); | 683 | ext3_nfs_get_inode); |
683 | } | 684 | } |
684 | 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 | |||
685 | #ifdef CONFIG_QUOTA | 706 | #ifdef CONFIG_QUOTA |
686 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") | 707 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") |
687 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) | 708 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) |
@@ -713,7 +734,9 @@ static struct dquot_operations ext3_quota_operations = { | |||
713 | .acquire_dquot = ext3_acquire_dquot, | 734 | .acquire_dquot = ext3_acquire_dquot, |
714 | .release_dquot = ext3_release_dquot, | 735 | .release_dquot = ext3_release_dquot, |
715 | .mark_dirty = ext3_mark_dquot_dirty, | 736 | .mark_dirty = ext3_mark_dquot_dirty, |
716 | .write_info = ext3_write_info | 737 | .write_info = ext3_write_info, |
738 | .alloc_dquot = dquot_alloc, | ||
739 | .destroy_dquot = dquot_destroy, | ||
717 | }; | 740 | }; |
718 | 741 | ||
719 | static struct quotactl_ops ext3_qctl_operations = { | 742 | static struct quotactl_ops ext3_qctl_operations = { |
@@ -736,8 +759,8 @@ static const struct super_operations ext3_sops = { | |||
736 | .put_super = ext3_put_super, | 759 | .put_super = ext3_put_super, |
737 | .write_super = ext3_write_super, | 760 | .write_super = ext3_write_super, |
738 | .sync_fs = ext3_sync_fs, | 761 | .sync_fs = ext3_sync_fs, |
739 | .write_super_lockfs = ext3_write_super_lockfs, | 762 | .freeze_fs = ext3_freeze, |
740 | .unlockfs = ext3_unlockfs, | 763 | .unfreeze_fs = ext3_unfreeze, |
741 | .statfs = ext3_statfs, | 764 | .statfs = ext3_statfs, |
742 | .remount_fs = ext3_remount, | 765 | .remount_fs = ext3_remount, |
743 | .clear_inode = ext3_clear_inode, | 766 | .clear_inode = ext3_clear_inode, |
@@ -746,6 +769,7 @@ static const struct super_operations ext3_sops = { | |||
746 | .quota_read = ext3_quota_read, | 769 | .quota_read = ext3_quota_read, |
747 | .quota_write = ext3_quota_write, | 770 | .quota_write = ext3_quota_write, |
748 | #endif | 771 | #endif |
772 | .bdev_try_to_free_page = bdev_try_to_free_page, | ||
749 | }; | 773 | }; |
750 | 774 | ||
751 | static const struct export_operations ext3_export_ops = { | 775 | static const struct export_operations ext3_export_ops = { |
@@ -1035,8 +1059,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
1035 | case Opt_grpjquota: | 1059 | case Opt_grpjquota: |
1036 | qtype = GRPQUOTA; | 1060 | qtype = GRPQUOTA; |
1037 | set_qf_name: | 1061 | set_qf_name: |
1038 | if ((sb_any_quota_enabled(sb) || | 1062 | if (sb_any_quota_loaded(sb) && |
1039 | sb_any_quota_suspended(sb)) && | ||
1040 | !sbi->s_qf_names[qtype]) { | 1063 | !sbi->s_qf_names[qtype]) { |
1041 | printk(KERN_ERR | 1064 | printk(KERN_ERR |
1042 | "EXT3-fs: Cannot change journaled " | 1065 | "EXT3-fs: Cannot change journaled " |
@@ -1075,8 +1098,7 @@ set_qf_name: | |||
1075 | case Opt_offgrpjquota: | 1098 | case Opt_offgrpjquota: |
1076 | qtype = GRPQUOTA; | 1099 | qtype = GRPQUOTA; |
1077 | clear_qf_name: | 1100 | clear_qf_name: |
1078 | if ((sb_any_quota_enabled(sb) || | 1101 | if (sb_any_quota_loaded(sb) && |
1079 | sb_any_quota_suspended(sb)) && | ||
1080 | sbi->s_qf_names[qtype]) { | 1102 | sbi->s_qf_names[qtype]) { |
1081 | printk(KERN_ERR "EXT3-fs: Cannot change " | 1103 | printk(KERN_ERR "EXT3-fs: Cannot change " |
1082 | "journaled quota options when " | 1104 | "journaled quota options when " |
@@ -1095,8 +1117,7 @@ clear_qf_name: | |||
1095 | case Opt_jqfmt_vfsv0: | 1117 | case Opt_jqfmt_vfsv0: |
1096 | qfmt = QFMT_VFS_V0; | 1118 | qfmt = QFMT_VFS_V0; |
1097 | set_qf_format: | 1119 | set_qf_format: |
1098 | if ((sb_any_quota_enabled(sb) || | 1120 | if (sb_any_quota_loaded(sb) && |
1099 | sb_any_quota_suspended(sb)) && | ||
1100 | sbi->s_jquota_fmt != qfmt) { | 1121 | sbi->s_jquota_fmt != qfmt) { |
1101 | printk(KERN_ERR "EXT3-fs: Cannot change " | 1122 | printk(KERN_ERR "EXT3-fs: Cannot change " |
1102 | "journaled quota options when " | 1123 | "journaled quota options when " |
@@ -1115,8 +1136,7 @@ set_qf_format: | |||
1115 | set_opt(sbi->s_mount_opt, GRPQUOTA); | 1136 | set_opt(sbi->s_mount_opt, GRPQUOTA); |
1116 | break; | 1137 | break; |
1117 | case Opt_noquota: | 1138 | case Opt_noquota: |
1118 | if (sb_any_quota_enabled(sb) || | 1139 | if (sb_any_quota_loaded(sb)) { |
1119 | sb_any_quota_suspended(sb)) { | ||
1120 | printk(KERN_ERR "EXT3-fs: Cannot change quota " | 1140 | printk(KERN_ERR "EXT3-fs: Cannot change quota " |
1121 | "options when quota turned on.\n"); | 1141 | "options when quota turned on.\n"); |
1122 | return 0; | 1142 | return 0; |
@@ -1548,6 +1568,13 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1548 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 1568 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
1549 | if (!sbi) | 1569 | if (!sbi) |
1550 | return -ENOMEM; | 1570 | return -ENOMEM; |
1571 | |||
1572 | sbi->s_blockgroup_lock = | ||
1573 | kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); | ||
1574 | if (!sbi->s_blockgroup_lock) { | ||
1575 | kfree(sbi); | ||
1576 | return -ENOMEM; | ||
1577 | } | ||
1551 | sb->s_fs_info = sbi; | 1578 | sb->s_fs_info = sbi; |
1552 | sbi->s_mount_opt = 0; | 1579 | sbi->s_mount_opt = 0; |
1553 | sbi->s_resuid = EXT3_DEF_RESUID; | 1580 | sbi->s_resuid = EXT3_DEF_RESUID; |
@@ -1744,6 +1771,18 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1744 | for (i=0; i < 4; i++) | 1771 | for (i=0; i < 4; i++) |
1745 | 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]); |
1746 | 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 | } | ||
1747 | 1786 | ||
1748 | if (sbi->s_blocks_per_group > blocksize * 8) { | 1787 | if (sbi->s_blocks_per_group > blocksize * 8) { |
1749 | printk (KERN_ERR | 1788 | printk (KERN_ERR |
@@ -1788,7 +1827,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1788 | goto failed_mount; | 1827 | goto failed_mount; |
1789 | } | 1828 | } |
1790 | 1829 | ||
1791 | bgl_lock_init(&sbi->s_blockgroup_lock); | 1830 | bgl_lock_init(sbi->s_blockgroup_lock); |
1792 | 1831 | ||
1793 | for (i = 0; i < db_count; i++) { | 1832 | for (i = 0; i < db_count; i++) { |
1794 | block = descriptor_loc(sb, logic_sb_block, i); | 1833 | block = descriptor_loc(sb, logic_sb_block, i); |
@@ -2272,21 +2311,23 @@ static int ext3_create_journal(struct super_block * sb, | |||
2272 | return 0; | 2311 | return 0; |
2273 | } | 2312 | } |
2274 | 2313 | ||
2275 | static void ext3_commit_super (struct super_block * sb, | 2314 | static int ext3_commit_super(struct super_block *sb, |
2276 | struct ext3_super_block * es, | 2315 | struct ext3_super_block *es, |
2277 | int sync) | 2316 | int sync) |
2278 | { | 2317 | { |
2279 | struct buffer_head *sbh = EXT3_SB(sb)->s_sbh; | 2318 | struct buffer_head *sbh = EXT3_SB(sb)->s_sbh; |
2319 | int error = 0; | ||
2280 | 2320 | ||
2281 | if (!sbh) | 2321 | if (!sbh) |
2282 | return; | 2322 | return error; |
2283 | es->s_wtime = cpu_to_le32(get_seconds()); | 2323 | es->s_wtime = cpu_to_le32(get_seconds()); |
2284 | es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb)); | 2324 | es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb)); |
2285 | es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); | 2325 | es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); |
2286 | BUFFER_TRACE(sbh, "marking dirty"); | 2326 | BUFFER_TRACE(sbh, "marking dirty"); |
2287 | mark_buffer_dirty(sbh); | 2327 | mark_buffer_dirty(sbh); |
2288 | if (sync) | 2328 | if (sync) |
2289 | sync_dirty_buffer(sbh); | 2329 | error = sync_dirty_buffer(sbh); |
2330 | return error; | ||
2290 | } | 2331 | } |
2291 | 2332 | ||
2292 | 2333 | ||
@@ -2400,12 +2441,14 @@ static int ext3_sync_fs(struct super_block *sb, int wait) | |||
2400 | * LVM calls this function before a (read-only) snapshot is created. This | 2441 | * LVM calls this function before a (read-only) snapshot is created. This |
2401 | * gives us a chance to flush the journal completely and mark the fs clean. | 2442 | * gives us a chance to flush the journal completely and mark the fs clean. |
2402 | */ | 2443 | */ |
2403 | static void ext3_write_super_lockfs(struct super_block *sb) | 2444 | static int ext3_freeze(struct super_block *sb) |
2404 | { | 2445 | { |
2446 | int error = 0; | ||
2447 | journal_t *journal; | ||
2405 | sb->s_dirt = 0; | 2448 | sb->s_dirt = 0; |
2406 | 2449 | ||
2407 | if (!(sb->s_flags & MS_RDONLY)) { | 2450 | if (!(sb->s_flags & MS_RDONLY)) { |
2408 | journal_t *journal = EXT3_SB(sb)->s_journal; | 2451 | journal = EXT3_SB(sb)->s_journal; |
2409 | 2452 | ||
2410 | /* Now we set up the journal barrier. */ | 2453 | /* Now we set up the journal barrier. */ |
2411 | journal_lock_updates(journal); | 2454 | journal_lock_updates(journal); |
@@ -2414,20 +2457,28 @@ static void ext3_write_super_lockfs(struct super_block *sb) | |||
2414 | * We don't want to clear needs_recovery flag when we failed | 2457 | * We don't want to clear needs_recovery flag when we failed |
2415 | * to flush the journal. | 2458 | * to flush the journal. |
2416 | */ | 2459 | */ |
2417 | if (journal_flush(journal) < 0) | 2460 | error = journal_flush(journal); |
2418 | return; | 2461 | if (error < 0) |
2462 | goto out; | ||
2419 | 2463 | ||
2420 | /* Journal blocked and flushed, clear needs_recovery flag. */ | 2464 | /* Journal blocked and flushed, clear needs_recovery flag. */ |
2421 | EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); | 2465 | EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); |
2422 | ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1); | 2466 | error = ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1); |
2467 | if (error) | ||
2468 | goto out; | ||
2423 | } | 2469 | } |
2470 | return 0; | ||
2471 | |||
2472 | out: | ||
2473 | journal_unlock_updates(journal); | ||
2474 | return error; | ||
2424 | } | 2475 | } |
2425 | 2476 | ||
2426 | /* | 2477 | /* |
2427 | * Called by LVM after the snapshot is done. We need to reset the RECOVER | 2478 | * Called by LVM after the snapshot is done. We need to reset the RECOVER |
2428 | * flag here, even though the filesystem is not technically dirty yet. | 2479 | * flag here, even though the filesystem is not technically dirty yet. |
2429 | */ | 2480 | */ |
2430 | static void ext3_unlockfs(struct super_block *sb) | 2481 | static int ext3_unfreeze(struct super_block *sb) |
2431 | { | 2482 | { |
2432 | if (!(sb->s_flags & MS_RDONLY)) { | 2483 | if (!(sb->s_flags & MS_RDONLY)) { |
2433 | lock_super(sb); | 2484 | lock_super(sb); |
@@ -2437,6 +2488,7 @@ static void ext3_unlockfs(struct super_block *sb) | |||
2437 | unlock_super(sb); | 2488 | unlock_super(sb); |
2438 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | 2489 | journal_unlock_updates(EXT3_SB(sb)->s_journal); |
2439 | } | 2490 | } |
2491 | return 0; | ||
2440 | } | 2492 | } |
2441 | 2493 | ||
2442 | static int ext3_remount (struct super_block * sb, int * flags, char * data) | 2494 | static int ext3_remount (struct super_block * sb, int * flags, char * data) |