Skip to content

Commit 4a165fe

Browse files
committed
Merge tag 'dio_for_v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull direct-io fix from Jan Kara: "Fix for unaligned direct IO read past EOF in legacy DIO code" * tag 'dio_for_v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: direct-io: defer alignment check until after the EOF check direct-io: don't force writeback for reads beyond EOF direct-io: clean up error paths of do_blockdev_direct_IO
2 parents b77a69b + 41b21af commit 4a165fe

File tree

1 file changed

+30
-39
lines changed

1 file changed

+30
-39
lines changed

fs/direct-io.c

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,22 +1146,13 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
11461146
* the early prefetch in the caller enough time.
11471147
*/
11481148

1149-
if (align & blocksize_mask) {
1150-
if (bdev)
1151-
blkbits = blksize_bits(bdev_logical_block_size(bdev));
1152-
blocksize_mask = (1 << blkbits) - 1;
1153-
if (align & blocksize_mask)
1154-
goto out;
1155-
}
1156-
11571149
/* watch out for a 0 len io from a tricksy fs */
11581150
if (iov_iter_rw(iter) == READ && !count)
11591151
return 0;
11601152

11611153
dio = kmem_cache_alloc(dio_cache, GFP_KERNEL);
1162-
retval = -ENOMEM;
11631154
if (!dio)
1164-
goto out;
1155+
return -ENOMEM;
11651156
/*
11661157
* Believe it or not, zeroing out the page array caused a .5%
11671158
* performance regression in a database benchmark. So, we take
@@ -1170,32 +1161,32 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
11701161
memset(dio, 0, offsetof(struct dio, pages));
11711162

11721163
dio->flags = flags;
1173-
if (dio->flags & DIO_LOCKING) {
1174-
if (iov_iter_rw(iter) == READ) {
1175-
struct address_space *mapping =
1176-
iocb->ki_filp->f_mapping;
1177-
1178-
/* will be released by direct_io_worker */
1179-
inode_lock(inode);
1180-
1181-
retval = filemap_write_and_wait_range(mapping, offset,
1182-
end - 1);
1183-
if (retval) {
1184-
inode_unlock(inode);
1185-
kmem_cache_free(dio_cache, dio);
1186-
goto out;
1187-
}
1188-
}
1164+
if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) {
1165+
/* will be released by direct_io_worker */
1166+
inode_lock(inode);
11891167
}
11901168

11911169
/* Once we sampled i_size check for reads beyond EOF */
11921170
dio->i_size = i_size_read(inode);
11931171
if (iov_iter_rw(iter) == READ && offset >= dio->i_size) {
1194-
if (dio->flags & DIO_LOCKING)
1195-
inode_unlock(inode);
1196-
kmem_cache_free(dio_cache, dio);
11971172
retval = 0;
1198-
goto out;
1173+
goto fail_dio;
1174+
}
1175+
1176+
if (align & blocksize_mask) {
1177+
if (bdev)
1178+
blkbits = blksize_bits(bdev_logical_block_size(bdev));
1179+
blocksize_mask = (1 << blkbits) - 1;
1180+
if (align & blocksize_mask)
1181+
goto fail_dio;
1182+
}
1183+
1184+
if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) {
1185+
struct address_space *mapping = iocb->ki_filp->f_mapping;
1186+
1187+
retval = filemap_write_and_wait_range(mapping, offset, end - 1);
1188+
if (retval)
1189+
goto fail_dio;
11991190
}
12001191

12011192
/*
@@ -1239,14 +1230,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
12391230
*/
12401231
retval = sb_init_dio_done_wq(dio->inode->i_sb);
12411232
}
1242-
if (retval) {
1243-
/*
1244-
* We grab i_mutex only for reads so we don't have
1245-
* to release it here
1246-
*/
1247-
kmem_cache_free(dio_cache, dio);
1248-
goto out;
1249-
}
1233+
if (retval)
1234+
goto fail_dio;
12501235
}
12511236

12521237
/*
@@ -1349,7 +1334,13 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
13491334
} else
13501335
BUG_ON(retval != -EIOCBQUEUED);
13511336

1352-
out:
1337+
return retval;
1338+
1339+
fail_dio:
1340+
if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ)
1341+
inode_unlock(inode);
1342+
1343+
kmem_cache_free(dio_cache, dio);
13531344
return retval;
13541345
}
13551346

0 commit comments

Comments
 (0)