data=journal mount option should disable O_DIRECT access (See Documentation/filesystems/ext4.txt) but open operations using O_CREAT|O_RDWR|O_DIRECT|O_SYNC have no warning in return and file is being created. This patch adds vfs super_operations compatibility flag function returning -EPERM in such a case. Signed-off-by: Fabian Frederick <fabf@xxxxxxxxx> --- fs/ext4/super.c | 10 ++++++++++ fs/namei.c | 12 ++++++++++++ include/linux/fs.h | 1 + 3 files changed, 23 insertions(+) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 72b459d..f2cd8e3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1195,6 +1195,15 @@ static struct fscrypt_operations ext4_cryptops = { }; #endif +static int ext4_compat_flag_check(struct inode *inode, int openflag) +{ + if (openflag & O_DIRECT && + test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) + return -EPERM; + + return 0; +} + #ifdef CONFIG_QUOTA static char *quotatypes[] = INITQFNAMES; #define QTYPE2NAME(t) (quotatypes[t]) @@ -1267,6 +1276,7 @@ static const struct super_operations ext4_sops = { .get_dquots = ext4_get_dquots, #endif .bdev_try_to_free_page = bdev_try_to_free_page, + .compat_flag_check = ext4_compat_flag_check, }; static const struct export_operations ext4_export_ops = { diff --git a/fs/namei.c b/fs/namei.c index 1669c93d..7edbfbb 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3493,6 +3493,18 @@ static struct file *path_openat(struct nameidata *nd, put_filp(file); return ERR_CAST(s); } + + if (unlikely(file->f_flags & O_DIRECT)) { + struct super_block *sb = nd->inode->i_sb; + + if (unlikely(sb->s_op->compat_flag_check)) { + error = sb->s_op->compat_flag_check(nd->inode, + op->open_flag); + if (error) + goto out2; + } + } + while (!(error = link_path_walk(s, nd)) && (error = do_last(nd, file, op, &opened)) > 0) { nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); diff --git a/include/linux/fs.h b/include/linux/fs.h index 03a5a39..bba6c0b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1776,6 +1776,7 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + int (*compat_flag_check)(struct inode *, int); }; /* -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html