]> git.ipfire.org Git - thirdparty/kernel/stable.git/blobdiff - fs/ext4/inode.c
Merge tag 'ext4-for-linus-5.8-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel...
[thirdparty/kernel/stable.git] / fs / ext4 / inode.c
index 40ec5c7ef0d35d247b451ba387570c5459944eb0..10dd470876b30256374996319304b5c0938c7a73 100644 (file)
@@ -4403,9 +4403,11 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
                !ext4_test_inode_state(inode, EXT4_STATE_XATTR));
 }
 
-static bool ext4_should_use_dax(struct inode *inode)
+static bool ext4_should_enable_dax(struct inode *inode)
 {
-       if (!test_opt(inode->i_sb, DAX))
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+
+       if (test_opt2(inode->i_sb, DAX_NEVER))
                return false;
        if (!S_ISREG(inode->i_mode))
                return false;
@@ -4417,14 +4419,21 @@ static bool ext4_should_use_dax(struct inode *inode)
                return false;
        if (ext4_test_inode_flag(inode, EXT4_INODE_VERITY))
                return false;
-       return true;
+       if (!test_bit(EXT4_FLAGS_BDEV_IS_DAX, &sbi->s_ext4_flags))
+               return false;
+       if (test_opt(inode->i_sb, DAX_ALWAYS))
+               return true;
+
+       return ext4_test_inode_flag(inode, EXT4_INODE_DAX);
 }
 
-void ext4_set_inode_flags(struct inode *inode)
+void ext4_set_inode_flags(struct inode *inode, bool init)
 {
        unsigned int flags = EXT4_I(inode)->i_flags;
        unsigned int new_fl = 0;
 
+       WARN_ON_ONCE(IS_DAX(inode) && init);
+
        if (flags & EXT4_SYNC_FL)
                new_fl |= S_SYNC;
        if (flags & EXT4_APPEND_FL)
@@ -4435,8 +4444,13 @@ void ext4_set_inode_flags(struct inode *inode)
                new_fl |= S_NOATIME;
        if (flags & EXT4_DIRSYNC_FL)
                new_fl |= S_DIRSYNC;
-       if (ext4_should_use_dax(inode))
+
+       /* Because of the way inode_set_flags() works we must preserve S_DAX
+        * here if already set. */
+       new_fl |= (inode->i_flags & S_DAX);
+       if (init && ext4_should_enable_dax(inode))
                new_fl |= S_DAX;
+
        if (flags & EXT4_ENCRYPT_FL)
                new_fl |= S_ENCRYPTED;
        if (flags & EXT4_CASEFOLD_FL)
@@ -4650,7 +4664,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
                 * not initialized on a new filesystem. */
        }
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
-       ext4_set_inode_flags(inode);
+       ext4_set_inode_flags(inode, true);
        inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
        ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
        if (ext4_has_feature_64bit(sb))