From 6c6578c9659b6cd4e9d5cd893f84007b81b5ac14 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 17 Dec 2016 19:54:21 -0500 Subject: [PATCH] rebase to 5084fdf08173 --- DAX-iomap-write-support | 228 ----------- ..._DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask | 47 --- add-sanity-checking-in-count_overhead | 36 -- add-select-for-CONFIG_FS_IOMAP | 28 -- allow-ext4_ext_truncate-to-return-an-error | 85 ---- allow-ext4_truncate-to-return-an-error | 190 --------- allow-inode-expansion-for-nojournal-file-systems | 50 --- ...kdep-warning-when-inheriting-encryption-context | 140 ------- avoid-split-extents-for-DAX-writes | 60 --- ...ct-when-verifying-flags-set-via-SETFLAGS-ioctls | 103 ----- convert-DAX-faults-to-iomap-infrastructure | 80 ---- convert-dax-reads-to-iomap-infrastructure | 161 -------- ...-detect-when-an-xattr-value-has-an-invalid-size | 80 ---- dax-rip-out-get_block-based-IO-support | 437 --------------------- ...pwsalt-ioctl-when-encryption-disabled-by-config | 65 --- do-not-perform-data-journaling-when-encrypting | 95 ----- ...r-head-in-ext4_commit_super-if-holding-spinlock | 63 --- ...out-of-bounds-when-checking-for-in-inode-xattrs | 55 --- ...ro_range-for-zeroing-truncated-page-in-DAX-path | 48 --- factor-out-checks-from-ext4_file_write_iter | 141 ------- fix-block_validity-documentation | 42 -- ...r-data-ordered-and-journal_async_commit-options | 70 ---- ...ecksum-calculation-if-i_extra_size-is-too-small | 41 -- fix-mballoc-breakage-with-64k-block-size | 35 -- fix-mmp-use-after-free-during-umount | 47 --- ...w-encrypted-symlinks-on-no-journal-file-systems | 34 -- fix-sb-mount-options-processing | 99 ----- fix-sleep-in-atomic-context-in-grab_mapping_entry | 55 --- fix-stack-corruption-with-64k-blocksize | 39 -- forbid-i_extra_isize-not-divisible-by-4 | 65 --- fscrypt-move-constants-to-uapi-header | 62 --- ...ve-ioctl-processing-more-fully-into-common-code | 260 ------------ ...pt-move-non-public-structures-to-private-header | 214 ---------- ...pt-recommend-linux-fsdevel-for-fscrypto-patches | 33 -- fscrypt-remove-unneeded-Kconfig-dependencies | 35 -- fscrypt-unexport-fscrypt_initialize | 51 --- get-rid-of-ext4_sb_has_crypto | 48 --- let-S_DAX-set-only-if-DAX-is-really-supported | 102 ----- mbache-dont-bug-if-entry-cache-cannot-be-allocated | 37 -- mbcache-correctly-handled-e_referenced-bit | 45 --- ...hat-find-functions-only-return-reusable-entries | 62 --- mbcache-remove-unnecessary-module_get_put | 57 --- mbcache-use-consistent-type-for-entry-count | 85 ---- reject-inodes-with-negative-size | 41 -- remove-another-test-in-ext4_alloc_file_blocks | 26 -- remove-parameter-from-ext4_xattr_ibody_set | 66 ---- remove-unused-function-ext4_aligned_io | 36 -- rename-get_crypt_info | 106 ----- return-enomem-instead-of-success | 28 -- rip-out-DAX-handling-from-direct-IO-path | 182 --------- sanity-check-block-and-cluster-size | 64 --- series | 183 +++------ timestamps | 60 +-- use-current_time-for-inode-timestamps | 342 ---------------- use-iomap-for-zeroing-blocks-in-DAX-mode | 36 -- validate-s_first_meta_bg-at-mount-time | 85 ---- verify-inodes_per_group-during-mount | 49 --- warn-when-page-is-dirtied-without-buffers | 57 --- 58 files changed, 61 insertions(+), 5110 deletions(-) delete mode 100644 DAX-iomap-write-support delete mode 100644 add-EXT4_JOURNAL_DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask delete mode 100644 add-sanity-checking-in-count_overhead delete mode 100644 add-select-for-CONFIG_FS_IOMAP delete mode 100644 allow-ext4_ext_truncate-to-return-an-error delete mode 100644 allow-ext4_truncate-to-return-an-error delete mode 100644 allow-inode-expansion-for-nojournal-file-systems delete mode 100644 avoid-lockdep-warning-when-inheriting-encryption-context delete mode 100644 avoid-split-extents-for-DAX-writes delete mode 100644 be-more-strict-when-verifying-flags-set-via-SETFLAGS-ioctls delete mode 100644 convert-DAX-faults-to-iomap-infrastructure delete mode 100644 convert-dax-reads-to-iomap-infrastructure delete mode 100644 correct-detect-when-an-xattr-value-has-an-invalid-size delete mode 100644 dax-rip-out-get_block-based-IO-support delete mode 100644 disable-pwsalt-ioctl-when-encryption-disabled-by-config delete mode 100644 do-not-perform-data-journaling-when-encrypting delete mode 100644 dont-lock-buffer-head-in-ext4_commit_super-if-holding-spinlock delete mode 100644 dont-read-out-of-bounds-when-checking-for-in-inode-xattrs delete mode 100644 ext2-use-iomap_zero_range-for-zeroing-truncated-page-in-DAX-path delete mode 100644 factor-out-checks-from-ext4_file_write_iter delete mode 100644 fix-block_validity-documentation delete mode 100644 fix-checks-for-data-ordered-and-journal_async_commit-options delete mode 100644 fix-inode-checksum-calculation-if-i_extra_size-is-too-small delete mode 100644 fix-mballoc-breakage-with-64k-block-size delete mode 100644 fix-mmp-use-after-free-during-umount delete mode 100644 fix-reading-new-encrypted-symlinks-on-no-journal-file-systems delete mode 100644 fix-sb-mount-options-processing delete mode 100644 fix-sleep-in-atomic-context-in-grab_mapping_entry delete mode 100644 fix-stack-corruption-with-64k-blocksize delete mode 100644 forbid-i_extra_isize-not-divisible-by-4 delete mode 100644 fscrypt-move-constants-to-uapi-header delete mode 100644 fscrypt-move-ioctl-processing-more-fully-into-common-code delete mode 100644 fscrypt-move-non-public-structures-to-private-header delete mode 100644 fscrypt-recommend-linux-fsdevel-for-fscrypto-patches delete mode 100644 fscrypt-remove-unneeded-Kconfig-dependencies delete mode 100644 fscrypt-unexport-fscrypt_initialize delete mode 100644 get-rid-of-ext4_sb_has_crypto delete mode 100644 let-S_DAX-set-only-if-DAX-is-really-supported delete mode 100644 mbache-dont-bug-if-entry-cache-cannot-be-allocated delete mode 100644 mbcache-correctly-handled-e_referenced-bit delete mode 100644 mbcache-document-that-find-functions-only-return-reusable-entries delete mode 100644 mbcache-remove-unnecessary-module_get_put delete mode 100644 mbcache-use-consistent-type-for-entry-count delete mode 100644 reject-inodes-with-negative-size delete mode 100644 remove-another-test-in-ext4_alloc_file_blocks delete mode 100644 remove-parameter-from-ext4_xattr_ibody_set delete mode 100644 remove-unused-function-ext4_aligned_io delete mode 100644 rename-get_crypt_info delete mode 100644 return-enomem-instead-of-success delete mode 100644 rip-out-DAX-handling-from-direct-IO-path delete mode 100644 sanity-check-block-and-cluster-size rewrite series (65%) delete mode 100644 use-current_time-for-inode-timestamps delete mode 100644 use-iomap-for-zeroing-blocks-in-DAX-mode delete mode 100644 validate-s_first_meta_bg-at-mount-time delete mode 100644 verify-inodes_per_group-during-mount delete mode 100644 warn-when-page-is-dirtied-without-buffers diff --git a/DAX-iomap-write-support b/DAX-iomap-write-support deleted file mode 100644 index cdb2404b..00000000 --- a/DAX-iomap-write-support +++ /dev/null @@ -1,228 +0,0 @@ -ext4: DAX iomap write support - -From: Jan Kara - -Implement DAX writes using the new iomap infrastructure instead of -overloading the direct IO path. - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/file.c | 40 ++++++++++++++++++ - fs/ext4/inode.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 160 insertions(+), 6 deletions(-) - -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index 1f25c644cb12..1953fe34f9fe 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -169,6 +169,41 @@ static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from) - return iov_iter_count(from); - } - -+#ifdef CONFIG_FS_DAX -+static ssize_t -+ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from) -+{ -+ struct inode *inode = file_inode(iocb->ki_filp); -+ ssize_t ret; -+ bool overwrite = false; -+ -+ inode_lock(inode); -+ ret = ext4_write_checks(iocb, from); -+ if (ret <= 0) -+ goto out; -+ ret = file_remove_privs(iocb->ki_filp); -+ if (ret) -+ goto out; -+ ret = file_update_time(iocb->ki_filp); -+ if (ret) -+ goto out; -+ -+ if (ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) { -+ overwrite = true; -+ downgrade_write(&inode->i_rwsem); -+ } -+ ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops); -+out: -+ if (!overwrite) -+ inode_unlock(inode); -+ else -+ inode_unlock_shared(inode); -+ if (ret > 0) -+ ret = generic_write_sync(iocb, ret); -+ return ret; -+} -+#endif -+ - static ssize_t - ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) - { -@@ -178,6 +213,11 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) - int overwrite = 0; - ssize_t ret; - -+#ifdef CONFIG_FS_DAX -+ if (IS_DAX(inode)) -+ return ext4_dax_write_iter(iocb, from); -+#endif -+ - inode_lock(inode); - ret = ext4_write_checks(iocb, from); - if (ret <= 0) -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index df017ce3e52d..a7079cab645a 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3321,18 +3321,79 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - struct ext4_map_blocks map; - int ret; - -- if (flags & IOMAP_WRITE) -- return -EIO; -- - if (WARN_ON_ONCE(ext4_has_inline_data(inode))) - return -ERANGE; - - map.m_lblk = first_block; - map.m_len = last_block - first_block + 1; - -- ret = ext4_map_blocks(NULL, inode, &map, 0); -- if (ret < 0) -- return ret; -+ if (!(flags & IOMAP_WRITE)) { -+ ret = ext4_map_blocks(NULL, inode, &map, 0); -+ } else { -+ int dio_credits; -+ handle_t *handle; -+ int retries = 0; -+ -+ /* Trim mapping request to maximum we can map at once for DIO */ -+ if (map.m_len > DIO_MAX_BLOCKS) -+ map.m_len = DIO_MAX_BLOCKS; -+ dio_credits = ext4_chunk_trans_blocks(inode, map.m_len); -+retry: -+ /* -+ * Either we allocate blocks and then we don't get unwritten -+ * extent so we have reserved enough credits, or the blocks -+ * are already allocated and unwritten and in that case -+ * extent conversion fits in the credits as well. -+ */ -+ handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, -+ dio_credits); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ ret = ext4_map_blocks(handle, inode, &map, -+ EXT4_GET_BLOCKS_PRE_IO | -+ EXT4_GET_BLOCKS_CREATE_ZERO); -+ if (ret < 0) { -+ ext4_journal_stop(handle); -+ if (ret == -ENOSPC && -+ ext4_should_retry_alloc(inode->i_sb, &retries)) -+ goto retry; -+ return ret; -+ } -+ /* For DAX writes we need to zero out unwritten extents */ -+ if (map.m_flags & EXT4_MAP_UNWRITTEN) { -+ /* -+ * We are protected by i_mmap_sem or i_rwsem so we know -+ * block cannot go away from under us even though we -+ * dropped i_data_sem. Convert extent to written and -+ * write zeros there. -+ */ -+ ret = ext4_map_blocks(handle, inode, &map, -+ EXT4_GET_BLOCKS_CONVERT | -+ EXT4_GET_BLOCKS_CREATE_ZERO); -+ if (ret < 0) { -+ ext4_journal_stop(handle); -+ return ret; -+ } -+ } -+ -+ /* -+ * If we added blocks beyond i_size we need to make sure they -+ * will get truncated if we crash before updating i_size in -+ * ext4_iomap_end(). -+ */ -+ if (first_block + map.m_len > -+ (inode->i_size + (1 << blkbits) - 1) >> blkbits) { -+ int err; -+ -+ err = ext4_orphan_add(handle, inode); -+ if (err < 0) { -+ ext4_journal_stop(handle); -+ return err; -+ } -+ } -+ ext4_journal_stop(handle); -+ } - - iomap->flags = 0; - iomap->bdev = inode->i_sb->s_bdev; -@@ -3360,8 +3421,61 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - return 0; - } - -+static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length, -+ ssize_t written, unsigned flags, struct iomap *iomap) -+{ -+ int ret = 0; -+ handle_t *handle; -+ int blkbits = inode->i_blkbits; -+ bool truncate = false; -+ -+ if (!(flags & IOMAP_WRITE)) -+ return 0; -+ -+ handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); -+ if (IS_ERR(handle)) { -+ ret = PTR_ERR(handle); -+ goto orphan_del; -+ } -+ if (ext4_update_inode_size(inode, offset + written)) -+ ext4_mark_inode_dirty(handle, inode); -+ /* -+ * We may need to truncate allocated but not written blocks beyond EOF. -+ */ -+ if (iomap->offset + iomap->length > -+ ALIGN(inode->i_size, 1 << blkbits)) { -+ ext4_lblk_t written_blk, end_blk; -+ -+ written_blk = (offset + written) >> blkbits; -+ end_blk = (offset + length) >> blkbits; -+ if (written_blk < end_blk && ext4_can_truncate(inode)) -+ truncate = true; -+ } -+ /* -+ * Remove inode from orphan list if we were extending a inode and -+ * everything went fine. -+ */ -+ if (!truncate && inode->i_nlink && -+ !list_empty(&EXT4_I(inode)->i_orphan)) -+ ext4_orphan_del(handle, inode); -+ ext4_journal_stop(handle); -+ if (truncate) { -+ ext4_truncate_failed_write(inode); -+orphan_del: -+ /* -+ * If truncate failed early the inode might still be on the -+ * orphan list; we need to make sure the inode is removed from -+ * the orphan list in that case. -+ */ -+ if (inode->i_nlink) -+ ext4_orphan_del(NULL, inode); -+ } -+ return ret; -+} -+ - struct iomap_ops ext4_iomap_ops = { - .iomap_begin = ext4_iomap_begin, -+ .iomap_end = ext4_iomap_end, - }; - - #else --- -2.6.6 - - diff --git a/add-EXT4_JOURNAL_DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask b/add-EXT4_JOURNAL_DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask deleted file mode 100644 index 4bfdfe4a..00000000 --- a/add-EXT4_JOURNAL_DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask +++ /dev/null @@ -1,47 +0,0 @@ -ext4: add EXT4_JOURNAL_DATA_FL and EXT4_EXTENTS_FL to modifiable mask - -From: Jan Kara - -Add EXT4_JOURNAL_DATA_FL and EXT4_EXTENTS_FL to EXT4_FL_USER_MODIFIABLE -to recognize that they are modifiable by userspace. So far we got away -without having them there because ext4_ioctl_setflags() treats them in a -special way. But it was really confusing like that. - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ext4.h | 2 +- - fs/ext4/ioctl.c | 3 +++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index ea31931386ec..0814c9570bf1 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -393,7 +393,7 @@ struct flex_groups { - #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ - - #define EXT4_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */ --#define EXT4_FL_USER_MODIFIABLE 0x204380FF /* User modifiable flags */ -+#define EXT4_FL_USER_MODIFIABLE 0x204BC0FF /* User modifiable flags */ - - #define EXT4_FL_XFLAG_VISIBLE (EXT4_SYNC_FL | \ - EXT4_IMMUTABLE_FL | \ -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index 1bb7df5e4536..e9433c155454 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -267,6 +267,9 @@ static int ext4_ioctl_setflags(struct inode *inode, - for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { - if (!(mask & EXT4_FL_USER_MODIFIABLE)) - continue; -+ /* These flags get special treatment later */ -+ if (mask == EXT4_JOURNAL_DATA_FL || mask == EXT4_EXTENTS_FL) -+ continue; - if (mask & flags) - ext4_set_inode_flag(inode, i); - else --- -2.6.6 - - diff --git a/add-sanity-checking-in-count_overhead b/add-sanity-checking-in-count_overhead deleted file mode 100644 index 0d1af2df..00000000 --- a/add-sanity-checking-in-count_overhead +++ /dev/null @@ -1,36 +0,0 @@ -ext4: add sanity checking to count_overhead() - -The commit "ext4: sanity check the block and cluster size at mount -time" should prevent any problems, but in case the superblock is -modified while the file system is mounted, add an extra safety check -to make sure we won't overrun the allocated buffer. - -Signed-off-by: Theodore Ts'o -Cc: stable@vger.kernel.org ---- - fs/ext4/super.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 689c02df1af4..2d8a49d74f56 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3195,10 +3195,15 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp, - ext4_set_bit(s++, buf); - count++; - } -- for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { -- ext4_set_bit(EXT4_B2C(sbi, s++), buf); -- count++; -+ j = ext4_bg_num_gdb(sb, grp); -+ if (s + j > EXT4_BLOCKS_PER_GROUP(sb)) { -+ ext4_error(sb, "Invalid number of block group " -+ "descriptor blocks: %d", j); -+ j = EXT4_BLOCKS_PER_GROUP(sb) - s; - } -+ count += j; -+ for (; j > 0; j--) -+ ext4_set_bit(EXT4_B2C(sbi, s++), buf); - } - if (!count) - return 0; diff --git a/add-select-for-CONFIG_FS_IOMAP b/add-select-for-CONFIG_FS_IOMAP deleted file mode 100644 index b42bfd42..00000000 --- a/add-select-for-CONFIG_FS_IOMAP +++ /dev/null @@ -1,28 +0,0 @@ -ext4: Add select for CONFIG_FS_IOMAP - -From: Jan Kara - -When ext4 is compiled with DAX support, it now needs the iomap code. Add -appropriate select to Kconfig. - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig -index e38039fd96ff..7b90691e98c4 100644 ---- a/fs/ext4/Kconfig -+++ b/fs/ext4/Kconfig -@@ -37,6 +37,7 @@ config EXT4_FS - select CRC16 - select CRYPTO - select CRYPTO_CRC32C -+ select FS_IOMAP if FS_DAX - help - This is the next generation of the ext3 filesystem. - --- -2.6.6 - diff --git a/allow-ext4_ext_truncate-to-return-an-error b/allow-ext4_ext_truncate-to-return-an-error deleted file mode 100644 index 6563dc82..00000000 --- a/allow-ext4_ext_truncate-to-return-an-error +++ /dev/null @@ -1,85 +0,0 @@ -ext4: allow ext4_ext_truncate() to return an error - -Return errors to the caller instead of declaring the file system -corrupted. - -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/ext4/ext4.h | 2 +- - fs/ext4/extents.c | 15 +++++++-------- - fs/ext4/inode.c | 4 +++- - 3 files changed, 11 insertions(+), 10 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index be2282dcde7d..54211c7876f8 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -3128,7 +3128,7 @@ extern int ext4_ext_writepage_trans_blocks(struct inode *, int); - extern int ext4_ext_index_trans_blocks(struct inode *inode, int extents); - extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, - struct ext4_map_blocks *map, int flags); --extern void ext4_ext_truncate(handle_t *, struct inode *); -+extern int ext4_ext_truncate(handle_t *, struct inode *); - extern int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, - ext4_lblk_t end); - extern void ext4_ext_init(struct super_block *); -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index c930a0110fb4..d3b119499c53 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -4631,7 +4631,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, - return err ? err : allocated; - } - --void ext4_ext_truncate(handle_t *handle, struct inode *inode) -+int ext4_ext_truncate(handle_t *handle, struct inode *inode) - { - struct super_block *sb = inode->i_sb; - ext4_lblk_t last_block; -@@ -4645,7 +4645,9 @@ void ext4_ext_truncate(handle_t *handle, struct inode *inode) - - /* we have to know where to truncate from in crash case */ - EXT4_I(inode)->i_disksize = inode->i_size; -- ext4_mark_inode_dirty(handle, inode); -+ err = ext4_mark_inode_dirty(handle, inode); -+ if (err) -+ return err; - - last_block = (inode->i_size + sb->s_blocksize - 1) - >> EXT4_BLOCK_SIZE_BITS(sb); -@@ -4657,12 +4659,9 @@ void ext4_ext_truncate(handle_t *handle, struct inode *inode) - congestion_wait(BLK_RW_ASYNC, HZ/50); - goto retry; - } -- if (err) { -- ext4_std_error(inode->i_sb, err); -- return; -- } -- err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); -- ext4_std_error(inode->i_sb, err); -+ if (err) -+ return err; -+ return ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); - } - - static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 40ea090d2e0e..7f32899c9701 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -4167,11 +4167,13 @@ int ext4_truncate(struct inode *inode) - ext4_discard_preallocations(inode); - - if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) -- ext4_ext_truncate(handle, inode); -+ err = ext4_ext_truncate(handle, inode); - else - ext4_ind_truncate(handle, inode); - - up_write(&ei->i_data_sem); -+ if (err) -+ goto out_stop; - - if (IS_SYNC(inode)) - ext4_handle_sync(handle); diff --git a/allow-ext4_truncate-to-return-an-error b/allow-ext4_truncate-to-return-an-error deleted file mode 100644 index 488a1e4c..00000000 --- a/allow-ext4_truncate-to-return-an-error +++ /dev/null @@ -1,190 +0,0 @@ -ext4: allow ext4_truncate() to return an error - -This allows us to properly propagate errors back up to -ext4_truncate()'s callers. This also means we no longer have to -silently ignore some errors (e.g., when trying to add the inode to the -orphan inode list). - -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/ext4/ext4.h | 2 +- - fs/ext4/inode.c | 41 ++++++++++++++++++++++++++--------------- - fs/ext4/ioctl.c | 7 +++++-- - fs/ext4/super.c | 6 ++++-- - 4 files changed, 36 insertions(+), 20 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 282a51b07c57..be2282dcde7d 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -2491,7 +2491,7 @@ extern int ext4_change_inode_journal_flag(struct inode *, int); - extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); - extern int ext4_inode_attach_jinode(struct inode *inode); - extern int ext4_can_truncate(struct inode *inode); --extern void ext4_truncate(struct inode *); -+extern int ext4_truncate(struct inode *); - extern int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length); - extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks); - extern void ext4_set_inode_flags(struct inode *); -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 9c064727ed62..40ea090d2e0e 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -261,8 +261,15 @@ void ext4_evict_inode(struct inode *inode) - "couldn't mark inode dirty (err %d)", err); - goto stop_handle; - } -- if (inode->i_blocks) -- ext4_truncate(inode); -+ if (inode->i_blocks) { -+ err = ext4_truncate(inode); -+ if (err) { -+ ext4_error(inode->i_sb, -+ "couldn't truncate inode %lu (err %d)", -+ inode->i_ino, err); -+ goto stop_handle; -+ } -+ } - - /* - * ext4_ext_truncate() doesn't reserve any slop when it -@@ -4091,10 +4098,11 @@ int ext4_inode_attach_jinode(struct inode *inode) - * that's fine - as long as they are linked from the inode, the post-crash - * ext4_truncate() run will find them and release them. - */ --void ext4_truncate(struct inode *inode) -+int ext4_truncate(struct inode *inode) - { - struct ext4_inode_info *ei = EXT4_I(inode); - unsigned int credits; -+ int err = 0; - handle_t *handle; - struct address_space *mapping = inode->i_mapping; - -@@ -4108,7 +4116,7 @@ void ext4_truncate(struct inode *inode) - trace_ext4_truncate_enter(inode); - - if (!ext4_can_truncate(inode)) -- return; -+ return 0; - - ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS); - -@@ -4120,13 +4128,13 @@ void ext4_truncate(struct inode *inode) - - ext4_inline_data_truncate(inode, &has_inline); - if (has_inline) -- return; -+ return 0; - } - - /* If we zero-out tail of the page, we have to create jinode for jbd2 */ - if (inode->i_size & (inode->i_sb->s_blocksize - 1)) { - if (ext4_inode_attach_jinode(inode) < 0) -- return; -+ return 0; - } - - if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) -@@ -4135,10 +4143,8 @@ void ext4_truncate(struct inode *inode) - credits = ext4_blocks_for_truncate(inode); - - handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); -- if (IS_ERR(handle)) { -- ext4_std_error(inode->i_sb, PTR_ERR(handle)); -- return; -- } -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); - - if (inode->i_size & (inode->i_sb->s_blocksize - 1)) - ext4_block_truncate_page(handle, mapping, inode->i_size); -@@ -4152,7 +4158,8 @@ void ext4_truncate(struct inode *inode) - * Implication: the file must always be in a sane, consistent - * truncatable state while each transaction commits. - */ -- if (ext4_orphan_add(handle, inode)) -+ err = ext4_orphan_add(handle, inode); -+ if (err) - goto out_stop; - - down_write(&EXT4_I(inode)->i_data_sem); -@@ -4185,6 +4192,7 @@ void ext4_truncate(struct inode *inode) - ext4_journal_stop(handle); - - trace_ext4_truncate_exit(inode); -+ return err; - } - - /* -@@ -5199,12 +5207,15 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) - * in data=journal mode to make pages freeable. - */ - truncate_pagecache(inode, inode->i_size); -- if (shrink) -- ext4_truncate(inode); -+ if (shrink) { -+ rc = ext4_truncate(inode); -+ if (rc) -+ error = rc; -+ } - up_write(&EXT4_I(inode)->i_mmap_sem); - } - -- if (!rc) { -+ if (!error) { - setattr_copy(inode, attr); - mark_inode_dirty(inode); - } -@@ -5216,7 +5227,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) - if (orphan && inode->i_nlink) - ext4_orphan_del(NULL, inode); - -- if (!rc && (ia_valid & ATTR_MODE)) -+ if (!error && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - - err_out: -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index bf5ae8ebbc97..99862a3726fc 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -248,8 +248,11 @@ static int ext4_ioctl_setflags(struct inode *inode, - err = -EOPNOTSUPP; - goto flags_out; - } -- } else if (oldflags & EXT4_EOFBLOCKS_FL) -- ext4_truncate(inode); -+ } else if (oldflags & EXT4_EOFBLOCKS_FL) { -+ err = ext4_truncate(inode); -+ if (err) -+ goto flags_out; -+ } - - handle = ext4_journal_start(inode, EXT4_HT_INODE, 1); - if (IS_ERR(handle)) { -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 20da99da0a34..e4f61c39328a 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -2330,7 +2330,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, - struct ext4_super_block *es) - { - unsigned int s_flags = sb->s_flags; -- int nr_orphans = 0, nr_truncates = 0; -+ int ret, nr_orphans = 0, nr_truncates = 0; - #ifdef CONFIG_QUOTA - int i; - #endif -@@ -2412,7 +2412,9 @@ static void ext4_orphan_cleanup(struct super_block *sb, - inode->i_ino, inode->i_size); - inode_lock(inode); - truncate_inode_pages(inode->i_mapping, inode->i_size); -- ext4_truncate(inode); -+ ret = ext4_truncate(inode); -+ if (ret) -+ ext4_std_error(inode->i_sb, ret); - inode_unlock(inode); - nr_truncates++; - } else { diff --git a/allow-inode-expansion-for-nojournal-file-systems b/allow-inode-expansion-for-nojournal-file-systems deleted file mode 100644 index cc57a5a1..00000000 --- a/allow-inode-expansion-for-nojournal-file-systems +++ /dev/null @@ -1,50 +0,0 @@ -ext4: allow inode expansion for nojournal file systems - -From: Eric Whitney - -Runs of xfstest ext4/022 on nojournal file systems result in failures -because the inodes of some of its test files do not expand as expected. -The cause is a conditional in ext4_mark_inode_dirty() that prevents inode -expansion unless the test file system has a journal. Remove this -unnecessary restriction. - -Signed-off-by: Eric Whitney -Signed-off-by: Theodore Ts'o ---- - fs/ext4/inode.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 9c06472..260da4d 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -5455,18 +5455,20 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (err) - return err; -- if (ext4_handle_valid(handle) && -- EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && -+ if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && - !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { - /* -- * We need extra buffer credits since we may write into EA block -+ * In nojournal mode, we can immediately attempt to expand -+ * the inode. When journaled, we first need to obtain extra -+ * buffer credits since we may write into the EA block - * with this same handle. If journal_extend fails, then it will - * only result in a minor loss of functionality for that inode. - * If this is felt to be critical, then e2fsck should be run to - * force a large enough s_min_extra_isize. - */ -- if ((jbd2_journal_extend(handle, -- EXT4_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) { -+ if (!ext4_handle_valid(handle) || -+ jbd2_journal_extend(handle, -+ EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) == 0) { - ret = ext4_expand_extra_isize(inode, - sbi->s_want_extra_isize, - iloc, handle); --- -2.1.4 - - diff --git a/avoid-lockdep-warning-when-inheriting-encryption-context b/avoid-lockdep-warning-when-inheriting-encryption-context deleted file mode 100644 index b49da774..00000000 --- a/avoid-lockdep-warning-when-inheriting-encryption-context +++ /dev/null @@ -1,140 +0,0 @@ -ext4: avoid lockdep warning when inheriting encryption context - -From: Eric Biggers - -On a lockdep-enabled kernel, xfstests generic/027 fails due to a lockdep -warning when run on ext4 mounted with -o test_dummy_encryption: - - xfs_io/4594 is trying to acquire lock: - (jbd2_handle - ){++++.+}, at: - [] jbd2_log_wait_commit+0x5/0x11b - - but task is already holding lock: - (jbd2_handle - ){++++.+}, at: - [] start_this_handle+0x354/0x3d8 - -The abbreviated call stack is: - - [] ? jbd2_log_wait_commit+0x5/0x11b - [] jbd2_log_wait_commit+0x40/0x11b - [] ? jbd2_log_wait_commit+0x5/0x11b - [] ? __jbd2_journal_force_commit+0x76/0xa6 - [] __jbd2_journal_force_commit+0x91/0xa6 - [] jbd2_journal_force_commit_nested+0xe/0x18 - [] ext4_should_retry_alloc+0x72/0x79 - [] ext4_xattr_set+0xef/0x11f - [] ext4_set_context+0x3a/0x16b - [] fscrypt_inherit_context+0xe3/0x103 - [] __ext4_new_inode+0x12dc/0x153a - [] ext4_create+0xb7/0x161 - -When a file is created in an encrypted directory, ext4_set_context() is -called to set an encryption context on the new file. This calls -ext4_xattr_set(), which contains a retry loop where the journal is -forced to commit if an ENOSPC error is encountered. - -If the task actually were to wait for the journal to commit in this -case, then it would deadlock because a handle remains open from -__ext4_new_inode(), so the running transaction can't be committed yet. -Fortunately, __jbd2_journal_force_commit() avoids the deadlock by not -allowing the running transaction to be committed while the current task -has it open. However, the above lockdep warning is still triggered. - -This was a false positive which was introduced by: 1eaa566d368b: jbd2: -track more dependencies on transaction commit - -Fix the problem by passing the handle through the 'fs_data' argument to -ext4_set_context(), then using ext4_xattr_set_handle() instead of -ext4_xattr_set(). And in the case where no journal handle is specified -and ext4_set_context() has to open one, add an ENOSPC retry loop since -in that case it is the outermost transaction. - -Signed-off-by: Eric Biggers ---- - fs/ext4/ialloc.c | 3 +-- - fs/ext4/super.c | 32 ++++++++++++++++++++++---------- - 2 files changed, 23 insertions(+), 12 deletions(-) - -diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c -index 170421e..f543281 100644 ---- a/fs/ext4/ialloc.c -+++ b/fs/ext4/ialloc.c -@@ -1115,8 +1115,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, - } - - if (encrypt) { -- /* give pointer to avoid set_context with journal ops. */ -- err = fscrypt_inherit_context(dir, inode, &encrypt, true); -+ err = fscrypt_inherit_context(dir, inode, handle, true); - if (err) - goto fail_free_drop; - } -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index ff6f3ab..22d50cb 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -1114,14 +1114,22 @@ static int ext4_prepare_context(struct inode *inode) - static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, - void *fs_data) - { -- handle_t *handle; -- int res, res2; -+ handle_t *handle = fs_data; -+ int res, res2, retries = 0; - -- /* fs_data is null when internally used. */ -- if (fs_data) { -- res = ext4_xattr_set(inode, EXT4_XATTR_INDEX_ENCRYPTION, -- EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, -- len, 0); -+ /* -+ * If a journal handle was specified, then the encryption context is -+ * being set on a new inode via inheritance and is part of a larger -+ * transaction to create the inode. Otherwise the encryption context is -+ * being set on an existing inode in its own transaction. Only in the -+ * latter case should the "retry on ENOSPC" logic be used. -+ */ -+ -+ if (handle) { -+ res = ext4_xattr_set_handle(handle, inode, -+ EXT4_XATTR_INDEX_ENCRYPTION, -+ EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, -+ ctx, len, 0); - if (!res) { - ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT); - ext4_clear_inode_state(inode, -@@ -1130,14 +1138,15 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, - return res; - } - -+retry: - handle = ext4_journal_start(inode, EXT4_HT_MISC, - ext4_jbd2_credits_xattr(inode)); - if (IS_ERR(handle)) - return PTR_ERR(handle); - -- res = ext4_xattr_set(inode, EXT4_XATTR_INDEX_ENCRYPTION, -- EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, ctx, -- len, 0); -+ res = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_ENCRYPTION, -+ EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, -+ ctx, len, 0); - if (!res) { - ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT); - res = ext4_mark_inode_dirty(handle, inode); -@@ -1145,6 +1154,9 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, - EXT4_ERROR_INODE(inode, "Failed to mark inode dirty"); - } - res2 = ext4_journal_stop(handle); -+ -+ if (res == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) -+ goto retry; - if (!res) - res = res2; - return res; --- -2.8.0.rc3.226.g39d4020 - - diff --git a/avoid-split-extents-for-DAX-writes b/avoid-split-extents-for-DAX-writes deleted file mode 100644 index e6c30529..00000000 --- a/avoid-split-extents-for-DAX-writes +++ /dev/null @@ -1,60 +0,0 @@ -ext4: avoid split extents for DAX writes - -From: Jan Kara - -Currently mapping of blocks for DAX writes happen with -EXT4_GET_BLOCKS_PRE_IO flag set. That has a result that each -ext4_map_blocks() call creates a separate written extent, although it -could be merged to the neighboring extents in the extent tree. The -reason for using this flag is that in case the extent is unwritten, we -need to convert it to written one and zero it out. However this "convert -mapped range to written" operation is already implemented by -ext4_map_blocks() for the case of data writes into unwritten extent. So -just use flags for that mode of operation, simplify the code, and avoid -unnecessary split extents. - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/inode.c | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index a7079cab645a..3192ec0768d4 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3351,7 +3351,6 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - return PTR_ERR(handle); - - ret = ext4_map_blocks(handle, inode, &map, -- EXT4_GET_BLOCKS_PRE_IO | - EXT4_GET_BLOCKS_CREATE_ZERO); - if (ret < 0) { - ext4_journal_stop(handle); -@@ -3360,22 +3359,6 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - goto retry; - return ret; - } -- /* For DAX writes we need to zero out unwritten extents */ -- if (map.m_flags & EXT4_MAP_UNWRITTEN) { -- /* -- * We are protected by i_mmap_sem or i_rwsem so we know -- * block cannot go away from under us even though we -- * dropped i_data_sem. Convert extent to written and -- * write zeros there. -- */ -- ret = ext4_map_blocks(handle, inode, &map, -- EXT4_GET_BLOCKS_CONVERT | -- EXT4_GET_BLOCKS_CREATE_ZERO); -- if (ret < 0) { -- ext4_journal_stop(handle); -- return ret; -- } -- } - - /* - * If we added blocks beyond i_size we need to make sure they --- -2.6.6 - - diff --git a/be-more-strict-when-verifying-flags-set-via-SETFLAGS-ioctls b/be-more-strict-when-verifying-flags-set-via-SETFLAGS-ioctls deleted file mode 100644 index 1001391f..00000000 --- a/be-more-strict-when-verifying-flags-set-via-SETFLAGS-ioctls +++ /dev/null @@ -1,103 +0,0 @@ -ext4: be more strict when verifying flags set via SETFLAGS ioctls - -From: Jan Kara - -Currently we just silently ignore flags that we don't understand (or -that cannot be manipulated) through EXT4_IOC_SETFLAGS and -EXT4_IOC_FSSETXATTR ioctls. This makes it problematic for the unused -flags to be used in future (some app may be inadvertedly setting them -and we won't notice until the flag gets used). Also this is inconsistent -with other filesystems like XFS or BTRFS which return EOPNOTSUPP when -they see a flag they cannot set. - -ext4 has the additional problem that there are flags which are returned -by EXT4_IOC_GETFLAGS ioctl but which cannot be modified via -EXT4_IOC_SETFLAGS. So we have to be careful to ignore value of these -flags and not fail the ioctl when they are set (as e.g. chattr(1) passes -flags returned from EXT4_IOC_GETFLAGS to EXT4_IOC_SETFLAGS without any -masking and thus we'd break this utility). - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ext4.h | 1 + - fs/ext4/ioctl.c | 28 +++++++++++++++++++++++----- - 2 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 0814c9570bf1..2874957e3ee2 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -395,6 +395,7 @@ struct flex_groups { - #define EXT4_FL_USER_VISIBLE 0x304BDFFF /* User visible flags */ - #define EXT4_FL_USER_MODIFIABLE 0x204BC0FF /* User modifiable flags */ - -+/* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */ - #define EXT4_FL_XFLAG_VISIBLE (EXT4_SYNC_FL | \ - EXT4_IMMUTABLE_FL | \ - EXT4_APPEND_FL | \ -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index e9433c155454..33af924fa7c4 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -415,6 +415,10 @@ static inline __u32 ext4_iflags_to_xflags(unsigned long iflags) - return xflags; - } - -+#define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \ -+ FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \ -+ FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT) -+ - /* Transfer xflags flags to internal */ - static inline unsigned long ext4_xflags_to_iflags(__u32 xflags) - { -@@ -459,12 +463,22 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - if (get_user(flags, (int __user *) arg)) - return -EFAULT; - -+ if (flags & ~EXT4_FL_USER_VISIBLE) -+ return -EOPNOTSUPP; -+ /* -+ * chattr(1) grabs flags via GETFLAGS, modifies the result and -+ * passes that to SETFLAGS. So we cannot easily make SETFLAGS -+ * more restrictive than just silently masking off visible but -+ * not settable flags as we always did. -+ */ -+ flags &= EXT4_FL_USER_MODIFIABLE; -+ if (ext4_mask_flags(inode->i_mode, flags) != flags) -+ return -EOPNOTSUPP; -+ - err = mnt_want_write_file(filp); - if (err) - return err; - -- flags = ext4_mask_flags(inode->i_mode, flags); -- - inode_lock(inode); - err = ext4_ioctl_setflags(inode, flags); - inode_unlock(inode); -@@ -869,13 +883,17 @@ resizefs_out: - if (!inode_owner_or_capable(inode)) - return -EACCES; - -+ if (fa.fsx_xflags & ~EXT4_SUPPORTED_FS_XFLAGS) -+ return -EOPNOTSUPP; -+ -+ flags = ext4_xflags_to_iflags(fa.fsx_xflags); -+ if (ext4_mask_flags(inode->i_mode, flags) != flags) -+ return -EOPNOTSUPP; -+ - err = mnt_want_write_file(filp); - if (err) - return err; - -- flags = ext4_xflags_to_iflags(fa.fsx_xflags); -- flags = ext4_mask_flags(inode->i_mode, flags); -- - inode_lock(inode); - flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) | - (flags & EXT4_FL_XFLAG_VISIBLE); --- -2.6.6 - - diff --git a/convert-DAX-faults-to-iomap-infrastructure b/convert-DAX-faults-to-iomap-infrastructure deleted file mode 100644 index 211a7501..00000000 --- a/convert-DAX-faults-to-iomap-infrastructure +++ /dev/null @@ -1,80 +0,0 @@ -ext4: convert DAX faults to iomap infrastructure - -From: Jan Kara - -Convert DAX faults to use iomap infrastructure. We would not have to start -transaction in ext4_dax_fault() anymore since ext4_iomap_begin takes -care of that but so far we do that to avoid lock inversion of -transaction start with DAX entry lock which gets acquired in -dax_iomap_fault() before calling ->iomap_begin handler. - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/file.c | 9 +++++---- - fs/ext4/inode.c | 14 +++++++++----- - 2 files changed, 14 insertions(+), 9 deletions(-) - -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index 1953fe34f9fe..b5f184493c57 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -275,7 +275,7 @@ static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) - if (IS_ERR(handle)) - result = VM_FAULT_SIGBUS; - else -- result = dax_fault(vma, vmf, ext4_dax_get_block); -+ result = dax_iomap_fault(vma, vmf, &ext4_iomap_ops); - - if (write) { - if (!IS_ERR(handle)) -@@ -309,9 +309,10 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, - - if (IS_ERR(handle)) - result = VM_FAULT_SIGBUS; -- else -- result = dax_pmd_fault(vma, addr, pmd, flags, -- ext4_dax_get_block); -+ else { -+ result = dax_iomap_pmd_fault(vma, addr, pmd, flags, -+ &ext4_iomap_ops); -+ } - - if (write) { - if (!IS_ERR(handle)) -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 3192ec0768d4..4d71c7bc3524 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3361,12 +3361,16 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - } - - /* -- * If we added blocks beyond i_size we need to make sure they -+ * If we added blocks beyond i_size, we need to make sure they - * will get truncated if we crash before updating i_size in -- * ext4_iomap_end(). -+ * ext4_iomap_end(). For faults we don't need to do that (and -+ * even cannot because for orphan list operations inode_lock is -+ * required) - if we happen to instantiate block beyond i_size, -+ * it is because we race with truncate which has already added -+ * the inode to the orphan list. - */ -- if (first_block + map.m_len > -- (inode->i_size + (1 << blkbits) - 1) >> blkbits) { -+ if (!(flags & IOMAP_FAULT) && first_block + map.m_len > -+ (i_size_read(inode) + (1 << blkbits) - 1) >> blkbits) { - int err; - - err = ext4_orphan_add(handle, inode); -@@ -3412,7 +3416,7 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length, - int blkbits = inode->i_blkbits; - bool truncate = false; - -- if (!(flags & IOMAP_WRITE)) -+ if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT)) - return 0; - - handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); --- -2.6.6 diff --git a/convert-dax-reads-to-iomap-infrastructure b/convert-dax-reads-to-iomap-infrastructure deleted file mode 100644 index 2ae825a6..00000000 --- a/convert-dax-reads-to-iomap-infrastructure +++ /dev/null @@ -1,161 +0,0 @@ -ext4: convert DAX reads to iomap infrastructure - -From: Jan Kara - -Implement basic iomap_begin function that handles reading and use it for -DAX reads. - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ext4.h | 2 ++ - fs/ext4/file.c | 38 +++++++++++++++++++++++++++++++++++++- - fs/ext4/inode.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 93 insertions(+), 1 deletion(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 282a51b07c57..098b39910001 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -3271,6 +3271,8 @@ static inline bool ext4_aligned_io(struct inode *inode, loff_t off, loff_t len) - return IS_ALIGNED(off, blksize) && IS_ALIGNED(len, blksize); - } - -+extern struct iomap_ops ext4_iomap_ops; -+ - #endif /* __KERNEL__ */ - - #define EFSBADCRC EBADMSG /* Bad CRC detected */ -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index 9facb4dc5c70..1f25c644cb12 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -31,6 +31,42 @@ - #include "xattr.h" - #include "acl.h" - -+#ifdef CONFIG_FS_DAX -+static ssize_t ext4_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) -+{ -+ struct inode *inode = file_inode(iocb->ki_filp); -+ ssize_t ret; -+ -+ inode_lock_shared(inode); -+ /* -+ * Recheck under inode lock - at this point we are sure it cannot -+ * change anymore -+ */ -+ if (!IS_DAX(inode)) { -+ inode_unlock_shared(inode); -+ /* Fallback to buffered IO in case we cannot support DAX */ -+ return generic_file_read_iter(iocb, to); -+ } -+ ret = dax_iomap_rw(iocb, to, &ext4_iomap_ops); -+ inode_unlock_shared(inode); -+ -+ file_accessed(iocb->ki_filp); -+ return ret; -+} -+#endif -+ -+static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to) -+{ -+ if (!iov_iter_count(to)) -+ return 0; /* skip atime */ -+ -+#ifdef CONFIG_FS_DAX -+ if (IS_DAX(file_inode(iocb->ki_filp))) -+ return ext4_dax_read_iter(iocb, to); -+#endif -+ return generic_file_read_iter(iocb, to); -+} -+ - /* - * Called when an inode is released. Note that this is different - * from ext4_file_open: open gets called at every open, but release -@@ -690,7 +726,7 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int whence) - - const struct file_operations ext4_file_operations = { - .llseek = ext4_llseek, -- .read_iter = generic_file_read_iter, -+ .read_iter = ext4_file_read_iter, - .write_iter = ext4_file_write_iter, - .unlocked_ioctl = ext4_ioctl, - #ifdef CONFIG_COMPAT -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 5337828c68a7..83e8411370d3 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include "ext4_jbd2.h" - #include "xattr.h" -@@ -3310,6 +3311,59 @@ int ext4_dax_get_block(struct inode *inode, sector_t iblock, - clear_buffer_new(bh_result); - return 0; - } -+ -+static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, -+ unsigned flags, struct iomap *iomap) -+{ -+ unsigned int blkbits = inode->i_blkbits; -+ unsigned long first_block = offset >> blkbits; -+ unsigned long last_block = (offset + length - 1) >> blkbits; -+ struct ext4_map_blocks map; -+ int ret; -+ -+ if (flags & IOMAP_WRITE) -+ return -EIO; -+ -+ if (WARN_ON_ONCE(ext4_has_inline_data(inode))) -+ return -ERANGE; -+ -+ map.m_lblk = first_block; -+ map.m_len = last_block - first_block + 1; -+ -+ ret = ext4_map_blocks(NULL, inode, &map, 0); -+ if (ret < 0) -+ return ret; -+ -+ iomap->flags = 0; -+ iomap->bdev = inode->i_sb->s_bdev; -+ iomap->offset = first_block << blkbits; -+ -+ if (ret == 0) { -+ iomap->type = IOMAP_HOLE; -+ iomap->blkno = IOMAP_NULL_BLOCK; -+ iomap->length = (u64)map.m_len << blkbits; -+ } else { -+ if (map.m_flags & EXT4_MAP_MAPPED) { -+ iomap->type = IOMAP_MAPPED; -+ } else if (map.m_flags & EXT4_MAP_UNWRITTEN) { -+ iomap->type = IOMAP_UNWRITTEN; -+ } else { -+ WARN_ON_ONCE(1); -+ return -EIO; -+ } -+ iomap->blkno = (sector_t)map.m_pblk << (blkbits - 9); -+ iomap->length = (u64)map.m_len << blkbits; -+ } -+ -+ if (map.m_flags & EXT4_MAP_NEW) -+ iomap->flags |= IOMAP_F_NEW; -+ return 0; -+} -+ -+struct iomap_ops ext4_iomap_ops = { -+ .iomap_begin = ext4_iomap_begin, -+}; -+ - #else - /* Just define empty function, it will never get called. */ - int ext4_dax_get_block(struct inode *inode, sector_t iblock, --- -2.6.6 - - diff --git a/correct-detect-when-an-xattr-value-has-an-invalid-size b/correct-detect-when-an-xattr-value-has-an-invalid-size deleted file mode 100644 index c6666e67..00000000 --- a/correct-detect-when-an-xattr-value-has-an-invalid-size +++ /dev/null @@ -1,80 +0,0 @@ -ext4: correctly detect when an xattr value has an invalid size - -From: Eric Biggers - -It was possible for an xattr value to have a very large size, which -would then pass validation on 32-bit architectures due to a pointer -wraparound. Fix this by validating the size in a way which avoids -pointer wraparound. - -It was also possible that a value's size would fit in the available -space but its padded size would not. This would cause an out-of-bounds -memory write in ext4_xattr_set_entry when replacing the xattr value. -For example, if an xattr value of unpadded size 253 bytes went until the -very end of the inode or block, then using setxattr(2) to replace this -xattr's value with 256 bytes would cause a write to the 3 bytes past the -end of the inode or buffer, and the new xattr value would be incorrectly -truncated. Fix this by requiring that the padded size fit in the -available space rather than the unpadded size. - -This patch shouldn't have any noticeable effect on -non-corrupted/non-malicious filesystems. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o ---- - fs/ext4/xattr.c | 27 +++++++++++++++++++++------ - 1 file changed, 21 insertions(+), 6 deletions(-) - -diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index 59c9ec7..5a94fa52 100644 ---- a/fs/ext4/xattr.c -+++ b/fs/ext4/xattr.c -@@ -185,6 +185,7 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end, - { - struct ext4_xattr_entry *e = entry; - -+ /* Find the end of the names list */ - while (!IS_LAST_ENTRY(e)) { - struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) -@@ -192,15 +193,29 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end, - e = next; - } - -+ /* Check the values */ - while (!IS_LAST_ENTRY(entry)) { - if (entry->e_value_block != 0) - return -EFSCORRUPTED; -- if (entry->e_value_size != 0 && -- (value_start + le16_to_cpu(entry->e_value_offs) < -- (void *)e + sizeof(__u32) || -- value_start + le16_to_cpu(entry->e_value_offs) + -- le32_to_cpu(entry->e_value_size) > end)) -- return -EFSCORRUPTED; -+ if (entry->e_value_size != 0) { -+ u16 offs = le16_to_cpu(entry->e_value_offs); -+ u32 size = le32_to_cpu(entry->e_value_size); -+ void *value; -+ -+ /* -+ * The value cannot overlap the names, and the value -+ * with padding cannot extend beyond 'end'. Check both -+ * the padded and unpadded sizes, since the size may -+ * overflow to 0 when adding padding. -+ */ -+ if (offs > end - value_start) -+ return -EFSCORRUPTED; -+ value = value_start + offs; -+ if (value < (void *)e + sizeof(u32) || -+ size > end - value || -+ EXT4_XATTR_SIZE(size) > end - value) -+ return -EFSCORRUPTED; -+ } - entry = EXT4_XATTR_NEXT(entry); - } - --- -2.8.0.rc3.226.g39d4020 - - diff --git a/dax-rip-out-get_block-based-IO-support b/dax-rip-out-get_block-based-IO-support deleted file mode 100644 index f1e3c0d9..00000000 --- a/dax-rip-out-get_block-based-IO-support +++ /dev/null @@ -1,437 +0,0 @@ -dax: rip out get_block based IO support - -From: Jan Kara - -No one uses functions using the get_block callback anymore. Rip them -out and update documentation. - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - Documentation/filesystems/dax.txt | 22 +-- - fs/dax.c | 315 -------------------------------------- - include/linux/dax.h | 12 -- - 3 files changed, 11 insertions(+), 338 deletions(-) - -diff --git a/Documentation/filesystems/dax.txt b/Documentation/filesystems/dax.txt -index 23d18b8a49d5..a7e6e14aeb08 100644 ---- a/Documentation/filesystems/dax.txt -+++ b/Documentation/filesystems/dax.txt -@@ -58,22 +58,22 @@ Implementation Tips for Filesystem Writers - Filesystem support consists of - - adding support to mark inodes as being DAX by setting the S_DAX flag in - i_flags --- implementing the direct_IO address space operation, and calling -- dax_do_io() instead of blockdev_direct_IO() if S_DAX is set -+- implementing ->read_iter and ->write_iter operations which use dax_iomap_rw() -+ when inode has S_DAX flag set - - implementing an mmap file operation for DAX files which sets the - VM_MIXEDMAP and VM_HUGEPAGE flags on the VMA, and setting the vm_ops to -- include handlers for fault, pmd_fault and page_mkwrite (which should -- probably call dax_fault(), dax_pmd_fault() and dax_mkwrite(), passing the -- appropriate get_block() callback) --- calling dax_truncate_page() instead of block_truncate_page() for DAX files --- calling dax_zero_page_range() instead of zero_user() for DAX files -+ include handlers for fault, pmd_fault, page_mkwrite, pfn_mkwrite. These -+ handlers should probably call dax_iomap_fault() (for fault and page_mkwrite -+ handlers), dax_iomap_pmd_fault(), dax_pfn_mkwrite() passing the appropriate -+ iomap operations. -+- calling iomap_zero_range() passing appropriate iomap operations instead of -+ block_truncate_page() for DAX files - - ensuring that there is sufficient locking between reads, writes, - truncates and page faults - --The get_block() callback passed to the DAX functions may return --uninitialised extents. If it does, it must ensure that simultaneous --calls to get_block() (for example by a page-fault racing with a read() --or a write()) work correctly. -+The iomap handlers for allocating blocks must make sure that allocated blocks -+are zeroed out and converted to written extents before being returned to avoid -+exposure of uninitialized data through mmap. - - These filesystems may be used for inspiration: - - ext2: see Documentation/filesystems/ext2.txt -diff --git a/fs/dax.c b/fs/dax.c -index 28af41b9da3a..ad131cd2605d 100644 ---- a/fs/dax.c -+++ b/fs/dax.c -@@ -116,168 +116,6 @@ struct page *read_dax_sector(struct block_device *bdev, sector_t n) - return page; - } - --static bool buffer_written(struct buffer_head *bh) --{ -- return buffer_mapped(bh) && !buffer_unwritten(bh); --} -- --static sector_t to_sector(const struct buffer_head *bh, -- const struct inode *inode) --{ -- sector_t sector = bh->b_blocknr << (inode->i_blkbits - 9); -- -- return sector; --} -- --static ssize_t dax_io(struct inode *inode, struct iov_iter *iter, -- loff_t start, loff_t end, get_block_t get_block, -- struct buffer_head *bh) --{ -- loff_t pos = start, max = start, bh_max = start; -- bool hole = false; -- struct block_device *bdev = NULL; -- int rw = iov_iter_rw(iter), rc; -- long map_len = 0; -- struct blk_dax_ctl dax = { -- .addr = ERR_PTR(-EIO), -- }; -- unsigned blkbits = inode->i_blkbits; -- sector_t file_blks = (i_size_read(inode) + (1 << blkbits) - 1) -- >> blkbits; -- -- if (rw == READ) -- end = min(end, i_size_read(inode)); -- -- while (pos < end) { -- size_t len; -- if (pos == max) { -- long page = pos >> PAGE_SHIFT; -- sector_t block = page << (PAGE_SHIFT - blkbits); -- unsigned first = pos - (block << blkbits); -- long size; -- -- if (pos == bh_max) { -- bh->b_size = PAGE_ALIGN(end - pos); -- bh->b_state = 0; -- rc = get_block(inode, block, bh, rw == WRITE); -- if (rc) -- break; -- bh_max = pos - first + bh->b_size; -- bdev = bh->b_bdev; -- /* -- * We allow uninitialized buffers for writes -- * beyond EOF as those cannot race with faults -- */ -- WARN_ON_ONCE( -- (buffer_new(bh) && block < file_blks) || -- (rw == WRITE && buffer_unwritten(bh))); -- } else { -- unsigned done = bh->b_size - -- (bh_max - (pos - first)); -- bh->b_blocknr += done >> blkbits; -- bh->b_size -= done; -- } -- -- hole = rw == READ && !buffer_written(bh); -- if (hole) { -- size = bh->b_size - first; -- } else { -- dax_unmap_atomic(bdev, &dax); -- dax.sector = to_sector(bh, inode); -- dax.size = bh->b_size; -- map_len = dax_map_atomic(bdev, &dax); -- if (map_len < 0) { -- rc = map_len; -- break; -- } -- dax.addr += first; -- size = map_len - first; -- } -- /* -- * pos + size is one past the last offset for IO, -- * so pos + size can overflow loff_t at extreme offsets. -- * Cast to u64 to catch this and get the true minimum. -- */ -- max = min_t(u64, pos + size, end); -- } -- -- if (iov_iter_rw(iter) == WRITE) { -- len = copy_from_iter_pmem(dax.addr, max - pos, iter); -- } else if (!hole) -- len = copy_to_iter((void __force *) dax.addr, max - pos, -- iter); -- else -- len = iov_iter_zero(max - pos, iter); -- -- if (!len) { -- rc = -EFAULT; -- break; -- } -- -- pos += len; -- if (!IS_ERR(dax.addr)) -- dax.addr += len; -- } -- -- dax_unmap_atomic(bdev, &dax); -- -- return (pos == start) ? rc : pos - start; --} -- --/** -- * dax_do_io - Perform I/O to a DAX file -- * @iocb: The control block for this I/O -- * @inode: The file which the I/O is directed at -- * @iter: The addresses to do I/O from or to -- * @get_block: The filesystem method used to translate file offsets to blocks -- * @end_io: A filesystem callback for I/O completion -- * @flags: See below -- * -- * This function uses the same locking scheme as do_blockdev_direct_IO: -- * If @flags has DIO_LOCKING set, we assume that the i_mutex is held by the -- * caller for writes. For reads, we take and release the i_mutex ourselves. -- * If DIO_LOCKING is not set, the filesystem takes care of its own locking. -- * As with do_blockdev_direct_IO(), we increment i_dio_count while the I/O -- * is in progress. -- */ --ssize_t dax_do_io(struct kiocb *iocb, struct inode *inode, -- struct iov_iter *iter, get_block_t get_block, -- dio_iodone_t end_io, int flags) --{ -- struct buffer_head bh; -- ssize_t retval = -EINVAL; -- loff_t pos = iocb->ki_pos; -- loff_t end = pos + iov_iter_count(iter); -- -- memset(&bh, 0, sizeof(bh)); -- bh.b_bdev = inode->i_sb->s_bdev; -- -- if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ) -- inode_lock(inode); -- -- /* Protects against truncate */ -- if (!(flags & DIO_SKIP_DIO_COUNT)) -- inode_dio_begin(inode); -- -- retval = dax_io(inode, iter, pos, end, get_block, &bh); -- -- if ((flags & DIO_LOCKING) && iov_iter_rw(iter) == READ) -- inode_unlock(inode); -- -- if (end_io) { -- int err; -- -- err = end_io(iocb, pos, retval, bh.b_private); -- if (err) -- retval = err; -- } -- -- if (!(flags & DIO_SKIP_DIO_COUNT)) -- inode_dio_end(inode); -- return retval; --} --EXPORT_SYMBOL_GPL(dax_do_io); -- - /* - * DAX radix tree locking - */ -@@ -920,105 +758,6 @@ static int dax_insert_mapping(struct address_space *mapping, - } - - /** -- * dax_fault - handle a page fault on a DAX file -- * @vma: The virtual memory area where the fault occurred -- * @vmf: The description of the fault -- * @get_block: The filesystem method used to translate file offsets to blocks -- * -- * When a page fault occurs, filesystems may call this helper in their -- * fault handler for DAX files. dax_fault() assumes the caller has done all -- * the necessary locking for the page fault to proceed successfully. -- */ --int dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, -- get_block_t get_block) --{ -- struct file *file = vma->vm_file; -- struct address_space *mapping = file->f_mapping; -- struct inode *inode = mapping->host; -- void *entry; -- struct buffer_head bh; -- unsigned long vaddr = (unsigned long)vmf->virtual_address; -- unsigned blkbits = inode->i_blkbits; -- sector_t block; -- pgoff_t size; -- int error; -- int major = 0; -- -- /* -- * Check whether offset isn't beyond end of file now. Caller is supposed -- * to hold locks serializing us with truncate / punch hole so this is -- * a reliable test. -- */ -- size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; -- if (vmf->pgoff >= size) -- return VM_FAULT_SIGBUS; -- -- memset(&bh, 0, sizeof(bh)); -- block = (sector_t)vmf->pgoff << (PAGE_SHIFT - blkbits); -- bh.b_bdev = inode->i_sb->s_bdev; -- bh.b_size = PAGE_SIZE; -- -- entry = grab_mapping_entry(mapping, vmf->pgoff, 0); -- if (IS_ERR(entry)) { -- error = PTR_ERR(entry); -- goto out; -- } -- -- error = get_block(inode, block, &bh, 0); -- if (!error && (bh.b_size < PAGE_SIZE)) -- error = -EIO; /* fs corruption? */ -- if (error) -- goto unlock_entry; -- -- if (vmf->cow_page) { -- struct page *new_page = vmf->cow_page; -- if (buffer_written(&bh)) -- error = copy_user_dax(bh.b_bdev, to_sector(&bh, inode), -- bh.b_size, new_page, vaddr); -- else -- clear_user_highpage(new_page, vaddr); -- if (error) -- goto unlock_entry; -- if (!radix_tree_exceptional_entry(entry)) { -- vmf->page = entry; -- return VM_FAULT_LOCKED; -- } -- vmf->entry = entry; -- return VM_FAULT_DAX_LOCKED; -- } -- -- if (!buffer_mapped(&bh)) { -- if (vmf->flags & FAULT_FLAG_WRITE) { -- error = get_block(inode, block, &bh, 1); -- count_vm_event(PGMAJFAULT); -- mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); -- major = VM_FAULT_MAJOR; -- if (!error && (bh.b_size < PAGE_SIZE)) -- error = -EIO; -- if (error) -- goto unlock_entry; -- } else { -- return dax_load_hole(mapping, entry, vmf); -- } -- } -- -- /* Filesystem should not return unwritten buffers to us! */ -- WARN_ON_ONCE(buffer_unwritten(&bh) || buffer_new(&bh)); -- error = dax_insert_mapping(mapping, bh.b_bdev, to_sector(&bh, inode), -- bh.b_size, &entry, vma, vmf); -- unlock_entry: -- put_locked_mapping_entry(mapping, vmf->pgoff, entry); -- out: -- if (error == -ENOMEM) -- return VM_FAULT_OOM | major; -- /* -EBUSY is fine, somebody else faulted on the same PTE */ -- if ((error < 0) && (error != -EBUSY)) -- return VM_FAULT_SIGBUS | major; -- return VM_FAULT_NOPAGE | major; --} --EXPORT_SYMBOL_GPL(dax_fault); -- --/** - * dax_pfn_mkwrite - handle first write to DAX page - * @vma: The virtual memory area where the fault occurred - * @vmf: The description of the fault -@@ -1078,60 +817,6 @@ int __dax_zero_page_range(struct block_device *bdev, sector_t sector, - } - EXPORT_SYMBOL_GPL(__dax_zero_page_range); - --/** -- * dax_zero_page_range - zero a range within a page of a DAX file -- * @inode: The file being truncated -- * @from: The file offset that is being truncated to -- * @length: The number of bytes to zero -- * @get_block: The filesystem method used to translate file offsets to blocks -- * -- * This function can be called by a filesystem when it is zeroing part of a -- * page in a DAX file. This is intended for hole-punch operations. If -- * you are truncating a file, the helper function dax_truncate_page() may be -- * more convenient. -- */ --int dax_zero_page_range(struct inode *inode, loff_t from, unsigned length, -- get_block_t get_block) --{ -- struct buffer_head bh; -- pgoff_t index = from >> PAGE_SHIFT; -- unsigned offset = from & (PAGE_SIZE-1); -- int err; -- -- /* Block boundary? Nothing to do */ -- if (!length) -- return 0; -- if (WARN_ON_ONCE((offset + length) > PAGE_SIZE)) -- return -EINVAL; -- -- memset(&bh, 0, sizeof(bh)); -- bh.b_bdev = inode->i_sb->s_bdev; -- bh.b_size = PAGE_SIZE; -- err = get_block(inode, index, &bh, 0); -- if (err < 0 || !buffer_written(&bh)) -- return err; -- -- return __dax_zero_page_range(bh.b_bdev, to_sector(&bh, inode), -- offset, length); --} --EXPORT_SYMBOL_GPL(dax_zero_page_range); -- --/** -- * dax_truncate_page - handle a partial page being truncated in a DAX file -- * @inode: The file being truncated -- * @from: The file offset that is being truncated to -- * @get_block: The filesystem method used to translate file offsets to blocks -- * -- * Similar to block_truncate_page(), this function can be called by a -- * filesystem when it is truncating a DAX file to handle the partial page. -- */ --int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) --{ -- unsigned length = PAGE_ALIGN(from) - from; -- return dax_zero_page_range(inode, from, length, get_block); --} --EXPORT_SYMBOL_GPL(dax_truncate_page); -- - #ifdef CONFIG_FS_IOMAP - static sector_t dax_iomap_sector(struct iomap *iomap, loff_t pos) - { -diff --git a/include/linux/dax.h b/include/linux/dax.h -index 8d1a5c47945f..0afade8bd3d7 100644 ---- a/include/linux/dax.h -+++ b/include/linux/dax.h -@@ -38,13 +38,8 @@ static inline void *dax_radix_locked_entry(sector_t sector, unsigned long flags) - - ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, - struct iomap_ops *ops); --ssize_t dax_do_io(struct kiocb *, struct inode *, struct iov_iter *, -- get_block_t, dio_iodone_t, int flags); --int dax_zero_page_range(struct inode *, loff_t from, unsigned len, get_block_t); --int dax_truncate_page(struct inode *, loff_t from, get_block_t); - int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf, - struct iomap_ops *ops); --int dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t); - int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index); - void dax_wake_mapping_entry_waiter(struct address_space *mapping, - pgoff_t index, void *entry, bool wake_all); -@@ -73,12 +68,6 @@ static inline int __dax_zero_page_range(struct block_device *bdev, - } - #endif - --static inline int dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, -- pmd_t *pmd, unsigned int flags, get_block_t gb) --{ -- return VM_FAULT_FALLBACK; --} -- - #ifdef CONFIG_FS_DAX_PMD - static inline unsigned int dax_radix_order(void *entry) - { -@@ -101,7 +90,6 @@ static inline int dax_iomap_pmd_fault(struct vm_area_struct *vma, - } - #endif - int dax_pfn_mkwrite(struct vm_area_struct *, struct vm_fault *); --#define dax_mkwrite(vma, vmf, gb) dax_fault(vma, vmf, gb) - - static inline bool vma_is_dax(struct vm_area_struct *vma) - { --- -2.6.6 - - diff --git a/disable-pwsalt-ioctl-when-encryption-disabled-by-config b/disable-pwsalt-ioctl-when-encryption-disabled-by-config deleted file mode 100644 index 34f7c4aa..00000000 --- a/disable-pwsalt-ioctl-when-encryption-disabled-by-config +++ /dev/null @@ -1,65 +0,0 @@ -ext4: disable pwsalt ioctl when encryption disabled by config - -From: Eric Biggers - -On a CONFIG_EXT4_FS_ENCRYPTION=n kernel, the ioctls to get and set -encryption policies were disabled but EXT4_IOC_GET_ENCRYPTION_PWSALT was -not. But there's no good reason to expose the pwsalt ioctl if the -kernel doesn't support encryption. The pwsalt ioctl was also disabled -pre-4.8 (via ext4_sb_has_crypto() previously returning 0 when encryption -was disabled by config) and seems to have been enabled by mistake when -ext4 encryption was refactored to use fs/crypto/. So let's disable it -again. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ioctl.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index a0db5d9..a8957d9 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -191,6 +191,7 @@ static long swap_inode_boot_loader(struct super_block *sb, - return err; - } - -+#ifdef CONFIG_EXT4_FS_ENCRYPTION - static int uuid_is_zero(__u8 u[16]) - { - int i; -@@ -200,6 +201,7 @@ static int uuid_is_zero(__u8 u[16]) - return 0; - return 1; - } -+#endif - - static int ext4_ioctl_setflags(struct inode *inode, - unsigned int flags) -@@ -782,6 +784,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - #endif - } - case EXT4_IOC_GET_ENCRYPTION_PWSALT: { -+#ifdef CONFIG_EXT4_FS_ENCRYPTION - int err, err2; - struct ext4_sb_info *sbi = EXT4_SB(sb); - handle_t *handle; -@@ -816,6 +819,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - sbi->s_es->s_encrypt_pw_salt, 16)) - return -EFAULT; - return 0; -+#else -+ return -EOPNOTSUPP; -+#endif - } - case EXT4_IOC_GET_ENCRYPTION_POLICY: { - #ifdef CONFIG_EXT4_FS_ENCRYPTION --- -2.8.0.rc3.226.g39d4020 - --- -To unsubscribe from this list: send the line "unsubscribe linux-ext4" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff --git a/do-not-perform-data-journaling-when-encrypting b/do-not-perform-data-journaling-when-encrypting deleted file mode 100644 index 94d18810..00000000 --- a/do-not-perform-data-journaling-when-encrypting +++ /dev/null @@ -1,95 +0,0 @@ -ext4: do not perform data journaling when data is encrypted - -From: Sergey Karamov - -Currently data journalling is incompatible with encryption: enabling both -at the same time has never been supported by design, and would result in -unpredictable behavior. However, users are not precluded from turning on -both features simultaneously. This change programmatically replaces data -journaling for encrypted regular files with ordered data journaling mode. - -Background: -Journaling encrypted data has not been supported because it operates on -buffer heads of the page in the page cache. Namely, when the commit -happens, which could be up to five seconds after caching, the commit -thread uses the buffer heads attached to the page to copy the contents of -the page to the journal. With encryption, it would have been required to -keep the bounce buffer with ciphertext for up to the aforementioned five -seconds, since the page cache can only hold plaintext and could not be -used for journaling. Alternatively, it would be required to setup the -journal to initiate a callback at the commit time to perform deferred -encryption - in this case, not only would the data have to be written -twice, but it would also have to be encrypted twice. This level of -complexity was not justified for a mode that in practice is very rarely -used because of the overhead from the data journalling. - -Solution: -If data=journaled has been set as a mount option for a filesystem, or if -journaling is enabled on a regular file, do not perform journaling if the -file is also encrypted, instead fall back to the data=ordered mode for the -file. - -Rationale: -The intent is to allow seamless and proper filesystem operation when -journaling and encryption have both been enabled, and have these two -conflicting features gracefully resolved by the filesystem. - -Fixes: 4461471107b7 -Signed-off-by: Sergey Karamov -Signed-off-by: Theodore Ts'o -Cc: stable@vger.kernel.org ---- - fs/ext4/ext4_jbd2.h | 14 ++++++++------ - fs/ext4/super.c | 5 +++++ - 2 files changed, 13 insertions(+), 6 deletions(-) - -diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h -index b1d52c1..f976111 100644 ---- a/fs/ext4/ext4_jbd2.h -+++ b/fs/ext4/ext4_jbd2.h -@@ -414,17 +414,19 @@ static inline int ext4_inode_journal_mode(struct inode *inode) - return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */ - /* We do not support data journalling with delayed allocation */ - if (!S_ISREG(inode->i_mode) || -- test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) -- return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */ -- if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) && -- !test_opt(inode->i_sb, DELALLOC)) -+ test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || -+ (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) && -+ !test_opt(inode->i_sb, DELALLOC))) { -+ /* We do not support data journalling for encrypted data */ -+ if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode)) -+ return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */ - return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */ -+ } - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) - return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */ - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) - return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */ -- else -- BUG(); -+ BUG(); - } - - static inline int ext4_should_journal_data(struct inode *inode) -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 20da99d..18a1722 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3505,6 +3505,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - "both data=journal and dax"); - goto failed_mount; - } -+ if (ext4_has_feature_encrypt(sb)) { -+ ext4_msg(sb, KERN_WARNING, -+ "encrypted files will use data=ordered " -+ "instead of data journaling mode"); -+ } - if (test_opt(sb, DELALLOC)) - clear_opt(sb, DELALLOC); - } else { --- -2.8.0.rc3.226.g39d4020 - - diff --git a/dont-lock-buffer-head-in-ext4_commit_super-if-holding-spinlock b/dont-lock-buffer-head-in-ext4_commit_super-if-holding-spinlock deleted file mode 100644 index eceeac05..00000000 --- a/dont-lock-buffer-head-in-ext4_commit_super-if-holding-spinlock +++ /dev/null @@ -1,63 +0,0 @@ -ext4: don't lock buffer in ext4_commit_super if holding spinlock - -If there is an error reported in mballoc via ext4_grp_locked_error(), -the code is holding a spinlock, so ext4_commit_super() must not try to -lock the buffer head, or else it will trigger a BUG: - - BUG: sleeping function called from invalid context at ./include/linux/buffer_head.h:358 - in_atomic(): 1, irqs_disabled(): 0, pid: 993, name: mount - CPU: 0 PID: 993 Comm: mount Not tainted 4.9.0-rc1-clouder1 #62 - Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.1-0-g4adadbd-20150316_085822-nilsson.home.kraxel.org 04/01/2014 - ffff880006423548 ffffffff81318c89 ffffffff819ecdd0 0000000000000166 - ffff880006423558 ffffffff810810b0 ffff880006423580 ffffffff81081153 - ffff880006e5a1a0 ffff88000690e400 0000000000000000 ffff8800064235c0 - Call Trace: - [] dump_stack+0x67/0x9e - [] ___might_sleep+0xf0/0x140 - [] __might_sleep+0x53/0xb0 - [] ext4_commit_super+0x19c/0x290 - [] __ext4_grp_locked_error+0x14a/0x230 - [] ? __might_sleep+0x53/0xb0 - [] ext4_mb_generate_buddy+0x1de/0x320 - -Since ext4_grp_locked_error() calls ext4_commit_super with sync == 0 -(and it is the only caller which does so), avoid locking and unlocking -the buffer in this case. - -This can result in races with ext4_commit_super() if there are other -problems (which is what commit 4743f83990614 was trying to address), -but a Warning is better than BUG. - -Fixes: 4743f83990614 -Cc: stable@vger.kernel.org # 4.9 -Reported-by: Nikolay Borisov -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/ext4/super.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index e4f61c39328a..ff6f3ab09c7e 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -4537,7 +4537,8 @@ static int ext4_commit_super(struct super_block *sb, int sync) - &EXT4_SB(sb)->s_freeinodes_counter)); - BUFFER_TRACE(sbh, "marking dirty"); - ext4_superblock_csum_set(sb); -- lock_buffer(sbh); -+ if (sync) -+ lock_buffer(sbh); - if (buffer_write_io_error(sbh)) { - /* - * Oh, dear. A previous attempt to write the -@@ -4553,8 +4554,8 @@ static int ext4_commit_super(struct super_block *sb, int sync) - set_buffer_uptodate(sbh); - } - mark_buffer_dirty(sbh); -- unlock_buffer(sbh); - if (sync) { -+ unlock_buffer(sbh); - error = __sync_dirty_buffer(sbh, - test_opt(sb, BARRIER) ? WRITE_FUA : WRITE_SYNC); - if (error) diff --git a/dont-read-out-of-bounds-when-checking-for-in-inode-xattrs b/dont-read-out-of-bounds-when-checking-for-in-inode-xattrs deleted file mode 100644 index 244c1886..00000000 --- a/dont-read-out-of-bounds-when-checking-for-in-inode-xattrs +++ /dev/null @@ -1,55 +0,0 @@ -ext4: don't read out of bounds when checking for in-inode xattrs - -From: Eric Biggers - -With i_extra_isize equal to or close to the available space, it was -possible for us to read past the end of the inode when trying to detect -or validate in-inode xattrs. Fix this by checking for the needed extra -space first. - -This patch shouldn't have any noticeable effect on -non-corrupted/non-malicious filesystems. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Andreas Dilger ---- - fs/ext4/inode.c | 4 +++- - fs/ext4/xattr.c | 5 ++--- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index e3e197898c66..59a518ad6bb2 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -4527,7 +4527,9 @@ static inline void ext4_iget_extra_inode(struct inode *inode, - { - __le32 *magic = (void *)raw_inode + - EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize; -- if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { -+ if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize + sizeof(__le32) <= -+ EXT4_INODE_SIZE(inode->i_sb) && -+ *magic == cpu_to_le32(EXT4_XATTR_MAGIC)) { - ext4_set_inode_state(inode, EXT4_STATE_XATTR); - ext4_find_inline_data_nolock(inode); - } else -diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index 1846e9168f80..59c9ec7eabae 100644 ---- a/fs/ext4/xattr.c -+++ b/fs/ext4/xattr.c -@@ -231,13 +231,12 @@ static int - __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, - void *end, const char *function, unsigned int line) - { -- struct ext4_xattr_entry *entry = IFIRST(header); - int error = -EFSCORRUPTED; - -- if (((void *) header >= end) || -+ if (end - (void *)header < sizeof(*header) + sizeof(u32) || - (header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC))) - goto errout; -- error = ext4_xattr_check_names(entry, end, entry); -+ error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header)); - errout: - if (error) - __ext4_error_inode(inode, function, line, 0, diff --git a/ext2-use-iomap_zero_range-for-zeroing-truncated-page-in-DAX-path b/ext2-use-iomap_zero_range-for-zeroing-truncated-page-in-DAX-path deleted file mode 100644 index efbc8aec..00000000 --- a/ext2-use-iomap_zero_range-for-zeroing-truncated-page-in-DAX-path +++ /dev/null @@ -1,48 +0,0 @@ -ext2: use iomap_zero_range() for zeroing truncated page in DAX path - -From: Jan Kara - -Currently the last user of ext2_get_blocks() for DAX inodes was -dax_truncate_page(). Convert that to iomap_zero_range() so that all DAX -IO uses the iomap path. - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext2/inode.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c -index 41b8b44a391c..046b642f3585 100644 ---- a/fs/ext2/inode.c -+++ b/fs/ext2/inode.c -@@ -850,6 +850,9 @@ struct iomap_ops ext2_iomap_ops = { - .iomap_begin = ext2_iomap_begin, - .iomap_end = ext2_iomap_end, - }; -+#else -+/* Define empty ops for !CONFIG_FS_DAX case to avoid ugly ifdefs */ -+struct iomap_ops ext2_iomap_ops; - #endif /* CONFIG_FS_DAX */ - - int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, -@@ -1293,9 +1296,11 @@ static int ext2_setsize(struct inode *inode, loff_t newsize) - - inode_dio_wait(inode); - -- if (IS_DAX(inode)) -- error = dax_truncate_page(inode, newsize, ext2_get_block); -- else if (test_opt(inode->i_sb, NOBH)) -+ if (IS_DAX(inode)) { -+ error = iomap_zero_range(inode, newsize, -+ PAGE_ALIGN(newsize) - newsize, NULL, -+ &ext2_iomap_ops); -+ } else if (test_opt(inode->i_sb, NOBH)) - error = nobh_truncate_page(inode->i_mapping, - newsize, ext2_get_block); - else --- -2.6.6 - - diff --git a/factor-out-checks-from-ext4_file_write_iter b/factor-out-checks-from-ext4_file_write_iter deleted file mode 100644 index f17aaa10..00000000 --- a/factor-out-checks-from-ext4_file_write_iter +++ /dev/null @@ -1,141 +0,0 @@ -ext4: factor out checks from ext4_file_write_iter() - -From: Jan Kara - -Factor out checks of 'from' and whether we are overwriting out of -ext4_file_write_iter() so that the function is easier to follow. - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/file.c | 97 ++++++++++++++++++++++++++++++---------------------------- - 1 file changed, 50 insertions(+), 47 deletions(-) - -diff --git a/fs/ext4/file.c b/fs/ext4/file.c -index 2a822d30e73f..9facb4dc5c70 100644 ---- a/fs/ext4/file.c -+++ b/fs/ext4/file.c -@@ -88,6 +88,51 @@ ext4_unaligned_aio(struct inode *inode, struct iov_iter *from, loff_t pos) - return 0; - } - -+/* Is IO overwriting allocated and initialized blocks? */ -+static bool ext4_overwrite_io(struct inode *inode, loff_t pos, loff_t len) -+{ -+ struct ext4_map_blocks map; -+ unsigned int blkbits = inode->i_blkbits; -+ int err, blklen; -+ -+ if (pos + len > i_size_read(inode)) -+ return false; -+ -+ map.m_lblk = pos >> blkbits; -+ map.m_len = EXT4_MAX_BLOCKS(len, pos, blkbits); -+ blklen = map.m_len; -+ -+ err = ext4_map_blocks(NULL, inode, &map, 0); -+ /* -+ * 'err==len' means that all of the blocks have been preallocated, -+ * regardless of whether they have been initialized or not. To exclude -+ * unwritten extents, we need to check m_flags. -+ */ -+ return err == blklen && (map.m_flags & EXT4_MAP_MAPPED); -+} -+ -+static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from) -+{ -+ struct inode *inode = file_inode(iocb->ki_filp); -+ ssize_t ret; -+ -+ ret = generic_write_checks(iocb, from); -+ if (ret <= 0) -+ return ret; -+ /* -+ * If we have encountered a bitmap-format file, the size limit -+ * is smaller than s_maxbytes, which is for extent-mapped files. -+ */ -+ if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { -+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -+ -+ if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) -+ return -EFBIG; -+ iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos); -+ } -+ return iov_iter_count(from); -+} -+ - static ssize_t - ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) - { -@@ -98,7 +143,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) - ssize_t ret; - - inode_lock(inode); -- ret = generic_write_checks(iocb, from); -+ ret = ext4_write_checks(iocb, from); - if (ret <= 0) - goto out; - -@@ -114,53 +159,11 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from) - ext4_unwritten_wait(inode); - } - -- /* -- * If we have encountered a bitmap-format file, the size limit -- * is smaller than s_maxbytes, which is for extent-mapped files. -- */ -- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { -- struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -- -- if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) { -- ret = -EFBIG; -- goto out; -- } -- iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos); -- } -- - iocb->private = &overwrite; -- if (o_direct) { -- size_t length = iov_iter_count(from); -- loff_t pos = iocb->ki_pos; -- -- /* check whether we do a DIO overwrite or not */ -- if (ext4_should_dioread_nolock(inode) && !unaligned_aio && -- pos + length <= i_size_read(inode)) { -- struct ext4_map_blocks map; -- unsigned int blkbits = inode->i_blkbits; -- int err, len; -- -- map.m_lblk = pos >> blkbits; -- map.m_len = EXT4_MAX_BLOCKS(length, pos, blkbits); -- len = map.m_len; -- -- err = ext4_map_blocks(NULL, inode, &map, 0); -- /* -- * 'err==len' means that all of blocks has -- * been preallocated no matter they are -- * initialized or not. For excluding -- * unwritten extents, we need to check -- * m_flags. There are two conditions that -- * indicate for initialized extents. 1) If we -- * hit extent cache, EXT4_MAP_MAPPED flag is -- * returned; 2) If we do a real lookup, -- * non-flags are returned. So we should check -- * these two conditions. -- */ -- if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) -- overwrite = 1; -- } -- } -+ /* Check whether we do a DIO overwrite or not */ -+ if (o_direct && ext4_should_dioread_nolock(inode) && !unaligned_aio && -+ ext4_overwrite_io(inode, iocb->ki_pos, iov_iter_count(from))) -+ overwrite = 1; - - ret = __generic_file_write_iter(iocb, from); - inode_unlock(inode); --- -2.6.6 - - diff --git a/fix-block_validity-documentation b/fix-block_validity-documentation deleted file mode 100644 index f089ada6..00000000 --- a/fix-block_validity-documentation +++ /dev/null @@ -1,42 +0,0 @@ -Documentation: fix description of ext4's block_validity mount option - -From: Fabian Frederick - -Fix ext4 documentation according to commit 45f1a9c3f63d -("ext4: enable block_validity by default") - -Also fix some typos. - -[ Further documentation cleanups by tytso ] - -Signed-off-by: Fabian Frederick -Signed-off-by: Theodore Ts'o ---- - Documentation/filesystems/ext4.txt | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt -index 6c0108eb0137..3698ed3146e3 100644 ---- a/Documentation/filesystems/ext4.txt -+++ b/Documentation/filesystems/ext4.txt -@@ -351,14 +351,13 @@ nouid32 Disables 32-bit UIDs and GIDs. This is for - interoperability with older kernels which only - store and expect 16-bit values. - --block_validity This options allows to enables/disables the in-kernel -+block_validity(*) These options enable or disable the in-kernel - noblock_validity facility for tracking filesystem metadata blocks -- within internal data structures. This allows multi- -- block allocator and other routines to quickly locate -- extents which might overlap with filesystem metadata -- blocks. This option is intended for debugging -- purposes and since it negatively affects the -- performance, it is off by default. -+ within internal data structures. This allows multi- -+ block allocator and other routines to notice -+ bugs or corrupted allocation bitmaps which cause -+ blocks to be allocated which overlap with -+ filesystem metadata blocks. - - dioread_lock Controls whether or not ext4 should use the DIO read - dioread_nolock locking. If the dioread_nolock option is specified diff --git a/fix-checks-for-data-ordered-and-journal_async_commit-options b/fix-checks-for-data-ordered-and-journal_async_commit-options deleted file mode 100644 index a81016ab..00000000 --- a/fix-checks-for-data-ordered-and-journal_async_commit-options +++ /dev/null @@ -1,70 +0,0 @@ -ext4: fix checks for data=ordered and journal_async_commit options - -From: Jan Kara - -Combination of data=ordered mode and journal_async_commit mount option -is invalid. However the check in parse_options() fails to detect the -case where we simply end up defaulting to data=ordered mode and we -detect the problem only on remount which triggers hard to understand -failure to remount the filesystem. - -Fix the checking of mount options to take into account also the default -mode by moving the check somewhat later in the mount sequence. - -Reported-by: Wolfgang Walter -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/super.c | 21 +++++++++++++++------ - 1 file changed, 15 insertions(+), 6 deletions(-) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 52b0530c5d65..58017f54a016 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -1883,12 +1883,6 @@ static int parse_options(char *options, struct super_block *sb, - return 0; - } - } -- if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA && -- test_opt(sb, JOURNAL_ASYNC_COMMIT)) { -- ext4_msg(sb, KERN_ERR, "can't mount with journal_async_commit " -- "in data=ordered mode"); -- return 0; -- } - return 1; - } - -@@ -3967,6 +3961,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - default: - break; - } -+ -+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA && -+ test_opt(sb, JOURNAL_ASYNC_COMMIT)) { -+ ext4_msg(sb, KERN_ERR, "can't mount with " -+ "journal_async_commit in data=ordered mode"); -+ goto failed_mount_wq; -+ } -+ - set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); - - sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; -@@ -4857,6 +4859,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) - err = -EINVAL; - goto restore_opts; - } -+ } else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) { -+ if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { -+ ext4_msg(sb, KERN_ERR, "can't mount with " -+ "journal_async_commit in data=ordered mode"); -+ err = -EINVAL; -+ goto restore_opts; -+ } - } - - if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_DAX) { --- -2.6.6 - - diff --git a/fix-inode-checksum-calculation-if-i_extra_size-is-too-small b/fix-inode-checksum-calculation-if-i_extra_size-is-too-small deleted file mode 100644 index 949103bb..00000000 --- a/fix-inode-checksum-calculation-if-i_extra_size-is-too-small +++ /dev/null @@ -1,41 +0,0 @@ -ext4: fix inode checksum calculation problem if i_extra_size is small - -From: Daeho Jeong - -We've fixed the race condition problem in calculating ext4 checksum -value in commit b47820edd163 ("ext4: avoid modifying checksum fields -directly during checksum veficationon"). However, by this change, -when calculating the checksum value of inode whose i_extra_size is -less than 4, we couldn't calculate the checksum value in a proper way. -This problem was found and reported by Nix, Thank you. - -Reported-by: Nix -Signed-off-by: Daeho Jeong -Signed-off-by: Youngjin Gil -Signed-off-by: Darrick J. Wong -Signed-off-by: Theodore Ts'o ---- - fs/ext4/inode.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 9c06472..eaab3c3 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -71,10 +71,9 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, - csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, - csum_size); - offset += csum_size; -- csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, -- EXT4_INODE_SIZE(inode->i_sb) - -- offset); - } -+ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, -+ EXT4_INODE_SIZE(inode->i_sb) - offset); - } - - return csum; --- -1.7.9.5 - - diff --git a/fix-mballoc-breakage-with-64k-block-size b/fix-mballoc-breakage-with-64k-block-size deleted file mode 100644 index b501b7f6..00000000 --- a/fix-mballoc-breakage-with-64k-block-size +++ /dev/null @@ -1,35 +0,0 @@ -ext4: fix mballoc breakage with 64k block size - -From: Chandan Rajendra - -'border' variable is set to a value of 2 times the block size of the -underlying filesystem. With 64k block size, the resulting value won't -fit into a 16-bit variable. Hence this commit changes the data type of -'border' to 'unsigned int'. - -Fixes: c9de560ded61f -Signed-off-by: Chandan Rajendra -Signed-off-by: Theodore Ts'o -Reviewed-by: Andreas Dilger -Cc: stable@vger.kernel.org ---- - fs/ext4/mballoc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index f418f55..a937ac7 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -669,7 +669,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, - ext4_grpblk_t min; - ext4_grpblk_t max; - ext4_grpblk_t chunk; -- unsigned short border; -+ unsigned int border; - - BUG_ON(len > EXT4_CLUSTERS_PER_GROUP(sb)); - --- -2.5.5 - - diff --git a/fix-mmp-use-after-free-during-umount b/fix-mmp-use-after-free-during-umount deleted file mode 100644 index 84da363f..00000000 --- a/fix-mmp-use-after-free-during-umount +++ /dev/null @@ -1,47 +0,0 @@ -ext4: fix mmp use after free during unmount - -From: Eric Sandeen - -In ext4_put_super, we call brelse on the buffer head containing -the ext4 superblock, but then try to use it when we stop the -mmp thread, because when the thread shuts down it does: - -write_mmp_block - ext4_mmp_csum_set - ext4_has_metadata_csum - WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb)...) - -which reaches into sb->s_fs_info->s_es->s_feature_ro_compat, -which lives in the superblock buffer s_sbh which we just released. - -Fix this by moving the brelse down to a point where we are no -longer using it. - -Reported-by: Wang Shu -Signed-off-by: Eric Sandeen -Signed-off-by: Theodore Ts'o -Reviewed-by: Andreas Dilger ---- - fs/ext4/super.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index bb3a8edc75db..a526956e49e7 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -863,7 +863,6 @@ static void ext4_put_super(struct super_block *sb) - percpu_counter_destroy(&sbi->s_dirs_counter); - percpu_counter_destroy(&sbi->s_dirtyclusters_counter); - percpu_free_rwsem(&sbi->s_journal_flag_rwsem); -- brelse(sbi->s_sbh); - #ifdef CONFIG_QUOTA - for (i = 0; i < EXT4_MAXQUOTAS; i++) - kfree(sbi->s_qf_names[i]); -@@ -895,6 +894,7 @@ static void ext4_put_super(struct super_block *sb) - } - if (sbi->s_mmp_tsk) - kthread_stop(sbi->s_mmp_tsk); -+ brelse(sbi->s_sbh); - sb->s_fs_info = NULL; - /* - * Now that we are completely done shutting down the diff --git a/fix-reading-new-encrypted-symlinks-on-no-journal-file-systems b/fix-reading-new-encrypted-symlinks-on-no-journal-file-systems deleted file mode 100644 index 5fc13fc2..00000000 --- a/fix-reading-new-encrypted-symlinks-on-no-journal-file-systems +++ /dev/null @@ -1,34 +0,0 @@ -ext4: fix reading new encrypted symlinks on no-journal file systems - -On a filesystem with no journal, a symlink longer than about 32 -characters (exact length depending on padding for encryption) could not -be followed or read immediately after being created in an encrypted -directory. This happened because when the symlink data went through the -delayed allocation path instead of the journaling path, the symlink was -incorrectly detected as a "fast" symlink rather than a "slow" symlink -until its data was written out. - -To fix this, disable delayed allocation for symlinks, since there is -no benefit for delayed allocation anyway. - -Reported-by: Eric Biggers -Signed-off-by: Theodore Ts'o - ---- - fs/ext4/inode.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 59a518ad6bb2..a1eac0054203 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -2902,7 +2902,8 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, - - index = pos >> PAGE_SHIFT; - -- if (ext4_nonda_switch(inode->i_sb)) { -+ if (ext4_nonda_switch(inode->i_sb) || -+ S_ISLNK(inode->i_mode)) { - *fsdata = (void *)FALL_BACK_TO_NONDELALLOC; - return ext4_write_begin(file, mapping, pos, - len, flags, pagep, fsdata); diff --git a/fix-sb-mount-options-processing b/fix-sb-mount-options-processing deleted file mode 100644 index 46112817..00000000 --- a/fix-sb-mount-options-processing +++ /dev/null @@ -1,99 +0,0 @@ -ext4: fix in-superblock mount options processing - -Fix a large number of problems with how we handle mount options in the -superblock. For one, if the string in the superblock is long enough -that it is not null terminated, we could run off the end of the string -and try to interpret superblocks fields as characters. It's unlikely -this will cause a security problem, but it could result in an invalid -parse. Also, parse_options is destructive to the string, so in some -cases if there is a comma-separated string, it would be modified in -the superblock. (Fortunately it only happens on file systems with a -1k block size.) - -Signed-off-by: Theodore Ts'o -Cc: stable@vger.kernel.org ---- - fs/ext4/super.c | 38 +++++++++++++++++++++++--------------- - 1 file changed, 23 insertions(+), 15 deletions(-) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 0f9ae4ce33d6..404e6f3c1bed 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3303,7 +3303,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - char *orig_data = kstrdup(data, GFP_KERNEL); - struct buffer_head *bh; - struct ext4_super_block *es = NULL; -- struct ext4_sb_info *sbi; -+ struct ext4_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); - ext4_fsblk_t block; - ext4_fsblk_t sb_block = get_sb_block(&data); - ext4_fsblk_t logical_sb_block; -@@ -3322,16 +3322,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; - ext4_group_t first_not_zeroed; - -- sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); -- if (!sbi) -- goto out_free_orig; -+ if ((data && !orig_data) || !sbi) -+ goto out_free_base; - - sbi->s_blockgroup_lock = - kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); -- if (!sbi->s_blockgroup_lock) { -- kfree(sbi); -- goto out_free_orig; -- } -+ if (!sbi->s_blockgroup_lock) -+ goto out_free_base; -+ - sb->s_fs_info = sbi; - sbi->s_sb = sb; - sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS; -@@ -3477,11 +3475,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - */ - sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT; - -- if (!parse_options((char *) sbi->s_es->s_mount_opts, sb, -- &journal_devnum, &journal_ioprio, 0)) { -- ext4_msg(sb, KERN_WARNING, -- "failed to parse options in superblock: %s", -- sbi->s_es->s_mount_opts); -+ if (sbi->s_es->s_mount_opts[0]) { -+ char *s_mount_opts = kstrndup(sbi->s_es->s_mount_opts, -+ sizeof(sbi->s_es->s_mount_opts), -+ GFP_KERNEL); -+ if (!s_mount_opts) -+ goto failed_mount; -+ if (!parse_options(s_mount_opts, sb, &journal_devnum, -+ &journal_ioprio, 0)) { -+ ext4_msg(sb, KERN_WARNING, -+ "failed to parse options in superblock: %s", -+ s_mount_opts); -+ } -+ kfree(s_mount_opts); - } - sbi->s_def_mount_opt = sbi->s_mount_opt; - if (!parse_options((char *) data, sb, &journal_devnum, -@@ -4162,7 +4168,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - - if (___ratelimit(&ext4_mount_msg_ratelimit, "EXT4-fs mount")) - ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. " -- "Opts: %s%s%s", descr, sbi->s_es->s_mount_opts, -+ "Opts: %.*s%s%s", descr, -+ (int) sizeof(sbi->s_es->s_mount_opts), -+ sbi->s_es->s_mount_opts, - *sbi->s_es->s_mount_opts ? "; " : "", orig_data); - - if (es->s_error_count) -@@ -4241,8 +4249,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - out_fail: - sb->s_fs_info = NULL; - kfree(sbi->s_blockgroup_lock); -+out_free_base: - kfree(sbi); --out_free_orig: - kfree(orig_data); - return err ? err : ret; - } diff --git a/fix-sleep-in-atomic-context-in-grab_mapping_entry b/fix-sleep-in-atomic-context-in-grab_mapping_entry deleted file mode 100644 index 55a96c41..00000000 --- a/fix-sleep-in-atomic-context-in-grab_mapping_entry +++ /dev/null @@ -1,55 +0,0 @@ -dax: Fix sleep in atomic contex in grab_mapping_entry() - -From: Jan Kara - -Commit 642261ac995e: "dax: add struct iomap based DAX PMD support" has -introduced unmapping of page tables if huge page needs to be split in -grab_mapping_entry(). However the unmapping happens after -radix_tree_preload() call which disables preemption and thus -unmap_mapping_range() tries to acquire i_mmap_lock in atomic context -which is a bug. Fix the problem by moving unmapping before -radix_tree_preload() call. - -Fixes: 642261ac995e01d7837db1f4b90181496f7e6835 -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/dax.c | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - -diff --git a/fs/dax.c b/fs/dax.c -index 51b03e91d3e2..5c74f60d0a50 100644 ---- a/fs/dax.c -+++ b/fs/dax.c -@@ -351,14 +351,6 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, - } - - spin_unlock_irq(&mapping->tree_lock); -- err = radix_tree_preload( -- mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM); -- if (err) { -- if (pmd_downgrade) -- put_locked_mapping_entry(mapping, index, entry); -- return ERR_PTR(err); -- } -- - /* - * Besides huge zero pages the only other thing that gets - * downgraded are empty entries which don't need to be -@@ -368,6 +360,13 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, - unmap_mapping_range(mapping, - (index << PAGE_SHIFT) & PMD_MASK, PMD_SIZE, 0); - -+ err = radix_tree_preload( -+ mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM); -+ if (err) { -+ if (pmd_downgrade) -+ put_locked_mapping_entry(mapping, index, entry); -+ return ERR_PTR(err); -+ } - spin_lock_irq(&mapping->tree_lock); - - if (pmd_downgrade) { --- -2.10.2 - diff --git a/fix-stack-corruption-with-64k-blocksize b/fix-stack-corruption-with-64k-blocksize deleted file mode 100644 index 961db43e..00000000 --- a/fix-stack-corruption-with-64k-blocksize +++ /dev/null @@ -1,39 +0,0 @@ -ext4: fix stack memory corruption with 64k block size - -From: Chandan Rajendra - -The number of 'counters' elements needed in 'struct sg' is -super_block->s_blocksize_bits + 2. Presently we have 16 'counters' -elements in the array. This is insufficient for block sizes >= 32k. In -such cases the memcpy operation performed in ext4_mb_seq_groups_show() -would cause stack memory corruption. - -Fixes: c9de560ded61f -Signed-off-by: Chandan Rajendra -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara -Cc: stable@vger.kernel.org ---- -Changelog: -v1->v2: Use EXT4_MAX_BLOCK_LOG_SIZE instead of the integer constant 16. - - fs/ext4/mballoc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index a937ac7..7ae43c5 100644 ---- a/fs/ext4/mballoc.c -+++ b/fs/ext4/mballoc.c -@@ -2287,7 +2287,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) - struct ext4_group_info *grinfo; - struct sg { - struct ext4_group_info info; -- ext4_grpblk_t counters[16]; -+ ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2]; - } sg; - - group--; --- -2.5.5 - - diff --git a/forbid-i_extra_isize-not-divisible-by-4 b/forbid-i_extra_isize-not-divisible-by-4 deleted file mode 100644 index 9f94a02a..00000000 --- a/forbid-i_extra_isize-not-divisible-by-4 +++ /dev/null @@ -1,65 +0,0 @@ -ext4: forbid i_extra_isize not divisible by 4 - -From: Eric Biggers - -i_extra_isize not divisible by 4 is problematic for several reasons: - -- It causes the in-inode xattr space to be misaligned, but the xattr - header and entries are not declared __packed to express this - possibility. This may cause poor performance or incorrect code - generation on some platforms. -- When validating the xattr entries we can read past the end of the - inode if the size available for xattrs is not a multiple of 4. -- It allows the nonsensical i_extra_isize=1, which doesn't even leave - enough room for i_extra_isize itself. - -Therefore, update ext4_iget() to consider i_extra_isize not divisible by -4 to be an error, like the case where i_extra_isize is too large. - -This also matches the rule recently added to e2fsck for determining -whether an inode has valid i_extra_isize. - -This patch shouldn't have any noticeable effect on -non-corrupted/non-malicious filesystems, since the size of ext4_inode -has always been a multiple of 4. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Andreas Dilger ---- - fs/ext4/inode.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 861f848..bc99ebe 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -4564,10 +4564,12 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) - if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { - ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); - if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > -- EXT4_INODE_SIZE(inode->i_sb)) { -- EXT4_ERROR_INODE(inode, "bad extra_isize (%u != %u)", -- EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize, -- EXT4_INODE_SIZE(inode->i_sb)); -+ EXT4_INODE_SIZE(inode->i_sb) || -+ (ei->i_extra_isize & 3)) { -+ EXT4_ERROR_INODE(inode, -+ "bad extra_isize %u (inode size %u)", -+ ei->i_extra_isize, -+ EXT4_INODE_SIZE(inode->i_sb)); - ret = -EFSCORRUPTED; - goto bad_inode; - } -@@ -4685,6 +4687,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) - if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { - if (ei->i_extra_isize == 0) { - /* The extra space is currently unused. Use it. */ -+ BUILD_BUG_ON(sizeof(struct ext4_inode) & 3); - ei->i_extra_isize = sizeof(struct ext4_inode) - - EXT4_GOOD_OLD_INODE_SIZE; - } else { --- -2.8.0.rc3.226.g39d4020 - - diff --git a/fscrypt-move-constants-to-uapi-header b/fscrypt-move-constants-to-uapi-header deleted file mode 100644 index 3b09f46d..00000000 --- a/fscrypt-move-constants-to-uapi-header +++ /dev/null @@ -1,62 +0,0 @@ -fscrypt: move the policy flags and encryption mode definitions to uapi header - -These constants are part of the UAPI, so they belong in -include/uapi/linux/fs.h instead of include/linux/fscrypto.h - -Signed-off-by: Theodore Ts'o -Reviewed-by: Eric Biggers ---- - include/linux/fscrypto.h | 14 -------------- - include/uapi/linux/fs.h | 14 ++++++++++++++ - 2 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h -index 71e8a20711ec..42ef82d60790 100644 ---- a/include/linux/fscrypto.h -+++ b/include/linux/fscrypto.h -@@ -18,20 +18,6 @@ - #include - #include - --#define FS_POLICY_FLAGS_PAD_4 0x00 --#define FS_POLICY_FLAGS_PAD_8 0x01 --#define FS_POLICY_FLAGS_PAD_16 0x02 --#define FS_POLICY_FLAGS_PAD_32 0x03 --#define FS_POLICY_FLAGS_PAD_MASK 0x03 --#define FS_POLICY_FLAGS_VALID 0x03 -- --/* Encryption algorithms */ --#define FS_ENCRYPTION_MODE_INVALID 0 --#define FS_ENCRYPTION_MODE_AES_256_XTS 1 --#define FS_ENCRYPTION_MODE_AES_256_GCM 2 --#define FS_ENCRYPTION_MODE_AES_256_CBC 3 --#define FS_ENCRYPTION_MODE_AES_256_CTS 4 -- - #define FS_CRYPTO_BLOCK_SIZE 16 - - struct fscrypt_info; -diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h -index acb2b6152ba0..0496d37abe28 100644 ---- a/include/uapi/linux/fs.h -+++ b/include/uapi/linux/fs.h -@@ -254,6 +254,20 @@ struct fsxattr { - /* Policy provided via an ioctl on the topmost directory */ - #define FS_KEY_DESCRIPTOR_SIZE 8 - -+#define FS_POLICY_FLAGS_PAD_4 0x00 -+#define FS_POLICY_FLAGS_PAD_8 0x01 -+#define FS_POLICY_FLAGS_PAD_16 0x02 -+#define FS_POLICY_FLAGS_PAD_32 0x03 -+#define FS_POLICY_FLAGS_PAD_MASK 0x03 -+#define FS_POLICY_FLAGS_VALID 0x03 -+ -+/* Encryption algorithms */ -+#define FS_ENCRYPTION_MODE_INVALID 0 -+#define FS_ENCRYPTION_MODE_AES_256_XTS 1 -+#define FS_ENCRYPTION_MODE_AES_256_GCM 2 -+#define FS_ENCRYPTION_MODE_AES_256_CBC 3 -+#define FS_ENCRYPTION_MODE_AES_256_CTS 4 -+ - struct fscrypt_policy { - __u8 version; - __u8 contents_encryption_mode; diff --git a/fscrypt-move-ioctl-processing-more-fully-into-common-code b/fscrypt-move-ioctl-processing-more-fully-into-common-code deleted file mode 100644 index 8bdb73dd..00000000 --- a/fscrypt-move-ioctl-processing-more-fully-into-common-code +++ /dev/null @@ -1,260 +0,0 @@ -fscrypto: move ioctl processing more fully into common code - -From: Eric Biggers - -Multiple bugs were recently fixed in the "set encryption policy" ioctl. -To make it clear that fscrypt_process_policy() and fscrypt_get_policy() -implement ioctls and therefore their implementations must take standard -security and correctness precautions, rename them to -fscrypt_ioctl_set_policy() and fscrypt_ioctl_get_policy(). Make the -latter take in a struct file * to make it consistent with the former. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o ---- - fs/crypto/policy.c | 34 +++++++++++++++++++++------------- - fs/ext4/ext4.h | 4 ++-- - fs/ext4/ioctl.c | 34 +++++----------------------------- - fs/f2fs/f2fs.h | 4 ++-- - fs/f2fs/file.c | 19 ++----------------- - include/linux/fscrypto.h | 12 ++++++------ - 6 files changed, 38 insertions(+), 69 deletions(-) - -diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c -index 6865663aac69..b96a10e3cf78 100644 ---- a/fs/crypto/policy.c -+++ b/fs/crypto/policy.c -@@ -93,16 +93,19 @@ static int create_encryption_context_from_policy(struct inode *inode, - return inode->i_sb->s_cop->set_context(inode, &ctx, sizeof(ctx), NULL); - } - --int fscrypt_process_policy(struct file *filp, -- const struct fscrypt_policy *policy) -+int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg) - { -+ struct fscrypt_policy policy; - struct inode *inode = file_inode(filp); - int ret; - -+ if (copy_from_user(&policy, arg, sizeof(policy))) -+ return -EFAULT; -+ - if (!inode_owner_or_capable(inode)) - return -EACCES; - -- if (policy->version != 0) -+ if (policy.version != 0) - return -EINVAL; - - ret = mnt_want_write_file(filp); -@@ -120,9 +123,9 @@ int fscrypt_process_policy(struct file *filp, - ret = -ENOTEMPTY; - else - ret = create_encryption_context_from_policy(inode, -- policy); -+ &policy); - } else if (!is_encryption_context_consistent_with_policy(inode, -- policy)) { -+ &policy)) { - printk(KERN_WARNING - "%s: Policy inconsistent with encryption context\n", - __func__); -@@ -134,11 +137,13 @@ int fscrypt_process_policy(struct file *filp, - mnt_drop_write_file(filp); - return ret; - } --EXPORT_SYMBOL(fscrypt_process_policy); -+EXPORT_SYMBOL(fscrypt_ioctl_set_policy); - --int fscrypt_get_policy(struct inode *inode, struct fscrypt_policy *policy) -+int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg) - { -+ struct inode *inode = file_inode(filp); - struct fscrypt_context ctx; -+ struct fscrypt_policy policy; - int res; - - if (!inode->i_sb->s_cop->get_context || -@@ -151,15 +156,18 @@ int fscrypt_get_policy(struct inode *inode, struct fscrypt_policy *policy) - if (ctx.format != FS_ENCRYPTION_CONTEXT_FORMAT_V1) - return -EINVAL; - -- policy->version = 0; -- policy->contents_encryption_mode = ctx.contents_encryption_mode; -- policy->filenames_encryption_mode = ctx.filenames_encryption_mode; -- policy->flags = ctx.flags; -- memcpy(&policy->master_key_descriptor, ctx.master_key_descriptor, -+ policy.version = 0; -+ policy.contents_encryption_mode = ctx.contents_encryption_mode; -+ policy.filenames_encryption_mode = ctx.filenames_encryption_mode; -+ policy.flags = ctx.flags; -+ memcpy(policy.master_key_descriptor, ctx.master_key_descriptor, - FS_KEY_DESCRIPTOR_SIZE); -+ -+ if (copy_to_user(arg, &policy, sizeof(policy))) -+ return -EFAULT; - return 0; - } --EXPORT_SYMBOL(fscrypt_get_policy); -+EXPORT_SYMBOL(fscrypt_ioctl_get_policy); - - int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) - { -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index aff204f040fc..f36bf98ef897 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -2333,8 +2333,8 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname) { } - #define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page - #define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page - #define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range --#define fscrypt_process_policy fscrypt_notsupp_process_policy --#define fscrypt_get_policy fscrypt_notsupp_get_policy -+#define fscrypt_ioctl_set_policy fscrypt_notsupp_ioctl_set_policy -+#define fscrypt_ioctl_get_policy fscrypt_notsupp_ioctl_get_policy - #define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context - #define fscrypt_inherit_context fscrypt_notsupp_inherit_context - #define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index fc1cd37ba2d9..46c38d0f18ea 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -768,22 +768,12 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - } - case EXT4_IOC_PRECACHE_EXTENTS: - return ext4_ext_precache(inode); -- case EXT4_IOC_SET_ENCRYPTION_POLICY: { --#ifdef CONFIG_EXT4_FS_ENCRYPTION -- struct fscrypt_policy policy; - -+ case EXT4_IOC_SET_ENCRYPTION_POLICY: - if (!ext4_has_feature_encrypt(sb)) - return -EOPNOTSUPP; -+ return fscrypt_ioctl_set_policy(filp, (const void __user *)arg); - -- if (copy_from_user(&policy, -- (struct fscrypt_policy __user *)arg, -- sizeof(policy))) -- return -EFAULT; -- return fscrypt_process_policy(filp, &policy); --#else -- return -EOPNOTSUPP; --#endif -- } - case EXT4_IOC_GET_ENCRYPTION_PWSALT: { - int err, err2; - struct ext4_sb_info *sbi = EXT4_SB(sb); -@@ -820,23 +810,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - return -EFAULT; - return 0; - } -- case EXT4_IOC_GET_ENCRYPTION_POLICY: { --#ifdef CONFIG_EXT4_FS_ENCRYPTION -- struct fscrypt_policy policy; -- int err = 0; -- -- if (!ext4_encrypted_inode(inode)) -- return -ENOENT; -- err = fscrypt_get_policy(inode, &policy); -- if (err) -- return err; -- if (copy_to_user((void __user *)arg, &policy, sizeof(policy))) -- return -EFAULT; -- return 0; --#else -- return -EOPNOTSUPP; --#endif -- } -+ case EXT4_IOC_GET_ENCRYPTION_POLICY: -+ return fscrypt_ioctl_get_policy(filp, (void __user *)arg); -+ - case EXT4_IOC_FSGETXATTR: - { - struct fsxattr fa; -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 9e8de18a168a..8e94b7bda42b 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -2453,8 +2453,8 @@ static inline bool f2fs_may_encrypt(struct inode *inode) - #define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page - #define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page - #define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range --#define fscrypt_process_policy fscrypt_notsupp_process_policy --#define fscrypt_get_policy fscrypt_notsupp_get_policy -+#define fscrypt_ioctl_set_policy fscrypt_notsupp_ioctl_set_policy -+#define fscrypt_ioctl_get_policy fscrypt_notsupp_ioctl_get_policy - #define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context - #define fscrypt_inherit_context fscrypt_notsupp_inherit_context - #define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index c7865073cd26..f0c83f74557d 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -1752,31 +1752,16 @@ static bool uuid_is_nonzero(__u8 u[16]) - - static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg) - { -- struct fscrypt_policy policy; - struct inode *inode = file_inode(filp); - -- if (copy_from_user(&policy, (struct fscrypt_policy __user *)arg, -- sizeof(policy))) -- return -EFAULT; -- - f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); - -- return fscrypt_process_policy(filp, &policy); -+ return fscrypt_ioctl_set_policy(filp, (const void __user *)arg); - } - - static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg) - { -- struct fscrypt_policy policy; -- struct inode *inode = file_inode(filp); -- int err; -- -- err = fscrypt_get_policy(inode, &policy); -- if (err) -- return err; -- -- if (copy_to_user((struct fscrypt_policy __user *)arg, &policy, sizeof(policy))) -- return -EFAULT; -- return 0; -+ return fscrypt_ioctl_get_policy(filp, (void __user *)arg); - } - - static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg) -diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h -index 98c71e973a96..be94684dc05f 100644 ---- a/include/linux/fscrypto.h -+++ b/include/linux/fscrypto.h -@@ -259,8 +259,8 @@ extern void fscrypt_restore_control_page(struct page *); - extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t, - unsigned int); - /* policy.c */ --extern int fscrypt_process_policy(struct file *, const struct fscrypt_policy *); --extern int fscrypt_get_policy(struct inode *, struct fscrypt_policy *); -+extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); -+extern int fscrypt_ioctl_get_policy(struct file *, void __user *); - extern int fscrypt_has_permitted_context(struct inode *, struct inode *); - extern int fscrypt_inherit_context(struct inode *, struct inode *, - void *, bool); -@@ -334,14 +334,14 @@ static inline int fscrypt_notsupp_zeroout_range(const struct inode *i, pgoff_t p - } - - /* policy.c */ --static inline int fscrypt_notsupp_process_policy(struct file *f, -- const struct fscrypt_policy *p) -+static inline int fscrypt_notsupp_ioctl_set_policy(struct file *f, -+ const void __user *arg) - { - return -EOPNOTSUPP; - } - --static inline int fscrypt_notsupp_get_policy(struct inode *i, -- struct fscrypt_policy *p) -+static inline int fscrypt_notsupp_ioctl_get_policy(struct file *f, -+ void __user *arg) - { - return -EOPNOTSUPP; - } diff --git a/fscrypt-move-non-public-structures-to-private-header b/fscrypt-move-non-public-structures-to-private-header deleted file mode 100644 index e8c63b62..00000000 --- a/fscrypt-move-non-public-structures-to-private-header +++ /dev/null @@ -1,214 +0,0 @@ -fscrypt: move non-public structures and constants to fscrypt_private.h - -Signed-off-by: Theodore Ts'o -Reviewed-by: Eric Biggers ---- - fs/crypto/crypto.c | 2 +- - fs/crypto/fscrypt_private.h | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - fs/crypto/policy.c | 2 +- - include/linux/fscrypto.h | 68 +++--------------------------------------------------- - 4 files changed, 76 insertions(+), 67 deletions(-) - -diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c -index 56f98f45cece..4d9d221b1d60 100644 ---- a/fs/crypto/crypto.c -+++ b/fs/crypto/crypto.c -@@ -27,7 +27,7 @@ - #include - #include - #include --#include -+#include "fscrypt_private.h" - - static unsigned int num_prealloc_crypto_pages = 32; - static unsigned int num_prealloc_crypto_ctxs = 128; -diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h -index bb92f0c0961b..c98b2a7fb6d3 100644 ---- a/fs/crypto/fscrypt_private.h -+++ b/fs/crypto/fscrypt_private.h -@@ -13,6 +13,77 @@ - - #include - -+#define FS_FNAME_CRYPTO_DIGEST_SIZE 32 -+ -+/* Encryption parameters */ -+#define FS_XTS_TWEAK_SIZE 16 -+#define FS_AES_128_ECB_KEY_SIZE 16 -+#define FS_AES_256_GCM_KEY_SIZE 32 -+#define FS_AES_256_CBC_KEY_SIZE 32 -+#define FS_AES_256_CTS_KEY_SIZE 32 -+#define FS_AES_256_XTS_KEY_SIZE 64 -+#define FS_MAX_KEY_SIZE 64 -+ -+#define FS_KEY_DESC_PREFIX "fscrypt:" -+#define FS_KEY_DESC_PREFIX_SIZE 8 -+ -+#define FS_KEY_DERIVATION_NONCE_SIZE 16 -+ -+/** -+ * Encryption context for inode -+ * -+ * Protector format: -+ * 1 byte: Protector format (1 = this version) -+ * 1 byte: File contents encryption mode -+ * 1 byte: File names encryption mode -+ * 1 byte: Flags -+ * 8 bytes: Master Key descriptor -+ * 16 bytes: Encryption Key derivation nonce -+ */ -+struct fscrypt_context { -+ u8 format; -+ u8 contents_encryption_mode; -+ u8 filenames_encryption_mode; -+ u8 flags; -+ u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; -+ u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; -+} __packed; -+ -+#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1 -+ -+/* This is passed in from userspace into the kernel keyring */ -+struct fscrypt_key { -+ u32 mode; -+ u8 raw[FS_MAX_KEY_SIZE]; -+ u32 size; -+} __packed; -+ -+/* -+ * A pointer to this structure is stored in the file system's in-core -+ * representation of an inode. -+ */ -+struct fscrypt_info { -+ u8 ci_data_mode; -+ u8 ci_filename_mode; -+ u8 ci_flags; -+ struct crypto_skcipher *ci_ctfm; -+ struct key *ci_keyring_key; -+ u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE]; -+}; -+ -+#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001 -+#define FS_WRITE_PATH_FL 0x00000002 -+ -+struct fscrypt_completion_result { -+ struct completion completion; -+ int res; -+}; -+ -+#define DECLARE_FS_COMPLETION_RESULT(ecr) \ -+ struct fscrypt_completion_result ecr = { \ -+ COMPLETION_INITIALIZER((ecr).completion), 0 } -+ -+ - /* crypto.c */ - int fscrypt_initialize(void); - -diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c -index b96a10e3cf78..6ed7c2eebeec 100644 ---- a/fs/crypto/policy.c -+++ b/fs/crypto/policy.c -@@ -10,8 +10,8 @@ - - #include - #include --#include - #include -+#include "fscrypt_private.h" - - static int inode_has_encryption_context(struct inode *inode) - { -diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h -index ce2ebdee6a89..71e8a20711ec 100644 ---- a/include/linux/fscrypto.h -+++ b/include/linux/fscrypto.h -@@ -18,9 +18,6 @@ - #include - #include - --#define FS_KEY_DERIVATION_NONCE_SIZE 16 --#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1 -- - #define FS_POLICY_FLAGS_PAD_4 0x00 - #define FS_POLICY_FLAGS_PAD_8 0x01 - #define FS_POLICY_FLAGS_PAD_16 0x02 -@@ -35,56 +32,10 @@ - #define FS_ENCRYPTION_MODE_AES_256_CBC 3 - #define FS_ENCRYPTION_MODE_AES_256_CTS 4 - --/** -- * Encryption context for inode -- * -- * Protector format: -- * 1 byte: Protector format (1 = this version) -- * 1 byte: File contents encryption mode -- * 1 byte: File names encryption mode -- * 1 byte: Flags -- * 8 bytes: Master Key descriptor -- * 16 bytes: Encryption Key derivation nonce -- */ --struct fscrypt_context { -- u8 format; -- u8 contents_encryption_mode; -- u8 filenames_encryption_mode; -- u8 flags; -- u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE]; -- u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE]; --} __packed; -- --/* Encryption parameters */ --#define FS_XTS_TWEAK_SIZE 16 --#define FS_AES_128_ECB_KEY_SIZE 16 --#define FS_AES_256_GCM_KEY_SIZE 32 --#define FS_AES_256_CBC_KEY_SIZE 32 --#define FS_AES_256_CTS_KEY_SIZE 32 --#define FS_AES_256_XTS_KEY_SIZE 64 --#define FS_MAX_KEY_SIZE 64 -- --#define FS_KEY_DESC_PREFIX "fscrypt:" --#define FS_KEY_DESC_PREFIX_SIZE 8 -- --/* This is passed in from userspace into the kernel keyring */ --struct fscrypt_key { -- u32 mode; -- u8 raw[FS_MAX_KEY_SIZE]; -- u32 size; --} __packed; -- --struct fscrypt_info { -- u8 ci_data_mode; -- u8 ci_filename_mode; -- u8 ci_flags; -- struct crypto_skcipher *ci_ctfm; -- struct key *ci_keyring_key; -- u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE]; --}; -+#define FS_CRYPTO_BLOCK_SIZE 16 - --#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001 --#define FS_WRITE_PATH_FL 0x00000002 -+struct fscrypt_info; -+struct fscrypt_ctx; - - struct fscrypt_ctx { - union { -@@ -102,19 +53,6 @@ struct fscrypt_ctx { - u8 mode; /* Encryption mode for tfm */ - }; - --struct fscrypt_completion_result { -- struct completion completion; -- int res; --}; -- --#define DECLARE_FS_COMPLETION_RESULT(ecr) \ -- struct fscrypt_completion_result ecr = { \ -- COMPLETION_INITIALIZER((ecr).completion), 0 } -- --#define FS_FNAME_NUM_SCATTER_ENTRIES 4 --#define FS_CRYPTO_BLOCK_SIZE 16 --#define FS_FNAME_CRYPTO_DIGEST_SIZE 32 -- - /** - * For encrypted symlinks, the ciphertext length is stored at the beginning - * of the string in little-endian format. diff --git a/fscrypt-recommend-linux-fsdevel-for-fscrypto-patches b/fscrypt-recommend-linux-fsdevel-for-fscrypto-patches deleted file mode 100644 index 36b879b8..00000000 --- a/fscrypt-recommend-linux-fsdevel-for-fscrypto-patches +++ /dev/null @@ -1,33 +0,0 @@ -MAINTAINERS: fscrypto: recommend linux-fsdevel for fscrypto patches - -From: Eric Biggers - -The filesystem level encryption support, currently used by ext4 and f2fs -and proposed for ubifs, does not yet have a dedicated mailing list. -Since no mailing lists were specified in MAINTAINERS, get_maintainer.pl -only recommended to send patches directly to the maintainers and to -linux-kernel. This patch adds linux-fsdevel as the preferred mailing -list for fscrypto patches for the time being. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o ---- - MAINTAINERS | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/MAINTAINERS b/MAINTAINERS -index ea4fbc9..d3ce20e 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -5123,6 +5123,7 @@ F: include/linux/fscache*.h - FS-CRYPTO: FILE SYSTEM LEVEL ENCRYPTION SUPPORT - M: Theodore Y. Ts'o - M: Jaegeuk Kim -+L: linux-fsdevel@vger.kernel.org - S: Supported - F: fs/crypto/ - F: include/linux/fscrypto.h --- -2.8.0.rc3.226.g39d4020 - - diff --git a/fscrypt-remove-unneeded-Kconfig-dependencies b/fscrypt-remove-unneeded-Kconfig-dependencies deleted file mode 100644 index a38d3886..00000000 --- a/fscrypt-remove-unneeded-Kconfig-dependencies +++ /dev/null @@ -1,35 +0,0 @@ -fscrypto: remove unneeded Kconfig dependencies - -From: Eric Biggers - -SHA256 and ENCRYPTED_KEYS are not needed. CTR shouldn't be needed -either, but I left it for now because it was intentionally added by -commit 71dea01ea2ed ("ext4 crypto: require CONFIG_CRYPTO_CTR if ext4 -encryption is enabled"). So it sounds like there may be a dependency -problem elsewhere, which I have not been able to identify specifically, -that must be solved before CTR can be removed. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o ---- - fs/crypto/Kconfig | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig -index 92348fa..f514978 100644 ---- a/fs/crypto/Kconfig -+++ b/fs/crypto/Kconfig -@@ -8,9 +8,7 @@ config FS_ENCRYPTION - select CRYPTO_XTS - select CRYPTO_CTS - select CRYPTO_CTR -- select CRYPTO_SHA256 - select KEYS -- select ENCRYPTED_KEYS - help - Enable encryption of files and directories. This - feature is similar to ecryptfs, but it is more memory --- -2.8.0.rc3.226.g39d4020 - - diff --git a/fscrypt-unexport-fscrypt_initialize b/fscrypt-unexport-fscrypt_initialize deleted file mode 100644 index a30c4b89..00000000 --- a/fscrypt-unexport-fscrypt_initialize +++ /dev/null @@ -1,51 +0,0 @@ -fscrypt: unexport fscrypt_initialize() - -The fscrypt_initalize() function isn't used outside fs/crypto, so -there's no point making it be an exported symbol. - -Signed-off-by: Theodore Ts'o -Reviewed-by: Eric Biggers ---- - fs/crypto/crypto.c | 1 - - fs/crypto/fscrypt_private.h | 3 +++ - include/linux/fscrypto.h | 1 - - 3 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c -index b6029785714c..56f98f45cece 100644 ---- a/fs/crypto/crypto.c -+++ b/fs/crypto/crypto.c -@@ -540,7 +540,6 @@ int fscrypt_initialize(void) - mutex_unlock(&fscrypt_init_mutex); - return res; - } --EXPORT_SYMBOL(fscrypt_initialize); - - /** - * fscrypt_init() - Set up for fs encryption. -diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h -index 7c31108728e4..bb92f0c0961b 100644 ---- a/fs/crypto/fscrypt_private.h -+++ b/fs/crypto/fscrypt_private.h -@@ -13,6 +13,9 @@ - - #include - -+/* crypto.c */ -+int fscrypt_initialize(void); -+ - /* keyinfo.c */ - extern int fscrypt_get_crypt_info(struct inode *); - -diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h -index 2f8894f0696c..ce2ebdee6a89 100644 ---- a/include/linux/fscrypto.h -+++ b/include/linux/fscrypto.h -@@ -244,7 +244,6 @@ static inline void fscrypt_set_d_op(struct dentry *dentry) - #if IS_ENABLED(CONFIG_FS_ENCRYPTION) - /* crypto.c */ - extern struct kmem_cache *fscrypt_info_cachep; --int fscrypt_initialize(void); - - extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t); - extern void fscrypt_release_ctx(struct fscrypt_ctx *); diff --git a/get-rid-of-ext4_sb_has_crypto b/get-rid-of-ext4_sb_has_crypto deleted file mode 100644 index 13853b3f..00000000 --- a/get-rid-of-ext4_sb_has_crypto +++ /dev/null @@ -1,48 +0,0 @@ -ext4: get rid of ext4_sb_has_crypto() - -From: Eric Biggers - -ext4_sb_has_crypto() just called through to ext4_has_feature_encrypt(), -and all callers except one were already using the latter. So remove it -and switch its one caller to ext4_has_feature_encrypt(). - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ext4.h | 5 ----- - fs/ext4/ioctl.c | 2 +- - 2 files changed, 1 insertion(+), 6 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index a8a750f..cc83482 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -2277,11 +2277,6 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb, - struct ext4_group_desc *gdp); - ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); - --static inline int ext4_sb_has_crypto(struct super_block *sb) --{ -- return ext4_has_feature_encrypt(sb); --} -- - static inline bool ext4_encrypted_inode(struct inode *inode) - { - return ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT); -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index bf5ae8e..a0db5d9 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -786,7 +786,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - struct ext4_sb_info *sbi = EXT4_SB(sb); - handle_t *handle; - -- if (!ext4_sb_has_crypto(sb)) -+ if (!ext4_has_feature_encrypt(sb)) - return -EOPNOTSUPP; - if (uuid_is_zero(sbi->s_es->s_encrypt_pw_salt)) { - err = mnt_want_write_file(filp); --- -2.8.0.rc3.226.g39d4020 - - diff --git a/let-S_DAX-set-only-if-DAX-is-really-supported b/let-S_DAX-set-only-if-DAX-is-really-supported deleted file mode 100644 index 9fd221d6..00000000 --- a/let-S_DAX-set-only-if-DAX-is-really-supported +++ /dev/null @@ -1,102 +0,0 @@ -ext4: only set S_DAX if DAX is really supported - -From: Jan Kara - -Currently we have S_DAX set inode->i_flags for a regular file whenever -ext4 is mounted with dax mount option. However in some cases we cannot -really do DAX - e.g. when inode is marked to use data journalling, when -inode data is being encrypted, or when inode is stored inline. Make sure -S_DAX flag is appropriately set/cleared in these cases. - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/inline.c | 10 ++++++++++ - fs/ext4/inode.c | 9 ++++++++- - fs/ext4/super.c | 6 ++++++ - 3 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c -index f74d5ee2cdec..c29678965c3c 100644 ---- a/fs/ext4/inline.c -+++ b/fs/ext4/inline.c -@@ -299,6 +299,11 @@ static int ext4_create_inline_data(handle_t *handle, - EXT4_I(inode)->i_inline_size = len + EXT4_MIN_INLINE_DATA_SIZE; - ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); - ext4_set_inode_flag(inode, EXT4_INODE_INLINE_DATA); -+ /* -+ * Propagate changes to inode->i_flags as well - e.g. S_DAX may -+ * get cleared -+ */ -+ ext4_set_inode_flags(inode); - get_bh(is.iloc.bh); - error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); - -@@ -442,6 +447,11 @@ static int ext4_destroy_inline_data_nolock(handle_t *handle, - } - } - ext4_clear_inode_flag(inode, EXT4_INODE_INLINE_DATA); -+ /* -+ * Propagate changes to inode->i_flags as well - e.g. S_DAX may -+ * get set. -+ */ -+ ext4_set_inode_flags(inode); - - get_bh(is.iloc.bh); - error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 3d58b2b477e8..5337828c68a7 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -4355,7 +4355,9 @@ void ext4_set_inode_flags(struct inode *inode) - new_fl |= S_NOATIME; - if (flags & EXT4_DIRSYNC_FL) - new_fl |= S_DIRSYNC; -- if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode)) -+ if (test_opt(inode->i_sb, DAX) && S_ISREG(inode->i_mode) && -+ !ext4_should_journal_data(inode) && !ext4_has_inline_data(inode) && -+ !ext4_encrypted_inode(inode)) - new_fl |= S_DAX; - inode_set_flags(inode, new_fl, - S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX); -@@ -5623,6 +5625,11 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val) - ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA); - } - ext4_set_aops(inode); -+ /* -+ * Update inode->i_flags after EXT4_INODE_JOURNAL_DATA was updated. -+ * E.g. S_DAX may get cleared / set. -+ */ -+ ext4_set_inode_flags(inode); - - jbd2_journal_unlock_updates(journal); - percpu_up_write(&sbi->s_journal_flag_rwsem); -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 20da99da0a34..d5b94cc6a74e 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -1126,6 +1126,10 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, - ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT); - ext4_clear_inode_state(inode, - EXT4_STATE_MAY_INLINE_DATA); -+ /* -+ * Update inode->i_flags - e.g. S_DAX may get disabled -+ */ -+ ext4_set_inode_flags(inode); - } - return res; - } -@@ -1140,6 +1144,8 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, - len, 0); - if (!res) { - ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT); -+ /* Update inode->i_flags - e.g. S_DAX may get disabled */ -+ ext4_set_inode_flags(inode); - res = ext4_mark_inode_dirty(handle, inode); - if (res) - EXT4_ERROR_INODE(inode, "Failed to mark inode dirty"); --- -2.6.6 - - diff --git a/mbache-dont-bug-if-entry-cache-cannot-be-allocated b/mbache-dont-bug-if-entry-cache-cannot-be-allocated deleted file mode 100644 index 84f60bcf..00000000 --- a/mbache-dont-bug-if-entry-cache-cannot-be-allocated +++ /dev/null @@ -1,37 +0,0 @@ -mbcache: don't BUG() if entry cache cannot be allocated - -From: Eric Biggers - -mbcache can be a module that is loaded long after startup, when someone -asks to mount an ext2 or ext4 filesystem. Therefore it should not BUG() -if kmem_cache_create() fails, but rather just fail the module load. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/mbcache.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/mbcache.c b/fs/mbcache.c -index 31e54c2..c56ab21 100644 ---- a/fs/mbcache.c -+++ b/fs/mbcache.c -@@ -420,7 +420,8 @@ static int __init mbcache_init(void) - mb_entry_cache = kmem_cache_create("mbcache", - sizeof(struct mb_cache_entry), 0, - SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL); -- BUG_ON(!mb_entry_cache); -+ if (!mb_entry_cache) -+ return -ENOMEM; - return 0; - } - --- -2.8.0.rc3.226.g39d4020 - --- -To unsubscribe from this list: send the line "unsubscribe linux-ext4" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff --git a/mbcache-correctly-handled-e_referenced-bit b/mbcache-correctly-handled-e_referenced-bit deleted file mode 100644 index fe89fb65..00000000 --- a/mbcache-correctly-handled-e_referenced-bit +++ /dev/null @@ -1,45 +0,0 @@ -mbcache: correctly handle 'e_referenced' bit - -From: Eric Biggers - -mbcache entries have an 'e_referenced' bit which users can set with -mb_cache_entry_touch() to indicate that an entry should be given another -pass through the LRU list before the shrinker can delete it. However, -mb_cache_shrink() actually would, when seeing an e_referenced entry at -the front of the list (the least-recently used end), place it right at -the front of the list again. The next iteration would then remove the -entry from the list and delete it. Consequently, e_referenced had -essentially no effect, so ext2/ext4 xattr blocks would sometimes not be -reused as often as expected. - -Fix this by making the shrinker move e_referenced entries to the back of -the list rather than the front. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/mbcache.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/fs/mbcache.c b/fs/mbcache.c -index c5bd19f..31e54c2 100644 ---- a/fs/mbcache.c -+++ b/fs/mbcache.c -@@ -286,7 +286,7 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache, - struct mb_cache_entry, e_list); - if (entry->e_referenced) { - entry->e_referenced = 0; -- list_move_tail(&cache->c_list, &entry->e_list); -+ list_move_tail(&entry->e_list, &cache->c_list); - continue; - } - list_del_init(&entry->e_list); --- -2.8.0.rc3.226.g39d4020 - --- -To unsubscribe from this list: send the line "unsubscribe linux-ext4" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff --git a/mbcache-document-that-find-functions-only-return-reusable-entries b/mbcache-document-that-find-functions-only-return-reusable-entries deleted file mode 100644 index 35109a62..00000000 --- a/mbcache-document-that-find-functions-only-return-reusable-entries +++ /dev/null @@ -1,62 +0,0 @@ -mbcache: document that "find" functions only return reusable entries - -From: Eric Biggers - -mb_cache_entry_find_first() and mb_cache_entry_find_next() only return -cache entries with the 'e_reusable' bit set. This should be documented. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/mbcache.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/fs/mbcache.c b/fs/mbcache.c -index bf65906..b19be42 100644 ---- a/fs/mbcache.c -+++ b/fs/mbcache.c -@@ -155,12 +155,12 @@ static struct mb_cache_entry *__entry_find(struct mb_cache *cache, - } - - /* -- * mb_cache_entry_find_first - find the first entry in cache with given key -+ * mb_cache_entry_find_first - find the first reusable entry with the given key - * @cache: cache where we should search - * @key: key to look for - * -- * Search in @cache for entry with key @key. Grabs reference to the first -- * entry found and returns the entry. -+ * Search in @cache for a reusable entry with key @key. Grabs reference to the -+ * first reusable entry found and returns the entry. - */ - struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, - u32 key) -@@ -170,14 +170,14 @@ struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, - EXPORT_SYMBOL(mb_cache_entry_find_first); - - /* -- * mb_cache_entry_find_next - find next entry in cache with the same -+ * mb_cache_entry_find_next - find next reusable entry with the same key - * @cache: cache where we should search - * @entry: entry to start search from - * -- * Finds next entry in the hash chain which has the same key as @entry. -- * If @entry is unhashed (which can happen when deletion of entry races -- * with the search), finds the first entry in the hash chain. The function -- * drops reference to @entry and returns with a reference to the found entry. -+ * Finds next reusable entry in the hash chain which has the same key as @entry. -+ * If @entry is unhashed (which can happen when deletion of entry races with the -+ * search), finds the first reusable entry in the hash chain. The function drops -+ * reference to @entry and returns with a reference to the found entry. - */ - struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache *cache, - struct mb_cache_entry *entry) --- -2.8.0.rc3.226.g39d4020 - --- -To unsubscribe from this list: send the line "unsubscribe linux-ext4" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff --git a/mbcache-remove-unnecessary-module_get_put b/mbcache-remove-unnecessary-module_get_put deleted file mode 100644 index 187f8cfe..00000000 --- a/mbcache-remove-unnecessary-module_get_put +++ /dev/null @@ -1,57 +0,0 @@ -mbcache: remove unnecessary module_get/module_put - -From: Eric Biggers - -When mbcache is built as a module, any modules that use it (ext2 and/or -ext4) will depend on its symbols directly, incrementing its reference -count. Therefore, there is no need to do module_get/module_put. - -Also note that since the module_get/module_put were in the mbcache -module itself, executing those lines of code was already dependent on -another reference to the mbcache module being held. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/mbcache.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/fs/mbcache.c b/fs/mbcache.c -index c56ab21..07c5d7d 100644 ---- a/fs/mbcache.c -+++ b/fs/mbcache.c -@@ -344,9 +344,6 @@ struct mb_cache *mb_cache_create(int bucket_bits) - int bucket_count = 1 << bucket_bits; - int i; - -- if (!try_module_get(THIS_MODULE)) -- return NULL; -- - cache = kzalloc(sizeof(struct mb_cache), GFP_KERNEL); - if (!cache) - goto err_out; -@@ -377,7 +374,6 @@ struct mb_cache *mb_cache_create(int bucket_bits) - return cache; - - err_out: -- module_put(THIS_MODULE); - return NULL; - } - EXPORT_SYMBOL(mb_cache_create); -@@ -411,7 +407,6 @@ void mb_cache_destroy(struct mb_cache *cache) - } - kfree(cache->c_hash); - kfree(cache); -- module_put(THIS_MODULE); - } - EXPORT_SYMBOL(mb_cache_destroy); - --- -2.8.0.rc3.226.g39d4020 - --- -To unsubscribe from this list: send the line "unsubscribe linux-ext4" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff --git a/mbcache-use-consistent-type-for-entry-count b/mbcache-use-consistent-type-for-entry-count deleted file mode 100644 index 6aec47d7..00000000 --- a/mbcache-use-consistent-type-for-entry-count +++ /dev/null @@ -1,85 +0,0 @@ -mbcache: use consistent type for entry count - -From: Eric Biggers - -mbcache used several different types to represent the number of entries -in the cache. For consistency within mbcache and with the shrinker API, -always use unsigned long. - -This does not change behavior for current mbcache users (ext2 and ext4) -since they limit the entry count to a value which easily fits in an int. - -Signed-off-by: Eric Biggers -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- - fs/mbcache.c | 15 +++++++-------- - 1 file changed, 7 insertions(+), 8 deletions(-) - -diff --git a/fs/mbcache.c b/fs/mbcache.c -index 07c5d7d..bf65906 100644 ---- a/fs/mbcache.c -+++ b/fs/mbcache.c -@@ -29,7 +29,7 @@ struct mb_cache { - /* log2 of hash table size */ - int c_bucket_bits; - /* Maximum entries in cache to avoid degrading hash too much */ -- int c_max_entries; -+ unsigned long c_max_entries; - /* Protects c_list, c_entry_count */ - spinlock_t c_list_lock; - struct list_head c_list; -@@ -43,7 +43,7 @@ struct mb_cache { - static struct kmem_cache *mb_entry_cache; - - static unsigned long mb_cache_shrink(struct mb_cache *cache, -- unsigned int nr_to_scan); -+ unsigned long nr_to_scan); - - static inline struct hlist_bl_head *mb_cache_entry_head(struct mb_cache *cache, - u32 key) -@@ -274,11 +274,11 @@ static unsigned long mb_cache_count(struct shrinker *shrink, - - /* Shrink number of entries in cache */ - static unsigned long mb_cache_shrink(struct mb_cache *cache, -- unsigned int nr_to_scan) -+ unsigned long nr_to_scan) - { - struct mb_cache_entry *entry; - struct hlist_bl_head *head; -- unsigned int shrunk = 0; -+ unsigned long shrunk = 0; - - spin_lock(&cache->c_list_lock); - while (nr_to_scan-- && !list_empty(&cache->c_list)) { -@@ -316,10 +316,9 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache, - static unsigned long mb_cache_scan(struct shrinker *shrink, - struct shrink_control *sc) - { -- int nr_to_scan = sc->nr_to_scan; - struct mb_cache *cache = container_of(shrink, struct mb_cache, - c_shrink); -- return mb_cache_shrink(cache, nr_to_scan); -+ return mb_cache_shrink(cache, sc->nr_to_scan); - } - - /* We shrink 1/X of the cache when we have too many entries in it */ -@@ -341,8 +340,8 @@ static void mb_cache_shrink_worker(struct work_struct *work) - struct mb_cache *mb_cache_create(int bucket_bits) - { - struct mb_cache *cache; -- int bucket_count = 1 << bucket_bits; -- int i; -+ unsigned long bucket_count = 1UL << bucket_bits; -+ unsigned long i; - - cache = kzalloc(sizeof(struct mb_cache), GFP_KERNEL); - if (!cache) --- -2.8.0.rc3.226.g39d4020 - --- -To unsubscribe from this list: send the line "unsubscribe linux-ext4" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - diff --git a/reject-inodes-with-negative-size b/reject-inodes-with-negative-size deleted file mode 100644 index 2315ea23..00000000 --- a/reject-inodes-with-negative-size +++ /dev/null @@ -1,41 +0,0 @@ -ext4: reject inodes with negative size - -From: "Darrick J. Wong" - -Don't load an inode with a negative size; this causes integer overflow -problems in the VFS. - -[ Added EXT4_ERROR_INODE() to mark file system as corrupted. -TYT] - -Fixes: a48380f769df (ext4: rename i_dir_acl to i_size_high) -Signed-off-by: Darrick J. Wong -Signed-off-by: Theodore Ts'o -Cc: stable@kernel.org ---- - fs/ext4/inode.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index a1eac0054203..f9f892212308 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -4553,6 +4553,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) - struct inode *inode; - journal_t *journal = EXT4_SB(sb)->s_journal; - long ret; -+ loff_t size; - int block; - uid_t i_uid; - gid_t i_gid; -@@ -4655,6 +4656,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) - ei->i_file_acl |= - ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; - inode->i_size = ext4_isize(raw_inode); -+ if ((size = i_size_read(inode)) < 0) { -+ EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); -+ ret = -EFSCORRUPTED; -+ goto bad_inode; -+ } - ei->i_disksize = inode->i_size; - #ifdef CONFIG_QUOTA - ei->i_reserved_quota = 0; diff --git a/remove-another-test-in-ext4_alloc_file_blocks b/remove-another-test-in-ext4_alloc_file_blocks deleted file mode 100644 index cdf177e9..00000000 --- a/remove-another-test-in-ext4_alloc_file_blocks +++ /dev/null @@ -1,26 +0,0 @@ -ext4: remove another test in ext4_alloc_file_blocks() - -From: Dan Carpenter - -Before commit c3fe493ccdb1 ('ext4: remove unneeded test in -ext4_alloc_file_blocks()') then it was possible for "depth" to be -1 -but now, it's not possible that it is negative. - -Signed-off-by: Dan Carpenter -Signed-off-by: Theodore Ts'o -Reviewed-by: Jan Kara ---- -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index c930a01..dca394c 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -4701,7 +4701,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, - /* - * Recalculate credits when extent tree depth changes. - */ -- if (depth >= 0 && depth != ext_depth(inode)) { -+ if (depth != ext_depth(inode)) { - credits = ext4_chunk_trans_blocks(inode, len); - depth = ext_depth(inode); - } - diff --git a/remove-parameter-from-ext4_xattr_ibody_set b/remove-parameter-from-ext4_xattr_ibody_set deleted file mode 100644 index 4daf94e2..00000000 --- a/remove-parameter-from-ext4_xattr_ibody_set +++ /dev/null @@ -1,66 +0,0 @@ -ext4: remove parameter from ext4_xattr_ibody_set() - -From: Eric Whitney - -The parameter "handle" isn't used. - -Signed-off-by: Eric Whitney -Signed-off-by: Theodore Ts'o ---- - fs/ext4/xattr.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index d77be9e..2ee1378 100644 ---- a/fs/ext4/xattr.c -+++ b/fs/ext4/xattr.c -@@ -1109,7 +1109,7 @@ int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode, - return 0; - } - --static int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, -+static int ext4_xattr_ibody_set(struct inode *inode, - struct ext4_xattr_info *i, - struct ext4_xattr_ibody_find *is) - { -@@ -1216,7 +1216,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, - } - if (!value) { - if (!is.s.not_found) -- error = ext4_xattr_ibody_set(handle, inode, &i, &is); -+ error = ext4_xattr_ibody_set(inode, &i, &is); - else if (!bs.s.not_found) - error = ext4_xattr_block_set(handle, inode, &i, &bs); - } else { -@@ -1227,7 +1227,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, - if (!bs.s.not_found && ext4_xattr_value_same(&bs.s, &i)) - goto cleanup; - -- error = ext4_xattr_ibody_set(handle, inode, &i, &is); -+ error = ext4_xattr_ibody_set(inode, &i, &is); - if (!error && !bs.s.not_found) { - i.value = NULL; - error = ext4_xattr_block_set(handle, inode, &i, &bs); -@@ -1242,8 +1242,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, - goto cleanup; - if (!is.s.not_found) { - i.value = NULL; -- error = ext4_xattr_ibody_set(handle, inode, &i, -- &is); -+ error = ext4_xattr_ibody_set(inode, &i, &is); - } - } - } -@@ -1384,7 +1383,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, - goto out; - - /* Remove the chosen entry from the inode */ -- error = ext4_xattr_ibody_set(handle, inode, &i, is); -+ error = ext4_xattr_ibody_set(inode, &i, is); - if (error) - goto out; - --- -2.1.4 - - diff --git a/remove-unused-function-ext4_aligned_io b/remove-unused-function-ext4_aligned_io deleted file mode 100644 index e7411973..00000000 --- a/remove-unused-function-ext4_aligned_io +++ /dev/null @@ -1,36 +0,0 @@ -ext4: remove unused function ext4_aligned_io() - -From: Ross Zwisler - -The last user of ext4_aligned_io() was the DAX path in -ext4_direct_IO_write(). This usage was removed by Jan Kara's patch -entitled "ext4: Rip out DAX handling from direct IO path". - -Signed-off-by: Ross Zwisler -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ext4.h | 7 ------- - 1 file changed, 7 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 8b76311..8a8a9b2 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -3262,13 +3262,6 @@ static inline void ext4_clear_io_unwritten_flag(ext4_io_end_t *io_end) - } - } - --static inline bool ext4_aligned_io(struct inode *inode, loff_t off, loff_t len) --{ -- int blksize = 1 << inode->i_blkbits; -- -- return IS_ALIGNED(off, blksize) && IS_ALIGNED(len, blksize); --} -- - extern struct iomap_ops ext4_iomap_ops; - - #endif /* __KERNEL__ */ --- -2.7.4 - - diff --git a/rename-get_crypt_info b/rename-get_crypt_info deleted file mode 100644 index f23c6c90..00000000 --- a/rename-get_crypt_info +++ /dev/null @@ -1,106 +0,0 @@ -fscrypt: rename get_crypt_info() to fscrypt_get_crypt_info() - -To avoid namespace collisions, rename get_crypt_info() to -fscrypt_get_crypt_info(). The function is only used inside the -fs/crypto directory, so declare it in the new header file, -fscrypt_private.h. - -Signed-off-by: Theodore Ts'o -Reviewed-by: Eric Biggers ---- - fs/crypto/fname.c | 4 ++-- - fs/crypto/fscrypt_private.h | 19 +++++++++++++++++++ - fs/crypto/keyinfo.c | 6 +++--- - include/linux/fscrypto.h | 1 - - 4 files changed, 24 insertions(+), 6 deletions(-) - -diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c -index 6b45d9caeeb0..56ad9d195f18 100644 ---- a/fs/crypto/fname.c -+++ b/fs/crypto/fname.c -@@ -12,7 +12,7 @@ - - #include - #include --#include -+#include "fscrypt_private.h" - - /** - * fname_crypt_complete() - completion callback for filename crypto -@@ -350,7 +350,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, - fname->disk_name.len = iname->len; - return 0; - } -- ret = get_crypt_info(dir); -+ ret = fscrypt_get_crypt_info(dir); - if (ret && ret != -EOPNOTSUPP) - return ret; - -diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h -new file mode 100644 -index 000000000000..7c31108728e4 ---- /dev/null -+++ b/fs/crypto/fscrypt_private.h -@@ -0,0 +1,19 @@ -+/* -+ * fscrypt_private.h -+ * -+ * Copyright (C) 2015, Google, Inc. -+ * -+ * This contains encryption key functions. -+ * -+ * Written by Michael Halcrow, Ildar Muslukhov, and Uday Savagaonkar, 2015. -+ */ -+ -+#ifndef _FSCRYPT_PRIVATE_H -+#define _FSCRYPT_PRIVATE_H -+ -+#include -+ -+/* keyinfo.c */ -+extern int fscrypt_get_crypt_info(struct inode *); -+ -+#endif /* _FSCRYPT_PRIVATE_H */ -diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c -index 67fb6d8876d0..35d3317a27b3 100644 ---- a/fs/crypto/keyinfo.c -+++ b/fs/crypto/keyinfo.c -@@ -10,7 +10,7 @@ - - #include - #include --#include -+#include "fscrypt_private.h" - - static void derive_crypt_complete(struct crypto_async_request *req, int rc) - { -@@ -178,7 +178,7 @@ static void put_crypt_info(struct fscrypt_info *ci) - kmem_cache_free(fscrypt_info_cachep, ci); - } - --int get_crypt_info(struct inode *inode) -+int fscrypt_get_crypt_info(struct inode *inode) - { - struct fscrypt_info *crypt_info; - struct fscrypt_context ctx; -@@ -327,7 +327,7 @@ int fscrypt_get_encryption_info(struct inode *inode) - (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | - (1 << KEY_FLAG_REVOKED) | - (1 << KEY_FLAG_DEAD))))) -- return get_crypt_info(inode); -+ return fscrypt_get_crypt_info(inode); - return 0; - } - EXPORT_SYMBOL(fscrypt_get_encryption_info); -diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h -index be94684dc05f..2f8894f0696c 100644 ---- a/include/linux/fscrypto.h -+++ b/include/linux/fscrypto.h -@@ -265,7 +265,6 @@ extern int fscrypt_has_permitted_context(struct inode *, struct inode *); - extern int fscrypt_inherit_context(struct inode *, struct inode *, - void *, bool); - /* keyinfo.c */ --extern int get_crypt_info(struct inode *); - extern int fscrypt_get_encryption_info(struct inode *); - extern void fscrypt_put_encryption_info(struct inode *, struct fscrypt_info *); - diff --git a/return-enomem-instead-of-success b/return-enomem-instead-of-success deleted file mode 100644 index 22be0a92..00000000 --- a/return-enomem-instead-of-success +++ /dev/null @@ -1,28 +0,0 @@ -ext4: return -ENOMEM instead of success - -From: Dan Carpenter - -We should set the error code if kzalloc() fails. - -Fixes: 67cf5b09a46f ("ext4: add the basic function for inline data support") -Signed-off-by: Dan Carpenter -Signed-off-by: Theodore Ts'o -Cc: stable@vger.kernel.org ---- -diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c -index 9b67f75bdcf7..437df6a1a841 100644 ---- a/fs/ext4/inline.c -+++ b/fs/ext4/inline.c -@@ -341,8 +341,10 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode, - - len -= EXT4_MIN_INLINE_DATA_SIZE; - value = kzalloc(len, GFP_NOFS); -- if (!value) -+ if (!value) { -+ error = -ENOMEM; - goto out; -+ } - - error = ext4_xattr_ibody_get(inode, i.name_index, i.name, - value, len); - diff --git a/rip-out-DAX-handling-from-direct-IO-path b/rip-out-DAX-handling-from-direct-IO-path deleted file mode 100644 index 1f2dda7f..00000000 --- a/rip-out-DAX-handling-from-direct-IO-path +++ /dev/null @@ -1,182 +0,0 @@ -ext4: rip out DAX handling from direct IO path - -From: Jan Kara - -Reads and writes for DAX inodes should no longer end up in direct IO -code. Rip out the support and add a warning. - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/ext4.h | 2 -- - fs/ext4/inode.c | 97 +++++++++------------------------------------------------ - 2 files changed, 15 insertions(+), 84 deletions(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 098b39910001..8b763113a1b8 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -2457,8 +2457,6 @@ struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int); - struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int); - int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create); --int ext4_dax_get_block(struct inode *inode, sector_t iblock, -- struct buffer_head *bh_result, int create); - int ext4_get_block(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create); - int ext4_dio_get_block(struct inode *inode, sector_t iblock, -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 4d71c7bc3524..d13f7cb6b1d5 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3272,46 +3272,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait) - } - - #ifdef CONFIG_FS_DAX --/* -- * Get block function for DAX IO and mmap faults. It takes care of converting -- * unwritten extents to written ones and initializes new / converted blocks -- * to zeros. -- */ --int ext4_dax_get_block(struct inode *inode, sector_t iblock, -- struct buffer_head *bh_result, int create) --{ -- int ret; -- -- ext4_debug("inode %lu, create flag %d\n", inode->i_ino, create); -- if (!create) -- return _ext4_get_block(inode, iblock, bh_result, 0); -- -- ret = ext4_get_block_trans(inode, iblock, bh_result, -- EXT4_GET_BLOCKS_PRE_IO | -- EXT4_GET_BLOCKS_CREATE_ZERO); -- if (ret < 0) -- return ret; -- -- if (buffer_unwritten(bh_result)) { -- /* -- * We are protected by i_mmap_sem or i_mutex so we know block -- * cannot go away from under us even though we dropped -- * i_data_sem. Convert extent to written and write zeros there. -- */ -- ret = ext4_get_block_trans(inode, iblock, bh_result, -- EXT4_GET_BLOCKS_CONVERT | -- EXT4_GET_BLOCKS_CREATE_ZERO); -- if (ret < 0) -- return ret; -- } -- /* -- * At least for now we have to clear BH_New so that DAX code -- * doesn't attempt to zero blocks again in a racy way. -- */ -- clear_buffer_new(bh_result); -- return 0; --} -- - static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - unsigned flags, struct iomap *iomap) - { -@@ -3465,14 +3425,6 @@ struct iomap_ops ext4_iomap_ops = { - .iomap_end = ext4_iomap_end, - }; - --#else --/* Just define empty function, it will never get called. */ --int ext4_dax_get_block(struct inode *inode, sector_t iblock, -- struct buffer_head *bh_result, int create) --{ -- BUG(); -- return 0; --} - #endif - - static int ext4_end_io_dio(struct kiocb *iocb, loff_t offset, -@@ -3594,19 +3546,7 @@ static ssize_t ext4_direct_IO_write(struct kiocb *iocb, struct iov_iter *iter) - iocb->private = NULL; - if (overwrite) - get_block_func = ext4_dio_get_block_overwrite; -- else if (IS_DAX(inode)) { -- /* -- * We can avoid zeroing for aligned DAX writes beyond EOF. Other -- * writes need zeroing either because they can race with page -- * faults or because they use partial blocks. -- */ -- if (round_down(offset, 1<i_blkbits) >= inode->i_size && -- ext4_aligned_io(inode, offset, count)) -- get_block_func = ext4_dio_get_block; -- else -- get_block_func = ext4_dax_get_block; -- dio_flags = DIO_LOCKING; -- } else if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) || -+ else if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) || - round_down(offset, 1 << inode->i_blkbits) >= inode->i_size) { - get_block_func = ext4_dio_get_block; - dio_flags = DIO_LOCKING | DIO_SKIP_HOLES; -@@ -3620,14 +3560,9 @@ static ssize_t ext4_direct_IO_write(struct kiocb *iocb, struct iov_iter *iter) - #ifdef CONFIG_EXT4_FS_ENCRYPTION - BUG_ON(ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)); - #endif -- if (IS_DAX(inode)) { -- ret = dax_do_io(iocb, inode, iter, get_block_func, -- ext4_end_io_dio, dio_flags); -- } else -- ret = __blockdev_direct_IO(iocb, inode, -- inode->i_sb->s_bdev, iter, -- get_block_func, -- ext4_end_io_dio, NULL, dio_flags); -+ ret = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter, -+ get_block_func, ext4_end_io_dio, NULL, -+ dio_flags); - - if (ret > 0 && !overwrite && ext4_test_inode_state(inode, - EXT4_STATE_DIO_UNWRITTEN)) { -@@ -3696,6 +3631,7 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) - { - struct address_space *mapping = iocb->ki_filp->f_mapping; - struct inode *inode = mapping->host; -+ size_t count = iov_iter_count(iter); - ssize_t ret; - - /* -@@ -3704,19 +3640,12 @@ static ssize_t ext4_direct_IO_read(struct kiocb *iocb, struct iov_iter *iter) - * we are protected against page writeback as well. - */ - inode_lock_shared(inode); -- if (IS_DAX(inode)) { -- ret = dax_do_io(iocb, inode, iter, ext4_dio_get_block, NULL, 0); -- } else { -- size_t count = iov_iter_count(iter); -- -- ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, -- iocb->ki_pos + count); -- if (ret) -- goto out_unlock; -- ret = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, -- iter, ext4_dio_get_block, -- NULL, NULL, 0); -- } -+ ret = filemap_write_and_wait_range(mapping, iocb->ki_pos, -+ iocb->ki_pos + count); -+ if (ret) -+ goto out_unlock; -+ ret = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, -+ iter, ext4_dio_get_block, NULL, NULL, 0); - out_unlock: - inode_unlock_shared(inode); - return ret; -@@ -3745,6 +3674,10 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter) - if (ext4_has_inline_data(inode)) - return 0; - -+ /* DAX uses iomap path now */ -+ if (WARN_ON_ONCE(IS_DAX(inode))) -+ return 0; -+ - trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); - if (iov_iter_rw(iter) == READ) - ret = ext4_direct_IO_read(iocb, iter); --- -2.6.6 - - diff --git a/sanity-check-block-and-cluster-size b/sanity-check-block-and-cluster-size deleted file mode 100644 index f9f64ac2..00000000 --- a/sanity-check-block-and-cluster-size +++ /dev/null @@ -1,64 +0,0 @@ -ext4: sanity check the block and cluster size at mount time - -If the block size or cluster size is insane, reject the mount. This -is important for security reasons (although we shouldn't be just -depending on this check). - -Ref: http://www.securityfocus.com/archive/1/539661 -Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1332506 -Reported-by: Borislav Petkov -Reported-by: Nikolay Borisov -Signed-off-by: Theodore Ts'o -Cc: stable@vger.kernel.org ---- - fs/ext4/ext4.h | 1 + - fs/ext4/super.c | 17 ++++++++++++++++- - 2 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 53d6d463ac4d..bdf1e5ee8642 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -235,6 +235,7 @@ struct ext4_io_submit { - #define EXT4_MAX_BLOCK_SIZE 65536 - #define EXT4_MIN_BLOCK_LOG_SIZE 10 - #define EXT4_MAX_BLOCK_LOG_SIZE 16 -+#define EXT4_MAX_CLUSTER_LOG_SIZE 30 - #ifdef __KERNEL__ - # define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) - #else -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 35ccbdc2d64e..0f9ae4ce33d6 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3567,7 +3567,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - if (blocksize < EXT4_MIN_BLOCK_SIZE || - blocksize > EXT4_MAX_BLOCK_SIZE) { - ext4_msg(sb, KERN_ERR, -- "Unsupported filesystem blocksize %d", blocksize); -+ "Unsupported filesystem blocksize %d (%d log_block_size)", -+ blocksize, le32_to_cpu(es->s_log_block_size)); -+ goto failed_mount; -+ } -+ if (le32_to_cpu(es->s_log_block_size) > -+ (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { -+ ext4_msg(sb, KERN_ERR, -+ "Invalid log block size: %u", -+ le32_to_cpu(es->s_log_block_size)); - goto failed_mount; - } - -@@ -3699,6 +3707,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - "block size (%d)", clustersize, blocksize); - goto failed_mount; - } -+ if (le32_to_cpu(es->s_log_cluster_size) > -+ (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { -+ ext4_msg(sb, KERN_ERR, -+ "Invalid log cluster size: %u", -+ le32_to_cpu(es->s_log_cluster_size)); -+ goto failed_mount; -+ } - sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - - le32_to_cpu(es->s_log_block_size); - sbi->s_clusters_per_group = diff --git a/series b/series dissimilarity index 65% index 99aaa6ba..2ec7846c 100644 --- a/series +++ b/series @@ -1,124 +1,59 @@ -# 6da22013bb79 - -allow-ext4_truncate-to-return-an-error -allow-ext4_ext_truncate-to-return-an-error -dont-lock-buffer-head-in-ext4_commit_super-if-holding-spinlock - -fix-mballoc-breakage-with-64k-block-size -fix-stack-corruption-with-64k-blocksize -use-current_time-for-inode-timestamps -allow-inode-expansion-for-nojournal-file-systems -remove-parameter-from-ext4_xattr_ibody_set -sanity-check-block-and-cluster-size -fix-sb-mount-options-processing -verify-inodes_per_group-during-mount -add-sanity-checking-in-count_overhead - -factor-out-checks-from-ext4_file_write_iter -let-S_DAX-set-only-if-DAX-is-really-supported -convert-dax-reads-to-iomap-infrastructure -use-iomap-for-zeroing-blocks-in-DAX-mode -DAX-iomap-write-support -avoid-split-extents-for-DAX-writes -convert-DAX-faults-to-iomap-infrastructure -rip-out-DAX-handling-from-direct-IO-path -ext2-use-iomap_zero_range-for-zeroing-truncated-page-in-DAX-path -dax-rip-out-get_block-based-IO-support -remove-unused-function-ext4_aligned_io - -avoid-lockdep-warning-when-inheriting-encryption-context -add-select-for-CONFIG_FS_IOMAP -fix-mmp-use-after-free-during-umount - -# fscrypt-recommend-linux-fsdevel-for-fscrypto-patches -# fscrypt-remove-unneeded-Kconfig-dependencies -# fscrypt-move-ioctl-processing-more-fully-into-common-code -# rename-get_crypt_info -# fscrypt-unexport-fscrypt_initialize -# fscrypt-move-non-public-structures-to-private-header -# fscrypt-move-constants-to-uapi-header - -add-EXT4_JOURNAL_DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask -be-more-strict-when-verifying-flags-set-via-SETFLAGS-ioctls -warn-when-page-is-dirtied-without-buffers -fix-inode-checksum-calculation-if-i_extra_size-is-too-small -get-rid-of-ext4_sb_has_crypto -disable-pwsalt-ioctl-when-encryption-disabled-by-config - -forbid-i_extra_isize-not-divisible-by-4 -dont-read-out-of-bounds-when-checking-for-in-inode-xattrs -correct-detect-when-an-xattr-value-has-an-invalid-size -validate-s_first_meta_bg-at-mount-time -fix-reading-new-encrypted-symlinks-on-no-journal-file-systems - -mbcache-correctly-handled-e_referenced-bit -mbache-dont-bug-if-entry-cache-cannot-be-allocated -mbcache-remove-unnecessary-module_get_put -mbcache-use-consistent-type-for-entry-count -mbcache-document-that-find-functions-only-return-reusable-entries - -fix-checks-for-data-ordered-and-journal_async_commit-options -fix-block_validity-documentation -remove-another-test-in-ext4_alloc_file_blocks -reject-inodes-with-negative-size -return-enomem-instead-of-success -do-not-perform-data-journaling-when-encrypting -fix-sleep-in-atomic-context-in-grab_mapping_entry - -#################################################### -# unstable patches -#################################################### - -stable-boundary -stable-boundary-undo.patch - -add-support-for-log-metadata-block-tracking-in-log -add-indirection-to-metadata-block-read-paths -cleaner -disable-writeback - -only-call-ext4_truncate-if-there-is-data-to-truncate -migrate-to-use-vfs-crypto-engine - -#crypto-rename-ext4_get_encryption_info - -crypto-add-ciphertext_access-mount-option -crypto-add-ioctls-to-backup-crypto-metadata - -add-encryption-debug-files - -# not yet ready -#dont-use-io-end-if-not-needed - -# not yet ready; patch series so ext4 has has full responsibility -# for ext4_readpage[s] and does not use mpage. -# -#move-read-page-functions-to-new-file -#include-mpage-functions-into-readpage.c -#inline-ext4_get_block-into-readpage - -add-fallocate-mode-blocking-for-debugging - -# use-discard-if-possible-in-blkdev_issue_zeroout -add-blkdiscard-ioctl - -block-dio-during-truncate - -delalloc-debug - -# note: this may make things slower... -commit-as-soon-as-possible-after-log_start_commit - -# Ted's squelch series, still needs work -add-sysfs-bool-support -add-squelch-errors-support - -# Various disabled patches... -# -#auto-enable-journal_async_commit -#mballoc-allocate-larger-extents - -# various debugging/benchmarking assists -dump-in-use-buffers -akpm-jbd2-locking-fix - +# 5084fdf08173 + +#################################################### +# unstable patches +#################################################### + +stable-boundary +stable-boundary-undo.patch + +add-support-for-log-metadata-block-tracking-in-log +add-indirection-to-metadata-block-read-paths +cleaner +disable-writeback + +only-call-ext4_truncate-if-there-is-data-to-truncate +migrate-to-use-vfs-crypto-engine + +#crypto-rename-ext4_get_encryption_info + +crypto-add-ciphertext_access-mount-option +crypto-add-ioctls-to-backup-crypto-metadata + +add-encryption-debug-files + +# not yet ready +#dont-use-io-end-if-not-needed + +# not yet ready; patch series so ext4 has has full responsibility +# for ext4_readpage[s] and does not use mpage. +# +#move-read-page-functions-to-new-file +#include-mpage-functions-into-readpage.c +#inline-ext4_get_block-into-readpage + +add-fallocate-mode-blocking-for-debugging + +# use-discard-if-possible-in-blkdev_issue_zeroout +add-blkdiscard-ioctl + +block-dio-during-truncate + +delalloc-debug + +# note: this may make things slower... +commit-as-soon-as-possible-after-log_start_commit + +# Ted's squelch series, still needs work +add-sysfs-bool-support +add-squelch-errors-support + +# Various disabled patches... +# +#auto-enable-journal_async_commit +#mballoc-allocate-larger-extents + +# various debugging/benchmarking assists +dump-in-use-buffers +akpm-jbd2-locking-fix + diff --git a/timestamps b/timestamps index 8d170251..49df4bec 100755 --- a/timestamps +++ b/timestamps @@ -43,64 +43,8 @@ touch -d @1478656656 add-support-for-log-metadata-block-tracking-in-log touch -d @1478656658 add-indirection-to-metadata-block-read-paths touch -d @1478656938 cleaner touch -d @1478656998 disable-writeback -touch -d @1479092546 allow-ext4_truncate-to-return-an-error -touch -d @1479092548 allow-ext4_ext_truncate-to-return-an-error -touch -d @1479092549 dont-lock-buffer-head-in-ext4_commit_super-if-holding-spinlock -touch -d @1479175477 fix-mballoc-breakage-with-64k-block-size -touch -d @1479176786 fix-stack-corruption-with-64k-blocksize -touch -d @1479177610 use-current_time-for-inode-timestamps -touch -d @1479178115 allow-inode-expansion-for-nojournal-file-systems -touch -d @1479178608 remove-parameter-from-ext4_xattr_ibody_set -touch -d @1479492024 sanity-check-block-and-cluster-size -touch -d @1479493466 fix-sb-mount-options-processing -touch -d @1479493710 verify-inodes_per_group-during-mount -touch -d @1479494267 add-sanity-checking-in-count_overhead -touch -d @1479680991 factor-out-checks-from-ext4_file_write_iter -touch -d @1479681179 let-S_DAX-set-only-if-DAX-is-really-supported -touch -d @1479681366 convert-dax-reads-to-iomap-infrastructure -touch -d @1479683285 use-iomap-for-zeroing-blocks-in-DAX-mode -touch -d @1479683351 DAX-iomap-write-support -touch -d @1479683409 avoid-split-extents-for-DAX-writes -touch -d @1479685884 convert-DAX-faults-to-iomap-infrastructure -touch -d @1479686010 rip-out-DAX-handling-from-direct-IO-path -touch -d @1479692827 ext2-use-iomap_zero_range-for-zeroing-truncated-page-in-DAX-path -touch -d @1479692916 dax-rip-out-get_block-based-IO-support touch -d @1479701398 fix-quota-lockdep-failure -touch -d @1479747104 remove-unused-function-ext4_aligned_io -touch -d @1479747164 avoid-lockdep-warning-when-inheriting-encryption-context -touch -d @1479874918 add-select-for-CONFIG_FS_IOMAP -touch -d @1480188291 fix-mmp-use-after-free-during-umount -touch -d @1480188820 fscrypt-recommend-linux-fsdevel-for-fscrypto-patches -touch -d @1480190803 fscrypt-remove-unneeded-Kconfig-dependencies -touch -d @1480205269 fscrypt-move-ioctl-processing-more-fully-into-common-code -touch -d @1480210366 rename-get_crypt_info -touch -d @1480210989 fscrypt-unexport-fscrypt_initialize -touch -d @1480215918 fscrypt-move-non-public-structures-to-private-header -touch -d @1480216739 fscrypt-move-constants-to-uapi-header -touch -d @1480435993 add-EXT4_JOURNAL_DATA_FL-and-EXT4_EXTENTS_FL-to-modifiable-mask -touch -d @1480436319 be-more-strict-when-verifying-flags-set-via-SETFLAGS-ioctls -touch -d @1480610800 warn-when-page-is-dirtied-without-buffers -touch -d @1480610952 fix-inode-checksum-calculation-if-i_extra_size-is-too-small -touch -d @1480611258 get-rid-of-ext4_sb_has_crypto -touch -d @1480611351 disable-pwsalt-ioctl-when-encryption-disabled-by-config -touch -d @1480621413 forbid-i_extra_isize-not-divisible-by-4 -touch -d @1480621918 dont-read-out-of-bounds-when-checking-for-in-inode-xattrs -touch -d @1480622249 correct-detect-when-an-xattr-value-has-an-invalid-size -touch -d @1480622917 validate-s_first_meta_bg-at-mount-time -touch -d @1480698773 fix-reading-new-encrypted-symlinks-on-no-journal-file-systems -touch -d @1480795995 mbcache-correctly-handled-e_referenced-bit -touch -d @1480796933 mbache-dont-bug-if-entry-cache-cannot-be-allocated -touch -d @1480797509 mbcache-remove-unnecessary-module_get_put -touch -d @1480797828 mbcache-use-consistent-type-for-entry-count -touch -d @1480798501 mbcache-document-that-find-functions-only-return-reusable-entries -touch -d @1480800053 fix-checks-for-data-ordered-and-journal_async_commit-options -touch -d @1480801485 fix-block_validity-documentation -touch -d @1480801618 remove-another-test-in-ext4_alloc_file_blocks -touch -d @1481381701 reject-inodes-with-negative-size -touch -d @1481381761 return-enomem-instead-of-success -touch -d @1481410498 do-not-perform-data-journaling-when-encrypting touch -d @1481410558 stable-boundary -touch -d @1481596452 fix-sleep-in-atomic-context-in-grab_mapping_entry -touch -d @1481597244 series touch -d @1482020421 status -touch -d @1482022145 timestamps +touch -d @1482022368 series +touch -d @1482022430 timestamps diff --git a/use-current_time-for-inode-timestamps b/use-current_time-for-inode-timestamps deleted file mode 100644 index 86763170..00000000 --- a/use-current_time-for-inode-timestamps +++ /dev/null @@ -1,342 +0,0 @@ -ext4: use current_time() for inode timestamps - -From: Deepa Dinamani - -CURRENT_TIME_SEC and CURRENT_TIME are not y2038 safe. -current_time() will be transitioned to be y2038 safe -along with vfs. - -current_time() returns timestamps according to the -granularities set in the super_block. -The granularity check in ext4_current_time() to call -current_time() or CURRENT_TIME_SEC is not required. -Use current_time() directly to obtain timestamps -unconditionally, and remove ext4_current_time(). - -Quota files are assumed to be on the same filesystem. -Hence, use current_time() for these files as well. - -Signed-off-by: Deepa Dinamani -Signed-off-by: Theodore Ts'o -Reviewed-by: Arnd Bergmann ---- - fs/ext4/acl.c | 2 +- - fs/ext4/ext4.h | 6 ------ - fs/ext4/extents.c | 10 +++++----- - fs/ext4/ialloc.c | 2 +- - fs/ext4/inline.c | 4 ++-- - fs/ext4/inode.c | 6 +++--- - fs/ext4/ioctl.c | 8 ++++---- - fs/ext4/namei.c | 24 +++++++++++++----------- - fs/ext4/super.c | 2 +- - fs/ext4/xattr.c | 2 +- - 10 files changed, 31 insertions(+), 35 deletions(-) - -diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c -index dfa5199..fd38993 100644 ---- a/fs/ext4/acl.c -+++ b/fs/ext4/acl.c -@@ -196,7 +196,7 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type, - error = posix_acl_update_mode(inode, &inode->i_mode, &acl); - if (error) - return error; -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - } - break; -diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index 282a51b..6789379 100644 ---- a/fs/ext4/ext4.h -+++ b/fs/ext4/ext4.h -@@ -1532,12 +1532,6 @@ static inline struct ext4_inode_info *EXT4_I(struct inode *inode) - return container_of(inode, struct ext4_inode_info, vfs_inode); - } - --static inline struct timespec ext4_current_time(struct inode *inode) --{ -- return (inode->i_sb->s_time_gran < NSEC_PER_SEC) ? -- current_fs_time(inode->i_sb) : CURRENT_TIME_SEC; --} -- - static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) - { - return ino == EXT4_ROOT_INO || -diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index c930a01..786be87 100644 ---- a/fs/ext4/extents.c -+++ b/fs/ext4/extents.c -@@ -4725,7 +4725,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, - map.m_lblk += ret; - map.m_len = len = len - ret; - epos = (loff_t)map.m_lblk << inode->i_blkbits; -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - if (new_size) { - if (epos > new_size) - epos = new_size; -@@ -4853,7 +4853,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, - } - /* Now release the pages and zero block aligned part of pages */ - truncate_pagecache_range(inode, start, end - 1); -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - - ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, - flags, mode); -@@ -4878,7 +4878,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, - goto out_dio; - } - -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - if (new_size) { - ext4_update_inode_size(inode, new_size); - } else { -@@ -5568,7 +5568,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) - up_write(&EXT4_I(inode)->i_data_sem); - if (IS_SYNC(inode)) - ext4_handle_sync(handle); -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - - out_stop: -@@ -5678,7 +5678,7 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) - /* Expand file to avoid data loss if there is error while shifting */ - inode->i_size += len; - EXT4_I(inode)->i_disksize += len; -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - ret = ext4_mark_inode_dirty(handle, inode); - if (ret) - goto out_stop; -diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c -index 170421e..088afe0 100644 ---- a/fs/ext4/ialloc.c -+++ b/fs/ext4/ialloc.c -@@ -1039,7 +1039,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, - /* This is the optimal IO size (for stat), not the fs block size */ - inode->i_blocks = 0; - inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime = -- ext4_current_time(inode); -+ current_time(inode); - - memset(ei->i_data, 0, sizeof(ei->i_data)); - ei->i_dir_start_lookup = 0; -diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c -index f74d5ee..cfa87bd 100644 ---- a/fs/ext4/inline.c -+++ b/fs/ext4/inline.c -@@ -1028,7 +1028,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle, - * happen is that the times are slightly out of date - * and/or different from the directory change time. - */ -- dir->i_mtime = dir->i_ctime = ext4_current_time(dir); -+ dir->i_mtime = dir->i_ctime = current_time(dir); - ext4_update_dx_flag(dir); - dir->i_version++; - ext4_mark_inode_dirty(handle, dir); -@@ -1971,7 +1971,7 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline) - if (inode->i_nlink) - ext4_orphan_del(handle, inode); - -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - if (IS_SYNC(inode)) - ext4_handle_sync(handle); -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 3d58b2b..926ed1f 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -4029,7 +4029,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) - if (IS_SYNC(inode)) - ext4_handle_sync(handle); - -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - out_stop: - ext4_journal_stop(handle); -@@ -4183,7 +4183,7 @@ void ext4_truncate(struct inode *inode) - if (inode->i_nlink) - ext4_orphan_del(handle, inode); - -- inode->i_mtime = inode->i_ctime = ext4_current_time(inode); -+ inode->i_mtime = inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - ext4_journal_stop(handle); - -@@ -5157,7 +5157,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) - * update c/mtime in shrink case below - */ - if (!shrink) { -- inode->i_mtime = ext4_current_time(inode); -+ inode->i_mtime = current_time(inode); - inode->i_ctime = inode->i_mtime; - } - down_write(&EXT4_I(inode)->i_data_sem); -diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c -index bf5ae8e..3bba9e9 100644 ---- a/fs/ext4/ioctl.c -+++ b/fs/ext4/ioctl.c -@@ -153,7 +153,7 @@ static long swap_inode_boot_loader(struct super_block *sb, - - swap_inode_data(inode, inode_bl); - -- inode->i_ctime = inode_bl->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = inode_bl->i_ctime = current_time(inode); - - spin_lock(&sbi->s_next_gen_lock); - inode->i_generation = sbi->s_next_generation++; -@@ -272,7 +272,7 @@ static int ext4_ioctl_setflags(struct inode *inode, - } - - ext4_set_inode_flags(inode); -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - - err = ext4_mark_iloc_dirty(handle, inode, &iloc); - flags_err: -@@ -368,7 +368,7 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) - } - - EXT4_I(inode)->i_projid = kprojid; -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - out_dirty: - rc = ext4_mark_iloc_dirty(handle, inode, &iloc); - if (!err) -@@ -500,7 +500,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - } - err = ext4_reserve_inode_write(handle, inode, &iloc); - if (err == 0) { -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - inode->i_generation = generation; - err = ext4_mark_iloc_dirty(handle, inode, &iloc); - } -diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c -index 104f8bf..eadba91 100644 ---- a/fs/ext4/namei.c -+++ b/fs/ext4/namei.c -@@ -1941,7 +1941,7 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname, - * happen is that the times are slightly out of date - * and/or different from the directory change time. - */ -- dir->i_mtime = dir->i_ctime = ext4_current_time(dir); -+ dir->i_mtime = dir->i_ctime = current_time(dir); - ext4_update_dx_flag(dir); - dir->i_version++; - ext4_mark_inode_dirty(handle, dir); -@@ -2987,7 +2987,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) - * recovery. */ - inode->i_size = 0; - ext4_orphan_add(handle, inode); -- inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode); -+ inode->i_ctime = dir->i_ctime = dir->i_mtime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - ext4_dec_count(handle, dir); - ext4_update_dx_flag(dir); -@@ -3050,13 +3050,13 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) - retval = ext4_delete_entry(handle, dir, de, bh); - if (retval) - goto end_unlink; -- dir->i_ctime = dir->i_mtime = ext4_current_time(dir); -+ dir->i_ctime = dir->i_mtime = current_time(dir); - ext4_update_dx_flag(dir); - ext4_mark_inode_dirty(handle, dir); - drop_nlink(inode); - if (!inode->i_nlink) - ext4_orphan_add(handle, inode); -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - - end_unlink: -@@ -3254,7 +3254,7 @@ static int ext4_link(struct dentry *old_dentry, - if (IS_DIRSYNC(dir)) - ext4_handle_sync(handle); - -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - ext4_inc_count(handle, inode); - ihold(inode); - -@@ -3381,7 +3381,7 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, - ent->de->file_type = file_type; - ent->dir->i_version++; - ent->dir->i_ctime = ent->dir->i_mtime = -- ext4_current_time(ent->dir); -+ current_time(ent->dir); - ext4_mark_inode_dirty(handle, ent->dir); - BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata"); - if (!ent->inlined) { -@@ -3651,7 +3651,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, - * Like most other Unix systems, set the ctime for inodes on a - * rename. - */ -- old.inode->i_ctime = ext4_current_time(old.inode); -+ old.inode->i_ctime = current_time(old.inode); - ext4_mark_inode_dirty(handle, old.inode); - - if (!whiteout) { -@@ -3663,9 +3663,9 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, - - if (new.inode) { - ext4_dec_count(handle, new.inode); -- new.inode->i_ctime = ext4_current_time(new.inode); -+ new.inode->i_ctime = current_time(new.inode); - } -- old.dir->i_ctime = old.dir->i_mtime = ext4_current_time(old.dir); -+ old.dir->i_ctime = old.dir->i_mtime = current_time(old.dir); - ext4_update_dx_flag(old.dir); - if (old.dir_bh) { - retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino); -@@ -3723,6 +3723,7 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry, - }; - u8 new_file_type; - int retval; -+ struct timespec ctime; - - if ((ext4_encrypted_inode(old_dir) || - ext4_encrypted_inode(new_dir)) && -@@ -3823,8 +3824,9 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry, - * Like most other Unix systems, set the ctime for inodes on a - * rename. - */ -- old.inode->i_ctime = ext4_current_time(old.inode); -- new.inode->i_ctime = ext4_current_time(new.inode); -+ ctime = current_time(old.inode); -+ old.inode->i_ctime = ctime; -+ new.inode->i_ctime = ctime; - ext4_mark_inode_dirty(handle, old.inode); - ext4_mark_inode_dirty(handle, new.inode); - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 45589c8..f86d0cb 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -5351,7 +5351,7 @@ static int ext4_quota_off(struct super_block *sb, int type) - handle = ext4_journal_start(inode, EXT4_HT_QUOTA, 1); - if (IS_ERR(handle)) - goto out; -- inode->i_mtime = inode->i_ctime = CURRENT_TIME; -+ inode->i_mtime = inode->i_ctime = current_time(inode); - ext4_mark_inode_dirty(handle, inode); - ext4_journal_stop(handle); - -diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index d77be9e..9c1bb5c 100644 ---- a/fs/ext4/xattr.c -+++ b/fs/ext4/xattr.c -@@ -1249,7 +1249,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, - } - if (!error) { - ext4_xattr_update_super_block(handle, inode->i_sb); -- inode->i_ctime = ext4_current_time(inode); -+ inode->i_ctime = current_time(inode); - if (!value) - ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); - error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); diff --git a/use-iomap-for-zeroing-blocks-in-DAX-mode b/use-iomap-for-zeroing-blocks-in-DAX-mode deleted file mode 100644 index 1b23eaf8..00000000 --- a/use-iomap-for-zeroing-blocks-in-DAX-mode +++ /dev/null @@ -1,36 +0,0 @@ -ext4: use iomap for zeroing blocks in DAX mode - -From: Jan Kara - -Use iomap infrastructure for zeroing blocks when in DAX mode. -ext4_iomap_begin() handles read requests just fine and that's all that -is needed for iomap_zero_range(). - -Reviewed-by: Ross Zwisler -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/inode.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 83e8411370d3..df017ce3e52d 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3849,8 +3849,10 @@ static int ext4_block_zero_page_range(handle_t *handle, - if (length > max || length < 0) - length = max; - -- if (IS_DAX(inode)) -- return dax_zero_page_range(inode, from, length, ext4_get_block); -+ if (IS_DAX(inode)) { -+ return iomap_zero_range(inode, from, length, NULL, -+ &ext4_iomap_ops); -+ } - return __ext4_block_zero_page_range(handle, mapping, from, length); - } - --- -2.6.6 - - diff --git a/validate-s_first_meta_bg-at-mount-time b/validate-s_first_meta_bg-at-mount-time deleted file mode 100644 index 6753384a..00000000 --- a/validate-s_first_meta_bg-at-mount-time +++ /dev/null @@ -1,85 +0,0 @@ -ext4: validate s_first_meta_bg at mount time - -From: Eryu Guan - -Ralf Spenneberg reported that he hit a kernel crash when mounting a -modified ext4 image. And it turns out that kernel crashed when -calculating fs overhead (ext4_calculate_overhead()), this is because -the image has very large s_first_meta_bg (debug code shows it's -842150400), and ext4 overruns the memory in count_overhead() when -setting bitmap buffer, which is PAGE_SIZE. - -ext4_calculate_overhead(): - buf = get_zeroed_page(GFP_NOFS); <=== PAGE_SIZE buffer - blks = count_overhead(sb, i, buf); - -count_overhead(): - for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { <=== j = 842150400 - ext4_set_bit(EXT4_B2C(sbi, s++), buf); <=== buffer overrun - count++; - } - -This can be reproduced easily for me by this script: - - #!/bin/bash - rm -f fs.img - mkdir -p /mnt/ext4 - fallocate -l 16M fs.img - mke2fs -t ext4 -O bigalloc,meta_bg,^resize_inode -F fs.img - debugfs -w -R "ssv first_meta_bg 842150400" fs.img - mount -o loop fs.img /mnt/ext4 - -Fix it by validating s_first_meta_bg first at mount time, and -refusing to mount if its value exceeds the largest possible meta_bg -number. - -Reported-by: Ralf Spenneberg -Signed-off-by: Eryu Guan -Signed-off-by: Theodore Ts'o -Reviewed-by: Andreas Dilger ---- - -In e2fsprogs, we avoided a similar buffer overrun: -f66e6ce libext2fs: avoid buffer overflow if s_first_meta_bg is too big - -and e2fsck could detect & fix large s_first_meta_bg: -7a4352d e2fsck: fix file systems with an overly large s_first_meta_bg - -But I suspect that there's an off-by-one bug in e2fsck code, shouldn't the -upper boundary of s_first_meta_bg be (fs->desc_blocks - 1)? Something like: - - e2fsck/super.c:643 - if (ext2fs_has_feature_meta_bg(fs->super) && - - (fs->super->s_first_meta_bg > fs->desc_blocks)) { - - pctx.group = fs->desc_blocks; - + (fs->super->s_first_meta_bg >= fs->desc_blocks)) { - + pctx.group = fs->desc_blocks - 1; - pctx.num = fs->super->s_first_meta_bg; - - fs/ext4/super.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 52b0530..8f46a07 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3814,6 +3814,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); - db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / - EXT4_DESC_PER_BLOCK(sb); -+ if (ext4_has_feature_meta_bg(sb)) { -+ if (le32_to_cpu(es->s_first_meta_bg) >= db_count) { -+ ext4_msg(sb, KERN_WARNING, -+ "first meta block group too large: %u " -+ "(group descriptor block count %u)", -+ le32_to_cpu(es->s_first_meta_bg), db_count); -+ goto failed_mount; -+ } -+ } - sbi->s_group_desc = ext4_kvmalloc(db_count * - sizeof(struct buffer_head *), - GFP_KERNEL); --- -2.9.3 - - diff --git a/verify-inodes_per_group-during-mount b/verify-inodes_per_group-during-mount deleted file mode 100644 index 257e9c03..00000000 --- a/verify-inodes_per_group-during-mount +++ /dev/null @@ -1,49 +0,0 @@ -ext4: use more strict checks for inodes_per_block on mount - -Centralize the checks for inodes_per_block and be more strict to make -sure the inodes_per_block_group can't end up being zero. - -Signed-off-by: Theodore Ts'o -Reviewed-by: Andreas Dilger -Cc: stable@vger.kernel.org ---- - fs/ext4/super.c | 15 ++++++--------- - 1 file changed, 6 insertions(+), 9 deletions(-) - -diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 404e6f3c1bed..689c02df1af4 100644 ---- a/fs/ext4/super.c -+++ b/fs/ext4/super.c -@@ -3668,12 +3668,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - - sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); - sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); -- if (EXT4_INODE_SIZE(sb) == 0 || EXT4_INODES_PER_GROUP(sb) == 0) -- goto cantfind_ext4; - - sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb); - if (sbi->s_inodes_per_block == 0) - goto cantfind_ext4; -+ if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || -+ sbi->s_inodes_per_group > blocksize * 8) { -+ ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n", -+ sbi->s_blocks_per_group); -+ goto failed_mount; -+ } - sbi->s_itb_per_group = sbi->s_inodes_per_group / - sbi->s_inodes_per_block; - sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb); -@@ -3756,13 +3760,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) - } - sbi->s_cluster_ratio = clustersize / blocksize; - -- if (sbi->s_inodes_per_group > blocksize * 8) { -- ext4_msg(sb, KERN_ERR, -- "#inodes per group too big: %lu", -- sbi->s_inodes_per_group); -- goto failed_mount; -- } -- - /* Do we have standard group size of clustersize * 8 blocks ? */ - if (sbi->s_blocks_per_group == clustersize << 3) - set_opt2(sb, STD_GROUP_SIZE); diff --git a/warn-when-page-is-dirtied-without-buffers b/warn-when-page-is-dirtied-without-buffers deleted file mode 100644 index de14391a..00000000 --- a/warn-when-page-is-dirtied-without-buffers +++ /dev/null @@ -1,57 +0,0 @@ -ext4: warn when page is dirtied without buffers - -From: Jan Kara - -Warn when a page is dirtied without buffers (as that will likely lead to -a crash in ext4_writepages()) or when it gets newly dirtied without the -page being locked (as there is nothing that prevents buffers to get -stripped just before calling set_page_dirty() under memory pressure). - -Signed-off-by: Jan Kara -Signed-off-by: Theodore Ts'o ---- - fs/ext4/inode.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -Ted, how about merging this debug patch? It should catch situations like what -Nikolai reported early. I've run xfstests and neither warning triggers in my -test setup but maybe it will for somebody. - -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 9c064727ed62..db0f11f49a37 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -3615,6 +3615,13 @@ static int ext4_journalled_set_page_dirty(struct page *page) - return __set_page_dirty_nobuffers(page); - } - -+static int ext4_set_page_dirty(struct page *page) -+{ -+ WARN_ON_ONCE(!PageLocked(page) && !PageDirty(page)); -+ WARN_ON_ONCE(!page_has_buffers(page)); -+ return __set_page_dirty_buffers(page); -+} -+ - static const struct address_space_operations ext4_aops = { - .readpage = ext4_readpage, - .readpages = ext4_readpages, -@@ -3622,6 +3629,7 @@ static const struct address_space_operations ext4_aops = { - .writepages = ext4_writepages, - .write_begin = ext4_write_begin, - .write_end = ext4_write_end, -+ .set_page_dirty = ext4_set_page_dirty, - .bmap = ext4_bmap, - .invalidatepage = ext4_invalidatepage, - .releasepage = ext4_releasepage, -@@ -3654,6 +3662,7 @@ static const struct address_space_operations ext4_da_aops = { - .writepages = ext4_writepages, - .write_begin = ext4_da_write_begin, - .write_end = ext4_da_write_end, -+ .set_page_dirty = ext4_set_page_dirty, - .bmap = ext4_bmap, - .invalidatepage = ext4_da_invalidatepage, - .releasepage = ext4_releasepage, --- -2.6.6 - - -- 2.11.4.GIT