summaryrefslogtreecommitdiff
path: root/fs/udf/inode.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2023-01-24 13:59:32 +0300
committerJan Kara <jack@suse.cz>2023-01-26 18:46:35 +0300
commitd5abfb1b7b26086db19ee430dea7282f01d4ef44 (patch)
tree72efb488b61b015e89e43ea65cfbd7ffcc437aa3 /fs/udf/inode.c
parent79d3c6dbada4a20193467f72c531ab99c173bf4f (diff)
downloadlinux-d5abfb1b7b26086db19ee430dea7282f01d4ef44.tar.xz
udf: Convert in-ICB files to use udf_direct_IO()
Switching address_space_operations while a file is used is difficult to do in a race-free way. To be able to use single address_space_operations in UDF, make in-ICB files use udf_direct_IO(). Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r--fs/udf/inode.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index f0ab4dd0d8ce..d01b97e9e4f4 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -243,7 +243,7 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
return ret;
}
-static ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
+ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
@@ -251,6 +251,9 @@ static ssize_t udf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
size_t count = iov_iter_count(iter);
ssize_t ret;
+ /* Fallback to buffered IO for in-ICB files */
+ if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
+ return 0;
ret = blockdev_direct_IO(iocb, inode, iter, udf_get_block);
if (unlikely(ret < 0 && iov_iter_rw(iter) == WRITE))
udf_write_failed(mapping, iocb->ki_pos + count);