From: Greg Kroah-Hartman Date: Mon, 2 May 2016 22:00:59 +0000 (-0700) Subject: 4.5-stable patches X-Git-Tag: v3.14.68~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=00fb2c000788596d5723ba2935d16322031991fb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.5-stable patches added patches: ext4-fscrypto-avoid-rcu-lookup-in-d_revalidate.patch f2fs-cover-large-section-in-sanity-check-of-super.patch f2fs-crypto-handle-unexpected-lack-of-encryption-keys.patch f2fs-crypto-make-sure-the-encryption-info-is-initialized-on-opendir-2.patch f2fs-do-f2fs_balance_fs-when-block-is-allocated.patch f2fs-don-t-need-to-call-set_page_dirty-for-io-error.patch --- diff --git a/queue-4.5/ext4-fscrypto-avoid-rcu-lookup-in-d_revalidate.patch b/queue-4.5/ext4-fscrypto-avoid-rcu-lookup-in-d_revalidate.patch new file mode 100644 index 00000000000..eed44756303 --- /dev/null +++ b/queue-4.5/ext4-fscrypto-avoid-rcu-lookup-in-d_revalidate.patch @@ -0,0 +1,42 @@ +From 03a8bb0e53d9562276045bdfcf2b5de2e4cff5a1 Mon Sep 17 00:00:00 2001 +From: Jaegeuk Kim +Date: Tue, 12 Apr 2016 16:05:36 -0700 +Subject: ext4/fscrypto: avoid RCU lookup in d_revalidate + +From: Jaegeuk Kim + +commit 03a8bb0e53d9562276045bdfcf2b5de2e4cff5a1 upstream. + +As Al pointed, d_revalidate should return RCU lookup before using d_inode. +This was originally introduced by: +commit 34286d666230 ("fs: rcu-walk aware d_revalidate method"). + +Reported-by: Al Viro +Signed-off-by: Jaegeuk Kim +Cc: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/crypto.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/ext4/crypto.c ++++ b/fs/ext4/crypto.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "ext4_extents.h" + #include "xattr.h" +@@ -479,6 +480,9 @@ static int ext4_d_revalidate(struct dent + struct ext4_crypt_info *ci; + int dir_has_key, cached_with_key; + ++ if (flags & LOOKUP_RCU) ++ return -ECHILD; ++ + dir = dget_parent(dentry); + if (!ext4_encrypted_inode(d_inode(dir))) { + dput(dir); diff --git a/queue-4.5/f2fs-cover-large-section-in-sanity-check-of-super.patch b/queue-4.5/f2fs-cover-large-section-in-sanity-check-of-super.patch new file mode 100644 index 00000000000..97c8898a048 --- /dev/null +++ b/queue-4.5/f2fs-cover-large-section-in-sanity-check-of-super.patch @@ -0,0 +1,209 @@ +From fd694733d523df1e0a583cf5c4c08e41d7bf9fa3 Mon Sep 17 00:00:00 2001 +From: Jaegeuk Kim +Date: Sun, 20 Mar 2016 15:33:20 -0700 +Subject: f2fs: cover large section in sanity check of super + +From: Jaegeuk Kim + +commit fd694733d523df1e0a583cf5c4c08e41d7bf9fa3 upstream. + +This patch fixes the bug which does not cover a large section case when checking +the sanity of superblock. +If f2fs detects misalignment, it will fix the superblock during the mount time, +so it doesn't need to trigger fsck.f2fs further. + +Reported-by: Matthias Prager +Reported-by: David Gnedt +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman + +--- + fs/f2fs/super.c | 102 +++++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 65 insertions(+), 37 deletions(-) + +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -926,9 +926,25 @@ static loff_t max_file_blocks(void) + return result; + } + ++static int __f2fs_commit_super(struct buffer_head *bh, ++ struct f2fs_super_block *super) ++{ ++ lock_buffer(bh); ++ if (super) ++ memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); ++ set_buffer_uptodate(bh); ++ set_buffer_dirty(bh); ++ unlock_buffer(bh); ++ ++ /* it's rare case, we can do fua all the time */ ++ return __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); ++} ++ + static inline bool sanity_check_area_boundary(struct super_block *sb, +- struct f2fs_super_block *raw_super) ++ struct buffer_head *bh) + { ++ struct f2fs_super_block *raw_super = (struct f2fs_super_block *) ++ (bh->b_data + F2FS_SUPER_OFFSET); + u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr); + u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr); + u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr); +@@ -942,6 +958,10 @@ static inline bool sanity_check_area_bou + u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main); + u32 segment_count = le32_to_cpu(raw_super->segment_count); + u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); ++ u64 main_end_blkaddr = main_blkaddr + ++ (segment_count_main << log_blocks_per_seg); ++ u64 seg_end_blkaddr = segment0_blkaddr + ++ (segment_count << log_blocks_per_seg); + + if (segment0_blkaddr != cp_blkaddr) { + f2fs_msg(sb, KERN_INFO, +@@ -986,22 +1006,45 @@ static inline bool sanity_check_area_bou + return true; + } + +- if (main_blkaddr + (segment_count_main << log_blocks_per_seg) != +- segment0_blkaddr + (segment_count << log_blocks_per_seg)) { ++ if (main_end_blkaddr > seg_end_blkaddr) { + f2fs_msg(sb, KERN_INFO, +- "Wrong MAIN_AREA boundary, start(%u) end(%u) blocks(%u)", ++ "Wrong MAIN_AREA boundary, start(%u) end(%u) block(%u)", + main_blkaddr, +- segment0_blkaddr + (segment_count << log_blocks_per_seg), ++ segment0_blkaddr + ++ (segment_count << log_blocks_per_seg), + segment_count_main << log_blocks_per_seg); + return true; ++ } else if (main_end_blkaddr < seg_end_blkaddr) { ++ int err = 0; ++ char *res; ++ ++ /* fix in-memory information all the time */ ++ raw_super->segment_count = cpu_to_le32((main_end_blkaddr - ++ segment0_blkaddr) >> log_blocks_per_seg); ++ ++ if (f2fs_readonly(sb) || bdev_read_only(sb->s_bdev)) { ++ res = "internally"; ++ } else { ++ err = __f2fs_commit_super(bh, NULL); ++ res = err ? "failed" : "done"; ++ } ++ f2fs_msg(sb, KERN_INFO, ++ "Fix alignment : %s, start(%u) end(%u) block(%u)", ++ res, main_blkaddr, ++ segment0_blkaddr + ++ (segment_count << log_blocks_per_seg), ++ segment_count_main << log_blocks_per_seg); ++ if (err) ++ return true; + } +- + return false; + } + + static int sanity_check_raw_super(struct super_block *sb, +- struct f2fs_super_block *raw_super) ++ struct buffer_head *bh) + { ++ struct f2fs_super_block *raw_super = (struct f2fs_super_block *) ++ (bh->b_data + F2FS_SUPER_OFFSET); + unsigned int blocksize; + + if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) { +@@ -1068,7 +1111,7 @@ static int sanity_check_raw_super(struct + } + + /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ +- if (sanity_check_area_boundary(sb, raw_super)) ++ if (sanity_check_area_boundary(sb, bh)) + return 1; + + return 0; +@@ -1144,7 +1187,7 @@ static int read_raw_super_block(struct s + { + int block; + struct buffer_head *bh; +- struct f2fs_super_block *super, *buf; ++ struct f2fs_super_block *super; + int err = 0; + + super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL); +@@ -1160,11 +1203,8 @@ static int read_raw_super_block(struct s + continue; + } + +- buf = (struct f2fs_super_block *) +- (bh->b_data + F2FS_SUPER_OFFSET); +- + /* sanity checking of raw super */ +- if (sanity_check_raw_super(sb, buf)) { ++ if (sanity_check_raw_super(sb, bh)) { + f2fs_msg(sb, KERN_ERR, + "Can't find valid F2FS filesystem in %dth superblock", + block + 1); +@@ -1174,7 +1214,8 @@ static int read_raw_super_block(struct s + } + + if (!*raw_super) { +- memcpy(super, buf, sizeof(*super)); ++ memcpy(super, bh->b_data + F2FS_SUPER_OFFSET, ++ sizeof(*super)); + *valid_super_block = block; + *raw_super = super; + } +@@ -1194,42 +1235,29 @@ static int read_raw_super_block(struct s + return err; + } + +-static int __f2fs_commit_super(struct f2fs_sb_info *sbi, int block) ++int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) + { +- struct f2fs_super_block *super = F2FS_RAW_SUPER(sbi); + struct buffer_head *bh; + int err; + +- bh = sb_getblk(sbi->sb, block); ++ /* write back-up superblock first */ ++ bh = sb_getblk(sbi->sb, sbi->valid_super_block ? 0: 1); + if (!bh) + return -EIO; +- +- lock_buffer(bh); +- memcpy(bh->b_data + F2FS_SUPER_OFFSET, super, sizeof(*super)); +- set_buffer_uptodate(bh); +- set_buffer_dirty(bh); +- unlock_buffer(bh); +- +- /* it's rare case, we can do fua all the time */ +- err = __sync_dirty_buffer(bh, WRITE_FLUSH_FUA); ++ err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi)); + brelse(bh); + +- return err; +-} +- +-int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) +-{ +- int err; +- +- /* write back-up superblock first */ +- err = __f2fs_commit_super(sbi, sbi->valid_super_block ? 0 : 1); +- + /* if we are in recovery path, skip writing valid superblock */ + if (recover || err) + return err; + + /* write current valid superblock */ +- return __f2fs_commit_super(sbi, sbi->valid_super_block); ++ bh = sb_getblk(sbi->sb, sbi->valid_super_block); ++ if (!bh) ++ return -EIO; ++ err = __f2fs_commit_super(bh, F2FS_RAW_SUPER(sbi)); ++ brelse(bh); ++ return err; + } + + static int f2fs_fill_super(struct super_block *sb, void *data, int silent) diff --git a/queue-4.5/f2fs-crypto-handle-unexpected-lack-of-encryption-keys.patch b/queue-4.5/f2fs-crypto-handle-unexpected-lack-of-encryption-keys.patch new file mode 100644 index 00000000000..d9e552a7fde --- /dev/null +++ b/queue-4.5/f2fs-crypto-handle-unexpected-lack-of-encryption-keys.patch @@ -0,0 +1,59 @@ +From ae1086686487f13130937918ca91d920c1daafcb Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Sun, 14 Feb 2016 18:58:35 +0800 +Subject: f2fs crypto: handle unexpected lack of encryption keys + +From: Chao Yu + +commit ae1086686487f13130937918ca91d920c1daafcb upstream. + +This patch syncs f2fs with commit abdd438b26b4 ("ext4 crypto: handle +unexpected lack of encryption keys") from ext4. + +Fix up attempts by users to try to write to a file when they don't +have access to the encryption key. + +Signed-off-by: Theodore Ts'o +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman + +--- + fs/f2fs/crypto_policy.c | 3 ++- + fs/f2fs/file.c | 6 +++++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/f2fs/crypto_policy.c ++++ b/fs/f2fs/crypto_policy.c +@@ -192,7 +192,8 @@ int f2fs_inherit_context(struct inode *p + return res; + + ci = F2FS_I(parent)->i_crypt_info; +- BUG_ON(ci == NULL); ++ if (ci == NULL) ++ return -ENOKEY; + + ctx.format = F2FS_ENCRYPTION_CONTEXT_FORMAT_V1; + +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -425,6 +425,8 @@ static int f2fs_file_mmap(struct file *f + err = f2fs_get_encryption_info(inode); + if (err) + return 0; ++ if (!f2fs_encrypted_inode(inode)) ++ return -ENOKEY; + } + + /* we don't need to use inline_data strictly */ +@@ -444,7 +446,9 @@ static int f2fs_file_open(struct inode * + if (!ret && f2fs_encrypted_inode(inode)) { + ret = f2fs_get_encryption_info(inode); + if (ret) +- ret = -EACCES; ++ return -EACCES; ++ if (!f2fs_encrypted_inode(inode)) ++ return -ENOKEY; + } + return ret; + } diff --git a/queue-4.5/f2fs-crypto-make-sure-the-encryption-info-is-initialized-on-opendir-2.patch b/queue-4.5/f2fs-crypto-make-sure-the-encryption-info-is-initialized-on-opendir-2.patch new file mode 100644 index 00000000000..ba658d6e592 --- /dev/null +++ b/queue-4.5/f2fs-crypto-make-sure-the-encryption-info-is-initialized-on-opendir-2.patch @@ -0,0 +1,43 @@ +From ed3360abbc0412f32c398e1c58887d74f3d04225 Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Sun, 14 Feb 2016 18:56:55 +0800 +Subject: f2fs crypto: make sure the encryption info is initialized on opendir(2) + +From: Chao Yu + +commit ed3360abbc0412f32c398e1c58887d74f3d04225 upstream. + +This patch syncs f2fs with commit 6bc445e0ff44 ("ext4 crypto: make +sure the encryption info is initialized on opendir(2)") from ext4. + +Signed-off-by: Theodore Ts'o +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman + +--- + fs/f2fs/dir.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/fs/f2fs/dir.c ++++ b/fs/f2fs/dir.c +@@ -892,11 +892,19 @@ out: + return err; + } + ++static int f2fs_dir_open(struct inode *inode, struct file *filp) ++{ ++ if (f2fs_encrypted_inode(inode)) ++ return f2fs_get_encryption_info(inode) ? -EACCES : 0; ++ return 0; ++} ++ + const struct file_operations f2fs_dir_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, + .iterate = f2fs_readdir, + .fsync = f2fs_sync_file, ++ .open = f2fs_dir_open, + .unlocked_ioctl = f2fs_ioctl, + #ifdef CONFIG_COMPAT + .compat_ioctl = f2fs_compat_ioctl, diff --git a/queue-4.5/f2fs-do-f2fs_balance_fs-when-block-is-allocated.patch b/queue-4.5/f2fs-do-f2fs_balance_fs-when-block-is-allocated.patch new file mode 100644 index 00000000000..ef1317f1277 --- /dev/null +++ b/queue-4.5/f2fs-do-f2fs_balance_fs-when-block-is-allocated.patch @@ -0,0 +1,73 @@ +From 3c082b7b5b28be606ed9ef11e4741df7c722c92e Mon Sep 17 00:00:00 2001 +From: Jaegeuk Kim +Date: Sat, 23 Jan 2016 13:35:18 -0800 +Subject: f2fs: do f2fs_balance_fs when block is allocated + +From: Jaegeuk Kim + +commit 3c082b7b5b28be606ed9ef11e4741df7c722c92e upstream. + +We should consider data block allocation to trigger f2fs_balance_fs. + +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman + +--- + fs/f2fs/data.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -504,7 +504,7 @@ static int __allocate_data_blocks(struct + struct dnode_of_data dn; + u64 start = F2FS_BYTES_TO_BLK(offset); + u64 len = F2FS_BYTES_TO_BLK(count); +- bool allocated; ++ bool allocated = false; + u64 end_offset; + int err = 0; + +@@ -546,7 +546,7 @@ static int __allocate_data_blocks(struct + f2fs_put_dnode(&dn); + f2fs_unlock_op(sbi); + +- f2fs_balance_fs(sbi, dn.node_changed); ++ f2fs_balance_fs(sbi, allocated); + } + return err; + +@@ -556,7 +556,7 @@ sync_out: + f2fs_put_dnode(&dn); + out: + f2fs_unlock_op(sbi); +- f2fs_balance_fs(sbi, dn.node_changed); ++ f2fs_balance_fs(sbi, allocated); + return err; + } + +@@ -650,14 +650,14 @@ get_next: + if (dn.ofs_in_node >= end_offset) { + if (allocated) + sync_inode_page(&dn); +- allocated = false; + f2fs_put_dnode(&dn); + + if (create) { + f2fs_unlock_op(sbi); +- f2fs_balance_fs(sbi, dn.node_changed); ++ f2fs_balance_fs(sbi, allocated); + f2fs_lock_op(sbi); + } ++ allocated = false; + + set_new_dnode(&dn, inode, NULL, NULL, 0); + err = get_dnode_of_data(&dn, pgofs, mode); +@@ -715,7 +715,7 @@ put_out: + unlock_out: + if (create) { + f2fs_unlock_op(sbi); +- f2fs_balance_fs(sbi, dn.node_changed); ++ f2fs_balance_fs(sbi, allocated); + } + out: + trace_f2fs_map_blocks(inode, map, err); diff --git a/queue-4.5/f2fs-don-t-need-to-call-set_page_dirty-for-io-error.patch b/queue-4.5/f2fs-don-t-need-to-call-set_page_dirty-for-io-error.patch new file mode 100644 index 00000000000..941931c0f84 --- /dev/null +++ b/queue-4.5/f2fs-don-t-need-to-call-set_page_dirty-for-io-error.patch @@ -0,0 +1,43 @@ +From e3ef18762f5757d3fb86f75ca59315db6d17d719 Mon Sep 17 00:00:00 2001 +From: Jaegeuk Kim +Date: Mon, 25 Jan 2016 14:31:58 -0800 +Subject: f2fs: don't need to call set_page_dirty for io error + +From: Jaegeuk Kim + +commit e3ef18762f5757d3fb86f75ca59315db6d17d719 upstream. + +If end_io gets an error, we don't need to set the page as dirty, since we +already set f2fs_stop_checkpoint which will not flush any data. + +This will resolve the following warning. + +====================================================== +[ INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected ] +4.4.0+ #9 Tainted: G O +------------------------------------------------------ +xfs_io/26773 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: + (&(&sbi->inode_lock[i])->rlock){+.+...}, at: [] update_dirty_page+0x6f/0xd0 [f2fs] + +and this task is already holding: + (&(&q->__queue_lock)->rlock){-.-.-.}, at: [] blk_queue_bio+0x422/0x490 +which would create a new lock dependency: + (&(&q->__queue_lock)->rlock){-.-.-.} -> (&(&sbi->inode_lock[i])->rlock){+.+...} + +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman + +--- + fs/f2fs/data.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -67,7 +67,6 @@ static void f2fs_write_end_io(struct bio + f2fs_restore_and_release_control_page(&page); + + if (unlikely(bio->bi_error)) { +- set_page_dirty(page); + set_bit(AS_EIO, &page->mapping->flags); + f2fs_stop_checkpoint(sbi); + } diff --git a/queue-4.5/series b/queue-4.5/series index 2edf1723249..7e3066583dc 100644 --- a/queue-4.5/series +++ b/queue-4.5/series @@ -161,3 +161,9 @@ x86-mm-kmmio-fix-mmiotrace-for-hugepages.patch ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch f2fs-crypto-fix-corrupted-symlink-in-encrypted-case.patch f2fs-slightly-reorganize-read_raw_super_block.patch +f2fs-cover-large-section-in-sanity-check-of-super.patch +ext4-fscrypto-avoid-rcu-lookup-in-d_revalidate.patch +f2fs-do-f2fs_balance_fs-when-block-is-allocated.patch +f2fs-don-t-need-to-call-set_page_dirty-for-io-error.patch +f2fs-crypto-handle-unexpected-lack-of-encryption-keys.patch +f2fs-crypto-make-sure-the-encryption-info-is-initialized-on-opendir-2.patch