diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 537 |
1 files changed, 353 insertions, 184 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d4ca92aab514..e14d22c170d5 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -68,7 +68,21 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); | |||
68 | static int ext4_unfreeze(struct super_block *sb); | 68 | static int ext4_unfreeze(struct super_block *sb); |
69 | static void ext4_write_super(struct super_block *sb); | 69 | static void ext4_write_super(struct super_block *sb); |
70 | static int ext4_freeze(struct super_block *sb); | 70 | static int ext4_freeze(struct super_block *sb); |
71 | static int ext4_get_sb(struct file_system_type *fs_type, int flags, | ||
72 | const char *dev_name, void *data, struct vfsmount *mnt); | ||
71 | 73 | ||
74 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | ||
75 | static struct file_system_type ext3_fs_type = { | ||
76 | .owner = THIS_MODULE, | ||
77 | .name = "ext3", | ||
78 | .get_sb = ext4_get_sb, | ||
79 | .kill_sb = kill_block_super, | ||
80 | .fs_flags = FS_REQUIRES_DEV, | ||
81 | }; | ||
82 | #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) | ||
83 | #else | ||
84 | #define IS_EXT3_SB(sb) (0) | ||
85 | #endif | ||
72 | 86 | ||
73 | ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, | 87 | ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, |
74 | struct ext4_group_desc *bg) | 88 | struct ext4_group_desc *bg) |
@@ -302,7 +316,7 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn, | |||
302 | * write out the superblock safely. | 316 | * write out the superblock safely. |
303 | * | 317 | * |
304 | * We'll just use the jbd2_journal_abort() error code to record an error in | 318 | * We'll just use the jbd2_journal_abort() error code to record an error in |
305 | * the journal instead. On recovery, the journal will compain about | 319 | * the journal instead. On recovery, the journal will complain about |
306 | * that error until we've noted it down and cleared it. | 320 | * that error until we've noted it down and cleared it. |
307 | */ | 321 | */ |
308 | 322 | ||
@@ -333,7 +347,7 @@ static void ext4_handle_error(struct super_block *sb) | |||
333 | sb->s_id); | 347 | sb->s_id); |
334 | } | 348 | } |
335 | 349 | ||
336 | void ext4_error(struct super_block *sb, const char *function, | 350 | void __ext4_error(struct super_block *sb, const char *function, |
337 | const char *fmt, ...) | 351 | const char *fmt, ...) |
338 | { | 352 | { |
339 | va_list args; | 353 | va_list args; |
@@ -347,6 +361,42 @@ void ext4_error(struct super_block *sb, const char *function, | |||
347 | ext4_handle_error(sb); | 361 | ext4_handle_error(sb); |
348 | } | 362 | } |
349 | 363 | ||
364 | void ext4_error_inode(const char *function, struct inode *inode, | ||
365 | const char *fmt, ...) | ||
366 | { | ||
367 | va_list args; | ||
368 | |||
369 | va_start(args, fmt); | ||
370 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: inode #%lu: (comm %s) ", | ||
371 | inode->i_sb->s_id, function, inode->i_ino, current->comm); | ||
372 | vprintk(fmt, args); | ||
373 | printk("\n"); | ||
374 | va_end(args); | ||
375 | |||
376 | ext4_handle_error(inode->i_sb); | ||
377 | } | ||
378 | |||
379 | void ext4_error_file(const char *function, struct file *file, | ||
380 | const char *fmt, ...) | ||
381 | { | ||
382 | va_list args; | ||
383 | struct inode *inode = file->f_dentry->d_inode; | ||
384 | char pathname[80], *path; | ||
385 | |||
386 | va_start(args, fmt); | ||
387 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | ||
388 | if (!path) | ||
389 | path = "(unknown)"; | ||
390 | printk(KERN_CRIT | ||
391 | "EXT4-fs error (device %s): %s: inode #%lu (comm %s path %s): ", | ||
392 | inode->i_sb->s_id, function, inode->i_ino, current->comm, path); | ||
393 | vprintk(fmt, args); | ||
394 | printk("\n"); | ||
395 | va_end(args); | ||
396 | |||
397 | ext4_handle_error(inode->i_sb); | ||
398 | } | ||
399 | |||
350 | static const char *ext4_decode_error(struct super_block *sb, int errno, | 400 | static const char *ext4_decode_error(struct super_block *sb, int errno, |
351 | char nbuf[16]) | 401 | char nbuf[16]) |
352 | { | 402 | { |
@@ -450,7 +500,7 @@ void ext4_msg (struct super_block * sb, const char *prefix, | |||
450 | va_end(args); | 500 | va_end(args); |
451 | } | 501 | } |
452 | 502 | ||
453 | void ext4_warning(struct super_block *sb, const char *function, | 503 | void __ext4_warning(struct super_block *sb, const char *function, |
454 | const char *fmt, ...) | 504 | const char *fmt, ...) |
455 | { | 505 | { |
456 | va_list args; | 506 | va_list args; |
@@ -507,7 +557,7 @@ void ext4_update_dynamic_rev(struct super_block *sb) | |||
507 | if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) | 557 | if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) |
508 | return; | 558 | return; |
509 | 559 | ||
510 | ext4_warning(sb, __func__, | 560 | ext4_warning(sb, |
511 | "updating to rev %d because of new feature flag, " | 561 | "updating to rev %d because of new feature flag, " |
512 | "running e2fsck is recommended", | 562 | "running e2fsck is recommended", |
513 | EXT4_DYNAMIC_REV); | 563 | EXT4_DYNAMIC_REV); |
@@ -603,10 +653,6 @@ static void ext4_put_super(struct super_block *sb) | |||
603 | if (sb->s_dirt) | 653 | if (sb->s_dirt) |
604 | ext4_commit_super(sb, 1); | 654 | ext4_commit_super(sb, 1); |
605 | 655 | ||
606 | ext4_release_system_zone(sb); | ||
607 | ext4_mb_release(sb); | ||
608 | ext4_ext_release(sb); | ||
609 | ext4_xattr_put_super(sb); | ||
610 | if (sbi->s_journal) { | 656 | if (sbi->s_journal) { |
611 | err = jbd2_journal_destroy(sbi->s_journal); | 657 | err = jbd2_journal_destroy(sbi->s_journal); |
612 | sbi->s_journal = NULL; | 658 | sbi->s_journal = NULL; |
@@ -614,6 +660,12 @@ static void ext4_put_super(struct super_block *sb) | |||
614 | ext4_abort(sb, __func__, | 660 | ext4_abort(sb, __func__, |
615 | "Couldn't clean up the journal"); | 661 | "Couldn't clean up the journal"); |
616 | } | 662 | } |
663 | |||
664 | ext4_release_system_zone(sb); | ||
665 | ext4_mb_release(sb); | ||
666 | ext4_ext_release(sb); | ||
667 | ext4_xattr_put_super(sb); | ||
668 | |||
617 | if (!(sb->s_flags & MS_RDONLY)) { | 669 | if (!(sb->s_flags & MS_RDONLY)) { |
618 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 670 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
619 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 671 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
@@ -700,10 +752,17 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
700 | ei->i_reserved_data_blocks = 0; | 752 | ei->i_reserved_data_blocks = 0; |
701 | ei->i_reserved_meta_blocks = 0; | 753 | ei->i_reserved_meta_blocks = 0; |
702 | ei->i_allocated_meta_blocks = 0; | 754 | ei->i_allocated_meta_blocks = 0; |
755 | ei->i_da_metadata_calc_len = 0; | ||
703 | ei->i_delalloc_reserved_flag = 0; | 756 | ei->i_delalloc_reserved_flag = 0; |
704 | spin_lock_init(&(ei->i_block_reservation_lock)); | 757 | spin_lock_init(&(ei->i_block_reservation_lock)); |
705 | INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); | 758 | #ifdef CONFIG_QUOTA |
759 | ei->i_reserved_quota = 0; | ||
760 | #endif | ||
761 | INIT_LIST_HEAD(&ei->i_completed_io_list); | ||
762 | spin_lock_init(&ei->i_completed_io_lock); | ||
706 | ei->cur_aio_dio = NULL; | 763 | ei->cur_aio_dio = NULL; |
764 | ei->i_sync_tid = 0; | ||
765 | ei->i_datasync_tid = 0; | ||
707 | 766 | ||
708 | return &ei->vfs_inode; | 767 | return &ei->vfs_inode; |
709 | } | 768 | } |
@@ -753,6 +812,7 @@ static void destroy_inodecache(void) | |||
753 | 812 | ||
754 | static void ext4_clear_inode(struct inode *inode) | 813 | static void ext4_clear_inode(struct inode *inode) |
755 | { | 814 | { |
815 | dquot_drop(inode); | ||
756 | ext4_discard_preallocations(inode); | 816 | ext4_discard_preallocations(inode); |
757 | if (EXT4_JOURNAL(inode)) | 817 | if (EXT4_JOURNAL(inode)) |
758 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, | 818 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, |
@@ -765,9 +825,22 @@ static inline void ext4_show_quota_options(struct seq_file *seq, | |||
765 | #if defined(CONFIG_QUOTA) | 825 | #if defined(CONFIG_QUOTA) |
766 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 826 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
767 | 827 | ||
768 | if (sbi->s_jquota_fmt) | 828 | if (sbi->s_jquota_fmt) { |
769 | seq_printf(seq, ",jqfmt=%s", | 829 | char *fmtname = ""; |
770 | (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold" : "vfsv0"); | 830 | |
831 | switch (sbi->s_jquota_fmt) { | ||
832 | case QFMT_VFS_OLD: | ||
833 | fmtname = "vfsold"; | ||
834 | break; | ||
835 | case QFMT_VFS_V0: | ||
836 | fmtname = "vfsv0"; | ||
837 | break; | ||
838 | case QFMT_VFS_V1: | ||
839 | fmtname = "vfsv1"; | ||
840 | break; | ||
841 | } | ||
842 | seq_printf(seq, ",jqfmt=%s", fmtname); | ||
843 | } | ||
771 | 844 | ||
772 | if (sbi->s_qf_names[USRQUOTA]) | 845 | if (sbi->s_qf_names[USRQUOTA]) |
773 | seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); | 846 | seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); |
@@ -775,10 +848,10 @@ static inline void ext4_show_quota_options(struct seq_file *seq, | |||
775 | if (sbi->s_qf_names[GRPQUOTA]) | 848 | if (sbi->s_qf_names[GRPQUOTA]) |
776 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | 849 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); |
777 | 850 | ||
778 | if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) | 851 | if (test_opt(sb, USRQUOTA)) |
779 | seq_puts(seq, ",usrquota"); | 852 | seq_puts(seq, ",usrquota"); |
780 | 853 | ||
781 | if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) | 854 | if (test_opt(sb, GRPQUOTA)) |
782 | seq_puts(seq, ",grpquota"); | 855 | seq_puts(seq, ",grpquota"); |
783 | #endif | 856 | #endif |
784 | } | 857 | } |
@@ -899,6 +972,15 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
899 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) | 972 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) |
900 | seq_puts(seq, ",noauto_da_alloc"); | 973 | seq_puts(seq, ",noauto_da_alloc"); |
901 | 974 | ||
975 | if (test_opt(sb, DISCARD)) | ||
976 | seq_puts(seq, ",discard"); | ||
977 | |||
978 | if (test_opt(sb, NOLOAD)) | ||
979 | seq_puts(seq, ",norecovery"); | ||
980 | |||
981 | if (test_opt(sb, DIOREAD_NOLOCK)) | ||
982 | seq_puts(seq, ",dioread_nolock"); | ||
983 | |||
902 | ext4_show_quota_options(seq, sb); | 984 | ext4_show_quota_options(seq, sb); |
903 | 985 | ||
904 | return 0; | 986 | return 0; |
@@ -985,17 +1067,9 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
985 | const char *data, size_t len, loff_t off); | 1067 | const char *data, size_t len, loff_t off); |
986 | 1068 | ||
987 | static const struct dquot_operations ext4_quota_operations = { | 1069 | static const struct dquot_operations ext4_quota_operations = { |
988 | .initialize = dquot_initialize, | 1070 | #ifdef CONFIG_QUOTA |
989 | .drop = dquot_drop, | ||
990 | .alloc_space = dquot_alloc_space, | ||
991 | .reserve_space = dquot_reserve_space, | ||
992 | .claim_space = dquot_claim_space, | ||
993 | .release_rsv = dquot_release_reserved_space, | ||
994 | .get_reserved_space = ext4_get_reserved_space, | 1071 | .get_reserved_space = ext4_get_reserved_space, |
995 | .alloc_inode = dquot_alloc_inode, | 1072 | #endif |
996 | .free_space = dquot_free_space, | ||
997 | .free_inode = dquot_free_inode, | ||
998 | .transfer = dquot_transfer, | ||
999 | .write_dquot = ext4_write_dquot, | 1073 | .write_dquot = ext4_write_dquot, |
1000 | .acquire_dquot = ext4_acquire_dquot, | 1074 | .acquire_dquot = ext4_acquire_dquot, |
1001 | .release_dquot = ext4_release_dquot, | 1075 | .release_dquot = ext4_release_dquot, |
@@ -1074,12 +1148,14 @@ enum { | |||
1074 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 1148 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
1075 | Opt_data_err_abort, Opt_data_err_ignore, | 1149 | Opt_data_err_abort, Opt_data_err_ignore, |
1076 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 1150 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
1077 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 1151 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
1078 | Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, | 1152 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, |
1079 | Opt_usrquota, Opt_grpquota, Opt_i_version, | 1153 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, |
1080 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1154 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
1081 | Opt_block_validity, Opt_noblock_validity, | 1155 | Opt_block_validity, Opt_noblock_validity, |
1082 | Opt_inode_readahead_blks, Opt_journal_ioprio | 1156 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1157 | Opt_dioread_nolock, Opt_dioread_lock, | ||
1158 | Opt_discard, Opt_nodiscard, | ||
1083 | }; | 1159 | }; |
1084 | 1160 | ||
1085 | static const match_table_t tokens = { | 1161 | static const match_table_t tokens = { |
@@ -1104,6 +1180,7 @@ static const match_table_t tokens = { | |||
1104 | {Opt_acl, "acl"}, | 1180 | {Opt_acl, "acl"}, |
1105 | {Opt_noacl, "noacl"}, | 1181 | {Opt_noacl, "noacl"}, |
1106 | {Opt_noload, "noload"}, | 1182 | {Opt_noload, "noload"}, |
1183 | {Opt_noload, "norecovery"}, | ||
1107 | {Opt_nobh, "nobh"}, | 1184 | {Opt_nobh, "nobh"}, |
1108 | {Opt_bh, "bh"}, | 1185 | {Opt_bh, "bh"}, |
1109 | {Opt_commit, "commit=%u"}, | 1186 | {Opt_commit, "commit=%u"}, |
@@ -1125,6 +1202,7 @@ static const match_table_t tokens = { | |||
1125 | {Opt_grpjquota, "grpjquota=%s"}, | 1202 | {Opt_grpjquota, "grpjquota=%s"}, |
1126 | {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, | 1203 | {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, |
1127 | {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, | 1204 | {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, |
1205 | {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"}, | ||
1128 | {Opt_grpquota, "grpquota"}, | 1206 | {Opt_grpquota, "grpquota"}, |
1129 | {Opt_noquota, "noquota"}, | 1207 | {Opt_noquota, "noquota"}, |
1130 | {Opt_quota, "quota"}, | 1208 | {Opt_quota, "quota"}, |
@@ -1144,6 +1222,10 @@ static const match_table_t tokens = { | |||
1144 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, | 1222 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, |
1145 | {Opt_auto_da_alloc, "auto_da_alloc"}, | 1223 | {Opt_auto_da_alloc, "auto_da_alloc"}, |
1146 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, | 1224 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, |
1225 | {Opt_dioread_nolock, "dioread_nolock"}, | ||
1226 | {Opt_dioread_lock, "dioread_lock"}, | ||
1227 | {Opt_discard, "discard"}, | ||
1228 | {Opt_nodiscard, "nodiscard"}, | ||
1147 | {Opt_err, NULL}, | 1229 | {Opt_err, NULL}, |
1148 | }; | 1230 | }; |
1149 | 1231 | ||
@@ -1171,6 +1253,66 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
1171 | } | 1253 | } |
1172 | 1254 | ||
1173 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) | 1255 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) |
1256 | static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" | ||
1257 | "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; | ||
1258 | |||
1259 | #ifdef CONFIG_QUOTA | ||
1260 | static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | ||
1261 | { | ||
1262 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1263 | char *qname; | ||
1264 | |||
1265 | if (sb_any_quota_loaded(sb) && | ||
1266 | !sbi->s_qf_names[qtype]) { | ||
1267 | ext4_msg(sb, KERN_ERR, | ||
1268 | "Cannot change journaled " | ||
1269 | "quota options when quota turned on"); | ||
1270 | return 0; | ||
1271 | } | ||
1272 | qname = match_strdup(args); | ||
1273 | if (!qname) { | ||
1274 | ext4_msg(sb, KERN_ERR, | ||
1275 | "Not enough memory for storing quotafile name"); | ||
1276 | return 0; | ||
1277 | } | ||
1278 | if (sbi->s_qf_names[qtype] && | ||
1279 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
1280 | ext4_msg(sb, KERN_ERR, | ||
1281 | "%s quota file already specified", QTYPE2NAME(qtype)); | ||
1282 | kfree(qname); | ||
1283 | return 0; | ||
1284 | } | ||
1285 | sbi->s_qf_names[qtype] = qname; | ||
1286 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1287 | ext4_msg(sb, KERN_ERR, | ||
1288 | "quotafile must be on filesystem root"); | ||
1289 | kfree(sbi->s_qf_names[qtype]); | ||
1290 | sbi->s_qf_names[qtype] = NULL; | ||
1291 | return 0; | ||
1292 | } | ||
1293 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1294 | return 1; | ||
1295 | } | ||
1296 | |||
1297 | static int clear_qf_name(struct super_block *sb, int qtype) | ||
1298 | { | ||
1299 | |||
1300 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1301 | |||
1302 | if (sb_any_quota_loaded(sb) && | ||
1303 | sbi->s_qf_names[qtype]) { | ||
1304 | ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" | ||
1305 | " when quota turned on"); | ||
1306 | return 0; | ||
1307 | } | ||
1308 | /* | ||
1309 | * The space will be released later when all options are confirmed | ||
1310 | * to be correct | ||
1311 | */ | ||
1312 | sbi->s_qf_names[qtype] = NULL; | ||
1313 | return 1; | ||
1314 | } | ||
1315 | #endif | ||
1174 | 1316 | ||
1175 | static int parse_options(char *options, struct super_block *sb, | 1317 | static int parse_options(char *options, struct super_block *sb, |
1176 | unsigned long *journal_devnum, | 1318 | unsigned long *journal_devnum, |
@@ -1183,8 +1325,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
1183 | int data_opt = 0; | 1325 | int data_opt = 0; |
1184 | int option; | 1326 | int option; |
1185 | #ifdef CONFIG_QUOTA | 1327 | #ifdef CONFIG_QUOTA |
1186 | int qtype, qfmt; | 1328 | int qfmt; |
1187 | char *qname; | ||
1188 | #endif | 1329 | #endif |
1189 | 1330 | ||
1190 | if (!options) | 1331 | if (!options) |
@@ -1195,19 +1336,31 @@ static int parse_options(char *options, struct super_block *sb, | |||
1195 | if (!*p) | 1336 | if (!*p) |
1196 | continue; | 1337 | continue; |
1197 | 1338 | ||
1339 | /* | ||
1340 | * Initialize args struct so we know whether arg was | ||
1341 | * found; some options take optional arguments. | ||
1342 | */ | ||
1343 | args[0].to = args[0].from = 0; | ||
1198 | token = match_token(p, tokens, args); | 1344 | token = match_token(p, tokens, args); |
1199 | switch (token) { | 1345 | switch (token) { |
1200 | case Opt_bsd_df: | 1346 | case Opt_bsd_df: |
1347 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1201 | clear_opt(sbi->s_mount_opt, MINIX_DF); | 1348 | clear_opt(sbi->s_mount_opt, MINIX_DF); |
1202 | break; | 1349 | break; |
1203 | case Opt_minix_df: | 1350 | case Opt_minix_df: |
1351 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1204 | set_opt(sbi->s_mount_opt, MINIX_DF); | 1352 | set_opt(sbi->s_mount_opt, MINIX_DF); |
1353 | |||
1205 | break; | 1354 | break; |
1206 | case Opt_grpid: | 1355 | case Opt_grpid: |
1356 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1207 | set_opt(sbi->s_mount_opt, GRPID); | 1357 | set_opt(sbi->s_mount_opt, GRPID); |
1358 | |||
1208 | break; | 1359 | break; |
1209 | case Opt_nogrpid: | 1360 | case Opt_nogrpid: |
1361 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1210 | clear_opt(sbi->s_mount_opt, GRPID); | 1362 | clear_opt(sbi->s_mount_opt, GRPID); |
1363 | |||
1211 | break; | 1364 | break; |
1212 | case Opt_resuid: | 1365 | case Opt_resuid: |
1213 | if (match_int(&args[0], &option)) | 1366 | if (match_int(&args[0], &option)) |
@@ -1344,14 +1497,13 @@ static int parse_options(char *options, struct super_block *sb, | |||
1344 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; | 1497 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; |
1345 | datacheck: | 1498 | datacheck: |
1346 | if (is_remount) { | 1499 | if (is_remount) { |
1347 | if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) | 1500 | if (test_opt(sb, DATA_FLAGS) != data_opt) { |
1348 | != data_opt) { | ||
1349 | ext4_msg(sb, KERN_ERR, | 1501 | ext4_msg(sb, KERN_ERR, |
1350 | "Cannot change data mode on remount"); | 1502 | "Cannot change data mode on remount"); |
1351 | return 0; | 1503 | return 0; |
1352 | } | 1504 | } |
1353 | } else { | 1505 | } else { |
1354 | sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS; | 1506 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
1355 | sbi->s_mount_opt |= data_opt; | 1507 | sbi->s_mount_opt |= data_opt; |
1356 | } | 1508 | } |
1357 | break; | 1509 | break; |
@@ -1363,68 +1515,30 @@ static int parse_options(char *options, struct super_block *sb, | |||
1363 | break; | 1515 | break; |
1364 | #ifdef CONFIG_QUOTA | 1516 | #ifdef CONFIG_QUOTA |
1365 | case Opt_usrjquota: | 1517 | case Opt_usrjquota: |
1366 | qtype = USRQUOTA; | 1518 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
1367 | goto set_qf_name; | ||
1368 | case Opt_grpjquota: | ||
1369 | qtype = GRPQUOTA; | ||
1370 | set_qf_name: | ||
1371 | if (sb_any_quota_loaded(sb) && | ||
1372 | !sbi->s_qf_names[qtype]) { | ||
1373 | ext4_msg(sb, KERN_ERR, | ||
1374 | "Cannot change journaled " | ||
1375 | "quota options when quota turned on"); | ||
1376 | return 0; | ||
1377 | } | ||
1378 | qname = match_strdup(&args[0]); | ||
1379 | if (!qname) { | ||
1380 | ext4_msg(sb, KERN_ERR, | ||
1381 | "Not enough memory for " | ||
1382 | "storing quotafile name"); | ||
1383 | return 0; | 1519 | return 0; |
1384 | } | 1520 | break; |
1385 | if (sbi->s_qf_names[qtype] && | 1521 | case Opt_grpjquota: |
1386 | strcmp(sbi->s_qf_names[qtype], qname)) { | 1522 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
1387 | ext4_msg(sb, KERN_ERR, | ||
1388 | "%s quota file already " | ||
1389 | "specified", QTYPE2NAME(qtype)); | ||
1390 | kfree(qname); | ||
1391 | return 0; | ||
1392 | } | ||
1393 | sbi->s_qf_names[qtype] = qname; | ||
1394 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1395 | ext4_msg(sb, KERN_ERR, | ||
1396 | "quotafile must be on " | ||
1397 | "filesystem root"); | ||
1398 | kfree(sbi->s_qf_names[qtype]); | ||
1399 | sbi->s_qf_names[qtype] = NULL; | ||
1400 | return 0; | 1523 | return 0; |
1401 | } | ||
1402 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1403 | break; | 1524 | break; |
1404 | case Opt_offusrjquota: | 1525 | case Opt_offusrjquota: |
1405 | qtype = USRQUOTA; | 1526 | if (!clear_qf_name(sb, USRQUOTA)) |
1406 | goto clear_qf_name; | 1527 | return 0; |
1528 | break; | ||
1407 | case Opt_offgrpjquota: | 1529 | case Opt_offgrpjquota: |
1408 | qtype = GRPQUOTA; | 1530 | if (!clear_qf_name(sb, GRPQUOTA)) |
1409 | clear_qf_name: | ||
1410 | if (sb_any_quota_loaded(sb) && | ||
1411 | sbi->s_qf_names[qtype]) { | ||
1412 | ext4_msg(sb, KERN_ERR, "Cannot change " | ||
1413 | "journaled quota options when " | ||
1414 | "quota turned on"); | ||
1415 | return 0; | 1531 | return 0; |
1416 | } | ||
1417 | /* | ||
1418 | * The space will be released later when all options | ||
1419 | * are confirmed to be correct | ||
1420 | */ | ||
1421 | sbi->s_qf_names[qtype] = NULL; | ||
1422 | break; | 1532 | break; |
1533 | |||
1423 | case Opt_jqfmt_vfsold: | 1534 | case Opt_jqfmt_vfsold: |
1424 | qfmt = QFMT_VFS_OLD; | 1535 | qfmt = QFMT_VFS_OLD; |
1425 | goto set_qf_format; | 1536 | goto set_qf_format; |
1426 | case Opt_jqfmt_vfsv0: | 1537 | case Opt_jqfmt_vfsv0: |
1427 | qfmt = QFMT_VFS_V0; | 1538 | qfmt = QFMT_VFS_V0; |
1539 | goto set_qf_format; | ||
1540 | case Opt_jqfmt_vfsv1: | ||
1541 | qfmt = QFMT_VFS_V1; | ||
1428 | set_qf_format: | 1542 | set_qf_format: |
1429 | if (sb_any_quota_loaded(sb) && | 1543 | if (sb_any_quota_loaded(sb) && |
1430 | sbi->s_jquota_fmt != qfmt) { | 1544 | sbi->s_jquota_fmt != qfmt) { |
@@ -1467,6 +1581,7 @@ set_qf_format: | |||
1467 | case Opt_offgrpjquota: | 1581 | case Opt_offgrpjquota: |
1468 | case Opt_jqfmt_vfsold: | 1582 | case Opt_jqfmt_vfsold: |
1469 | case Opt_jqfmt_vfsv0: | 1583 | case Opt_jqfmt_vfsv0: |
1584 | case Opt_jqfmt_vfsv1: | ||
1470 | ext4_msg(sb, KERN_ERR, | 1585 | ext4_msg(sb, KERN_ERR, |
1471 | "journaled quota options not supported"); | 1586 | "journaled quota options not supported"); |
1472 | break; | 1587 | break; |
@@ -1480,10 +1595,11 @@ set_qf_format: | |||
1480 | clear_opt(sbi->s_mount_opt, BARRIER); | 1595 | clear_opt(sbi->s_mount_opt, BARRIER); |
1481 | break; | 1596 | break; |
1482 | case Opt_barrier: | 1597 | case Opt_barrier: |
1483 | if (match_int(&args[0], &option)) { | 1598 | if (args[0].from) { |
1484 | set_opt(sbi->s_mount_opt, BARRIER); | 1599 | if (match_int(&args[0], &option)) |
1485 | break; | 1600 | return 0; |
1486 | } | 1601 | } else |
1602 | option = 1; /* No argument, default to 1 */ | ||
1487 | if (option) | 1603 | if (option) |
1488 | set_opt(sbi->s_mount_opt, BARRIER); | 1604 | set_opt(sbi->s_mount_opt, BARRIER); |
1489 | else | 1605 | else |
@@ -1556,15 +1672,28 @@ set_qf_format: | |||
1556 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); | 1672 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); |
1557 | break; | 1673 | break; |
1558 | case Opt_auto_da_alloc: | 1674 | case Opt_auto_da_alloc: |
1559 | if (match_int(&args[0], &option)) { | 1675 | if (args[0].from) { |
1560 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); | 1676 | if (match_int(&args[0], &option)) |
1561 | break; | 1677 | return 0; |
1562 | } | 1678 | } else |
1679 | option = 1; /* No argument, default to 1 */ | ||
1563 | if (option) | 1680 | if (option) |
1564 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); | 1681 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); |
1565 | else | 1682 | else |
1566 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); | 1683 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); |
1567 | break; | 1684 | break; |
1685 | case Opt_discard: | ||
1686 | set_opt(sbi->s_mount_opt, DISCARD); | ||
1687 | break; | ||
1688 | case Opt_nodiscard: | ||
1689 | clear_opt(sbi->s_mount_opt, DISCARD); | ||
1690 | break; | ||
1691 | case Opt_dioread_nolock: | ||
1692 | set_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
1693 | break; | ||
1694 | case Opt_dioread_lock: | ||
1695 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
1696 | break; | ||
1568 | default: | 1697 | default: |
1569 | ext4_msg(sb, KERN_ERR, | 1698 | ext4_msg(sb, KERN_ERR, |
1570 | "Unrecognized mount option \"%s\" " | 1699 | "Unrecognized mount option \"%s\" " |
@@ -1574,18 +1703,13 @@ set_qf_format: | |||
1574 | } | 1703 | } |
1575 | #ifdef CONFIG_QUOTA | 1704 | #ifdef CONFIG_QUOTA |
1576 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1705 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { |
1577 | if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) && | 1706 | if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) |
1578 | sbi->s_qf_names[USRQUOTA]) | ||
1579 | clear_opt(sbi->s_mount_opt, USRQUOTA); | 1707 | clear_opt(sbi->s_mount_opt, USRQUOTA); |
1580 | 1708 | ||
1581 | if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) && | 1709 | if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) |
1582 | sbi->s_qf_names[GRPQUOTA]) | ||
1583 | clear_opt(sbi->s_mount_opt, GRPQUOTA); | 1710 | clear_opt(sbi->s_mount_opt, GRPQUOTA); |
1584 | 1711 | ||
1585 | if ((sbi->s_qf_names[USRQUOTA] && | 1712 | if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) { |
1586 | (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || | ||
1587 | (sbi->s_qf_names[GRPQUOTA] && | ||
1588 | (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { | ||
1589 | ext4_msg(sb, KERN_ERR, "old and new quota " | 1713 | ext4_msg(sb, KERN_ERR, "old and new quota " |
1590 | "format mixing"); | 1714 | "format mixing"); |
1591 | return 0; | 1715 | return 0; |
@@ -1673,14 +1797,14 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1673 | size_t size; | 1797 | size_t size; |
1674 | int i; | 1798 | int i; |
1675 | 1799 | ||
1676 | if (!sbi->s_es->s_log_groups_per_flex) { | 1800 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; |
1801 | groups_per_flex = 1 << sbi->s_log_groups_per_flex; | ||
1802 | |||
1803 | if (groups_per_flex < 2) { | ||
1677 | sbi->s_log_groups_per_flex = 0; | 1804 | sbi->s_log_groups_per_flex = 0; |
1678 | return 1; | 1805 | return 1; |
1679 | } | 1806 | } |
1680 | 1807 | ||
1681 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; | ||
1682 | groups_per_flex = 1 << sbi->s_log_groups_per_flex; | ||
1683 | |||
1684 | /* We allocate both existing and potentially added groups */ | 1808 | /* We allocate both existing and potentially added groups */ |
1685 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + | 1809 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + |
1686 | ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << | 1810 | ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << |
@@ -1895,7 +2019,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1895 | } | 2019 | } |
1896 | 2020 | ||
1897 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); | 2021 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); |
1898 | vfs_dq_init(inode); | 2022 | dquot_initialize(inode); |
1899 | if (inode->i_nlink) { | 2023 | if (inode->i_nlink) { |
1900 | ext4_msg(sb, KERN_DEBUG, | 2024 | ext4_msg(sb, KERN_DEBUG, |
1901 | "%s: truncating inode %lu to %lld bytes", | 2025 | "%s: truncating inode %lu to %lld bytes", |
@@ -2099,11 +2223,8 @@ static int parse_strtoul(const char *buf, | |||
2099 | { | 2223 | { |
2100 | char *endp; | 2224 | char *endp; |
2101 | 2225 | ||
2102 | while (*buf && isspace(*buf)) | 2226 | *value = simple_strtoul(skip_spaces(buf), &endp, 0); |
2103 | buf++; | 2227 | endp = skip_spaces(endp); |
2104 | *value = simple_strtoul(buf, &endp, 0); | ||
2105 | while (*endp && isspace(*endp)) | ||
2106 | endp++; | ||
2107 | if (*endp || *value > max) | 2228 | if (*endp || *value > max) |
2108 | return -EINVAL; | 2229 | return -EINVAL; |
2109 | 2230 | ||
@@ -2134,9 +2255,9 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, | |||
2134 | struct super_block *sb = sbi->s_buddy_cache->i_sb; | 2255 | struct super_block *sb = sbi->s_buddy_cache->i_sb; |
2135 | 2256 | ||
2136 | return snprintf(buf, PAGE_SIZE, "%llu\n", | 2257 | return snprintf(buf, PAGE_SIZE, "%llu\n", |
2137 | sbi->s_kbytes_written + | 2258 | (unsigned long long)(sbi->s_kbytes_written + |
2138 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - | 2259 | ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) - |
2139 | EXT4_SB(sb)->s_sectors_written_start) >> 1)); | 2260 | EXT4_SB(sb)->s_sectors_written_start) >> 1))); |
2140 | } | 2261 | } |
2141 | 2262 | ||
2142 | static ssize_t inode_readahead_blks_store(struct ext4_attr *a, | 2263 | static ssize_t inode_readahead_blks_store(struct ext4_attr *a, |
@@ -2251,7 +2372,7 @@ static void ext4_sb_release(struct kobject *kobj) | |||
2251 | } | 2372 | } |
2252 | 2373 | ||
2253 | 2374 | ||
2254 | static struct sysfs_ops ext4_attr_ops = { | 2375 | static const struct sysfs_ops ext4_attr_ops = { |
2255 | .show = ext4_attr_show, | 2376 | .show = ext4_attr_show, |
2256 | .store = ext4_attr_store, | 2377 | .store = ext4_attr_store, |
2257 | }; | 2378 | }; |
@@ -2391,8 +2512,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2391 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | 2512 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); |
2392 | if (def_mount_opts & EXT4_DEFM_DEBUG) | 2513 | if (def_mount_opts & EXT4_DEFM_DEBUG) |
2393 | set_opt(sbi->s_mount_opt, DEBUG); | 2514 | set_opt(sbi->s_mount_opt, DEBUG); |
2394 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) | 2515 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { |
2516 | ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups", | ||
2517 | "2.6.38"); | ||
2395 | set_opt(sbi->s_mount_opt, GRPID); | 2518 | set_opt(sbi->s_mount_opt, GRPID); |
2519 | } | ||
2396 | if (def_mount_opts & EXT4_DEFM_UID16) | 2520 | if (def_mount_opts & EXT4_DEFM_UID16) |
2397 | set_opt(sbi->s_mount_opt, NO_UID32); | 2521 | set_opt(sbi->s_mount_opt, NO_UID32); |
2398 | #ifdef CONFIG_EXT4_FS_XATTR | 2522 | #ifdef CONFIG_EXT4_FS_XATTR |
@@ -2404,11 +2528,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2404 | set_opt(sbi->s_mount_opt, POSIX_ACL); | 2528 | set_opt(sbi->s_mount_opt, POSIX_ACL); |
2405 | #endif | 2529 | #endif |
2406 | if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) | 2530 | if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) |
2407 | sbi->s_mount_opt |= EXT4_MOUNT_JOURNAL_DATA; | 2531 | set_opt(sbi->s_mount_opt, JOURNAL_DATA); |
2408 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) | 2532 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) |
2409 | sbi->s_mount_opt |= EXT4_MOUNT_ORDERED_DATA; | 2533 | set_opt(sbi->s_mount_opt, ORDERED_DATA); |
2410 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) | 2534 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) |
2411 | sbi->s_mount_opt |= EXT4_MOUNT_WRITEBACK_DATA; | 2535 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
2412 | 2536 | ||
2413 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) | 2537 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) |
2414 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 2538 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
@@ -2429,14 +2553,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2429 | * enable delayed allocation by default | 2553 | * enable delayed allocation by default |
2430 | * Use -o nodelalloc to turn it off | 2554 | * Use -o nodelalloc to turn it off |
2431 | */ | 2555 | */ |
2432 | set_opt(sbi->s_mount_opt, DELALLOC); | 2556 | if (!IS_EXT3_SB(sb)) |
2557 | set_opt(sbi->s_mount_opt, DELALLOC); | ||
2433 | 2558 | ||
2434 | if (!parse_options((char *) data, sb, &journal_devnum, | 2559 | if (!parse_options((char *) data, sb, &journal_devnum, |
2435 | &journal_ioprio, NULL, 0)) | 2560 | &journal_ioprio, NULL, 0)) |
2436 | goto failed_mount; | 2561 | goto failed_mount; |
2437 | 2562 | ||
2438 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 2563 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
2439 | ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 2564 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
2440 | 2565 | ||
2441 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && | 2566 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && |
2442 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || | 2567 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || |
@@ -2721,31 +2846,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2721 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { | 2846 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { |
2722 | if (ext4_load_journal(sb, es, journal_devnum)) | 2847 | if (ext4_load_journal(sb, es, journal_devnum)) |
2723 | goto failed_mount3; | 2848 | goto failed_mount3; |
2724 | if (!(sb->s_flags & MS_RDONLY) && | ||
2725 | EXT4_SB(sb)->s_journal->j_failed_commit) { | ||
2726 | ext4_msg(sb, KERN_CRIT, "error: " | ||
2727 | "ext4_fill_super: Journal transaction " | ||
2728 | "%u is corrupt", | ||
2729 | EXT4_SB(sb)->s_journal->j_failed_commit); | ||
2730 | if (test_opt(sb, ERRORS_RO)) { | ||
2731 | ext4_msg(sb, KERN_CRIT, | ||
2732 | "Mounting filesystem read-only"); | ||
2733 | sb->s_flags |= MS_RDONLY; | ||
2734 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2735 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2736 | } | ||
2737 | if (test_opt(sb, ERRORS_PANIC)) { | ||
2738 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2739 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2740 | ext4_commit_super(sb, 1); | ||
2741 | goto failed_mount4; | ||
2742 | } | ||
2743 | } | ||
2744 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && | 2849 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && |
2745 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { | 2850 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { |
2746 | ext4_msg(sb, KERN_ERR, "required journal recovery " | 2851 | ext4_msg(sb, KERN_ERR, "required journal recovery " |
2747 | "suppressed and not mounted read-only"); | 2852 | "suppressed and not mounted read-only"); |
2748 | goto failed_mount4; | 2853 | goto failed_mount_wq; |
2749 | } else { | 2854 | } else { |
2750 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); | 2855 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
2751 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); | 2856 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
@@ -2758,7 +2863,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2758 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | 2863 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, |
2759 | JBD2_FEATURE_INCOMPAT_64BIT)) { | 2864 | JBD2_FEATURE_INCOMPAT_64BIT)) { |
2760 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); | 2865 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); |
2761 | goto failed_mount4; | 2866 | goto failed_mount_wq; |
2762 | } | 2867 | } |
2763 | 2868 | ||
2764 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { | 2869 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { |
@@ -2797,7 +2902,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2797 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { | 2902 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { |
2798 | ext4_msg(sb, KERN_ERR, "Journal does not support " | 2903 | ext4_msg(sb, KERN_ERR, "Journal does not support " |
2799 | "requested data journaling mode"); | 2904 | "requested data journaling mode"); |
2800 | goto failed_mount4; | 2905 | goto failed_mount_wq; |
2801 | } | 2906 | } |
2802 | default: | 2907 | default: |
2803 | break; | 2908 | break; |
@@ -2805,13 +2910,17 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2805 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 2910 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
2806 | 2911 | ||
2807 | no_journal: | 2912 | no_journal: |
2808 | |||
2809 | if (test_opt(sb, NOBH)) { | 2913 | if (test_opt(sb, NOBH)) { |
2810 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { | 2914 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { |
2811 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " | 2915 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " |
2812 | "its supported only with writeback mode"); | 2916 | "its supported only with writeback mode"); |
2813 | clear_opt(sbi->s_mount_opt, NOBH); | 2917 | clear_opt(sbi->s_mount_opt, NOBH); |
2814 | } | 2918 | } |
2919 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2920 | ext4_msg(sb, KERN_WARNING, "dioread_nolock option is " | ||
2921 | "not supported with nobh mode"); | ||
2922 | goto failed_mount_wq; | ||
2923 | } | ||
2815 | } | 2924 | } |
2816 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 2925 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
2817 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 2926 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
@@ -2876,6 +2985,18 @@ no_journal: | |||
2876 | "requested data journaling mode"); | 2985 | "requested data journaling mode"); |
2877 | clear_opt(sbi->s_mount_opt, DELALLOC); | 2986 | clear_opt(sbi->s_mount_opt, DELALLOC); |
2878 | } | 2987 | } |
2988 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2989 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2990 | ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " | ||
2991 | "option - requested data journaling mode"); | ||
2992 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
2993 | } | ||
2994 | if (sb->s_blocksize < PAGE_SIZE) { | ||
2995 | ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " | ||
2996 | "option - block size is too small"); | ||
2997 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
2998 | } | ||
2999 | } | ||
2879 | 3000 | ||
2880 | err = ext4_setup_system_zone(sb); | 3001 | err = ext4_setup_system_zone(sb); |
2881 | if (err) { | 3002 | if (err) { |
@@ -3339,10 +3460,9 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
3339 | char nbuf[16]; | 3460 | char nbuf[16]; |
3340 | 3461 | ||
3341 | errstr = ext4_decode_error(sb, j_errno, nbuf); | 3462 | errstr = ext4_decode_error(sb, j_errno, nbuf); |
3342 | ext4_warning(sb, __func__, "Filesystem error recorded " | 3463 | ext4_warning(sb, "Filesystem error recorded " |
3343 | "from previous mount: %s", errstr); | 3464 | "from previous mount: %s", errstr); |
3344 | ext4_warning(sb, __func__, "Marking fs in need of " | 3465 | ext4_warning(sb, "Marking fs in need of filesystem check."); |
3345 | "filesystem check."); | ||
3346 | 3466 | ||
3347 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 3467 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
3348 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 3468 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
@@ -3493,7 +3613,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3493 | ext4_abort(sb, __func__, "Abort forced by user"); | 3613 | ext4_abort(sb, __func__, "Abort forced by user"); |
3494 | 3614 | ||
3495 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 3615 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3496 | ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 3616 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
3497 | 3617 | ||
3498 | es = sbi->s_es; | 3618 | es = sbi->s_es; |
3499 | 3619 | ||
@@ -3668,13 +3788,11 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3668 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; | 3788 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
3669 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - | 3789 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - |
3670 | percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); | 3790 | percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); |
3671 | ext4_free_blocks_count_set(es, buf->f_bfree); | ||
3672 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 3791 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
3673 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 3792 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
3674 | buf->f_bavail = 0; | 3793 | buf->f_bavail = 0; |
3675 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 3794 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
3676 | buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter); | 3795 | buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter); |
3677 | es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); | ||
3678 | buf->f_namelen = EXT4_NAME_LEN; | 3796 | buf->f_namelen = EXT4_NAME_LEN; |
3679 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | 3797 | fsid = le64_to_cpup((void *)es->s_uuid) ^ |
3680 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 3798 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |
@@ -3689,7 +3807,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3689 | * Process 1 Process 2 | 3807 | * Process 1 Process 2 |
3690 | * ext4_create() quota_sync() | 3808 | * ext4_create() quota_sync() |
3691 | * jbd2_journal_start() write_dquot() | 3809 | * jbd2_journal_start() write_dquot() |
3692 | * vfs_dq_init() down(dqio_mutex) | 3810 | * dquot_initialize() down(dqio_mutex) |
3693 | * down(dqio_mutex) jbd2_journal_start() | 3811 | * down(dqio_mutex) jbd2_journal_start() |
3694 | * | 3812 | * |
3695 | */ | 3813 | */ |
@@ -3898,9 +4016,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3898 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); | 4016 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); |
3899 | int err = 0; | 4017 | int err = 0; |
3900 | int offset = off & (sb->s_blocksize - 1); | 4018 | int offset = off & (sb->s_blocksize - 1); |
3901 | int tocopy; | ||
3902 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; | 4019 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; |
3903 | size_t towrite = len; | ||
3904 | struct buffer_head *bh; | 4020 | struct buffer_head *bh; |
3905 | handle_t *handle = journal_current_handle(); | 4021 | handle_t *handle = journal_current_handle(); |
3906 | 4022 | ||
@@ -3910,52 +4026,53 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3910 | (unsigned long long)off, (unsigned long long)len); | 4026 | (unsigned long long)off, (unsigned long long)len); |
3911 | return -EIO; | 4027 | return -EIO; |
3912 | } | 4028 | } |
4029 | /* | ||
4030 | * Since we account only one data block in transaction credits, | ||
4031 | * then it is impossible to cross a block boundary. | ||
4032 | */ | ||
4033 | if (sb->s_blocksize - offset < len) { | ||
4034 | ext4_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)" | ||
4035 | " cancelled because not block aligned", | ||
4036 | (unsigned long long)off, (unsigned long long)len); | ||
4037 | return -EIO; | ||
4038 | } | ||
4039 | |||
3913 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | 4040 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
3914 | while (towrite > 0) { | 4041 | bh = ext4_bread(handle, inode, blk, 1, &err); |
3915 | tocopy = sb->s_blocksize - offset < towrite ? | 4042 | if (!bh) |
3916 | sb->s_blocksize - offset : towrite; | 4043 | goto out; |
3917 | bh = ext4_bread(handle, inode, blk, 1, &err); | 4044 | if (journal_quota) { |
3918 | if (!bh) | 4045 | err = ext4_journal_get_write_access(handle, bh); |
4046 | if (err) { | ||
4047 | brelse(bh); | ||
3919 | goto out; | 4048 | goto out; |
3920 | if (journal_quota) { | ||
3921 | err = ext4_journal_get_write_access(handle, bh); | ||
3922 | if (err) { | ||
3923 | brelse(bh); | ||
3924 | goto out; | ||
3925 | } | ||
3926 | } | ||
3927 | lock_buffer(bh); | ||
3928 | memcpy(bh->b_data+offset, data, tocopy); | ||
3929 | flush_dcache_page(bh->b_page); | ||
3930 | unlock_buffer(bh); | ||
3931 | if (journal_quota) | ||
3932 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
3933 | else { | ||
3934 | /* Always do at least ordered writes for quotas */ | ||
3935 | err = ext4_jbd2_file_inode(handle, inode); | ||
3936 | mark_buffer_dirty(bh); | ||
3937 | } | 4049 | } |
3938 | brelse(bh); | ||
3939 | if (err) | ||
3940 | goto out; | ||
3941 | offset = 0; | ||
3942 | towrite -= tocopy; | ||
3943 | data += tocopy; | ||
3944 | blk++; | ||
3945 | } | 4050 | } |
4051 | lock_buffer(bh); | ||
4052 | memcpy(bh->b_data+offset, data, len); | ||
4053 | flush_dcache_page(bh->b_page); | ||
4054 | unlock_buffer(bh); | ||
4055 | if (journal_quota) | ||
4056 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
4057 | else { | ||
4058 | /* Always do at least ordered writes for quotas */ | ||
4059 | err = ext4_jbd2_file_inode(handle, inode); | ||
4060 | mark_buffer_dirty(bh); | ||
4061 | } | ||
4062 | brelse(bh); | ||
3946 | out: | 4063 | out: |
3947 | if (len == towrite) { | 4064 | if (err) { |
3948 | mutex_unlock(&inode->i_mutex); | 4065 | mutex_unlock(&inode->i_mutex); |
3949 | return err; | 4066 | return err; |
3950 | } | 4067 | } |
3951 | if (inode->i_size < off+len-towrite) { | 4068 | if (inode->i_size < off + len) { |
3952 | i_size_write(inode, off+len-towrite); | 4069 | i_size_write(inode, off + len); |
3953 | EXT4_I(inode)->i_disksize = inode->i_size; | 4070 | EXT4_I(inode)->i_disksize = inode->i_size; |
3954 | } | 4071 | } |
3955 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 4072 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
3956 | ext4_mark_inode_dirty(handle, inode); | 4073 | ext4_mark_inode_dirty(handle, inode); |
3957 | mutex_unlock(&inode->i_mutex); | 4074 | mutex_unlock(&inode->i_mutex); |
3958 | return len - towrite; | 4075 | return len; |
3959 | } | 4076 | } |
3960 | 4077 | ||
3961 | #endif | 4078 | #endif |
@@ -3966,6 +4083,52 @@ static int ext4_get_sb(struct file_system_type *fs_type, int flags, | |||
3966 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); | 4083 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); |
3967 | } | 4084 | } |
3968 | 4085 | ||
4086 | #if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | ||
4087 | static struct file_system_type ext2_fs_type = { | ||
4088 | .owner = THIS_MODULE, | ||
4089 | .name = "ext2", | ||
4090 | .get_sb = ext4_get_sb, | ||
4091 | .kill_sb = kill_block_super, | ||
4092 | .fs_flags = FS_REQUIRES_DEV, | ||
4093 | }; | ||
4094 | |||
4095 | static inline void register_as_ext2(void) | ||
4096 | { | ||
4097 | int err = register_filesystem(&ext2_fs_type); | ||
4098 | if (err) | ||
4099 | printk(KERN_WARNING | ||
4100 | "EXT4-fs: Unable to register as ext2 (%d)\n", err); | ||
4101 | } | ||
4102 | |||
4103 | static inline void unregister_as_ext2(void) | ||
4104 | { | ||
4105 | unregister_filesystem(&ext2_fs_type); | ||
4106 | } | ||
4107 | MODULE_ALIAS("ext2"); | ||
4108 | #else | ||
4109 | static inline void register_as_ext2(void) { } | ||
4110 | static inline void unregister_as_ext2(void) { } | ||
4111 | #endif | ||
4112 | |||
4113 | #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | ||
4114 | static inline void register_as_ext3(void) | ||
4115 | { | ||
4116 | int err = register_filesystem(&ext3_fs_type); | ||
4117 | if (err) | ||
4118 | printk(KERN_WARNING | ||
4119 | "EXT4-fs: Unable to register as ext3 (%d)\n", err); | ||
4120 | } | ||
4121 | |||
4122 | static inline void unregister_as_ext3(void) | ||
4123 | { | ||
4124 | unregister_filesystem(&ext3_fs_type); | ||
4125 | } | ||
4126 | MODULE_ALIAS("ext3"); | ||
4127 | #else | ||
4128 | static inline void register_as_ext3(void) { } | ||
4129 | static inline void unregister_as_ext3(void) { } | ||
4130 | #endif | ||
4131 | |||
3969 | static struct file_system_type ext4_fs_type = { | 4132 | static struct file_system_type ext4_fs_type = { |
3970 | .owner = THIS_MODULE, | 4133 | .owner = THIS_MODULE, |
3971 | .name = "ext4", | 4134 | .name = "ext4", |
@@ -3995,11 +4158,15 @@ static int __init init_ext4_fs(void) | |||
3995 | err = init_inodecache(); | 4158 | err = init_inodecache(); |
3996 | if (err) | 4159 | if (err) |
3997 | goto out1; | 4160 | goto out1; |
4161 | register_as_ext2(); | ||
4162 | register_as_ext3(); | ||
3998 | err = register_filesystem(&ext4_fs_type); | 4163 | err = register_filesystem(&ext4_fs_type); |
3999 | if (err) | 4164 | if (err) |
4000 | goto out; | 4165 | goto out; |
4001 | return 0; | 4166 | return 0; |
4002 | out: | 4167 | out: |
4168 | unregister_as_ext2(); | ||
4169 | unregister_as_ext3(); | ||
4003 | destroy_inodecache(); | 4170 | destroy_inodecache(); |
4004 | out1: | 4171 | out1: |
4005 | exit_ext4_xattr(); | 4172 | exit_ext4_xattr(); |
@@ -4015,6 +4182,8 @@ out4: | |||
4015 | 4182 | ||
4016 | static void __exit exit_ext4_fs(void) | 4183 | static void __exit exit_ext4_fs(void) |
4017 | { | 4184 | { |
4185 | unregister_as_ext2(); | ||
4186 | unregister_as_ext3(); | ||
4018 | unregister_filesystem(&ext4_fs_type); | 4187 | unregister_filesystem(&ext4_fs_type); |
4019 | destroy_inodecache(); | 4188 | destroy_inodecache(); |
4020 | exit_ext4_xattr(); | 4189 | exit_ext4_xattr(); |