Merge tag 's390-6.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-block.git] / fs / f2fs / file.c
index ce4905a073b3c413a751efc0dec5069a1a5e32c7..79177050732803eadd5e3d3bb68577b67e743ccc 100644 (file)
@@ -808,6 +808,29 @@ int f2fs_truncate(struct inode *inode)
        return 0;
 }
 
+static bool f2fs_force_buffered_io(struct inode *inode, int rw)
+{
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+
+       if (!fscrypt_dio_supported(inode))
+               return true;
+       if (fsverity_active(inode))
+               return true;
+       if (f2fs_compressed_file(inode))
+               return true;
+
+       /* disallow direct IO if any of devices has unaligned blksize */
+       if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
+               return true;
+
+       if (f2fs_lfs_mode(sbi) && rw == WRITE && F2FS_IO_ALIGNED(sbi))
+               return true;
+       if (is_sbi_flag_set(sbi, SBI_CP_DISABLED))
+               return true;
+
+       return false;
+}
+
 int f2fs_getattr(struct user_namespace *mnt_userns, const struct path *path,
                 struct kstat *stat, u32 request_mask, unsigned int query_flags)
 {
@@ -824,6 +847,24 @@ int f2fs_getattr(struct user_namespace *mnt_userns, const struct path *path,
                stat->btime.tv_nsec = fi->i_crtime.tv_nsec;
        }
 
+       /*
+        * Return the DIO alignment restrictions if requested.  We only return
+        * this information when requested, since on encrypted files it might
+        * take a fair bit of work to get if the file wasn't opened recently.
+        *
+        * f2fs sometimes supports DIO reads but not DIO writes.  STATX_DIOALIGN
+        * cannot represent that, so in that case we report no DIO support.
+        */
+       if ((request_mask & STATX_DIOALIGN) && S_ISREG(inode->i_mode)) {
+               unsigned int bsize = i_blocksize(inode);
+
+               stat->result_mask |= STATX_DIOALIGN;
+               if (!f2fs_force_buffered_io(inode, WRITE)) {
+                       stat->dio_mem_align = bsize;
+                       stat->dio_offset_align = bsize;
+               }
+       }
+
        flags = fi->i_flags;
        if (flags & F2FS_COMPR_FL)
                stat->attributes |= STATX_ATTR_COMPRESSED;
@@ -4182,7 +4223,7 @@ static bool f2fs_should_use_dio(struct inode *inode, struct kiocb *iocb,
        if (!(iocb->ki_flags & IOCB_DIRECT))
                return false;
 
-       if (f2fs_force_buffered_io(inode, iocb, iter))
+       if (f2fs_force_buffered_io(inode, iov_iter_rw(iter)))
                return false;
 
        /*