Skip to content

Commit 5688978

Browse files
committed
ext4: improve handling of conflicting mount options
If the user explicitly specifies conflicting mount options for delalloc or dioread_nolock and data=journal, fail the mount, instead of printing a warning and continuing (since many user's won't look at dmesg and notice the warning). Also, print a single warning that data=journal implies that delayed allocation is not on by default (since it's not supported), and furthermore that O_DIRECT is not supported. Improve the text in Documentation/filesystems/ext4.txt so this is clear there as well. Similarly, if the dioread_nolock mount option is specified when the file system block size != PAGE_SIZE, fail the mount instead of printing a warning message and ignoring the mount option. Signed-off-by: "Theodore Ts'o" <[email protected]>
1 parent 2be4751 commit 5688978

File tree

3 files changed

+37
-24
lines changed

3 files changed

+37
-24
lines changed

Documentation/filesystems/ext4.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ noload if the filesystem was not unmounted cleanly,
160160
lead to any number of problems.
161161

162162
data=journal All data are committed into the journal prior to being
163-
written into the main file system.
163+
written into the main file system. Enabling
164+
this mode will disable delayed allocation and
165+
O_DIRECT support.
164166

165167
data=ordered (*) All data are forced directly out to the main file
166168
system prior to its metadata being committed to the
@@ -419,8 +421,8 @@ written to the journal first, and then to its final location.
419421
In the event of a crash, the journal can be replayed, bringing both data and
420422
metadata into a consistent state. This mode is the slowest except when data
421423
needs to be read from and written to disk at the same time where it
422-
outperforms all others modes. Currently ext4 does not have delayed
423-
allocation support if this data journalling mode is selected.
424+
outperforms all others modes. Enabling this mode will disable delayed
425+
allocation and O_DIRECT support.
424426

425427
/proc entries
426428
=============

fs/ext4/ext4.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,9 @@ struct ext4_inode_info {
922922
#define EXT4_MOUNT_DISCARD 0x40000000 /* Issue DISCARD requests */
923923
#define EXT4_MOUNT_INIT_INODE_TABLE 0x80000000 /* Initialize uninitialized itables */
924924

925+
#define EXT4_MOUNT2_EXPLICIT_DELALLOC 0x00000001 /* User explicitly
926+
specified delalloc */
927+
925928
#define clear_opt(sb, opt) EXT4_SB(sb)->s_mount_opt &= \
926929
~EXT4_MOUNT_##opt
927930
#define set_opt(sb, opt) EXT4_SB(sb)->s_mount_opt |= \

fs/ext4/super.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,7 @@ static int parse_options(char *options, struct super_block *sb,
18011801
break;
18021802
case Opt_nodelalloc:
18031803
clear_opt(sb, DELALLOC);
1804+
clear_opt2(sb, EXPLICIT_DELALLOC);
18041805
break;
18051806
case Opt_mblk_io_submit:
18061807
set_opt(sb, MBLK_IO_SUBMIT);
@@ -1817,6 +1818,7 @@ static int parse_options(char *options, struct super_block *sb,
18171818
break;
18181819
case Opt_delalloc:
18191820
set_opt(sb, DELALLOC);
1821+
set_opt2(sb, EXPLICIT_DELALLOC);
18201822
break;
18211823
case Opt_block_validity:
18221824
set_opt(sb, BLOCK_VALIDITY);
@@ -3224,6 +3226,33 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
32243226
&journal_ioprio, NULL, 0))
32253227
goto failed_mount;
32263228

3229+
if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
3230+
printk_once(KERN_WARNING "EXT4-fs: Warning: mounting "
3231+
"with data=journal disables delayed "
3232+
"allocation and O_DIRECT support!\n");
3233+
if (test_opt2(sb, EXPLICIT_DELALLOC)) {
3234+
ext4_msg(sb, KERN_ERR, "can't mount with "
3235+
"both data=journal and delalloc");
3236+
goto failed_mount;
3237+
}
3238+
if (test_opt(sb, DIOREAD_NOLOCK)) {
3239+
ext4_msg(sb, KERN_ERR, "can't mount with "
3240+
"both data=journal and delalloc");
3241+
goto failed_mount;
3242+
}
3243+
if (test_opt(sb, DELALLOC))
3244+
clear_opt(sb, DELALLOC);
3245+
}
3246+
3247+
blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
3248+
if (test_opt(sb, DIOREAD_NOLOCK)) {
3249+
if (blocksize < PAGE_SIZE) {
3250+
ext4_msg(sb, KERN_ERR, "can't mount with "
3251+
"dioread_nolock if block size != PAGE_SIZE");
3252+
goto failed_mount;
3253+
}
3254+
}
3255+
32273256
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
32283257
(test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
32293258

@@ -3265,8 +3294,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
32653294
if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY)))
32663295
goto failed_mount;
32673296

3268-
blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
3269-
32703297
if (blocksize < EXT4_MIN_BLOCK_SIZE ||
32713298
blocksize > EXT4_MAX_BLOCK_SIZE) {
32723299
ext4_msg(sb, KERN_ERR,
@@ -3679,25 +3706,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
36793706
"available");
36803707
}
36813708

3682-
if (test_opt(sb, DELALLOC) &&
3683-
(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) {
3684-
ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - "
3685-
"requested data journaling mode");
3686-
clear_opt(sb, DELALLOC);
3687-
}
3688-
if (test_opt(sb, DIOREAD_NOLOCK)) {
3689-
if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
3690-
ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock "
3691-
"option - requested data journaling mode");
3692-
clear_opt(sb, DIOREAD_NOLOCK);
3693-
}
3694-
if (sb->s_blocksize < PAGE_SIZE) {
3695-
ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock "
3696-
"option - block size is too small");
3697-
clear_opt(sb, DIOREAD_NOLOCK);
3698-
}
3699-
}
3700-
37013709
err = ext4_setup_system_zone(sb);
37023710
if (err) {
37033711
ext4_msg(sb, KERN_ERR, "failed to initialize system "

0 commit comments

Comments
 (0)