Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt

Pull fscrypt updates from Eric Biggers:
"Add support for direct I/O on encrypted files when blk-crypto (inline
encryption) is being used for file contents encryption"

* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
fscrypt: update documentation for direct I/O support
f2fs: support direct I/O with fscrypt using blk-crypto
ext4: support direct I/O with fscrypt using blk-crypto
iomap: support direct I/O with fscrypt using blk-crypto
fscrypt: add functions for direct I/O support

+173 -7
+23 -2
Documentation/filesystems/fscrypt.rst
··· 1047 1047 may be used to overwrite the source files but isn't guaranteed to be 1048 1048 effective on all filesystems and storage devices. 1049 1049 1050 - - Direct I/O is not supported on encrypted files. Attempts to use 1051 - direct I/O on such files will fall back to buffered I/O. 1050 + - Direct I/O is supported on encrypted files only under some 1051 + circumstances. For details, see `Direct I/O support`_. 1052 1052 1053 1053 - The fallocate operations FALLOC_FL_COLLAPSE_RANGE and 1054 1054 FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will ··· 1178 1178 Inline encryption doesn't affect the ciphertext or other aspects of 1179 1179 the on-disk format, so users may freely switch back and forth between 1180 1180 using "inlinecrypt" and not using "inlinecrypt". 1181 + 1182 + Direct I/O support 1183 + ================== 1184 + 1185 + For direct I/O on an encrypted file to work, the following conditions 1186 + must be met (in addition to the conditions for direct I/O on an 1187 + unencrypted file): 1188 + 1189 + * The file must be using inline encryption. Usually this means that 1190 + the filesystem must be mounted with ``-o inlinecrypt`` and inline 1191 + encryption hardware must be present. However, a software fallback 1192 + is also available. For details, see `Inline encryption support`_. 1193 + 1194 + * The I/O request must be fully aligned to the filesystem block size. 1195 + This means that the file position the I/O is targeting, the lengths 1196 + of all I/O segments, and the memory addresses of all I/O buffers 1197 + must be multiples of this value. Note that the filesystem block 1198 + size may be greater than the logical block size of the block device. 1199 + 1200 + If either of the above conditions is not met, then direct I/O on the 1201 + encrypted file will fall back to buffered I/O. 1181 1202 1182 1203 Implementation details 1183 1204 ======================
+8
fs/crypto/crypto.c
··· 69 69 } 70 70 EXPORT_SYMBOL(fscrypt_free_bounce_page); 71 71 72 + /* 73 + * Generate the IV for the given logical block number within the given file. 74 + * For filenames encryption, lblk_num == 0. 75 + * 76 + * Keep this in sync with fscrypt_limit_io_blocks(). fscrypt_limit_io_blocks() 77 + * needs to know about any IV generation methods where the low bits of IV don't 78 + * simply contain the lblk_num (e.g., IV_INO_LBLK_32). 79 + */ 72 80 void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, 73 81 const struct fscrypt_info *ci) 74 82 {
+93
fs/crypto/inline_crypt.c
··· 17 17 #include <linux/buffer_head.h> 18 18 #include <linux/sched/mm.h> 19 19 #include <linux/slab.h> 20 + #include <linux/uio.h> 20 21 21 22 #include "fscrypt_private.h" 22 23 ··· 316 315 * 317 316 * fscrypt_set_bio_crypt_ctx() must have already been called on the bio. 318 317 * 318 + * This function isn't required in cases where crypto-mergeability is ensured in 319 + * another way, such as I/O targeting only a single file (and thus a single key) 320 + * combined with fscrypt_limit_io_blocks() to ensure DUN contiguity. 321 + * 319 322 * Return: true iff the I/O is mergeable 320 323 */ 321 324 bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, ··· 368 363 return fscrypt_mergeable_bio(bio, inode, next_lblk); 369 364 } 370 365 EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio_bh); 366 + 367 + /** 368 + * fscrypt_dio_supported() - check whether a DIO (direct I/O) request is 369 + * supported as far as encryption is concerned 370 + * @iocb: the file and position the I/O is targeting 371 + * @iter: the I/O data segment(s) 372 + * 373 + * Return: %true if there are no encryption constraints that prevent DIO from 374 + * being supported; %false if DIO is unsupported. (Note that in the 375 + * %true case, the filesystem might have other, non-encryption-related 376 + * constraints that prevent DIO from actually being supported.) 377 + */ 378 + bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter) 379 + { 380 + const struct inode *inode = file_inode(iocb->ki_filp); 381 + const unsigned int blocksize = i_blocksize(inode); 382 + 383 + /* If the file is unencrypted, no veto from us. */ 384 + if (!fscrypt_needs_contents_encryption(inode)) 385 + return true; 386 + 387 + /* We only support DIO with inline crypto, not fs-layer crypto. */ 388 + if (!fscrypt_inode_uses_inline_crypto(inode)) 389 + return false; 390 + 391 + /* 392 + * Since the granularity of encryption is filesystem blocks, the file 393 + * position and total I/O length must be aligned to the filesystem block 394 + * size -- not just to the block device's logical block size as is 395 + * traditionally the case for DIO on many filesystems. 396 + * 397 + * We require that the user-provided memory buffers be filesystem block 398 + * aligned too. It is simpler to have a single alignment value required 399 + * for all properties of the I/O, as is normally the case for DIO. 400 + * Also, allowing less aligned buffers would imply that data units could 401 + * cross bvecs, which would greatly complicate the I/O stack, which 402 + * assumes that bios can be split at any bvec boundary. 403 + */ 404 + if (!IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(iter), blocksize)) 405 + return false; 406 + 407 + return true; 408 + } 409 + EXPORT_SYMBOL_GPL(fscrypt_dio_supported); 410 + 411 + /** 412 + * fscrypt_limit_io_blocks() - limit I/O blocks to avoid discontiguous DUNs 413 + * @inode: the file on which I/O is being done 414 + * @lblk: the block at which the I/O is being started from 415 + * @nr_blocks: the number of blocks we want to submit starting at @lblk 416 + * 417 + * Determine the limit to the number of blocks that can be submitted in a bio 418 + * targeting @lblk without causing a data unit number (DUN) discontiguity. 419 + * 420 + * This is normally just @nr_blocks, as normally the DUNs just increment along 421 + * with the logical blocks. (Or the file is not encrypted.) 422 + * 423 + * In rare cases, fscrypt can be using an IV generation method that allows the 424 + * DUN to wrap around within logically contiguous blocks, and that wraparound 425 + * will occur. If this happens, a value less than @nr_blocks will be returned 426 + * so that the wraparound doesn't occur in the middle of a bio, which would 427 + * cause encryption/decryption to produce wrong results. 428 + * 429 + * Return: the actual number of blocks that can be submitted 430 + */ 431 + u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks) 432 + { 433 + const struct fscrypt_info *ci; 434 + u32 dun; 435 + 436 + if (!fscrypt_inode_uses_inline_crypto(inode)) 437 + return nr_blocks; 438 + 439 + if (nr_blocks <= 1) 440 + return nr_blocks; 441 + 442 + ci = inode->i_crypt_info; 443 + if (!(fscrypt_policy_flags(&ci->ci_policy) & 444 + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) 445 + return nr_blocks; 446 + 447 + /* With IV_INO_LBLK_32, the DUN can wrap around from U32_MAX to 0. */ 448 + 449 + dun = ci->ci_hashed_ino + lblk; 450 + 451 + return min_t(u64, nr_blocks, (u64)U32_MAX + 1 - dun); 452 + } 453 + EXPORT_SYMBOL_GPL(fscrypt_limit_io_blocks);
+6 -4
fs/ext4/file.c
··· 36 36 #include "acl.h" 37 37 #include "truncate.h" 38 38 39 - static bool ext4_dio_supported(struct inode *inode) 39 + static bool ext4_dio_supported(struct kiocb *iocb, struct iov_iter *iter) 40 40 { 41 - if (IS_ENABLED(CONFIG_FS_ENCRYPTION) && IS_ENCRYPTED(inode)) 41 + struct inode *inode = file_inode(iocb->ki_filp); 42 + 43 + if (!fscrypt_dio_supported(iocb, iter)) 42 44 return false; 43 45 if (fsverity_active(inode)) 44 46 return false; ··· 63 61 inode_lock_shared(inode); 64 62 } 65 63 66 - if (!ext4_dio_supported(inode)) { 64 + if (!ext4_dio_supported(iocb, to)) { 67 65 inode_unlock_shared(inode); 68 66 /* 69 67 * Fallback to buffered I/O if the operation being performed on ··· 511 509 } 512 510 513 511 /* Fallback to buffered I/O if the inode does not support direct I/O. */ 514 - if (!ext4_dio_supported(inode)) { 512 + if (!ext4_dio_supported(iocb, from)) { 515 513 if (ilock_shared) 516 514 inode_unlock_shared(inode); 517 515 else
+7
fs/ext4/inode.c
··· 3409 3409 if (ret < 0) 3410 3410 return ret; 3411 3411 out: 3412 + /* 3413 + * When inline encryption is enabled, sometimes I/O to an encrypted file 3414 + * has to be broken up to guarantee DUN contiguity. Handle this by 3415 + * limiting the length of the mapping returned. 3416 + */ 3417 + map.m_len = fscrypt_limit_io_blocks(inode, map.m_lblk, map.m_len); 3418 + 3412 3419 ext4_set_iomap(inode, iomap, &map, offset, length, flags); 3413 3420 3414 3421 return 0;
+7
fs/f2fs/data.c
··· 4032 4032 4033 4033 iomap->offset = blks_to_bytes(inode, map.m_lblk); 4034 4034 4035 + /* 4036 + * When inline encryption is enabled, sometimes I/O to an encrypted file 4037 + * has to be broken up to guarantee DUN contiguity. Handle this by 4038 + * limiting the length of the mapping returned. 4039 + */ 4040 + map.m_len = fscrypt_limit_io_blocks(inode, map.m_lblk, map.m_len); 4041 + 4035 4042 if (map.m_flags & (F2FS_MAP_MAPPED | F2FS_MAP_UNWRITTEN)) { 4036 4043 iomap->length = blks_to_bytes(inode, map.m_len); 4037 4044 if (map.m_flags & F2FS_MAP_MAPPED) {
+5 -1
fs/f2fs/f2fs.h
··· 4371 4371 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 4372 4372 int rw = iov_iter_rw(iter); 4373 4373 4374 - if (f2fs_post_read_required(inode)) 4374 + if (!fscrypt_dio_supported(iocb, iter)) 4375 + return true; 4376 + if (fsverity_active(inode)) 4377 + return true; 4378 + if (f2fs_compressed_file(inode)) 4375 4379 return true; 4376 4380 4377 4381 /* disallow direct IO if any of devices has unaligned blksize */
+6
fs/iomap/direct-io.c
··· 6 6 #include <linux/module.h> 7 7 #include <linux/compiler.h> 8 8 #include <linux/fs.h> 9 + #include <linux/fscrypt.h> 9 10 #include <linux/pagemap.h> 10 11 #include <linux/iomap.h> 11 12 #include <linux/backing-dev.h> ··· 180 179 static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio, 181 180 loff_t pos, unsigned len) 182 181 { 182 + struct inode *inode = file_inode(dio->iocb->ki_filp); 183 183 struct page *page = ZERO_PAGE(0); 184 184 int flags = REQ_SYNC | REQ_IDLE; 185 185 struct bio *bio; 186 186 187 187 bio = bio_alloc(iter->iomap.bdev, 1, REQ_OP_WRITE | flags, GFP_KERNEL); 188 + fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits, 189 + GFP_KERNEL); 188 190 bio->bi_iter.bi_sector = iomap_sector(&iter->iomap, pos); 189 191 bio->bi_private = dio; 190 192 bio->bi_end_io = iomap_dio_bio_end_io; ··· 312 308 } 313 309 314 310 bio = bio_alloc(iomap->bdev, nr_pages, bio_opf, GFP_KERNEL); 311 + fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits, 312 + GFP_KERNEL); 315 313 bio->bi_iter.bi_sector = iomap_sector(iomap, pos); 316 314 bio->bi_write_hint = dio->iocb->ki_hint; 317 315 bio->bi_ioprio = dio->iocb->ki_ioprio;
+18
include/linux/fscrypt.h
··· 714 714 bool fscrypt_mergeable_bio_bh(struct bio *bio, 715 715 const struct buffer_head *next_bh); 716 716 717 + bool fscrypt_dio_supported(struct kiocb *iocb, struct iov_iter *iter); 718 + 719 + u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks); 720 + 717 721 #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ 718 722 719 723 static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode) ··· 745 741 const struct buffer_head *next_bh) 746 742 { 747 743 return true; 744 + } 745 + 746 + static inline bool fscrypt_dio_supported(struct kiocb *iocb, 747 + struct iov_iter *iter) 748 + { 749 + const struct inode *inode = file_inode(iocb->ki_filp); 750 + 751 + return !fscrypt_needs_contents_encryption(inode); 752 + } 753 + 754 + static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, 755 + u64 nr_blocks) 756 + { 757 + return nr_blocks; 748 758 } 749 759 #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ 750 760