ext4: Regularize mount options

Add support for using the mount options "barrier" and "nobarrier", and
"auto_da_alloc" and "noauto_da_alloc", which is more consistent than
"barrier=<0|1>" or "auto_da_alloc=<0|1>".  Most other ext3/ext4 mount
options use the foo/nofoo naming convention.  We allow the old forms
of these mount options for backwards compatibility.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
Theodore Ts'o 2009-03-28 10:59:57 -04:00
parent e7c9e3e99a
commit 06705bff91
2 changed files with 45 additions and 10 deletions

View file

@ -183,8 +183,8 @@ commit=nrsec (*) Ext4 can be told to sync all its data and metadata
performance. performance.
barrier=<0|1(*)> This enables/disables the use of write barriers in barrier=<0|1(*)> This enables/disables the use of write barriers in
the jbd code. barrier=0 disables, barrier=1 enables. barrier(*) the jbd code. barrier=0 disables, barrier=1 enables.
This also requires an IO stack which can support nobarrier This also requires an IO stack which can support
barriers, and if jbd gets an error on a barrier barriers, and if jbd gets an error on a barrier
write, it will disable again with a warning. write, it will disable again with a warning.
Write barriers enforce proper on-disk ordering Write barriers enforce proper on-disk ordering
@ -192,6 +192,9 @@ barrier=<0|1(*)> This enables/disables the use of write barriers in
safe to use, at some performance penalty. If safe to use, at some performance penalty. If
your disks are battery-backed in one way or another, your disks are battery-backed in one way or another,
disabling barriers may safely improve performance. disabling barriers may safely improve performance.
The mount options "barrier" and "nobarrier" can
also be used to enable or disable barriers, for
consistency with other ext4 mount options.
inode_readahead=n This tuning parameter controls the maximum inode_readahead=n This tuning parameter controls the maximum
number of inode table blocks that ext4's inode number of inode table blocks that ext4's inode
@ -313,6 +316,24 @@ journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the
a slightly higher priority than the default I/O a slightly higher priority than the default I/O
priority. priority.
auto_da_alloc(*) Many broken applications don't use fsync() when
noauto_da_alloc replacing existing files via patterns such as
fd = open("foo.new")/write(fd,..)/close(fd)/
rename("foo.new", "foo"), or worse yet,
fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
If auto_da_alloc is enabled, ext4 will detect
the replace-via-rename and replace-via-truncate
patterns and force that any delayed allocation
blocks are allocated such that at the next
journal commit, in the default data=ordered
mode, the data blocks of the new file are forced
to disk before the rename() operation is
commited. This provides roughly the same level
of guarantees as ext3, and avoids the
"zero-length" problem that can happen when a
system crashes before the delayed allocation
blocks are forced to disk.
Data Mode Data Mode
========= =========
There are 3 different data modes: There are 3 different data modes:

View file

@ -867,7 +867,7 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
seq_puts(seq, ",data_err=abort"); seq_puts(seq, ",data_err=abort");
if (test_opt(sb, NO_AUTO_DA_ALLOC)) if (test_opt(sb, NO_AUTO_DA_ALLOC))
seq_puts(seq, ",auto_da_alloc=0"); seq_puts(seq, ",noauto_da_alloc");
ext4_show_quota_options(seq, sb); ext4_show_quota_options(seq, sb);
return 0; return 0;
@ -1018,7 +1018,7 @@ enum {
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, 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_oldalloc, Opt_orlov,
Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
Opt_auto_da_alloc, Opt_noload, Opt_nobh, Opt_bh, Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload, Opt_nobh, Opt_bh,
Opt_commit, Opt_min_batch_time, Opt_max_batch_time, Opt_commit, Opt_min_batch_time, Opt_max_batch_time,
Opt_journal_update, Opt_journal_dev, Opt_journal_update, Opt_journal_dev,
Opt_journal_checksum, Opt_journal_async_commit, Opt_journal_checksum, Opt_journal_async_commit,
@ -1026,8 +1026,8 @@ enum {
Opt_data_err_abort, Opt_data_err_ignore, Opt_data_err_abort, Opt_data_err_ignore,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
Opt_grpquota, Opt_i_version, Opt_usrquota, Opt_grpquota, Opt_i_version,
Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_stripe, Opt_delalloc, Opt_nodelalloc,
Opt_inode_readahead_blks, Opt_journal_ioprio Opt_inode_readahead_blks, Opt_journal_ioprio
}; };
@ -1080,6 +1080,8 @@ static const match_table_t tokens = {
{Opt_quota, "quota"}, {Opt_quota, "quota"},
{Opt_usrquota, "usrquota"}, {Opt_usrquota, "usrquota"},
{Opt_barrier, "barrier=%u"}, {Opt_barrier, "barrier=%u"},
{Opt_barrier, "barrier"},
{Opt_nobarrier, "nobarrier"},
{Opt_i_version, "i_version"}, {Opt_i_version, "i_version"},
{Opt_stripe, "stripe=%u"}, {Opt_stripe, "stripe=%u"},
{Opt_resize, "resize"}, {Opt_resize, "resize"},
@ -1088,6 +1090,8 @@ static const match_table_t tokens = {
{Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
{Opt_journal_ioprio, "journal_ioprio=%u"}, {Opt_journal_ioprio, "journal_ioprio=%u"},
{Opt_auto_da_alloc, "auto_da_alloc=%u"}, {Opt_auto_da_alloc, "auto_da_alloc=%u"},
{Opt_auto_da_alloc, "auto_da_alloc"},
{Opt_noauto_da_alloc, "noauto_da_alloc"},
{Opt_err, NULL}, {Opt_err, NULL},
}; };
@ -1422,9 +1426,14 @@ static int parse_options(char *options, struct super_block *sb,
case Opt_abort: case Opt_abort:
set_opt(sbi->s_mount_opt, ABORT); set_opt(sbi->s_mount_opt, ABORT);
break; break;
case Opt_nobarrier:
clear_opt(sbi->s_mount_opt, BARRIER);
break;
case Opt_barrier: case Opt_barrier:
if (match_int(&args[0], &option)) if (match_int(&args[0], &option)) {
return 0; set_opt(sbi->s_mount_opt, BARRIER);
break;
}
if (option) if (option)
set_opt(sbi->s_mount_opt, BARRIER); set_opt(sbi->s_mount_opt, BARRIER);
else else
@ -1485,9 +1494,14 @@ static int parse_options(char *options, struct super_block *sb,
*journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE,
option); option);
break; break;
case Opt_noauto_da_alloc:
set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
break;
case Opt_auto_da_alloc: case Opt_auto_da_alloc:
if (match_int(&args[0], &option)) if (match_int(&args[0], &option)) {
return 0; clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);
break;
}
if (option) if (option)
clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);
else else