diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 1075 |
1 files changed, 464 insertions, 611 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 933900909ed0..ceebaf853beb 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -62,6 +62,7 @@ static struct ext4_features *ext4_feat; | |||
62 | 62 | ||
63 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, | 63 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, |
64 | unsigned long journal_devnum); | 64 | unsigned long journal_devnum); |
65 | static int ext4_show_options(struct seq_file *seq, struct dentry *root); | ||
65 | static int ext4_commit_super(struct super_block *sb, int sync); | 66 | static int ext4_commit_super(struct super_block *sb, int sync); |
66 | static void ext4_mark_recovery_complete(struct super_block *sb, | 67 | static void ext4_mark_recovery_complete(struct super_block *sb, |
67 | struct ext4_super_block *es); | 68 | struct ext4_super_block *es); |
@@ -375,7 +376,7 @@ void ext4_journal_abort_handle(const char *caller, unsigned int line, | |||
375 | if (is_handle_aborted(handle)) | 376 | if (is_handle_aborted(handle)) |
376 | return; | 377 | return; |
377 | 378 | ||
378 | printk(KERN_ERR "%s:%d: aborting transaction: %s in %s\n", | 379 | printk(KERN_ERR "EXT4-fs: %s:%d: aborting transaction: %s in %s\n", |
379 | caller, line, errstr, err_fn); | 380 | caller, line, errstr, err_fn); |
380 | 381 | ||
381 | jbd2_journal_abort_handle(handle); | 382 | jbd2_journal_abort_handle(handle); |
@@ -431,6 +432,22 @@ static int block_device_ejected(struct super_block *sb) | |||
431 | return bdi->dev == NULL; | 432 | return bdi->dev == NULL; |
432 | } | 433 | } |
433 | 434 | ||
435 | static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn) | ||
436 | { | ||
437 | struct super_block *sb = journal->j_private; | ||
438 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
439 | int error = is_journal_aborted(journal); | ||
440 | struct ext4_journal_cb_entry *jce, *tmp; | ||
441 | |||
442 | spin_lock(&sbi->s_md_lock); | ||
443 | list_for_each_entry_safe(jce, tmp, &txn->t_private_list, jce_list) { | ||
444 | list_del_init(&jce->jce_list); | ||
445 | spin_unlock(&sbi->s_md_lock); | ||
446 | jce->jce_func(sb, jce, error); | ||
447 | spin_lock(&sbi->s_md_lock); | ||
448 | } | ||
449 | spin_unlock(&sbi->s_md_lock); | ||
450 | } | ||
434 | 451 | ||
435 | /* Deal with the reporting of failure conditions on a filesystem such as | 452 | /* Deal with the reporting of failure conditions on a filesystem such as |
436 | * inconsistencies detected or read IO failures. | 453 | * inconsistencies detected or read IO failures. |
@@ -498,11 +515,16 @@ void ext4_error_inode(struct inode *inode, const char *function, | |||
498 | va_start(args, fmt); | 515 | va_start(args, fmt); |
499 | vaf.fmt = fmt; | 516 | vaf.fmt = fmt; |
500 | vaf.va = &args; | 517 | vaf.va = &args; |
501 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ", | ||
502 | inode->i_sb->s_id, function, line, inode->i_ino); | ||
503 | if (block) | 518 | if (block) |
504 | printk(KERN_CONT "block %llu: ", block); | 519 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: " |
505 | printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf); | 520 | "inode #%lu: block %llu: comm %s: %pV\n", |
521 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
522 | block, current->comm, &vaf); | ||
523 | else | ||
524 | printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: " | ||
525 | "inode #%lu: comm %s: %pV\n", | ||
526 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
527 | current->comm, &vaf); | ||
506 | va_end(args); | 528 | va_end(args); |
507 | 529 | ||
508 | ext4_handle_error(inode->i_sb); | 530 | ext4_handle_error(inode->i_sb); |
@@ -524,15 +546,21 @@ void ext4_error_file(struct file *file, const char *function, | |||
524 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | 546 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); |
525 | if (IS_ERR(path)) | 547 | if (IS_ERR(path)) |
526 | path = "(unknown)"; | 548 | path = "(unknown)"; |
527 | printk(KERN_CRIT | ||
528 | "EXT4-fs error (device %s): %s:%d: inode #%lu: ", | ||
529 | inode->i_sb->s_id, function, line, inode->i_ino); | ||
530 | if (block) | ||
531 | printk(KERN_CONT "block %llu: ", block); | ||
532 | va_start(args, fmt); | 549 | va_start(args, fmt); |
533 | vaf.fmt = fmt; | 550 | vaf.fmt = fmt; |
534 | vaf.va = &args; | 551 | vaf.va = &args; |
535 | printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf); | 552 | if (block) |
553 | printk(KERN_CRIT | ||
554 | "EXT4-fs error (device %s): %s:%d: inode #%lu: " | ||
555 | "block %llu: comm %s: path %s: %pV\n", | ||
556 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
557 | block, current->comm, path, &vaf); | ||
558 | else | ||
559 | printk(KERN_CRIT | ||
560 | "EXT4-fs error (device %s): %s:%d: inode #%lu: " | ||
561 | "comm %s: path %s: %pV\n", | ||
562 | inode->i_sb->s_id, function, line, inode->i_ino, | ||
563 | current->comm, path, &vaf); | ||
536 | va_end(args); | 564 | va_end(args); |
537 | 565 | ||
538 | ext4_handle_error(inode->i_sb); | 566 | ext4_handle_error(inode->i_sb); |
@@ -808,9 +836,6 @@ static void ext4_put_super(struct super_block *sb) | |||
808 | destroy_workqueue(sbi->dio_unwritten_wq); | 836 | destroy_workqueue(sbi->dio_unwritten_wq); |
809 | 837 | ||
810 | lock_super(sb); | 838 | lock_super(sb); |
811 | if (sb->s_dirt) | ||
812 | ext4_commit_super(sb, 1); | ||
813 | |||
814 | if (sbi->s_journal) { | 839 | if (sbi->s_journal) { |
815 | err = jbd2_journal_destroy(sbi->s_journal); | 840 | err = jbd2_journal_destroy(sbi->s_journal); |
816 | sbi->s_journal = NULL; | 841 | sbi->s_journal = NULL; |
@@ -827,9 +852,12 @@ static void ext4_put_super(struct super_block *sb) | |||
827 | if (!(sb->s_flags & MS_RDONLY)) { | 852 | if (!(sb->s_flags & MS_RDONLY)) { |
828 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 853 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
829 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 854 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
830 | ext4_commit_super(sb, 1); | ||
831 | } | 855 | } |
856 | if (sb->s_dirt || !(sb->s_flags & MS_RDONLY)) | ||
857 | ext4_commit_super(sb, 1); | ||
858 | |||
832 | if (sbi->s_proc) { | 859 | if (sbi->s_proc) { |
860 | remove_proc_entry("options", sbi->s_proc); | ||
833 | remove_proc_entry(sb->s_id, ext4_proc_root); | 861 | remove_proc_entry(sb->s_id, ext4_proc_root); |
834 | } | 862 | } |
835 | kobject_del(&sbi->s_kobj); | 863 | kobject_del(&sbi->s_kobj); |
@@ -990,180 +1018,6 @@ void ext4_clear_inode(struct inode *inode) | |||
990 | } | 1018 | } |
991 | } | 1019 | } |
992 | 1020 | ||
993 | static inline void ext4_show_quota_options(struct seq_file *seq, | ||
994 | struct super_block *sb) | ||
995 | { | ||
996 | #if defined(CONFIG_QUOTA) | ||
997 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
998 | |||
999 | if (sbi->s_jquota_fmt) { | ||
1000 | char *fmtname = ""; | ||
1001 | |||
1002 | switch (sbi->s_jquota_fmt) { | ||
1003 | case QFMT_VFS_OLD: | ||
1004 | fmtname = "vfsold"; | ||
1005 | break; | ||
1006 | case QFMT_VFS_V0: | ||
1007 | fmtname = "vfsv0"; | ||
1008 | break; | ||
1009 | case QFMT_VFS_V1: | ||
1010 | fmtname = "vfsv1"; | ||
1011 | break; | ||
1012 | } | ||
1013 | seq_printf(seq, ",jqfmt=%s", fmtname); | ||
1014 | } | ||
1015 | |||
1016 | if (sbi->s_qf_names[USRQUOTA]) | ||
1017 | seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); | ||
1018 | |||
1019 | if (sbi->s_qf_names[GRPQUOTA]) | ||
1020 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | ||
1021 | |||
1022 | if (test_opt(sb, USRQUOTA)) | ||
1023 | seq_puts(seq, ",usrquota"); | ||
1024 | |||
1025 | if (test_opt(sb, GRPQUOTA)) | ||
1026 | seq_puts(seq, ",grpquota"); | ||
1027 | #endif | ||
1028 | } | ||
1029 | |||
1030 | /* | ||
1031 | * Show an option if | ||
1032 | * - it's set to a non-default value OR | ||
1033 | * - if the per-sb default is different from the global default | ||
1034 | */ | ||
1035 | static int ext4_show_options(struct seq_file *seq, struct dentry *root) | ||
1036 | { | ||
1037 | int def_errors; | ||
1038 | unsigned long def_mount_opts; | ||
1039 | struct super_block *sb = root->d_sb; | ||
1040 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1041 | struct ext4_super_block *es = sbi->s_es; | ||
1042 | |||
1043 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | ||
1044 | def_errors = le16_to_cpu(es->s_errors); | ||
1045 | |||
1046 | if (sbi->s_sb_block != 1) | ||
1047 | seq_printf(seq, ",sb=%llu", sbi->s_sb_block); | ||
1048 | if (test_opt(sb, MINIX_DF)) | ||
1049 | seq_puts(seq, ",minixdf"); | ||
1050 | if (test_opt(sb, GRPID) && !(def_mount_opts & EXT4_DEFM_BSDGROUPS)) | ||
1051 | seq_puts(seq, ",grpid"); | ||
1052 | if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS)) | ||
1053 | seq_puts(seq, ",nogrpid"); | ||
1054 | if (sbi->s_resuid != EXT4_DEF_RESUID || | ||
1055 | le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) { | ||
1056 | seq_printf(seq, ",resuid=%u", sbi->s_resuid); | ||
1057 | } | ||
1058 | if (sbi->s_resgid != EXT4_DEF_RESGID || | ||
1059 | le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) { | ||
1060 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); | ||
1061 | } | ||
1062 | if (test_opt(sb, ERRORS_RO)) { | ||
1063 | if (def_errors == EXT4_ERRORS_PANIC || | ||
1064 | def_errors == EXT4_ERRORS_CONTINUE) { | ||
1065 | seq_puts(seq, ",errors=remount-ro"); | ||
1066 | } | ||
1067 | } | ||
1068 | if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE) | ||
1069 | seq_puts(seq, ",errors=continue"); | ||
1070 | if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC) | ||
1071 | seq_puts(seq, ",errors=panic"); | ||
1072 | if (test_opt(sb, NO_UID32) && !(def_mount_opts & EXT4_DEFM_UID16)) | ||
1073 | seq_puts(seq, ",nouid32"); | ||
1074 | if (test_opt(sb, DEBUG) && !(def_mount_opts & EXT4_DEFM_DEBUG)) | ||
1075 | seq_puts(seq, ",debug"); | ||
1076 | #ifdef CONFIG_EXT4_FS_XATTR | ||
1077 | if (test_opt(sb, XATTR_USER)) | ||
1078 | seq_puts(seq, ",user_xattr"); | ||
1079 | if (!test_opt(sb, XATTR_USER)) | ||
1080 | seq_puts(seq, ",nouser_xattr"); | ||
1081 | #endif | ||
1082 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | ||
1083 | if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL)) | ||
1084 | seq_puts(seq, ",acl"); | ||
1085 | if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL)) | ||
1086 | seq_puts(seq, ",noacl"); | ||
1087 | #endif | ||
1088 | if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) { | ||
1089 | seq_printf(seq, ",commit=%u", | ||
1090 | (unsigned) (sbi->s_commit_interval / HZ)); | ||
1091 | } | ||
1092 | if (sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME) { | ||
1093 | seq_printf(seq, ",min_batch_time=%u", | ||
1094 | (unsigned) sbi->s_min_batch_time); | ||
1095 | } | ||
1096 | if (sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME) { | ||
1097 | seq_printf(seq, ",max_batch_time=%u", | ||
1098 | (unsigned) sbi->s_max_batch_time); | ||
1099 | } | ||
1100 | |||
1101 | /* | ||
1102 | * We're changing the default of barrier mount option, so | ||
1103 | * let's always display its mount state so it's clear what its | ||
1104 | * status is. | ||
1105 | */ | ||
1106 | seq_puts(seq, ",barrier="); | ||
1107 | seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); | ||
1108 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) | ||
1109 | seq_puts(seq, ",journal_async_commit"); | ||
1110 | else if (test_opt(sb, JOURNAL_CHECKSUM)) | ||
1111 | seq_puts(seq, ",journal_checksum"); | ||
1112 | if (test_opt(sb, I_VERSION)) | ||
1113 | seq_puts(seq, ",i_version"); | ||
1114 | if (!test_opt(sb, DELALLOC) && | ||
1115 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | ||
1116 | seq_puts(seq, ",nodelalloc"); | ||
1117 | |||
1118 | if (!test_opt(sb, MBLK_IO_SUBMIT)) | ||
1119 | seq_puts(seq, ",nomblk_io_submit"); | ||
1120 | if (sbi->s_stripe) | ||
1121 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | ||
1122 | /* | ||
1123 | * journal mode get enabled in different ways | ||
1124 | * So just print the value even if we didn't specify it | ||
1125 | */ | ||
1126 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) | ||
1127 | seq_puts(seq, ",data=journal"); | ||
1128 | else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) | ||
1129 | seq_puts(seq, ",data=ordered"); | ||
1130 | else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | ||
1131 | seq_puts(seq, ",data=writeback"); | ||
1132 | |||
1133 | if (sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS) | ||
1134 | seq_printf(seq, ",inode_readahead_blks=%u", | ||
1135 | sbi->s_inode_readahead_blks); | ||
1136 | |||
1137 | if (test_opt(sb, DATA_ERR_ABORT)) | ||
1138 | seq_puts(seq, ",data_err=abort"); | ||
1139 | |||
1140 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) | ||
1141 | seq_puts(seq, ",noauto_da_alloc"); | ||
1142 | |||
1143 | if (test_opt(sb, DISCARD) && !(def_mount_opts & EXT4_DEFM_DISCARD)) | ||
1144 | seq_puts(seq, ",discard"); | ||
1145 | |||
1146 | if (test_opt(sb, NOLOAD)) | ||
1147 | seq_puts(seq, ",norecovery"); | ||
1148 | |||
1149 | if (test_opt(sb, DIOREAD_NOLOCK)) | ||
1150 | seq_puts(seq, ",dioread_nolock"); | ||
1151 | |||
1152 | if (test_opt(sb, BLOCK_VALIDITY) && | ||
1153 | !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY)) | ||
1154 | seq_puts(seq, ",block_validity"); | ||
1155 | |||
1156 | if (!test_opt(sb, INIT_INODE_TABLE)) | ||
1157 | seq_puts(seq, ",noinit_itable"); | ||
1158 | else if (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT) | ||
1159 | seq_printf(seq, ",init_itable=%u", | ||
1160 | (unsigned) sbi->s_li_wait_mult); | ||
1161 | |||
1162 | ext4_show_quota_options(seq, sb); | ||
1163 | |||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1167 | static struct inode *ext4_nfs_get_inode(struct super_block *sb, | 1021 | static struct inode *ext4_nfs_get_inode(struct super_block *sb, |
1168 | u64 ino, u32 generation) | 1022 | u64 ino, u32 generation) |
1169 | { | 1023 | { |
@@ -1316,18 +1170,17 @@ static const struct export_operations ext4_export_ops = { | |||
1316 | enum { | 1170 | enum { |
1317 | Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, | 1171 | Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, |
1318 | Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, | 1172 | Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, |
1319 | Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov, | 1173 | Opt_nouid32, Opt_debug, Opt_removed, |
1320 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, | 1174 | Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, |
1321 | Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload, Opt_nobh, Opt_bh, | 1175 | Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload, |
1322 | Opt_commit, Opt_min_batch_time, Opt_max_batch_time, | 1176 | Opt_commit, Opt_min_batch_time, Opt_max_batch_time, |
1323 | Opt_journal_update, Opt_journal_dev, | 1177 | Opt_journal_dev, Opt_journal_checksum, Opt_journal_async_commit, |
1324 | Opt_journal_checksum, Opt_journal_async_commit, | ||
1325 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 1178 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
1326 | Opt_data_err_abort, Opt_data_err_ignore, | 1179 | Opt_data_err_abort, Opt_data_err_ignore, |
1327 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 1180 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
1328 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1181 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
1329 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, | 1182 | Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, |
1330 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, | 1183 | Opt_usrquota, Opt_grpquota, Opt_i_version, |
1331 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, | 1184 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, |
1332 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, | 1185 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
1333 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1186 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
@@ -1350,20 +1203,19 @@ static const match_table_t tokens = { | |||
1350 | {Opt_err_ro, "errors=remount-ro"}, | 1203 | {Opt_err_ro, "errors=remount-ro"}, |
1351 | {Opt_nouid32, "nouid32"}, | 1204 | {Opt_nouid32, "nouid32"}, |
1352 | {Opt_debug, "debug"}, | 1205 | {Opt_debug, "debug"}, |
1353 | {Opt_oldalloc, "oldalloc"}, | 1206 | {Opt_removed, "oldalloc"}, |
1354 | {Opt_orlov, "orlov"}, | 1207 | {Opt_removed, "orlov"}, |
1355 | {Opt_user_xattr, "user_xattr"}, | 1208 | {Opt_user_xattr, "user_xattr"}, |
1356 | {Opt_nouser_xattr, "nouser_xattr"}, | 1209 | {Opt_nouser_xattr, "nouser_xattr"}, |
1357 | {Opt_acl, "acl"}, | 1210 | {Opt_acl, "acl"}, |
1358 | {Opt_noacl, "noacl"}, | 1211 | {Opt_noacl, "noacl"}, |
1359 | {Opt_noload, "noload"}, | ||
1360 | {Opt_noload, "norecovery"}, | 1212 | {Opt_noload, "norecovery"}, |
1361 | {Opt_nobh, "nobh"}, | 1213 | {Opt_noload, "noload"}, |
1362 | {Opt_bh, "bh"}, | 1214 | {Opt_removed, "nobh"}, |
1215 | {Opt_removed, "bh"}, | ||
1363 | {Opt_commit, "commit=%u"}, | 1216 | {Opt_commit, "commit=%u"}, |
1364 | {Opt_min_batch_time, "min_batch_time=%u"}, | 1217 | {Opt_min_batch_time, "min_batch_time=%u"}, |
1365 | {Opt_max_batch_time, "max_batch_time=%u"}, | 1218 | {Opt_max_batch_time, "max_batch_time=%u"}, |
1366 | {Opt_journal_update, "journal=update"}, | ||
1367 | {Opt_journal_dev, "journal_dev=%u"}, | 1219 | {Opt_journal_dev, "journal_dev=%u"}, |
1368 | {Opt_journal_checksum, "journal_checksum"}, | 1220 | {Opt_journal_checksum, "journal_checksum"}, |
1369 | {Opt_journal_async_commit, "journal_async_commit"}, | 1221 | {Opt_journal_async_commit, "journal_async_commit"}, |
@@ -1389,7 +1241,6 @@ static const match_table_t tokens = { | |||
1389 | {Opt_nobarrier, "nobarrier"}, | 1241 | {Opt_nobarrier, "nobarrier"}, |
1390 | {Opt_i_version, "i_version"}, | 1242 | {Opt_i_version, "i_version"}, |
1391 | {Opt_stripe, "stripe=%u"}, | 1243 | {Opt_stripe, "stripe=%u"}, |
1392 | {Opt_resize, "resize"}, | ||
1393 | {Opt_delalloc, "delalloc"}, | 1244 | {Opt_delalloc, "delalloc"}, |
1394 | {Opt_nodelalloc, "nodelalloc"}, | 1245 | {Opt_nodelalloc, "nodelalloc"}, |
1395 | {Opt_mblk_io_submit, "mblk_io_submit"}, | 1246 | {Opt_mblk_io_submit, "mblk_io_submit"}, |
@@ -1408,6 +1259,11 @@ static const match_table_t tokens = { | |||
1408 | {Opt_init_itable, "init_itable=%u"}, | 1259 | {Opt_init_itable, "init_itable=%u"}, |
1409 | {Opt_init_itable, "init_itable"}, | 1260 | {Opt_init_itable, "init_itable"}, |
1410 | {Opt_noinit_itable, "noinit_itable"}, | 1261 | {Opt_noinit_itable, "noinit_itable"}, |
1262 | {Opt_removed, "check=none"}, /* mount option from ext2/3 */ | ||
1263 | {Opt_removed, "nocheck"}, /* mount option from ext2/3 */ | ||
1264 | {Opt_removed, "reservation"}, /* mount option from ext2/3 */ | ||
1265 | {Opt_removed, "noreservation"}, /* mount option from ext2/3 */ | ||
1266 | {Opt_removed, "journal=%u"}, /* mount option from ext2/3 */ | ||
1411 | {Opt_err, NULL}, | 1267 | {Opt_err, NULL}, |
1412 | }; | 1268 | }; |
1413 | 1269 | ||
@@ -1496,420 +1352,273 @@ static int clear_qf_name(struct super_block *sb, int qtype) | |||
1496 | } | 1352 | } |
1497 | #endif | 1353 | #endif |
1498 | 1354 | ||
1499 | static int parse_options(char *options, struct super_block *sb, | 1355 | #define MOPT_SET 0x0001 |
1500 | unsigned long *journal_devnum, | 1356 | #define MOPT_CLEAR 0x0002 |
1501 | unsigned int *journal_ioprio, | 1357 | #define MOPT_NOSUPPORT 0x0004 |
1502 | ext4_fsblk_t *n_blocks_count, int is_remount) | 1358 | #define MOPT_EXPLICIT 0x0008 |
1503 | { | 1359 | #define MOPT_CLEAR_ERR 0x0010 |
1504 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1360 | #define MOPT_GTE0 0x0020 |
1505 | char *p; | ||
1506 | substring_t args[MAX_OPT_ARGS]; | ||
1507 | int data_opt = 0; | ||
1508 | int option; | ||
1509 | #ifdef CONFIG_QUOTA | 1361 | #ifdef CONFIG_QUOTA |
1510 | int qfmt; | 1362 | #define MOPT_Q 0 |
1363 | #define MOPT_QFMT 0x0040 | ||
1364 | #else | ||
1365 | #define MOPT_Q MOPT_NOSUPPORT | ||
1366 | #define MOPT_QFMT MOPT_NOSUPPORT | ||
1511 | #endif | 1367 | #endif |
1512 | 1368 | #define MOPT_DATAJ 0x0080 | |
1513 | if (!options) | 1369 | |
1514 | return 1; | 1370 | static const struct mount_opts { |
1515 | 1371 | int token; | |
1516 | while ((p = strsep(&options, ",")) != NULL) { | 1372 | int mount_opt; |
1517 | int token; | 1373 | int flags; |
1518 | if (!*p) | 1374 | } ext4_mount_opts[] = { |
1519 | continue; | 1375 | {Opt_minix_df, EXT4_MOUNT_MINIX_DF, MOPT_SET}, |
1520 | 1376 | {Opt_bsd_df, EXT4_MOUNT_MINIX_DF, MOPT_CLEAR}, | |
1521 | /* | 1377 | {Opt_grpid, EXT4_MOUNT_GRPID, MOPT_SET}, |
1522 | * Initialize args struct so we know whether arg was | 1378 | {Opt_nogrpid, EXT4_MOUNT_GRPID, MOPT_CLEAR}, |
1523 | * found; some options take optional arguments. | 1379 | {Opt_mblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_SET}, |
1524 | */ | 1380 | {Opt_nomblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_CLEAR}, |
1525 | args[0].to = args[0].from = NULL; | 1381 | {Opt_block_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_SET}, |
1526 | token = match_token(p, tokens, args); | 1382 | {Opt_noblock_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_CLEAR}, |
1527 | switch (token) { | 1383 | {Opt_dioread_nolock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_SET}, |
1528 | case Opt_bsd_df: | 1384 | {Opt_dioread_lock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_CLEAR}, |
1529 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | 1385 | {Opt_discard, EXT4_MOUNT_DISCARD, MOPT_SET}, |
1530 | clear_opt(sb, MINIX_DF); | 1386 | {Opt_nodiscard, EXT4_MOUNT_DISCARD, MOPT_CLEAR}, |
1531 | break; | 1387 | {Opt_delalloc, EXT4_MOUNT_DELALLOC, MOPT_SET | MOPT_EXPLICIT}, |
1532 | case Opt_minix_df: | 1388 | {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, MOPT_CLEAR | MOPT_EXPLICIT}, |
1533 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | 1389 | {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_SET}, |
1534 | set_opt(sb, MINIX_DF); | 1390 | {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT | |
1535 | 1391 | EXT4_MOUNT_JOURNAL_CHECKSUM), MOPT_SET}, | |
1536 | break; | 1392 | {Opt_noload, EXT4_MOUNT_NOLOAD, MOPT_SET}, |
1537 | case Opt_grpid: | 1393 | {Opt_err_panic, EXT4_MOUNT_ERRORS_PANIC, MOPT_SET | MOPT_CLEAR_ERR}, |
1538 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | 1394 | {Opt_err_ro, EXT4_MOUNT_ERRORS_RO, MOPT_SET | MOPT_CLEAR_ERR}, |
1539 | set_opt(sb, GRPID); | 1395 | {Opt_err_cont, EXT4_MOUNT_ERRORS_CONT, MOPT_SET | MOPT_CLEAR_ERR}, |
1540 | 1396 | {Opt_data_err_abort, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_SET}, | |
1541 | break; | 1397 | {Opt_data_err_ignore, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_CLEAR}, |
1542 | case Opt_nogrpid: | 1398 | {Opt_barrier, EXT4_MOUNT_BARRIER, MOPT_SET}, |
1543 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | 1399 | {Opt_nobarrier, EXT4_MOUNT_BARRIER, MOPT_CLEAR}, |
1544 | clear_opt(sb, GRPID); | 1400 | {Opt_noauto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_SET}, |
1545 | 1401 | {Opt_auto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_CLEAR}, | |
1546 | break; | 1402 | {Opt_noinit_itable, EXT4_MOUNT_INIT_INODE_TABLE, MOPT_CLEAR}, |
1547 | case Opt_resuid: | 1403 | {Opt_commit, 0, MOPT_GTE0}, |
1548 | if (match_int(&args[0], &option)) | 1404 | {Opt_max_batch_time, 0, MOPT_GTE0}, |
1549 | return 0; | 1405 | {Opt_min_batch_time, 0, MOPT_GTE0}, |
1550 | sbi->s_resuid = option; | 1406 | {Opt_inode_readahead_blks, 0, MOPT_GTE0}, |
1551 | break; | 1407 | {Opt_init_itable, 0, MOPT_GTE0}, |
1552 | case Opt_resgid: | 1408 | {Opt_stripe, 0, MOPT_GTE0}, |
1553 | if (match_int(&args[0], &option)) | 1409 | {Opt_data_journal, EXT4_MOUNT_JOURNAL_DATA, MOPT_DATAJ}, |
1554 | return 0; | 1410 | {Opt_data_ordered, EXT4_MOUNT_ORDERED_DATA, MOPT_DATAJ}, |
1555 | sbi->s_resgid = option; | 1411 | {Opt_data_writeback, EXT4_MOUNT_WRITEBACK_DATA, MOPT_DATAJ}, |
1556 | break; | ||
1557 | case Opt_sb: | ||
1558 | /* handled by get_sb_block() instead of here */ | ||
1559 | /* *sb_block = match_int(&args[0]); */ | ||
1560 | break; | ||
1561 | case Opt_err_panic: | ||
1562 | clear_opt(sb, ERRORS_CONT); | ||
1563 | clear_opt(sb, ERRORS_RO); | ||
1564 | set_opt(sb, ERRORS_PANIC); | ||
1565 | break; | ||
1566 | case Opt_err_ro: | ||
1567 | clear_opt(sb, ERRORS_CONT); | ||
1568 | clear_opt(sb, ERRORS_PANIC); | ||
1569 | set_opt(sb, ERRORS_RO); | ||
1570 | break; | ||
1571 | case Opt_err_cont: | ||
1572 | clear_opt(sb, ERRORS_RO); | ||
1573 | clear_opt(sb, ERRORS_PANIC); | ||
1574 | set_opt(sb, ERRORS_CONT); | ||
1575 | break; | ||
1576 | case Opt_nouid32: | ||
1577 | set_opt(sb, NO_UID32); | ||
1578 | break; | ||
1579 | case Opt_debug: | ||
1580 | set_opt(sb, DEBUG); | ||
1581 | break; | ||
1582 | case Opt_oldalloc: | ||
1583 | ext4_msg(sb, KERN_WARNING, | ||
1584 | "Ignoring deprecated oldalloc option"); | ||
1585 | break; | ||
1586 | case Opt_orlov: | ||
1587 | ext4_msg(sb, KERN_WARNING, | ||
1588 | "Ignoring deprecated orlov option"); | ||
1589 | break; | ||
1590 | #ifdef CONFIG_EXT4_FS_XATTR | 1412 | #ifdef CONFIG_EXT4_FS_XATTR |
1591 | case Opt_user_xattr: | 1413 | {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, |
1592 | set_opt(sb, XATTR_USER); | 1414 | {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, |
1593 | break; | ||
1594 | case Opt_nouser_xattr: | ||
1595 | clear_opt(sb, XATTR_USER); | ||
1596 | break; | ||
1597 | #else | 1415 | #else |
1598 | case Opt_user_xattr: | 1416 | {Opt_user_xattr, 0, MOPT_NOSUPPORT}, |
1599 | case Opt_nouser_xattr: | 1417 | {Opt_nouser_xattr, 0, MOPT_NOSUPPORT}, |
1600 | ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported"); | ||
1601 | break; | ||
1602 | #endif | 1418 | #endif |
1603 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 1419 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
1604 | case Opt_acl: | 1420 | {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, |
1605 | set_opt(sb, POSIX_ACL); | 1421 | {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, |
1606 | break; | ||
1607 | case Opt_noacl: | ||
1608 | clear_opt(sb, POSIX_ACL); | ||
1609 | break; | ||
1610 | #else | 1422 | #else |
1611 | case Opt_acl: | 1423 | {Opt_acl, 0, MOPT_NOSUPPORT}, |
1612 | case Opt_noacl: | 1424 | {Opt_noacl, 0, MOPT_NOSUPPORT}, |
1613 | ext4_msg(sb, KERN_ERR, "(no)acl options not supported"); | ||
1614 | break; | ||
1615 | #endif | 1425 | #endif |
1616 | case Opt_journal_update: | 1426 | {Opt_nouid32, EXT4_MOUNT_NO_UID32, MOPT_SET}, |
1617 | /* @@@ FIXME */ | 1427 | {Opt_debug, EXT4_MOUNT_DEBUG, MOPT_SET}, |
1618 | /* Eventually we will want to be able to create | 1428 | {Opt_quota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, MOPT_SET | MOPT_Q}, |
1619 | a journal file here. For now, only allow the | 1429 | {Opt_usrquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, |
1620 | user to specify an existing inode to be the | 1430 | MOPT_SET | MOPT_Q}, |
1621 | journal file. */ | 1431 | {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA, |
1622 | if (is_remount) { | 1432 | MOPT_SET | MOPT_Q}, |
1623 | ext4_msg(sb, KERN_ERR, | 1433 | {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA | |
1624 | "Cannot specify journal on remount"); | 1434 | EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q}, |
1625 | return 0; | 1435 | {Opt_usrjquota, 0, MOPT_Q}, |
1626 | } | 1436 | {Opt_grpjquota, 0, MOPT_Q}, |
1627 | set_opt(sb, UPDATE_JOURNAL); | 1437 | {Opt_offusrjquota, 0, MOPT_Q}, |
1628 | break; | 1438 | {Opt_offgrpjquota, 0, MOPT_Q}, |
1629 | case Opt_journal_dev: | 1439 | {Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT}, |
1630 | if (is_remount) { | 1440 | {Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT}, |
1441 | {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT}, | ||
1442 | {Opt_err, 0, 0} | ||
1443 | }; | ||
1444 | |||
1445 | static int handle_mount_opt(struct super_block *sb, char *opt, int token, | ||
1446 | substring_t *args, unsigned long *journal_devnum, | ||
1447 | unsigned int *journal_ioprio, int is_remount) | ||
1448 | { | ||
1449 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1450 | const struct mount_opts *m; | ||
1451 | int arg = 0; | ||
1452 | |||
1453 | if (args->from && match_int(args, &arg)) | ||
1454 | return -1; | ||
1455 | switch (token) { | ||
1456 | case Opt_noacl: | ||
1457 | case Opt_nouser_xattr: | ||
1458 | ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); | ||
1459 | break; | ||
1460 | case Opt_sb: | ||
1461 | return 1; /* handled by get_sb_block() */ | ||
1462 | case Opt_removed: | ||
1463 | ext4_msg(sb, KERN_WARNING, | ||
1464 | "Ignoring removed %s option", opt); | ||
1465 | return 1; | ||
1466 | case Opt_resuid: | ||
1467 | sbi->s_resuid = arg; | ||
1468 | return 1; | ||
1469 | case Opt_resgid: | ||
1470 | sbi->s_resgid = arg; | ||
1471 | return 1; | ||
1472 | case Opt_abort: | ||
1473 | sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; | ||
1474 | return 1; | ||
1475 | case Opt_i_version: | ||
1476 | sb->s_flags |= MS_I_VERSION; | ||
1477 | return 1; | ||
1478 | case Opt_journal_dev: | ||
1479 | if (is_remount) { | ||
1480 | ext4_msg(sb, KERN_ERR, | ||
1481 | "Cannot specify journal on remount"); | ||
1482 | return -1; | ||
1483 | } | ||
1484 | *journal_devnum = arg; | ||
1485 | return 1; | ||
1486 | case Opt_journal_ioprio: | ||
1487 | if (arg < 0 || arg > 7) | ||
1488 | return -1; | ||
1489 | *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg); | ||
1490 | return 1; | ||
1491 | } | ||
1492 | |||
1493 | for (m = ext4_mount_opts; m->token != Opt_err; m++) { | ||
1494 | if (token != m->token) | ||
1495 | continue; | ||
1496 | if (args->from && (m->flags & MOPT_GTE0) && (arg < 0)) | ||
1497 | return -1; | ||
1498 | if (m->flags & MOPT_EXPLICIT) | ||
1499 | set_opt2(sb, EXPLICIT_DELALLOC); | ||
1500 | if (m->flags & MOPT_CLEAR_ERR) | ||
1501 | clear_opt(sb, ERRORS_MASK); | ||
1502 | if (token == Opt_noquota && sb_any_quota_loaded(sb)) { | ||
1503 | ext4_msg(sb, KERN_ERR, "Cannot change quota " | ||
1504 | "options when quota turned on"); | ||
1505 | return -1; | ||
1506 | } | ||
1507 | |||
1508 | if (m->flags & MOPT_NOSUPPORT) { | ||
1509 | ext4_msg(sb, KERN_ERR, "%s option not supported", opt); | ||
1510 | } else if (token == Opt_commit) { | ||
1511 | if (arg == 0) | ||
1512 | arg = JBD2_DEFAULT_MAX_COMMIT_AGE; | ||
1513 | sbi->s_commit_interval = HZ * arg; | ||
1514 | } else if (token == Opt_max_batch_time) { | ||
1515 | if (arg == 0) | ||
1516 | arg = EXT4_DEF_MAX_BATCH_TIME; | ||
1517 | sbi->s_max_batch_time = arg; | ||
1518 | } else if (token == Opt_min_batch_time) { | ||
1519 | sbi->s_min_batch_time = arg; | ||
1520 | } else if (token == Opt_inode_readahead_blks) { | ||
1521 | if (arg > (1 << 30)) | ||
1522 | return -1; | ||
1523 | if (arg && !is_power_of_2(arg)) { | ||
1631 | ext4_msg(sb, KERN_ERR, | 1524 | ext4_msg(sb, KERN_ERR, |
1632 | "Cannot specify journal on remount"); | 1525 | "EXT4-fs: inode_readahead_blks" |
1633 | return 0; | 1526 | " must be a power of 2"); |
1527 | return -1; | ||
1634 | } | 1528 | } |
1635 | if (match_int(&args[0], &option)) | 1529 | sbi->s_inode_readahead_blks = arg; |
1636 | return 0; | 1530 | } else if (token == Opt_init_itable) { |
1637 | *journal_devnum = option; | 1531 | set_opt(sb, INIT_INODE_TABLE); |
1638 | break; | 1532 | if (!args->from) |
1639 | case Opt_journal_checksum: | 1533 | arg = EXT4_DEF_LI_WAIT_MULT; |
1640 | set_opt(sb, JOURNAL_CHECKSUM); | 1534 | sbi->s_li_wait_mult = arg; |
1641 | break; | 1535 | } else if (token == Opt_stripe) { |
1642 | case Opt_journal_async_commit: | 1536 | sbi->s_stripe = arg; |
1643 | set_opt(sb, JOURNAL_ASYNC_COMMIT); | 1537 | } else if (m->flags & MOPT_DATAJ) { |
1644 | set_opt(sb, JOURNAL_CHECKSUM); | ||
1645 | break; | ||
1646 | case Opt_noload: | ||
1647 | set_opt(sb, NOLOAD); | ||
1648 | break; | ||
1649 | case Opt_commit: | ||
1650 | if (match_int(&args[0], &option)) | ||
1651 | return 0; | ||
1652 | if (option < 0) | ||
1653 | return 0; | ||
1654 | if (option == 0) | ||
1655 | option = JBD2_DEFAULT_MAX_COMMIT_AGE; | ||
1656 | sbi->s_commit_interval = HZ * option; | ||
1657 | break; | ||
1658 | case Opt_max_batch_time: | ||
1659 | if (match_int(&args[0], &option)) | ||
1660 | return 0; | ||
1661 | if (option < 0) | ||
1662 | return 0; | ||
1663 | if (option == 0) | ||
1664 | option = EXT4_DEF_MAX_BATCH_TIME; | ||
1665 | sbi->s_max_batch_time = option; | ||
1666 | break; | ||
1667 | case Opt_min_batch_time: | ||
1668 | if (match_int(&args[0], &option)) | ||
1669 | return 0; | ||
1670 | if (option < 0) | ||
1671 | return 0; | ||
1672 | sbi->s_min_batch_time = option; | ||
1673 | break; | ||
1674 | case Opt_data_journal: | ||
1675 | data_opt = EXT4_MOUNT_JOURNAL_DATA; | ||
1676 | goto datacheck; | ||
1677 | case Opt_data_ordered: | ||
1678 | data_opt = EXT4_MOUNT_ORDERED_DATA; | ||
1679 | goto datacheck; | ||
1680 | case Opt_data_writeback: | ||
1681 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; | ||
1682 | datacheck: | ||
1683 | if (is_remount) { | 1538 | if (is_remount) { |
1684 | if (!sbi->s_journal) | 1539 | if (!sbi->s_journal) |
1685 | ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option"); | 1540 | ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option"); |
1686 | else if (test_opt(sb, DATA_FLAGS) != data_opt) { | 1541 | else if (test_opt(sb, DATA_FLAGS) != |
1542 | m->mount_opt) { | ||
1687 | ext4_msg(sb, KERN_ERR, | 1543 | ext4_msg(sb, KERN_ERR, |
1688 | "Cannot change data mode on remount"); | 1544 | "Cannot change data mode on remount"); |
1689 | return 0; | 1545 | return -1; |
1690 | } | 1546 | } |
1691 | } else { | 1547 | } else { |
1692 | clear_opt(sb, DATA_FLAGS); | 1548 | clear_opt(sb, DATA_FLAGS); |
1693 | sbi->s_mount_opt |= data_opt; | 1549 | sbi->s_mount_opt |= m->mount_opt; |
1694 | } | 1550 | } |
1695 | break; | ||
1696 | case Opt_data_err_abort: | ||
1697 | set_opt(sb, DATA_ERR_ABORT); | ||
1698 | break; | ||
1699 | case Opt_data_err_ignore: | ||
1700 | clear_opt(sb, DATA_ERR_ABORT); | ||
1701 | break; | ||
1702 | #ifdef CONFIG_QUOTA | 1551 | #ifdef CONFIG_QUOTA |
1703 | case Opt_usrjquota: | 1552 | } else if (token == Opt_usrjquota) { |
1704 | if (!set_qf_name(sb, USRQUOTA, &args[0])) | 1553 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
1705 | return 0; | 1554 | return -1; |
1706 | break; | 1555 | } else if (token == Opt_grpjquota) { |
1707 | case Opt_grpjquota: | ||
1708 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) | 1556 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
1709 | return 0; | 1557 | return -1; |
1710 | break; | 1558 | } else if (token == Opt_offusrjquota) { |
1711 | case Opt_offusrjquota: | ||
1712 | if (!clear_qf_name(sb, USRQUOTA)) | 1559 | if (!clear_qf_name(sb, USRQUOTA)) |
1713 | return 0; | 1560 | return -1; |
1714 | break; | 1561 | } else if (token == Opt_offgrpjquota) { |
1715 | case Opt_offgrpjquota: | ||
1716 | if (!clear_qf_name(sb, GRPQUOTA)) | 1562 | if (!clear_qf_name(sb, GRPQUOTA)) |
1717 | return 0; | 1563 | return -1; |
1718 | break; | 1564 | } else if (m->flags & MOPT_QFMT) { |
1719 | |||
1720 | case Opt_jqfmt_vfsold: | ||
1721 | qfmt = QFMT_VFS_OLD; | ||
1722 | goto set_qf_format; | ||
1723 | case Opt_jqfmt_vfsv0: | ||
1724 | qfmt = QFMT_VFS_V0; | ||
1725 | goto set_qf_format; | ||
1726 | case Opt_jqfmt_vfsv1: | ||
1727 | qfmt = QFMT_VFS_V1; | ||
1728 | set_qf_format: | ||
1729 | if (sb_any_quota_loaded(sb) && | 1565 | if (sb_any_quota_loaded(sb) && |
1730 | sbi->s_jquota_fmt != qfmt) { | 1566 | sbi->s_jquota_fmt != m->mount_opt) { |
1731 | ext4_msg(sb, KERN_ERR, "Cannot change " | 1567 | ext4_msg(sb, KERN_ERR, "Cannot " |
1732 | "journaled quota options when " | 1568 | "change journaled quota options " |
1733 | "quota turned on"); | 1569 | "when quota turned on"); |
1734 | return 0; | 1570 | return -1; |
1735 | } | ||
1736 | sbi->s_jquota_fmt = qfmt; | ||
1737 | break; | ||
1738 | case Opt_quota: | ||
1739 | case Opt_usrquota: | ||
1740 | set_opt(sb, QUOTA); | ||
1741 | set_opt(sb, USRQUOTA); | ||
1742 | break; | ||
1743 | case Opt_grpquota: | ||
1744 | set_opt(sb, QUOTA); | ||
1745 | set_opt(sb, GRPQUOTA); | ||
1746 | break; | ||
1747 | case Opt_noquota: | ||
1748 | if (sb_any_quota_loaded(sb)) { | ||
1749 | ext4_msg(sb, KERN_ERR, "Cannot change quota " | ||
1750 | "options when quota turned on"); | ||
1751 | return 0; | ||
1752 | } | 1571 | } |
1753 | clear_opt(sb, QUOTA); | 1572 | sbi->s_jquota_fmt = m->mount_opt; |
1754 | clear_opt(sb, USRQUOTA); | ||
1755 | clear_opt(sb, GRPQUOTA); | ||
1756 | break; | ||
1757 | #else | ||
1758 | case Opt_quota: | ||
1759 | case Opt_usrquota: | ||
1760 | case Opt_grpquota: | ||
1761 | ext4_msg(sb, KERN_ERR, | ||
1762 | "quota options not supported"); | ||
1763 | break; | ||
1764 | case Opt_usrjquota: | ||
1765 | case Opt_grpjquota: | ||
1766 | case Opt_offusrjquota: | ||
1767 | case Opt_offgrpjquota: | ||
1768 | case Opt_jqfmt_vfsold: | ||
1769 | case Opt_jqfmt_vfsv0: | ||
1770 | case Opt_jqfmt_vfsv1: | ||
1771 | ext4_msg(sb, KERN_ERR, | ||
1772 | "journaled quota options not supported"); | ||
1773 | break; | ||
1774 | case Opt_noquota: | ||
1775 | break; | ||
1776 | #endif | 1573 | #endif |
1777 | case Opt_abort: | 1574 | } else { |
1778 | sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; | 1575 | if (!args->from) |
1779 | break; | 1576 | arg = 1; |
1780 | case Opt_nobarrier: | 1577 | if (m->flags & MOPT_CLEAR) |
1781 | clear_opt(sb, BARRIER); | 1578 | arg = !arg; |
1782 | break; | 1579 | else if (unlikely(!(m->flags & MOPT_SET))) { |
1783 | case Opt_barrier: | 1580 | ext4_msg(sb, KERN_WARNING, |
1784 | if (args[0].from) { | 1581 | "buggy handling of option %s", opt); |
1785 | if (match_int(&args[0], &option)) | 1582 | WARN_ON(1); |
1786 | return 0; | 1583 | return -1; |
1787 | } else | ||
1788 | option = 1; /* No argument, default to 1 */ | ||
1789 | if (option) | ||
1790 | set_opt(sb, BARRIER); | ||
1791 | else | ||
1792 | clear_opt(sb, BARRIER); | ||
1793 | break; | ||
1794 | case Opt_ignore: | ||
1795 | break; | ||
1796 | case Opt_resize: | ||
1797 | if (!is_remount) { | ||
1798 | ext4_msg(sb, KERN_ERR, | ||
1799 | "resize option only available " | ||
1800 | "for remount"); | ||
1801 | return 0; | ||
1802 | } | ||
1803 | if (match_int(&args[0], &option) != 0) | ||
1804 | return 0; | ||
1805 | *n_blocks_count = option; | ||
1806 | break; | ||
1807 | case Opt_nobh: | ||
1808 | ext4_msg(sb, KERN_WARNING, | ||
1809 | "Ignoring deprecated nobh option"); | ||
1810 | break; | ||
1811 | case Opt_bh: | ||
1812 | ext4_msg(sb, KERN_WARNING, | ||
1813 | "Ignoring deprecated bh option"); | ||
1814 | break; | ||
1815 | case Opt_i_version: | ||
1816 | set_opt(sb, I_VERSION); | ||
1817 | sb->s_flags |= MS_I_VERSION; | ||
1818 | break; | ||
1819 | case Opt_nodelalloc: | ||
1820 | clear_opt(sb, DELALLOC); | ||
1821 | clear_opt2(sb, EXPLICIT_DELALLOC); | ||
1822 | break; | ||
1823 | case Opt_mblk_io_submit: | ||
1824 | set_opt(sb, MBLK_IO_SUBMIT); | ||
1825 | break; | ||
1826 | case Opt_nomblk_io_submit: | ||
1827 | clear_opt(sb, MBLK_IO_SUBMIT); | ||
1828 | break; | ||
1829 | case Opt_stripe: | ||
1830 | if (match_int(&args[0], &option)) | ||
1831 | return 0; | ||
1832 | if (option < 0) | ||
1833 | return 0; | ||
1834 | sbi->s_stripe = option; | ||
1835 | break; | ||
1836 | case Opt_delalloc: | ||
1837 | set_opt(sb, DELALLOC); | ||
1838 | set_opt2(sb, EXPLICIT_DELALLOC); | ||
1839 | break; | ||
1840 | case Opt_block_validity: | ||
1841 | set_opt(sb, BLOCK_VALIDITY); | ||
1842 | break; | ||
1843 | case Opt_noblock_validity: | ||
1844 | clear_opt(sb, BLOCK_VALIDITY); | ||
1845 | break; | ||
1846 | case Opt_inode_readahead_blks: | ||
1847 | if (match_int(&args[0], &option)) | ||
1848 | return 0; | ||
1849 | if (option < 0 || option > (1 << 30)) | ||
1850 | return 0; | ||
1851 | if (option && !is_power_of_2(option)) { | ||
1852 | ext4_msg(sb, KERN_ERR, | ||
1853 | "EXT4-fs: inode_readahead_blks" | ||
1854 | " must be a power of 2"); | ||
1855 | return 0; | ||
1856 | } | 1584 | } |
1857 | sbi->s_inode_readahead_blks = option; | 1585 | if (arg != 0) |
1858 | break; | 1586 | sbi->s_mount_opt |= m->mount_opt; |
1859 | case Opt_journal_ioprio: | ||
1860 | if (match_int(&args[0], &option)) | ||
1861 | return 0; | ||
1862 | if (option < 0 || option > 7) | ||
1863 | break; | ||
1864 | *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, | ||
1865 | option); | ||
1866 | break; | ||
1867 | case Opt_noauto_da_alloc: | ||
1868 | set_opt(sb, NO_AUTO_DA_ALLOC); | ||
1869 | break; | ||
1870 | case Opt_auto_da_alloc: | ||
1871 | if (args[0].from) { | ||
1872 | if (match_int(&args[0], &option)) | ||
1873 | return 0; | ||
1874 | } else | ||
1875 | option = 1; /* No argument, default to 1 */ | ||
1876 | if (option) | ||
1877 | clear_opt(sb, NO_AUTO_DA_ALLOC); | ||
1878 | else | 1587 | else |
1879 | set_opt(sb,NO_AUTO_DA_ALLOC); | 1588 | sbi->s_mount_opt &= ~m->mount_opt; |
1880 | break; | ||
1881 | case Opt_discard: | ||
1882 | set_opt(sb, DISCARD); | ||
1883 | break; | ||
1884 | case Opt_nodiscard: | ||
1885 | clear_opt(sb, DISCARD); | ||
1886 | break; | ||
1887 | case Opt_dioread_nolock: | ||
1888 | set_opt(sb, DIOREAD_NOLOCK); | ||
1889 | break; | ||
1890 | case Opt_dioread_lock: | ||
1891 | clear_opt(sb, DIOREAD_NOLOCK); | ||
1892 | break; | ||
1893 | case Opt_init_itable: | ||
1894 | set_opt(sb, INIT_INODE_TABLE); | ||
1895 | if (args[0].from) { | ||
1896 | if (match_int(&args[0], &option)) | ||
1897 | return 0; | ||
1898 | } else | ||
1899 | option = EXT4_DEF_LI_WAIT_MULT; | ||
1900 | if (option < 0) | ||
1901 | return 0; | ||
1902 | sbi->s_li_wait_mult = option; | ||
1903 | break; | ||
1904 | case Opt_noinit_itable: | ||
1905 | clear_opt(sb, INIT_INODE_TABLE); | ||
1906 | break; | ||
1907 | default: | ||
1908 | ext4_msg(sb, KERN_ERR, | ||
1909 | "Unrecognized mount option \"%s\" " | ||
1910 | "or missing value", p); | ||
1911 | return 0; | ||
1912 | } | 1589 | } |
1590 | return 1; | ||
1591 | } | ||
1592 | ext4_msg(sb, KERN_ERR, "Unrecognized mount option \"%s\" " | ||
1593 | "or missing value", opt); | ||
1594 | return -1; | ||
1595 | } | ||
1596 | |||
1597 | static int parse_options(char *options, struct super_block *sb, | ||
1598 | unsigned long *journal_devnum, | ||
1599 | unsigned int *journal_ioprio, | ||
1600 | int is_remount) | ||
1601 | { | ||
1602 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1603 | char *p; | ||
1604 | substring_t args[MAX_OPT_ARGS]; | ||
1605 | int token; | ||
1606 | |||
1607 | if (!options) | ||
1608 | return 1; | ||
1609 | |||
1610 | while ((p = strsep(&options, ",")) != NULL) { | ||
1611 | if (!*p) | ||
1612 | continue; | ||
1613 | /* | ||
1614 | * Initialize args struct so we know whether arg was | ||
1615 | * found; some options take optional arguments. | ||
1616 | */ | ||
1617 | args[0].to = args[0].from = 0; | ||
1618 | token = match_token(p, tokens, args); | ||
1619 | if (handle_mount_opt(sb, p, token, args, journal_devnum, | ||
1620 | journal_ioprio, is_remount) < 0) | ||
1621 | return 0; | ||
1913 | } | 1622 | } |
1914 | #ifdef CONFIG_QUOTA | 1623 | #ifdef CONFIG_QUOTA |
1915 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1624 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { |
@@ -1942,6 +1651,160 @@ set_qf_format: | |||
1942 | return 1; | 1651 | return 1; |
1943 | } | 1652 | } |
1944 | 1653 | ||
1654 | static inline void ext4_show_quota_options(struct seq_file *seq, | ||
1655 | struct super_block *sb) | ||
1656 | { | ||
1657 | #if defined(CONFIG_QUOTA) | ||
1658 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1659 | |||
1660 | if (sbi->s_jquota_fmt) { | ||
1661 | char *fmtname = ""; | ||
1662 | |||
1663 | switch (sbi->s_jquota_fmt) { | ||
1664 | case QFMT_VFS_OLD: | ||
1665 | fmtname = "vfsold"; | ||
1666 | break; | ||
1667 | case QFMT_VFS_V0: | ||
1668 | fmtname = "vfsv0"; | ||
1669 | break; | ||
1670 | case QFMT_VFS_V1: | ||
1671 | fmtname = "vfsv1"; | ||
1672 | break; | ||
1673 | } | ||
1674 | seq_printf(seq, ",jqfmt=%s", fmtname); | ||
1675 | } | ||
1676 | |||
1677 | if (sbi->s_qf_names[USRQUOTA]) | ||
1678 | seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); | ||
1679 | |||
1680 | if (sbi->s_qf_names[GRPQUOTA]) | ||
1681 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | ||
1682 | |||
1683 | if (test_opt(sb, USRQUOTA)) | ||
1684 | seq_puts(seq, ",usrquota"); | ||
1685 | |||
1686 | if (test_opt(sb, GRPQUOTA)) | ||
1687 | seq_puts(seq, ",grpquota"); | ||
1688 | #endif | ||
1689 | } | ||
1690 | |||
1691 | static const char *token2str(int token) | ||
1692 | { | ||
1693 | static const struct match_token *t; | ||
1694 | |||
1695 | for (t = tokens; t->token != Opt_err; t++) | ||
1696 | if (t->token == token && !strchr(t->pattern, '=')) | ||
1697 | break; | ||
1698 | return t->pattern; | ||
1699 | } | ||
1700 | |||
1701 | /* | ||
1702 | * Show an option if | ||
1703 | * - it's set to a non-default value OR | ||
1704 | * - if the per-sb default is different from the global default | ||
1705 | */ | ||
1706 | static int _ext4_show_options(struct seq_file *seq, struct super_block *sb, | ||
1707 | int nodefs) | ||
1708 | { | ||
1709 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1710 | struct ext4_super_block *es = sbi->s_es; | ||
1711 | int def_errors, def_mount_opt = nodefs ? 0 : sbi->s_def_mount_opt; | ||
1712 | const struct mount_opts *m; | ||
1713 | char sep = nodefs ? '\n' : ','; | ||
1714 | |||
1715 | #define SEQ_OPTS_PUTS(str) seq_printf(seq, "%c" str, sep) | ||
1716 | #define SEQ_OPTS_PRINT(str, arg) seq_printf(seq, "%c" str, sep, arg) | ||
1717 | |||
1718 | if (sbi->s_sb_block != 1) | ||
1719 | SEQ_OPTS_PRINT("sb=%llu", sbi->s_sb_block); | ||
1720 | |||
1721 | for (m = ext4_mount_opts; m->token != Opt_err; m++) { | ||
1722 | int want_set = m->flags & MOPT_SET; | ||
1723 | if (((m->flags & (MOPT_SET|MOPT_CLEAR)) == 0) || | ||
1724 | (m->flags & MOPT_CLEAR_ERR)) | ||
1725 | continue; | ||
1726 | if (!(m->mount_opt & (sbi->s_mount_opt ^ def_mount_opt))) | ||
1727 | continue; /* skip if same as the default */ | ||
1728 | if ((want_set && | ||
1729 | (sbi->s_mount_opt & m->mount_opt) != m->mount_opt) || | ||
1730 | (!want_set && (sbi->s_mount_opt & m->mount_opt))) | ||
1731 | continue; /* select Opt_noFoo vs Opt_Foo */ | ||
1732 | SEQ_OPTS_PRINT("%s", token2str(m->token)); | ||
1733 | } | ||
1734 | |||
1735 | if (nodefs || sbi->s_resuid != EXT4_DEF_RESUID || | ||
1736 | le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) | ||
1737 | SEQ_OPTS_PRINT("resuid=%u", sbi->s_resuid); | ||
1738 | if (nodefs || sbi->s_resgid != EXT4_DEF_RESGID || | ||
1739 | le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) | ||
1740 | SEQ_OPTS_PRINT("resgid=%u", sbi->s_resgid); | ||
1741 | def_errors = nodefs ? -1 : le16_to_cpu(es->s_errors); | ||
1742 | if (test_opt(sb, ERRORS_RO) && def_errors != EXT4_ERRORS_RO) | ||
1743 | SEQ_OPTS_PUTS("errors=remount-ro"); | ||
1744 | if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE) | ||
1745 | SEQ_OPTS_PUTS("errors=continue"); | ||
1746 | if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC) | ||
1747 | SEQ_OPTS_PUTS("errors=panic"); | ||
1748 | if (nodefs || sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) | ||
1749 | SEQ_OPTS_PRINT("commit=%lu", sbi->s_commit_interval / HZ); | ||
1750 | if (nodefs || sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME) | ||
1751 | SEQ_OPTS_PRINT("min_batch_time=%u", sbi->s_min_batch_time); | ||
1752 | if (nodefs || sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME) | ||
1753 | SEQ_OPTS_PRINT("max_batch_time=%u", sbi->s_max_batch_time); | ||
1754 | if (sb->s_flags & MS_I_VERSION) | ||
1755 | SEQ_OPTS_PUTS("i_version"); | ||
1756 | if (nodefs || sbi->s_stripe) | ||
1757 | SEQ_OPTS_PRINT("stripe=%lu", sbi->s_stripe); | ||
1758 | if (EXT4_MOUNT_DATA_FLAGS & (sbi->s_mount_opt ^ def_mount_opt)) { | ||
1759 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) | ||
1760 | SEQ_OPTS_PUTS("data=journal"); | ||
1761 | else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) | ||
1762 | SEQ_OPTS_PUTS("data=ordered"); | ||
1763 | else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | ||
1764 | SEQ_OPTS_PUTS("data=writeback"); | ||
1765 | } | ||
1766 | if (nodefs || | ||
1767 | sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS) | ||
1768 | SEQ_OPTS_PRINT("inode_readahead_blks=%u", | ||
1769 | sbi->s_inode_readahead_blks); | ||
1770 | |||
1771 | if (nodefs || (test_opt(sb, INIT_INODE_TABLE) && | ||
1772 | (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT))) | ||
1773 | SEQ_OPTS_PRINT("init_itable=%u", sbi->s_li_wait_mult); | ||
1774 | |||
1775 | ext4_show_quota_options(seq, sb); | ||
1776 | return 0; | ||
1777 | } | ||
1778 | |||
1779 | static int ext4_show_options(struct seq_file *seq, struct dentry *root) | ||
1780 | { | ||
1781 | return _ext4_show_options(seq, root->d_sb, 0); | ||
1782 | } | ||
1783 | |||
1784 | static int options_seq_show(struct seq_file *seq, void *offset) | ||
1785 | { | ||
1786 | struct super_block *sb = seq->private; | ||
1787 | int rc; | ||
1788 | |||
1789 | seq_puts(seq, (sb->s_flags & MS_RDONLY) ? "ro" : "rw"); | ||
1790 | rc = _ext4_show_options(seq, sb, 1); | ||
1791 | seq_puts(seq, "\n"); | ||
1792 | return rc; | ||
1793 | } | ||
1794 | |||
1795 | static int options_open_fs(struct inode *inode, struct file *file) | ||
1796 | { | ||
1797 | return single_open(file, options_seq_show, PDE(inode)->data); | ||
1798 | } | ||
1799 | |||
1800 | static const struct file_operations ext4_seq_options_fops = { | ||
1801 | .owner = THIS_MODULE, | ||
1802 | .open = options_open_fs, | ||
1803 | .read = seq_read, | ||
1804 | .llseek = seq_lseek, | ||
1805 | .release = single_release, | ||
1806 | }; | ||
1807 | |||
1945 | static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | 1808 | static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, |
1946 | int read_only) | 1809 | int read_only) |
1947 | { | 1810 | { |
@@ -2945,7 +2808,7 @@ static int ext4_run_lazyinit_thread(void) | |||
2945 | ext4_clear_request_list(); | 2808 | ext4_clear_request_list(); |
2946 | kfree(ext4_li_info); | 2809 | kfree(ext4_li_info); |
2947 | ext4_li_info = NULL; | 2810 | ext4_li_info = NULL; |
2948 | printk(KERN_CRIT "EXT4: error %d creating inode table " | 2811 | printk(KERN_CRIT "EXT4-fs: error %d creating inode table " |
2949 | "initialization thread\n", | 2812 | "initialization thread\n", |
2950 | err); | 2813 | err); |
2951 | return err; | 2814 | return err; |
@@ -3183,11 +3046,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3183 | set_opt(sb, INIT_INODE_TABLE); | 3046 | set_opt(sb, INIT_INODE_TABLE); |
3184 | if (def_mount_opts & EXT4_DEFM_DEBUG) | 3047 | if (def_mount_opts & EXT4_DEFM_DEBUG) |
3185 | set_opt(sb, DEBUG); | 3048 | set_opt(sb, DEBUG); |
3186 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { | 3049 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) |
3187 | ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups", | ||
3188 | "2.6.38"); | ||
3189 | set_opt(sb, GRPID); | 3050 | set_opt(sb, GRPID); |
3190 | } | ||
3191 | if (def_mount_opts & EXT4_DEFM_UID16) | 3051 | if (def_mount_opts & EXT4_DEFM_UID16) |
3192 | set_opt(sb, NO_UID32); | 3052 | set_opt(sb, NO_UID32); |
3193 | /* xattr user namespace & acls are now defaulted on */ | 3053 | /* xattr user namespace & acls are now defaulted on */ |
@@ -3240,13 +3100,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3240 | sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT; | 3100 | sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT; |
3241 | 3101 | ||
3242 | if (!parse_options((char *) sbi->s_es->s_mount_opts, sb, | 3102 | if (!parse_options((char *) sbi->s_es->s_mount_opts, sb, |
3243 | &journal_devnum, &journal_ioprio, NULL, 0)) { | 3103 | &journal_devnum, &journal_ioprio, 0)) { |
3244 | ext4_msg(sb, KERN_WARNING, | 3104 | ext4_msg(sb, KERN_WARNING, |
3245 | "failed to parse options in superblock: %s", | 3105 | "failed to parse options in superblock: %s", |
3246 | sbi->s_es->s_mount_opts); | 3106 | sbi->s_es->s_mount_opts); |
3247 | } | 3107 | } |
3108 | sbi->s_def_mount_opt = sbi->s_mount_opt; | ||
3248 | if (!parse_options((char *) data, sb, &journal_devnum, | 3109 | if (!parse_options((char *) data, sb, &journal_devnum, |
3249 | &journal_ioprio, NULL, 0)) | 3110 | &journal_ioprio, 0)) |
3250 | goto failed_mount; | 3111 | goto failed_mount; |
3251 | 3112 | ||
3252 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | 3113 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { |
@@ -3416,7 +3277,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3416 | #else | 3277 | #else |
3417 | es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); | 3278 | es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); |
3418 | #endif | 3279 | #endif |
3419 | sb->s_dirt = 1; | ||
3420 | } | 3280 | } |
3421 | 3281 | ||
3422 | /* Handle clustersize */ | 3282 | /* Handle clustersize */ |
@@ -3540,6 +3400,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3540 | if (ext4_proc_root) | 3400 | if (ext4_proc_root) |
3541 | sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); | 3401 | sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); |
3542 | 3402 | ||
3403 | if (sbi->s_proc) | ||
3404 | proc_create_data("options", S_IRUGO, sbi->s_proc, | ||
3405 | &ext4_seq_options_fops, sb); | ||
3406 | |||
3543 | bgl_lock_init(sbi->s_blockgroup_lock); | 3407 | bgl_lock_init(sbi->s_blockgroup_lock); |
3544 | 3408 | ||
3545 | for (i = 0; i < db_count; i++) { | 3409 | for (i = 0; i < db_count; i++) { |
@@ -3694,6 +3558,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3694 | } | 3558 | } |
3695 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 3559 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
3696 | 3560 | ||
3561 | sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; | ||
3562 | |||
3697 | /* | 3563 | /* |
3698 | * The journal may have updated the bg summary counts, so we | 3564 | * The journal may have updated the bg summary counts, so we |
3699 | * need to update the global counters. | 3565 | * need to update the global counters. |
@@ -3861,6 +3727,7 @@ failed_mount2: | |||
3861 | ext4_kvfree(sbi->s_group_desc); | 3727 | ext4_kvfree(sbi->s_group_desc); |
3862 | failed_mount: | 3728 | failed_mount: |
3863 | if (sbi->s_proc) { | 3729 | if (sbi->s_proc) { |
3730 | remove_proc_entry("options", sbi->s_proc); | ||
3864 | remove_proc_entry(sb->s_id, ext4_proc_root); | 3731 | remove_proc_entry(sb->s_id, ext4_proc_root); |
3865 | } | 3732 | } |
3866 | #ifdef CONFIG_QUOTA | 3733 | #ifdef CONFIG_QUOTA |
@@ -4090,15 +3957,6 @@ static int ext4_load_journal(struct super_block *sb, | |||
4090 | if (!(journal->j_flags & JBD2_BARRIER)) | 3957 | if (!(journal->j_flags & JBD2_BARRIER)) |
4091 | ext4_msg(sb, KERN_INFO, "barriers disabled"); | 3958 | ext4_msg(sb, KERN_INFO, "barriers disabled"); |
4092 | 3959 | ||
4093 | if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { | ||
4094 | err = jbd2_journal_update_format(journal); | ||
4095 | if (err) { | ||
4096 | ext4_msg(sb, KERN_ERR, "error updating journal"); | ||
4097 | jbd2_journal_destroy(journal); | ||
4098 | return err; | ||
4099 | } | ||
4100 | } | ||
4101 | |||
4102 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) | 3960 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) |
4103 | err = jbd2_journal_wipe(journal, !really_read_only); | 3961 | err = jbd2_journal_wipe(journal, !really_read_only); |
4104 | if (!err) { | 3962 | if (!err) { |
@@ -4385,7 +4243,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4385 | { | 4243 | { |
4386 | struct ext4_super_block *es; | 4244 | struct ext4_super_block *es; |
4387 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 4245 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
4388 | ext4_fsblk_t n_blocks_count = 0; | ||
4389 | unsigned long old_sb_flags; | 4246 | unsigned long old_sb_flags; |
4390 | struct ext4_mount_options old_opts; | 4247 | struct ext4_mount_options old_opts; |
4391 | int enable_quota = 0; | 4248 | int enable_quota = 0; |
@@ -4418,8 +4275,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4418 | /* | 4275 | /* |
4419 | * Allow the "check" option to be passed as a remount option. | 4276 | * Allow the "check" option to be passed as a remount option. |
4420 | */ | 4277 | */ |
4421 | if (!parse_options(data, sb, NULL, &journal_ioprio, | 4278 | if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) { |
4422 | &n_blocks_count, 1)) { | ||
4423 | err = -EINVAL; | 4279 | err = -EINVAL; |
4424 | goto restore_opts; | 4280 | goto restore_opts; |
4425 | } | 4281 | } |
@@ -4437,8 +4293,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4437 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 4293 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
4438 | } | 4294 | } |
4439 | 4295 | ||
4440 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || | 4296 | if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) { |
4441 | n_blocks_count > ext4_blocks_count(es)) { | ||
4442 | if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) { | 4297 | if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) { |
4443 | err = -EROFS; | 4298 | err = -EROFS; |
4444 | goto restore_opts; | 4299 | goto restore_opts; |
@@ -4513,8 +4368,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
4513 | if (sbi->s_journal) | 4368 | if (sbi->s_journal) |
4514 | ext4_clear_journal_err(sb, es); | 4369 | ext4_clear_journal_err(sb, es); |
4515 | sbi->s_mount_state = le16_to_cpu(es->s_state); | 4370 | sbi->s_mount_state = le16_to_cpu(es->s_state); |
4516 | if ((err = ext4_group_extend(sb, es, n_blocks_count))) | ||
4517 | goto restore_opts; | ||
4518 | if (!ext4_setup_super(sb, es, 0)) | 4371 | if (!ext4_setup_super(sb, es, 0)) |
4519 | sb->s_flags &= ~MS_RDONLY; | 4372 | sb->s_flags &= ~MS_RDONLY; |
4520 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, | 4373 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, |