|
@@ -62,6 +62,7 @@ static struct ext4_features *ext4_feat;
|
|
|
|
|
|
static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
|
|
|
unsigned long journal_devnum);
|
|
|
+static int ext4_show_options(struct seq_file *seq, struct dentry *root);
|
|
|
static int ext4_commit_super(struct super_block *sb, int sync);
|
|
|
static void ext4_mark_recovery_complete(struct super_block *sb,
|
|
|
struct ext4_super_block *es);
|
|
@@ -375,7 +376,7 @@ void ext4_journal_abort_handle(const char *caller, unsigned int line,
|
|
|
if (is_handle_aborted(handle))
|
|
|
return;
|
|
|
|
|
|
- printk(KERN_ERR "%s:%d: aborting transaction: %s in %s\n",
|
|
|
+ printk(KERN_ERR "EXT4-fs: %s:%d: aborting transaction: %s in %s\n",
|
|
|
caller, line, errstr, err_fn);
|
|
|
|
|
|
jbd2_journal_abort_handle(handle);
|
|
@@ -431,6 +432,22 @@ static int block_device_ejected(struct super_block *sb)
|
|
|
return bdi->dev == NULL;
|
|
|
}
|
|
|
|
|
|
+static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
|
|
|
+{
|
|
|
+ struct super_block *sb = journal->j_private;
|
|
|
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
+ int error = is_journal_aborted(journal);
|
|
|
+ struct ext4_journal_cb_entry *jce, *tmp;
|
|
|
+
|
|
|
+ spin_lock(&sbi->s_md_lock);
|
|
|
+ list_for_each_entry_safe(jce, tmp, &txn->t_private_list, jce_list) {
|
|
|
+ list_del_init(&jce->jce_list);
|
|
|
+ spin_unlock(&sbi->s_md_lock);
|
|
|
+ jce->jce_func(sb, jce, error);
|
|
|
+ spin_lock(&sbi->s_md_lock);
|
|
|
+ }
|
|
|
+ spin_unlock(&sbi->s_md_lock);
|
|
|
+}
|
|
|
|
|
|
/* Deal with the reporting of failure conditions on a filesystem such as
|
|
|
* inconsistencies detected or read IO failures.
|
|
@@ -498,11 +515,16 @@ void ext4_error_inode(struct inode *inode, const char *function,
|
|
|
va_start(args, fmt);
|
|
|
vaf.fmt = fmt;
|
|
|
vaf.va = &args;
|
|
|
- printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
|
|
|
- inode->i_sb->s_id, function, line, inode->i_ino);
|
|
|
if (block)
|
|
|
- printk(KERN_CONT "block %llu: ", block);
|
|
|
- printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf);
|
|
|
+ printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: "
|
|
|
+ "inode #%lu: block %llu: comm %s: %pV\n",
|
|
|
+ inode->i_sb->s_id, function, line, inode->i_ino,
|
|
|
+ block, current->comm, &vaf);
|
|
|
+ else
|
|
|
+ printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: "
|
|
|
+ "inode #%lu: comm %s: %pV\n",
|
|
|
+ inode->i_sb->s_id, function, line, inode->i_ino,
|
|
|
+ current->comm, &vaf);
|
|
|
va_end(args);
|
|
|
|
|
|
ext4_handle_error(inode->i_sb);
|
|
@@ -524,15 +546,21 @@ void ext4_error_file(struct file *file, const char *function,
|
|
|
path = d_path(&(file->f_path), pathname, sizeof(pathname));
|
|
|
if (IS_ERR(path))
|
|
|
path = "(unknown)";
|
|
|
- printk(KERN_CRIT
|
|
|
- "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
|
|
|
- inode->i_sb->s_id, function, line, inode->i_ino);
|
|
|
- if (block)
|
|
|
- printk(KERN_CONT "block %llu: ", block);
|
|
|
va_start(args, fmt);
|
|
|
vaf.fmt = fmt;
|
|
|
vaf.va = &args;
|
|
|
- printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf);
|
|
|
+ if (block)
|
|
|
+ printk(KERN_CRIT
|
|
|
+ "EXT4-fs error (device %s): %s:%d: inode #%lu: "
|
|
|
+ "block %llu: comm %s: path %s: %pV\n",
|
|
|
+ inode->i_sb->s_id, function, line, inode->i_ino,
|
|
|
+ block, current->comm, path, &vaf);
|
|
|
+ else
|
|
|
+ printk(KERN_CRIT
|
|
|
+ "EXT4-fs error (device %s): %s:%d: inode #%lu: "
|
|
|
+ "comm %s: path %s: %pV\n",
|
|
|
+ inode->i_sb->s_id, function, line, inode->i_ino,
|
|
|
+ current->comm, path, &vaf);
|
|
|
va_end(args);
|
|
|
|
|
|
ext4_handle_error(inode->i_sb);
|
|
@@ -808,9 +836,6 @@ static void ext4_put_super(struct super_block *sb)
|
|
|
destroy_workqueue(sbi->dio_unwritten_wq);
|
|
|
|
|
|
lock_super(sb);
|
|
|
- if (sb->s_dirt)
|
|
|
- ext4_commit_super(sb, 1);
|
|
|
-
|
|
|
if (sbi->s_journal) {
|
|
|
err = jbd2_journal_destroy(sbi->s_journal);
|
|
|
sbi->s_journal = NULL;
|
|
@@ -827,9 +852,12 @@ static void ext4_put_super(struct super_block *sb)
|
|
|
if (!(sb->s_flags & MS_RDONLY)) {
|
|
|
EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
|
|
|
es->s_state = cpu_to_le16(sbi->s_mount_state);
|
|
|
- ext4_commit_super(sb, 1);
|
|
|
}
|
|
|
+ if (sb->s_dirt || !(sb->s_flags & MS_RDONLY))
|
|
|
+ ext4_commit_super(sb, 1);
|
|
|
+
|
|
|
if (sbi->s_proc) {
|
|
|
+ remove_proc_entry("options", sbi->s_proc);
|
|
|
remove_proc_entry(sb->s_id, ext4_proc_root);
|
|
|
}
|
|
|
kobject_del(&sbi->s_kobj);
|
|
@@ -990,180 +1018,6 @@ void ext4_clear_inode(struct inode *inode)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static inline void ext4_show_quota_options(struct seq_file *seq,
|
|
|
- struct super_block *sb)
|
|
|
-{
|
|
|
-#if defined(CONFIG_QUOTA)
|
|
|
- struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
-
|
|
|
- if (sbi->s_jquota_fmt) {
|
|
|
- char *fmtname = "";
|
|
|
-
|
|
|
- switch (sbi->s_jquota_fmt) {
|
|
|
- case QFMT_VFS_OLD:
|
|
|
- fmtname = "vfsold";
|
|
|
- break;
|
|
|
- case QFMT_VFS_V0:
|
|
|
- fmtname = "vfsv0";
|
|
|
- break;
|
|
|
- case QFMT_VFS_V1:
|
|
|
- fmtname = "vfsv1";
|
|
|
- break;
|
|
|
- }
|
|
|
- seq_printf(seq, ",jqfmt=%s", fmtname);
|
|
|
- }
|
|
|
-
|
|
|
- if (sbi->s_qf_names[USRQUOTA])
|
|
|
- seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
|
|
|
-
|
|
|
- if (sbi->s_qf_names[GRPQUOTA])
|
|
|
- seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
|
|
|
-
|
|
|
- if (test_opt(sb, USRQUOTA))
|
|
|
- seq_puts(seq, ",usrquota");
|
|
|
-
|
|
|
- if (test_opt(sb, GRPQUOTA))
|
|
|
- seq_puts(seq, ",grpquota");
|
|
|
-#endif
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Show an option if
|
|
|
- * - it's set to a non-default value OR
|
|
|
- * - if the per-sb default is different from the global default
|
|
|
- */
|
|
|
-static int ext4_show_options(struct seq_file *seq, struct dentry *root)
|
|
|
-{
|
|
|
- int def_errors;
|
|
|
- unsigned long def_mount_opts;
|
|
|
- struct super_block *sb = root->d_sb;
|
|
|
- struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
- struct ext4_super_block *es = sbi->s_es;
|
|
|
-
|
|
|
- def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
|
|
|
- def_errors = le16_to_cpu(es->s_errors);
|
|
|
-
|
|
|
- if (sbi->s_sb_block != 1)
|
|
|
- seq_printf(seq, ",sb=%llu", sbi->s_sb_block);
|
|
|
- if (test_opt(sb, MINIX_DF))
|
|
|
- seq_puts(seq, ",minixdf");
|
|
|
- if (test_opt(sb, GRPID) && !(def_mount_opts & EXT4_DEFM_BSDGROUPS))
|
|
|
- seq_puts(seq, ",grpid");
|
|
|
- if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS))
|
|
|
- seq_puts(seq, ",nogrpid");
|
|
|
- if (sbi->s_resuid != EXT4_DEF_RESUID ||
|
|
|
- le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) {
|
|
|
- seq_printf(seq, ",resuid=%u", sbi->s_resuid);
|
|
|
- }
|
|
|
- if (sbi->s_resgid != EXT4_DEF_RESGID ||
|
|
|
- le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) {
|
|
|
- seq_printf(seq, ",resgid=%u", sbi->s_resgid);
|
|
|
- }
|
|
|
- if (test_opt(sb, ERRORS_RO)) {
|
|
|
- if (def_errors == EXT4_ERRORS_PANIC ||
|
|
|
- def_errors == EXT4_ERRORS_CONTINUE) {
|
|
|
- seq_puts(seq, ",errors=remount-ro");
|
|
|
- }
|
|
|
- }
|
|
|
- if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE)
|
|
|
- seq_puts(seq, ",errors=continue");
|
|
|
- if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC)
|
|
|
- seq_puts(seq, ",errors=panic");
|
|
|
- if (test_opt(sb, NO_UID32) && !(def_mount_opts & EXT4_DEFM_UID16))
|
|
|
- seq_puts(seq, ",nouid32");
|
|
|
- if (test_opt(sb, DEBUG) && !(def_mount_opts & EXT4_DEFM_DEBUG))
|
|
|
- seq_puts(seq, ",debug");
|
|
|
-#ifdef CONFIG_EXT4_FS_XATTR
|
|
|
- if (test_opt(sb, XATTR_USER))
|
|
|
- seq_puts(seq, ",user_xattr");
|
|
|
- if (!test_opt(sb, XATTR_USER))
|
|
|
- seq_puts(seq, ",nouser_xattr");
|
|
|
-#endif
|
|
|
-#ifdef CONFIG_EXT4_FS_POSIX_ACL
|
|
|
- if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL))
|
|
|
- seq_puts(seq, ",acl");
|
|
|
- if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
|
|
|
- seq_puts(seq, ",noacl");
|
|
|
-#endif
|
|
|
- if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
|
|
|
- seq_printf(seq, ",commit=%u",
|
|
|
- (unsigned) (sbi->s_commit_interval / HZ));
|
|
|
- }
|
|
|
- if (sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME) {
|
|
|
- seq_printf(seq, ",min_batch_time=%u",
|
|
|
- (unsigned) sbi->s_min_batch_time);
|
|
|
- }
|
|
|
- if (sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME) {
|
|
|
- seq_printf(seq, ",max_batch_time=%u",
|
|
|
- (unsigned) sbi->s_max_batch_time);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * We're changing the default of barrier mount option, so
|
|
|
- * let's always display its mount state so it's clear what its
|
|
|
- * status is.
|
|
|
- */
|
|
|
- seq_puts(seq, ",barrier=");
|
|
|
- seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0");
|
|
|
- if (test_opt(sb, JOURNAL_ASYNC_COMMIT))
|
|
|
- seq_puts(seq, ",journal_async_commit");
|
|
|
- else if (test_opt(sb, JOURNAL_CHECKSUM))
|
|
|
- seq_puts(seq, ",journal_checksum");
|
|
|
- if (test_opt(sb, I_VERSION))
|
|
|
- seq_puts(seq, ",i_version");
|
|
|
- if (!test_opt(sb, DELALLOC) &&
|
|
|
- !(def_mount_opts & EXT4_DEFM_NODELALLOC))
|
|
|
- seq_puts(seq, ",nodelalloc");
|
|
|
-
|
|
|
- if (!test_opt(sb, MBLK_IO_SUBMIT))
|
|
|
- seq_puts(seq, ",nomblk_io_submit");
|
|
|
- if (sbi->s_stripe)
|
|
|
- seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
|
|
|
- /*
|
|
|
- * journal mode get enabled in different ways
|
|
|
- * So just print the value even if we didn't specify it
|
|
|
- */
|
|
|
- if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
|
|
|
- seq_puts(seq, ",data=journal");
|
|
|
- else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
|
|
|
- seq_puts(seq, ",data=ordered");
|
|
|
- else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
|
|
|
- seq_puts(seq, ",data=writeback");
|
|
|
-
|
|
|
- if (sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS)
|
|
|
- seq_printf(seq, ",inode_readahead_blks=%u",
|
|
|
- sbi->s_inode_readahead_blks);
|
|
|
-
|
|
|
- if (test_opt(sb, DATA_ERR_ABORT))
|
|
|
- seq_puts(seq, ",data_err=abort");
|
|
|
-
|
|
|
- if (test_opt(sb, NO_AUTO_DA_ALLOC))
|
|
|
- seq_puts(seq, ",noauto_da_alloc");
|
|
|
-
|
|
|
- if (test_opt(sb, DISCARD) && !(def_mount_opts & EXT4_DEFM_DISCARD))
|
|
|
- seq_puts(seq, ",discard");
|
|
|
-
|
|
|
- if (test_opt(sb, NOLOAD))
|
|
|
- seq_puts(seq, ",norecovery");
|
|
|
-
|
|
|
- if (test_opt(sb, DIOREAD_NOLOCK))
|
|
|
- seq_puts(seq, ",dioread_nolock");
|
|
|
-
|
|
|
- if (test_opt(sb, BLOCK_VALIDITY) &&
|
|
|
- !(def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY))
|
|
|
- seq_puts(seq, ",block_validity");
|
|
|
-
|
|
|
- if (!test_opt(sb, INIT_INODE_TABLE))
|
|
|
- seq_puts(seq, ",noinit_itable");
|
|
|
- else if (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)
|
|
|
- seq_printf(seq, ",init_itable=%u",
|
|
|
- (unsigned) sbi->s_li_wait_mult);
|
|
|
-
|
|
|
- ext4_show_quota_options(seq, sb);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static struct inode *ext4_nfs_get_inode(struct super_block *sb,
|
|
|
u64 ino, u32 generation)
|
|
|
{
|
|
@@ -1316,18 +1170,17 @@ static const struct export_operations ext4_export_ops = {
|
|
|
enum {
|
|
|
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
|
|
|
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
|
|
|
- Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,
|
|
|
+ Opt_nouid32, Opt_debug, Opt_removed,
|
|
|
Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
|
|
|
- Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload, Opt_nobh, Opt_bh,
|
|
|
+ Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload,
|
|
|
Opt_commit, Opt_min_batch_time, Opt_max_batch_time,
|
|
|
- Opt_journal_update, Opt_journal_dev,
|
|
|
- Opt_journal_checksum, Opt_journal_async_commit,
|
|
|
+ Opt_journal_dev, Opt_journal_checksum, Opt_journal_async_commit,
|
|
|
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
|
|
|
Opt_data_err_abort, Opt_data_err_ignore,
|
|
|
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
|
|
|
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
|
|
|
- Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
|
|
|
- Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
|
|
|
+ Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
|
|
|
+ Opt_usrquota, Opt_grpquota, Opt_i_version,
|
|
|
Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
|
|
|
Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
|
|
|
Opt_inode_readahead_blks, Opt_journal_ioprio,
|
|
@@ -1350,20 +1203,19 @@ static const match_table_t tokens = {
|
|
|
{Opt_err_ro, "errors=remount-ro"},
|
|
|
{Opt_nouid32, "nouid32"},
|
|
|
{Opt_debug, "debug"},
|
|
|
- {Opt_oldalloc, "oldalloc"},
|
|
|
- {Opt_orlov, "orlov"},
|
|
|
+ {Opt_removed, "oldalloc"},
|
|
|
+ {Opt_removed, "orlov"},
|
|
|
{Opt_user_xattr, "user_xattr"},
|
|
|
{Opt_nouser_xattr, "nouser_xattr"},
|
|
|
{Opt_acl, "acl"},
|
|
|
{Opt_noacl, "noacl"},
|
|
|
- {Opt_noload, "noload"},
|
|
|
{Opt_noload, "norecovery"},
|
|
|
- {Opt_nobh, "nobh"},
|
|
|
- {Opt_bh, "bh"},
|
|
|
+ {Opt_noload, "noload"},
|
|
|
+ {Opt_removed, "nobh"},
|
|
|
+ {Opt_removed, "bh"},
|
|
|
{Opt_commit, "commit=%u"},
|
|
|
{Opt_min_batch_time, "min_batch_time=%u"},
|
|
|
{Opt_max_batch_time, "max_batch_time=%u"},
|
|
|
- {Opt_journal_update, "journal=update"},
|
|
|
{Opt_journal_dev, "journal_dev=%u"},
|
|
|
{Opt_journal_checksum, "journal_checksum"},
|
|
|
{Opt_journal_async_commit, "journal_async_commit"},
|
|
@@ -1389,7 +1241,6 @@ static const match_table_t tokens = {
|
|
|
{Opt_nobarrier, "nobarrier"},
|
|
|
{Opt_i_version, "i_version"},
|
|
|
{Opt_stripe, "stripe=%u"},
|
|
|
- {Opt_resize, "resize"},
|
|
|
{Opt_delalloc, "delalloc"},
|
|
|
{Opt_nodelalloc, "nodelalloc"},
|
|
|
{Opt_mblk_io_submit, "mblk_io_submit"},
|
|
@@ -1408,6 +1259,11 @@ static const match_table_t tokens = {
|
|
|
{Opt_init_itable, "init_itable=%u"},
|
|
|
{Opt_init_itable, "init_itable"},
|
|
|
{Opt_noinit_itable, "noinit_itable"},
|
|
|
+ {Opt_removed, "check=none"}, /* mount option from ext2/3 */
|
|
|
+ {Opt_removed, "nocheck"}, /* mount option from ext2/3 */
|
|
|
+ {Opt_removed, "reservation"}, /* mount option from ext2/3 */
|
|
|
+ {Opt_removed, "noreservation"}, /* mount option from ext2/3 */
|
|
|
+ {Opt_removed, "journal=%u"}, /* mount option from ext2/3 */
|
|
|
{Opt_err, NULL},
|
|
|
};
|
|
|
|
|
@@ -1496,420 +1352,273 @@ static int clear_qf_name(struct super_block *sb, int qtype)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-static int parse_options(char *options, struct super_block *sb,
|
|
|
- unsigned long *journal_devnum,
|
|
|
- unsigned int *journal_ioprio,
|
|
|
- ext4_fsblk_t *n_blocks_count, int is_remount)
|
|
|
-{
|
|
|
- struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
- char *p;
|
|
|
- substring_t args[MAX_OPT_ARGS];
|
|
|
- int data_opt = 0;
|
|
|
- int option;
|
|
|
+#define MOPT_SET 0x0001
|
|
|
+#define MOPT_CLEAR 0x0002
|
|
|
+#define MOPT_NOSUPPORT 0x0004
|
|
|
+#define MOPT_EXPLICIT 0x0008
|
|
|
+#define MOPT_CLEAR_ERR 0x0010
|
|
|
+#define MOPT_GTE0 0x0020
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
- int qfmt;
|
|
|
+#define MOPT_Q 0
|
|
|
+#define MOPT_QFMT 0x0040
|
|
|
+#else
|
|
|
+#define MOPT_Q MOPT_NOSUPPORT
|
|
|
+#define MOPT_QFMT MOPT_NOSUPPORT
|
|
|
#endif
|
|
|
-
|
|
|
- if (!options)
|
|
|
- return 1;
|
|
|
-
|
|
|
- while ((p = strsep(&options, ",")) != NULL) {
|
|
|
- int token;
|
|
|
- if (!*p)
|
|
|
- continue;
|
|
|
-
|
|
|
- /*
|
|
|
- * Initialize args struct so we know whether arg was
|
|
|
- * found; some options take optional arguments.
|
|
|
- */
|
|
|
- args[0].to = args[0].from = NULL;
|
|
|
- token = match_token(p, tokens, args);
|
|
|
- switch (token) {
|
|
|
- case Opt_bsd_df:
|
|
|
- ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
|
|
|
- clear_opt(sb, MINIX_DF);
|
|
|
- break;
|
|
|
- case Opt_minix_df:
|
|
|
- ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
|
|
|
- set_opt(sb, MINIX_DF);
|
|
|
-
|
|
|
- break;
|
|
|
- case Opt_grpid:
|
|
|
- ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
|
|
|
- set_opt(sb, GRPID);
|
|
|
-
|
|
|
- break;
|
|
|
- case Opt_nogrpid:
|
|
|
- ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38");
|
|
|
- clear_opt(sb, GRPID);
|
|
|
-
|
|
|
- break;
|
|
|
- case Opt_resuid:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- sbi->s_resuid = option;
|
|
|
- break;
|
|
|
- case Opt_resgid:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- sbi->s_resgid = option;
|
|
|
- break;
|
|
|
- case Opt_sb:
|
|
|
- /* handled by get_sb_block() instead of here */
|
|
|
- /* *sb_block = match_int(&args[0]); */
|
|
|
- break;
|
|
|
- case Opt_err_panic:
|
|
|
- clear_opt(sb, ERRORS_CONT);
|
|
|
- clear_opt(sb, ERRORS_RO);
|
|
|
- set_opt(sb, ERRORS_PANIC);
|
|
|
- break;
|
|
|
- case Opt_err_ro:
|
|
|
- clear_opt(sb, ERRORS_CONT);
|
|
|
- clear_opt(sb, ERRORS_PANIC);
|
|
|
- set_opt(sb, ERRORS_RO);
|
|
|
- break;
|
|
|
- case Opt_err_cont:
|
|
|
- clear_opt(sb, ERRORS_RO);
|
|
|
- clear_opt(sb, ERRORS_PANIC);
|
|
|
- set_opt(sb, ERRORS_CONT);
|
|
|
- break;
|
|
|
- case Opt_nouid32:
|
|
|
- set_opt(sb, NO_UID32);
|
|
|
- break;
|
|
|
- case Opt_debug:
|
|
|
- set_opt(sb, DEBUG);
|
|
|
- break;
|
|
|
- case Opt_oldalloc:
|
|
|
- ext4_msg(sb, KERN_WARNING,
|
|
|
- "Ignoring deprecated oldalloc option");
|
|
|
- break;
|
|
|
- case Opt_orlov:
|
|
|
- ext4_msg(sb, KERN_WARNING,
|
|
|
- "Ignoring deprecated orlov option");
|
|
|
- break;
|
|
|
+#define MOPT_DATAJ 0x0080
|
|
|
+
|
|
|
+static const struct mount_opts {
|
|
|
+ int token;
|
|
|
+ int mount_opt;
|
|
|
+ int flags;
|
|
|
+} ext4_mount_opts[] = {
|
|
|
+ {Opt_minix_df, EXT4_MOUNT_MINIX_DF, MOPT_SET},
|
|
|
+ {Opt_bsd_df, EXT4_MOUNT_MINIX_DF, MOPT_CLEAR},
|
|
|
+ {Opt_grpid, EXT4_MOUNT_GRPID, MOPT_SET},
|
|
|
+ {Opt_nogrpid, EXT4_MOUNT_GRPID, MOPT_CLEAR},
|
|
|
+ {Opt_mblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_SET},
|
|
|
+ {Opt_nomblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_CLEAR},
|
|
|
+ {Opt_block_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_SET},
|
|
|
+ {Opt_noblock_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_CLEAR},
|
|
|
+ {Opt_dioread_nolock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_SET},
|
|
|
+ {Opt_dioread_lock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_CLEAR},
|
|
|
+ {Opt_discard, EXT4_MOUNT_DISCARD, MOPT_SET},
|
|
|
+ {Opt_nodiscard, EXT4_MOUNT_DISCARD, MOPT_CLEAR},
|
|
|
+ {Opt_delalloc, EXT4_MOUNT_DELALLOC, MOPT_SET | MOPT_EXPLICIT},
|
|
|
+ {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, MOPT_CLEAR | MOPT_EXPLICIT},
|
|
|
+ {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_SET},
|
|
|
+ {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT |
|
|
|
+ EXT4_MOUNT_JOURNAL_CHECKSUM), MOPT_SET},
|
|
|
+ {Opt_noload, EXT4_MOUNT_NOLOAD, MOPT_SET},
|
|
|
+ {Opt_err_panic, EXT4_MOUNT_ERRORS_PANIC, MOPT_SET | MOPT_CLEAR_ERR},
|
|
|
+ {Opt_err_ro, EXT4_MOUNT_ERRORS_RO, MOPT_SET | MOPT_CLEAR_ERR},
|
|
|
+ {Opt_err_cont, EXT4_MOUNT_ERRORS_CONT, MOPT_SET | MOPT_CLEAR_ERR},
|
|
|
+ {Opt_data_err_abort, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_SET},
|
|
|
+ {Opt_data_err_ignore, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_CLEAR},
|
|
|
+ {Opt_barrier, EXT4_MOUNT_BARRIER, MOPT_SET},
|
|
|
+ {Opt_nobarrier, EXT4_MOUNT_BARRIER, MOPT_CLEAR},
|
|
|
+ {Opt_noauto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_SET},
|
|
|
+ {Opt_auto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_CLEAR},
|
|
|
+ {Opt_noinit_itable, EXT4_MOUNT_INIT_INODE_TABLE, MOPT_CLEAR},
|
|
|
+ {Opt_commit, 0, MOPT_GTE0},
|
|
|
+ {Opt_max_batch_time, 0, MOPT_GTE0},
|
|
|
+ {Opt_min_batch_time, 0, MOPT_GTE0},
|
|
|
+ {Opt_inode_readahead_blks, 0, MOPT_GTE0},
|
|
|
+ {Opt_init_itable, 0, MOPT_GTE0},
|
|
|
+ {Opt_stripe, 0, MOPT_GTE0},
|
|
|
+ {Opt_data_journal, EXT4_MOUNT_JOURNAL_DATA, MOPT_DATAJ},
|
|
|
+ {Opt_data_ordered, EXT4_MOUNT_ORDERED_DATA, MOPT_DATAJ},
|
|
|
+ {Opt_data_writeback, EXT4_MOUNT_WRITEBACK_DATA, MOPT_DATAJ},
|
|
|
#ifdef CONFIG_EXT4_FS_XATTR
|
|
|
- case Opt_user_xattr:
|
|
|
- set_opt(sb, XATTR_USER);
|
|
|
- break;
|
|
|
- case Opt_nouser_xattr:
|
|
|
- clear_opt(sb, XATTR_USER);
|
|
|
- break;
|
|
|
+ {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET},
|
|
|
+ {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR},
|
|
|
#else
|
|
|
- case Opt_user_xattr:
|
|
|
- case Opt_nouser_xattr:
|
|
|
- ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported");
|
|
|
- break;
|
|
|
+ {Opt_user_xattr, 0, MOPT_NOSUPPORT},
|
|
|
+ {Opt_nouser_xattr, 0, MOPT_NOSUPPORT},
|
|
|
#endif
|
|
|
#ifdef CONFIG_EXT4_FS_POSIX_ACL
|
|
|
- case Opt_acl:
|
|
|
- set_opt(sb, POSIX_ACL);
|
|
|
- break;
|
|
|
- case Opt_noacl:
|
|
|
- clear_opt(sb, POSIX_ACL);
|
|
|
- break;
|
|
|
+ {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET},
|
|
|
+ {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR},
|
|
|
#else
|
|
|
- case Opt_acl:
|
|
|
- case Opt_noacl:
|
|
|
- ext4_msg(sb, KERN_ERR, "(no)acl options not supported");
|
|
|
- break;
|
|
|
+ {Opt_acl, 0, MOPT_NOSUPPORT},
|
|
|
+ {Opt_noacl, 0, MOPT_NOSUPPORT},
|
|
|
#endif
|
|
|
- case Opt_journal_update:
|
|
|
- /* @@@ FIXME */
|
|
|
- /* Eventually we will want to be able to create
|
|
|
- a journal file here. For now, only allow the
|
|
|
- user to specify an existing inode to be the
|
|
|
- journal file. */
|
|
|
- if (is_remount) {
|
|
|
- ext4_msg(sb, KERN_ERR,
|
|
|
- "Cannot specify journal on remount");
|
|
|
- return 0;
|
|
|
- }
|
|
|
- set_opt(sb, UPDATE_JOURNAL);
|
|
|
- break;
|
|
|
- case Opt_journal_dev:
|
|
|
- if (is_remount) {
|
|
|
+ {Opt_nouid32, EXT4_MOUNT_NO_UID32, MOPT_SET},
|
|
|
+ {Opt_debug, EXT4_MOUNT_DEBUG, MOPT_SET},
|
|
|
+ {Opt_quota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, MOPT_SET | MOPT_Q},
|
|
|
+ {Opt_usrquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA,
|
|
|
+ MOPT_SET | MOPT_Q},
|
|
|
+ {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA,
|
|
|
+ MOPT_SET | MOPT_Q},
|
|
|
+ {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA |
|
|
|
+ EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q},
|
|
|
+ {Opt_usrjquota, 0, MOPT_Q},
|
|
|
+ {Opt_grpjquota, 0, MOPT_Q},
|
|
|
+ {Opt_offusrjquota, 0, MOPT_Q},
|
|
|
+ {Opt_offgrpjquota, 0, MOPT_Q},
|
|
|
+ {Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
|
|
|
+ {Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
|
|
|
+ {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
|
|
|
+ {Opt_err, 0, 0}
|
|
|
+};
|
|
|
+
|
|
|
+static int handle_mount_opt(struct super_block *sb, char *opt, int token,
|
|
|
+ substring_t *args, unsigned long *journal_devnum,
|
|
|
+ unsigned int *journal_ioprio, int is_remount)
|
|
|
+{
|
|
|
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
+ const struct mount_opts *m;
|
|
|
+ int arg = 0;
|
|
|
+
|
|
|
+ if (args->from && match_int(args, &arg))
|
|
|
+ return -1;
|
|
|
+ switch (token) {
|
|
|
+ case Opt_noacl:
|
|
|
+ case Opt_nouser_xattr:
|
|
|
+ ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5");
|
|
|
+ break;
|
|
|
+ case Opt_sb:
|
|
|
+ return 1; /* handled by get_sb_block() */
|
|
|
+ case Opt_removed:
|
|
|
+ ext4_msg(sb, KERN_WARNING,
|
|
|
+ "Ignoring removed %s option", opt);
|
|
|
+ return 1;
|
|
|
+ case Opt_resuid:
|
|
|
+ sbi->s_resuid = arg;
|
|
|
+ return 1;
|
|
|
+ case Opt_resgid:
|
|
|
+ sbi->s_resgid = arg;
|
|
|
+ return 1;
|
|
|
+ case Opt_abort:
|
|
|
+ sbi->s_mount_flags |= EXT4_MF_FS_ABORTED;
|
|
|
+ return 1;
|
|
|
+ case Opt_i_version:
|
|
|
+ sb->s_flags |= MS_I_VERSION;
|
|
|
+ return 1;
|
|
|
+ case Opt_journal_dev:
|
|
|
+ if (is_remount) {
|
|
|
+ ext4_msg(sb, KERN_ERR,
|
|
|
+ "Cannot specify journal on remount");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ *journal_devnum = arg;
|
|
|
+ return 1;
|
|
|
+ case Opt_journal_ioprio:
|
|
|
+ if (arg < 0 || arg > 7)
|
|
|
+ return -1;
|
|
|
+ *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (m = ext4_mount_opts; m->token != Opt_err; m++) {
|
|
|
+ if (token != m->token)
|
|
|
+ continue;
|
|
|
+ if (args->from && (m->flags & MOPT_GTE0) && (arg < 0))
|
|
|
+ return -1;
|
|
|
+ if (m->flags & MOPT_EXPLICIT)
|
|
|
+ set_opt2(sb, EXPLICIT_DELALLOC);
|
|
|
+ if (m->flags & MOPT_CLEAR_ERR)
|
|
|
+ clear_opt(sb, ERRORS_MASK);
|
|
|
+ if (token == Opt_noquota && sb_any_quota_loaded(sb)) {
|
|
|
+ ext4_msg(sb, KERN_ERR, "Cannot change quota "
|
|
|
+ "options when quota turned on");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m->flags & MOPT_NOSUPPORT) {
|
|
|
+ ext4_msg(sb, KERN_ERR, "%s option not supported", opt);
|
|
|
+ } else if (token == Opt_commit) {
|
|
|
+ if (arg == 0)
|
|
|
+ arg = JBD2_DEFAULT_MAX_COMMIT_AGE;
|
|
|
+ sbi->s_commit_interval = HZ * arg;
|
|
|
+ } else if (token == Opt_max_batch_time) {
|
|
|
+ if (arg == 0)
|
|
|
+ arg = EXT4_DEF_MAX_BATCH_TIME;
|
|
|
+ sbi->s_max_batch_time = arg;
|
|
|
+ } else if (token == Opt_min_batch_time) {
|
|
|
+ sbi->s_min_batch_time = arg;
|
|
|
+ } else if (token == Opt_inode_readahead_blks) {
|
|
|
+ if (arg > (1 << 30))
|
|
|
+ return -1;
|
|
|
+ if (arg && !is_power_of_2(arg)) {
|
|
|
ext4_msg(sb, KERN_ERR,
|
|
|
- "Cannot specify journal on remount");
|
|
|
- return 0;
|
|
|
+ "EXT4-fs: inode_readahead_blks"
|
|
|
+ " must be a power of 2");
|
|
|
+ return -1;
|
|
|
}
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- *journal_devnum = option;
|
|
|
- break;
|
|
|
- case Opt_journal_checksum:
|
|
|
- set_opt(sb, JOURNAL_CHECKSUM);
|
|
|
- break;
|
|
|
- case Opt_journal_async_commit:
|
|
|
- set_opt(sb, JOURNAL_ASYNC_COMMIT);
|
|
|
- set_opt(sb, JOURNAL_CHECKSUM);
|
|
|
- break;
|
|
|
- case Opt_noload:
|
|
|
- set_opt(sb, NOLOAD);
|
|
|
- break;
|
|
|
- case Opt_commit:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- if (option < 0)
|
|
|
- return 0;
|
|
|
- if (option == 0)
|
|
|
- option = JBD2_DEFAULT_MAX_COMMIT_AGE;
|
|
|
- sbi->s_commit_interval = HZ * option;
|
|
|
- break;
|
|
|
- case Opt_max_batch_time:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- if (option < 0)
|
|
|
- return 0;
|
|
|
- if (option == 0)
|
|
|
- option = EXT4_DEF_MAX_BATCH_TIME;
|
|
|
- sbi->s_max_batch_time = option;
|
|
|
- break;
|
|
|
- case Opt_min_batch_time:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- if (option < 0)
|
|
|
- return 0;
|
|
|
- sbi->s_min_batch_time = option;
|
|
|
- break;
|
|
|
- case Opt_data_journal:
|
|
|
- data_opt = EXT4_MOUNT_JOURNAL_DATA;
|
|
|
- goto datacheck;
|
|
|
- case Opt_data_ordered:
|
|
|
- data_opt = EXT4_MOUNT_ORDERED_DATA;
|
|
|
- goto datacheck;
|
|
|
- case Opt_data_writeback:
|
|
|
- data_opt = EXT4_MOUNT_WRITEBACK_DATA;
|
|
|
- datacheck:
|
|
|
+ sbi->s_inode_readahead_blks = arg;
|
|
|
+ } else if (token == Opt_init_itable) {
|
|
|
+ set_opt(sb, INIT_INODE_TABLE);
|
|
|
+ if (!args->from)
|
|
|
+ arg = EXT4_DEF_LI_WAIT_MULT;
|
|
|
+ sbi->s_li_wait_mult = arg;
|
|
|
+ } else if (token == Opt_stripe) {
|
|
|
+ sbi->s_stripe = arg;
|
|
|
+ } else if (m->flags & MOPT_DATAJ) {
|
|
|
if (is_remount) {
|
|
|
if (!sbi->s_journal)
|
|
|
ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option");
|
|
|
- else if (test_opt(sb, DATA_FLAGS) != data_opt) {
|
|
|
+ else if (test_opt(sb, DATA_FLAGS) !=
|
|
|
+ m->mount_opt) {
|
|
|
ext4_msg(sb, KERN_ERR,
|
|
|
- "Cannot change data mode on remount");
|
|
|
- return 0;
|
|
|
+ "Cannot change data mode on remount");
|
|
|
+ return -1;
|
|
|
}
|
|
|
} else {
|
|
|
clear_opt(sb, DATA_FLAGS);
|
|
|
- sbi->s_mount_opt |= data_opt;
|
|
|
+ sbi->s_mount_opt |= m->mount_opt;
|
|
|
}
|
|
|
- break;
|
|
|
- case Opt_data_err_abort:
|
|
|
- set_opt(sb, DATA_ERR_ABORT);
|
|
|
- break;
|
|
|
- case Opt_data_err_ignore:
|
|
|
- clear_opt(sb, DATA_ERR_ABORT);
|
|
|
- break;
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
- case Opt_usrjquota:
|
|
|
+ } else if (token == Opt_usrjquota) {
|
|
|
if (!set_qf_name(sb, USRQUOTA, &args[0]))
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- case Opt_grpjquota:
|
|
|
+ return -1;
|
|
|
+ } else if (token == Opt_grpjquota) {
|
|
|
if (!set_qf_name(sb, GRPQUOTA, &args[0]))
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- case Opt_offusrjquota:
|
|
|
+ return -1;
|
|
|
+ } else if (token == Opt_offusrjquota) {
|
|
|
if (!clear_qf_name(sb, USRQUOTA))
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- case Opt_offgrpjquota:
|
|
|
+ return -1;
|
|
|
+ } else if (token == Opt_offgrpjquota) {
|
|
|
if (!clear_qf_name(sb, GRPQUOTA))
|
|
|
- return 0;
|
|
|
- break;
|
|
|
-
|
|
|
- case Opt_jqfmt_vfsold:
|
|
|
- qfmt = QFMT_VFS_OLD;
|
|
|
- goto set_qf_format;
|
|
|
- case Opt_jqfmt_vfsv0:
|
|
|
- qfmt = QFMT_VFS_V0;
|
|
|
- goto set_qf_format;
|
|
|
- case Opt_jqfmt_vfsv1:
|
|
|
- qfmt = QFMT_VFS_V1;
|
|
|
-set_qf_format:
|
|
|
+ return -1;
|
|
|
+ } else if (m->flags & MOPT_QFMT) {
|
|
|
if (sb_any_quota_loaded(sb) &&
|
|
|
- sbi->s_jquota_fmt != qfmt) {
|
|
|
- ext4_msg(sb, KERN_ERR, "Cannot change "
|
|
|
- "journaled quota options when "
|
|
|
- "quota turned on");
|
|
|
- return 0;
|
|
|
- }
|
|
|
- sbi->s_jquota_fmt = qfmt;
|
|
|
- break;
|
|
|
- case Opt_quota:
|
|
|
- case Opt_usrquota:
|
|
|
- set_opt(sb, QUOTA);
|
|
|
- set_opt(sb, USRQUOTA);
|
|
|
- break;
|
|
|
- case Opt_grpquota:
|
|
|
- set_opt(sb, QUOTA);
|
|
|
- set_opt(sb, GRPQUOTA);
|
|
|
- break;
|
|
|
- case Opt_noquota:
|
|
|
- if (sb_any_quota_loaded(sb)) {
|
|
|
- ext4_msg(sb, KERN_ERR, "Cannot change quota "
|
|
|
- "options when quota turned on");
|
|
|
- return 0;
|
|
|
+ sbi->s_jquota_fmt != m->mount_opt) {
|
|
|
+ ext4_msg(sb, KERN_ERR, "Cannot "
|
|
|
+ "change journaled quota options "
|
|
|
+ "when quota turned on");
|
|
|
+ return -1;
|
|
|
}
|
|
|
- clear_opt(sb, QUOTA);
|
|
|
- clear_opt(sb, USRQUOTA);
|
|
|
- clear_opt(sb, GRPQUOTA);
|
|
|
- break;
|
|
|
-#else
|
|
|
- case Opt_quota:
|
|
|
- case Opt_usrquota:
|
|
|
- case Opt_grpquota:
|
|
|
- ext4_msg(sb, KERN_ERR,
|
|
|
- "quota options not supported");
|
|
|
- break;
|
|
|
- case Opt_usrjquota:
|
|
|
- case Opt_grpjquota:
|
|
|
- case Opt_offusrjquota:
|
|
|
- case Opt_offgrpjquota:
|
|
|
- case Opt_jqfmt_vfsold:
|
|
|
- case Opt_jqfmt_vfsv0:
|
|
|
- case Opt_jqfmt_vfsv1:
|
|
|
- ext4_msg(sb, KERN_ERR,
|
|
|
- "journaled quota options not supported");
|
|
|
- break;
|
|
|
- case Opt_noquota:
|
|
|
- break;
|
|
|
+ sbi->s_jquota_fmt = m->mount_opt;
|
|
|
#endif
|
|
|
- case Opt_abort:
|
|
|
- sbi->s_mount_flags |= EXT4_MF_FS_ABORTED;
|
|
|
- break;
|
|
|
- case Opt_nobarrier:
|
|
|
- clear_opt(sb, BARRIER);
|
|
|
- break;
|
|
|
- case Opt_barrier:
|
|
|
- if (args[0].from) {
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- } else
|
|
|
- option = 1; /* No argument, default to 1 */
|
|
|
- if (option)
|
|
|
- set_opt(sb, BARRIER);
|
|
|
- else
|
|
|
- clear_opt(sb, BARRIER);
|
|
|
- break;
|
|
|
- case Opt_ignore:
|
|
|
- break;
|
|
|
- case Opt_resize:
|
|
|
- if (!is_remount) {
|
|
|
- ext4_msg(sb, KERN_ERR,
|
|
|
- "resize option only available "
|
|
|
- "for remount");
|
|
|
- return 0;
|
|
|
- }
|
|
|
- if (match_int(&args[0], &option) != 0)
|
|
|
- return 0;
|
|
|
- *n_blocks_count = option;
|
|
|
- break;
|
|
|
- case Opt_nobh:
|
|
|
- ext4_msg(sb, KERN_WARNING,
|
|
|
- "Ignoring deprecated nobh option");
|
|
|
- break;
|
|
|
- case Opt_bh:
|
|
|
- ext4_msg(sb, KERN_WARNING,
|
|
|
- "Ignoring deprecated bh option");
|
|
|
- break;
|
|
|
- case Opt_i_version:
|
|
|
- set_opt(sb, I_VERSION);
|
|
|
- sb->s_flags |= MS_I_VERSION;
|
|
|
- break;
|
|
|
- case Opt_nodelalloc:
|
|
|
- clear_opt(sb, DELALLOC);
|
|
|
- clear_opt2(sb, EXPLICIT_DELALLOC);
|
|
|
- break;
|
|
|
- case Opt_mblk_io_submit:
|
|
|
- set_opt(sb, MBLK_IO_SUBMIT);
|
|
|
- break;
|
|
|
- case Opt_nomblk_io_submit:
|
|
|
- clear_opt(sb, MBLK_IO_SUBMIT);
|
|
|
- break;
|
|
|
- case Opt_stripe:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- if (option < 0)
|
|
|
- return 0;
|
|
|
- sbi->s_stripe = option;
|
|
|
- break;
|
|
|
- case Opt_delalloc:
|
|
|
- set_opt(sb, DELALLOC);
|
|
|
- set_opt2(sb, EXPLICIT_DELALLOC);
|
|
|
- break;
|
|
|
- case Opt_block_validity:
|
|
|
- set_opt(sb, BLOCK_VALIDITY);
|
|
|
- break;
|
|
|
- case Opt_noblock_validity:
|
|
|
- clear_opt(sb, BLOCK_VALIDITY);
|
|
|
- break;
|
|
|
- case Opt_inode_readahead_blks:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- if (option < 0 || option > (1 << 30))
|
|
|
- return 0;
|
|
|
- if (option && !is_power_of_2(option)) {
|
|
|
- ext4_msg(sb, KERN_ERR,
|
|
|
- "EXT4-fs: inode_readahead_blks"
|
|
|
- " must be a power of 2");
|
|
|
- return 0;
|
|
|
+ } else {
|
|
|
+ if (!args->from)
|
|
|
+ arg = 1;
|
|
|
+ if (m->flags & MOPT_CLEAR)
|
|
|
+ arg = !arg;
|
|
|
+ else if (unlikely(!(m->flags & MOPT_SET))) {
|
|
|
+ ext4_msg(sb, KERN_WARNING,
|
|
|
+ "buggy handling of option %s", opt);
|
|
|
+ WARN_ON(1);
|
|
|
+ return -1;
|
|
|
}
|
|
|
- sbi->s_inode_readahead_blks = option;
|
|
|
- break;
|
|
|
- case Opt_journal_ioprio:
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- if (option < 0 || option > 7)
|
|
|
- break;
|
|
|
- *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE,
|
|
|
- option);
|
|
|
- break;
|
|
|
- case Opt_noauto_da_alloc:
|
|
|
- set_opt(sb, NO_AUTO_DA_ALLOC);
|
|
|
- break;
|
|
|
- case Opt_auto_da_alloc:
|
|
|
- if (args[0].from) {
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- } else
|
|
|
- option = 1; /* No argument, default to 1 */
|
|
|
- if (option)
|
|
|
- clear_opt(sb, NO_AUTO_DA_ALLOC);
|
|
|
+ if (arg != 0)
|
|
|
+ sbi->s_mount_opt |= m->mount_opt;
|
|
|
else
|
|
|
- set_opt(sb,NO_AUTO_DA_ALLOC);
|
|
|
- break;
|
|
|
- case Opt_discard:
|
|
|
- set_opt(sb, DISCARD);
|
|
|
- break;
|
|
|
- case Opt_nodiscard:
|
|
|
- clear_opt(sb, DISCARD);
|
|
|
- break;
|
|
|
- case Opt_dioread_nolock:
|
|
|
- set_opt(sb, DIOREAD_NOLOCK);
|
|
|
- break;
|
|
|
- case Opt_dioread_lock:
|
|
|
- clear_opt(sb, DIOREAD_NOLOCK);
|
|
|
- break;
|
|
|
- case Opt_init_itable:
|
|
|
- set_opt(sb, INIT_INODE_TABLE);
|
|
|
- if (args[0].from) {
|
|
|
- if (match_int(&args[0], &option))
|
|
|
- return 0;
|
|
|
- } else
|
|
|
- option = EXT4_DEF_LI_WAIT_MULT;
|
|
|
- if (option < 0)
|
|
|
- return 0;
|
|
|
- sbi->s_li_wait_mult = option;
|
|
|
- break;
|
|
|
- case Opt_noinit_itable:
|
|
|
- clear_opt(sb, INIT_INODE_TABLE);
|
|
|
- break;
|
|
|
- default:
|
|
|
- ext4_msg(sb, KERN_ERR,
|
|
|
- "Unrecognized mount option \"%s\" "
|
|
|
- "or missing value", p);
|
|
|
- return 0;
|
|
|
+ sbi->s_mount_opt &= ~m->mount_opt;
|
|
|
}
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ ext4_msg(sb, KERN_ERR, "Unrecognized mount option \"%s\" "
|
|
|
+ "or missing value", opt);
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+static int parse_options(char *options, struct super_block *sb,
|
|
|
+ unsigned long *journal_devnum,
|
|
|
+ unsigned int *journal_ioprio,
|
|
|
+ int is_remount)
|
|
|
+{
|
|
|
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
+ char *p;
|
|
|
+ substring_t args[MAX_OPT_ARGS];
|
|
|
+ int token;
|
|
|
+
|
|
|
+ if (!options)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ while ((p = strsep(&options, ",")) != NULL) {
|
|
|
+ if (!*p)
|
|
|
+ continue;
|
|
|
+ /*
|
|
|
+ * Initialize args struct so we know whether arg was
|
|
|
+ * found; some options take optional arguments.
|
|
|
+ */
|
|
|
+ args[0].to = args[0].from = 0;
|
|
|
+ token = match_token(p, tokens, args);
|
|
|
+ if (handle_mount_opt(sb, p, token, args, journal_devnum,
|
|
|
+ journal_ioprio, is_remount) < 0)
|
|
|
+ return 0;
|
|
|
}
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
|
|
@@ -1942,6 +1651,160 @@ set_qf_format:
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static inline void ext4_show_quota_options(struct seq_file *seq,
|
|
|
+ struct super_block *sb)
|
|
|
+{
|
|
|
+#if defined(CONFIG_QUOTA)
|
|
|
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
+
|
|
|
+ if (sbi->s_jquota_fmt) {
|
|
|
+ char *fmtname = "";
|
|
|
+
|
|
|
+ switch (sbi->s_jquota_fmt) {
|
|
|
+ case QFMT_VFS_OLD:
|
|
|
+ fmtname = "vfsold";
|
|
|
+ break;
|
|
|
+ case QFMT_VFS_V0:
|
|
|
+ fmtname = "vfsv0";
|
|
|
+ break;
|
|
|
+ case QFMT_VFS_V1:
|
|
|
+ fmtname = "vfsv1";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ seq_printf(seq, ",jqfmt=%s", fmtname);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sbi->s_qf_names[USRQUOTA])
|
|
|
+ seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
|
|
|
+
|
|
|
+ if (sbi->s_qf_names[GRPQUOTA])
|
|
|
+ seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
|
|
|
+
|
|
|
+ if (test_opt(sb, USRQUOTA))
|
|
|
+ seq_puts(seq, ",usrquota");
|
|
|
+
|
|
|
+ if (test_opt(sb, GRPQUOTA))
|
|
|
+ seq_puts(seq, ",grpquota");
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+static const char *token2str(int token)
|
|
|
+{
|
|
|
+ static const struct match_token *t;
|
|
|
+
|
|
|
+ for (t = tokens; t->token != Opt_err; t++)
|
|
|
+ if (t->token == token && !strchr(t->pattern, '='))
|
|
|
+ break;
|
|
|
+ return t->pattern;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Show an option if
|
|
|
+ * - it's set to a non-default value OR
|
|
|
+ * - if the per-sb default is different from the global default
|
|
|
+ */
|
|
|
+static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
|
|
|
+ int nodefs)
|
|
|
+{
|
|
|
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
+ struct ext4_super_block *es = sbi->s_es;
|
|
|
+ int def_errors, def_mount_opt = nodefs ? 0 : sbi->s_def_mount_opt;
|
|
|
+ const struct mount_opts *m;
|
|
|
+ char sep = nodefs ? '\n' : ',';
|
|
|
+
|
|
|
+#define SEQ_OPTS_PUTS(str) seq_printf(seq, "%c" str, sep)
|
|
|
+#define SEQ_OPTS_PRINT(str, arg) seq_printf(seq, "%c" str, sep, arg)
|
|
|
+
|
|
|
+ if (sbi->s_sb_block != 1)
|
|
|
+ SEQ_OPTS_PRINT("sb=%llu", sbi->s_sb_block);
|
|
|
+
|
|
|
+ for (m = ext4_mount_opts; m->token != Opt_err; m++) {
|
|
|
+ int want_set = m->flags & MOPT_SET;
|
|
|
+ if (((m->flags & (MOPT_SET|MOPT_CLEAR)) == 0) ||
|
|
|
+ (m->flags & MOPT_CLEAR_ERR))
|
|
|
+ continue;
|
|
|
+ if (!(m->mount_opt & (sbi->s_mount_opt ^ def_mount_opt)))
|
|
|
+ continue; /* skip if same as the default */
|
|
|
+ if ((want_set &&
|
|
|
+ (sbi->s_mount_opt & m->mount_opt) != m->mount_opt) ||
|
|
|
+ (!want_set && (sbi->s_mount_opt & m->mount_opt)))
|
|
|
+ continue; /* select Opt_noFoo vs Opt_Foo */
|
|
|
+ SEQ_OPTS_PRINT("%s", token2str(m->token));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nodefs || sbi->s_resuid != EXT4_DEF_RESUID ||
|
|
|
+ le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID)
|
|
|
+ SEQ_OPTS_PRINT("resuid=%u", sbi->s_resuid);
|
|
|
+ if (nodefs || sbi->s_resgid != EXT4_DEF_RESGID ||
|
|
|
+ le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID)
|
|
|
+ SEQ_OPTS_PRINT("resgid=%u", sbi->s_resgid);
|
|
|
+ def_errors = nodefs ? -1 : le16_to_cpu(es->s_errors);
|
|
|
+ if (test_opt(sb, ERRORS_RO) && def_errors != EXT4_ERRORS_RO)
|
|
|
+ SEQ_OPTS_PUTS("errors=remount-ro");
|
|
|
+ if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE)
|
|
|
+ SEQ_OPTS_PUTS("errors=continue");
|
|
|
+ if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC)
|
|
|
+ SEQ_OPTS_PUTS("errors=panic");
|
|
|
+ if (nodefs || sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ)
|
|
|
+ SEQ_OPTS_PRINT("commit=%lu", sbi->s_commit_interval / HZ);
|
|
|
+ if (nodefs || sbi->s_min_batch_time != EXT4_DEF_MIN_BATCH_TIME)
|
|
|
+ SEQ_OPTS_PRINT("min_batch_time=%u", sbi->s_min_batch_time);
|
|
|
+ if (nodefs || sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME)
|
|
|
+ SEQ_OPTS_PRINT("max_batch_time=%u", sbi->s_max_batch_time);
|
|
|
+ if (sb->s_flags & MS_I_VERSION)
|
|
|
+ SEQ_OPTS_PUTS("i_version");
|
|
|
+ if (nodefs || sbi->s_stripe)
|
|
|
+ SEQ_OPTS_PRINT("stripe=%lu", sbi->s_stripe);
|
|
|
+ if (EXT4_MOUNT_DATA_FLAGS & (sbi->s_mount_opt ^ def_mount_opt)) {
|
|
|
+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
|
|
|
+ SEQ_OPTS_PUTS("data=journal");
|
|
|
+ else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
|
|
|
+ SEQ_OPTS_PUTS("data=ordered");
|
|
|
+ else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
|
|
|
+ SEQ_OPTS_PUTS("data=writeback");
|
|
|
+ }
|
|
|
+ if (nodefs ||
|
|
|
+ sbi->s_inode_readahead_blks != EXT4_DEF_INODE_READAHEAD_BLKS)
|
|
|
+ SEQ_OPTS_PRINT("inode_readahead_blks=%u",
|
|
|
+ sbi->s_inode_readahead_blks);
|
|
|
+
|
|
|
+ if (nodefs || (test_opt(sb, INIT_INODE_TABLE) &&
|
|
|
+ (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)))
|
|
|
+ SEQ_OPTS_PRINT("init_itable=%u", sbi->s_li_wait_mult);
|
|
|
+
|
|
|
+ ext4_show_quota_options(seq, sb);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int ext4_show_options(struct seq_file *seq, struct dentry *root)
|
|
|
+{
|
|
|
+ return _ext4_show_options(seq, root->d_sb, 0);
|
|
|
+}
|
|
|
+
|
|
|
+static int options_seq_show(struct seq_file *seq, void *offset)
|
|
|
+{
|
|
|
+ struct super_block *sb = seq->private;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ seq_puts(seq, (sb->s_flags & MS_RDONLY) ? "ro" : "rw");
|
|
|
+ rc = _ext4_show_options(seq, sb, 1);
|
|
|
+ seq_puts(seq, "\n");
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+static int options_open_fs(struct inode *inode, struct file *file)
|
|
|
+{
|
|
|
+ return single_open(file, options_seq_show, PDE(inode)->data);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct file_operations ext4_seq_options_fops = {
|
|
|
+ .owner = THIS_MODULE,
|
|
|
+ .open = options_open_fs,
|
|
|
+ .read = seq_read,
|
|
|
+ .llseek = seq_lseek,
|
|
|
+ .release = single_release,
|
|
|
+};
|
|
|
+
|
|
|
static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
|
|
|
int read_only)
|
|
|
{
|
|
@@ -2945,7 +2808,7 @@ static int ext4_run_lazyinit_thread(void)
|
|
|
ext4_clear_request_list();
|
|
|
kfree(ext4_li_info);
|
|
|
ext4_li_info = NULL;
|
|
|
- printk(KERN_CRIT "EXT4: error %d creating inode table "
|
|
|
+ printk(KERN_CRIT "EXT4-fs: error %d creating inode table "
|
|
|
"initialization thread\n",
|
|
|
err);
|
|
|
return err;
|
|
@@ -3183,11 +3046,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|
|
set_opt(sb, INIT_INODE_TABLE);
|
|
|
if (def_mount_opts & EXT4_DEFM_DEBUG)
|
|
|
set_opt(sb, DEBUG);
|
|
|
- if (def_mount_opts & EXT4_DEFM_BSDGROUPS) {
|
|
|
- ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups",
|
|
|
- "2.6.38");
|
|
|
+ if (def_mount_opts & EXT4_DEFM_BSDGROUPS)
|
|
|
set_opt(sb, GRPID);
|
|
|
- }
|
|
|
if (def_mount_opts & EXT4_DEFM_UID16)
|
|
|
set_opt(sb, NO_UID32);
|
|
|
/* 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)
|
|
|
sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
|
|
|
|
|
|
if (!parse_options((char *) sbi->s_es->s_mount_opts, sb,
|
|
|
- &journal_devnum, &journal_ioprio, NULL, 0)) {
|
|
|
+ &journal_devnum, &journal_ioprio, 0)) {
|
|
|
ext4_msg(sb, KERN_WARNING,
|
|
|
"failed to parse options in superblock: %s",
|
|
|
sbi->s_es->s_mount_opts);
|
|
|
}
|
|
|
+ sbi->s_def_mount_opt = sbi->s_mount_opt;
|
|
|
if (!parse_options((char *) data, sb, &journal_devnum,
|
|
|
- &journal_ioprio, NULL, 0))
|
|
|
+ &journal_ioprio, 0))
|
|
|
goto failed_mount;
|
|
|
|
|
|
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)
|
|
|
#else
|
|
|
es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
|
|
|
#endif
|
|
|
- sb->s_dirt = 1;
|
|
|
}
|
|
|
|
|
|
/* Handle clustersize */
|
|
@@ -3540,6 +3400,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|
|
if (ext4_proc_root)
|
|
|
sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root);
|
|
|
|
|
|
+ if (sbi->s_proc)
|
|
|
+ proc_create_data("options", S_IRUGO, sbi->s_proc,
|
|
|
+ &ext4_seq_options_fops, sb);
|
|
|
+
|
|
|
bgl_lock_init(sbi->s_blockgroup_lock);
|
|
|
|
|
|
for (i = 0; i < db_count; i++) {
|
|
@@ -3694,6 +3558,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|
|
}
|
|
|
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
|
|
|
|
|
|
+ sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
|
|
|
+
|
|
|
/*
|
|
|
* The journal may have updated the bg summary counts, so we
|
|
|
* need to update the global counters.
|
|
@@ -3861,6 +3727,7 @@ failed_mount2:
|
|
|
ext4_kvfree(sbi->s_group_desc);
|
|
|
failed_mount:
|
|
|
if (sbi->s_proc) {
|
|
|
+ remove_proc_entry("options", sbi->s_proc);
|
|
|
remove_proc_entry(sb->s_id, ext4_proc_root);
|
|
|
}
|
|
|
#ifdef CONFIG_QUOTA
|
|
@@ -4090,15 +3957,6 @@ static int ext4_load_journal(struct super_block *sb,
|
|
|
if (!(journal->j_flags & JBD2_BARRIER))
|
|
|
ext4_msg(sb, KERN_INFO, "barriers disabled");
|
|
|
|
|
|
- if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
|
|
|
- err = jbd2_journal_update_format(journal);
|
|
|
- if (err) {
|
|
|
- ext4_msg(sb, KERN_ERR, "error updating journal");
|
|
|
- jbd2_journal_destroy(journal);
|
|
|
- return err;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
|
|
|
err = jbd2_journal_wipe(journal, !really_read_only);
|
|
|
if (!err) {
|
|
@@ -4385,7 +4243,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|
|
{
|
|
|
struct ext4_super_block *es;
|
|
|
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
|
|
- ext4_fsblk_t n_blocks_count = 0;
|
|
|
unsigned long old_sb_flags;
|
|
|
struct ext4_mount_options old_opts;
|
|
|
int enable_quota = 0;
|
|
@@ -4418,8 +4275,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|
|
/*
|
|
|
* Allow the "check" option to be passed as a remount option.
|
|
|
*/
|
|
|
- if (!parse_options(data, sb, NULL, &journal_ioprio,
|
|
|
- &n_blocks_count, 1)) {
|
|
|
+ if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) {
|
|
|
err = -EINVAL;
|
|
|
goto restore_opts;
|
|
|
}
|
|
@@ -4437,8 +4293,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|
|
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
|
|
|
}
|
|
|
|
|
|
- if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
|
|
|
- n_blocks_count > ext4_blocks_count(es)) {
|
|
|
+ if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
|
|
|
if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) {
|
|
|
err = -EROFS;
|
|
|
goto restore_opts;
|
|
@@ -4513,8 +4368,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
|
|
if (sbi->s_journal)
|
|
|
ext4_clear_journal_err(sb, es);
|
|
|
sbi->s_mount_state = le16_to_cpu(es->s_state);
|
|
|
- if ((err = ext4_group_extend(sb, es, n_blocks_count)))
|
|
|
- goto restore_opts;
|
|
|
if (!ext4_setup_super(sb, es, 0))
|
|
|
sb->s_flags &= ~MS_RDONLY;
|
|
|
if (EXT4_HAS_INCOMPAT_FEATURE(sb,
|