]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 May 2016 22:00:59 +0000 (15:00 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 May 2016 22:00:59 +0000 (15:00 -0700)
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

queue-4.5/ext4-fscrypto-avoid-rcu-lookup-in-d_revalidate.patch [new file with mode: 0644]
queue-4.5/f2fs-cover-large-section-in-sanity-check-of-super.patch [new file with mode: 0644]
queue-4.5/f2fs-crypto-handle-unexpected-lack-of-encryption-keys.patch [new file with mode: 0644]
queue-4.5/f2fs-crypto-make-sure-the-encryption-info-is-initialized-on-opendir-2.patch [new file with mode: 0644]
queue-4.5/f2fs-do-f2fs_balance_fs-when-block-is-allocated.patch [new file with mode: 0644]
queue-4.5/f2fs-don-t-need-to-call-set_page_dirty-for-io-error.patch [new file with mode: 0644]
queue-4.5/series

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 (file)
index 0000000..eed4475
--- /dev/null
@@ -0,0 +1,42 @@
+From 03a8bb0e53d9562276045bdfcf2b5de2e4cff5a1 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Tue, 12 Apr 2016 16:05:36 -0700
+Subject: ext4/fscrypto: avoid RCU lookup in d_revalidate
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+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 <viro@zeniv.linux.org.uk>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Cc: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/random.h>
+ #include <linux/scatterlist.h>
+ #include <linux/spinlock_types.h>
++#include <linux/namei.h>
+ #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 (file)
index 0000000..97c8898
--- /dev/null
@@ -0,0 +1,209 @@
+From fd694733d523df1e0a583cf5c4c08e41d7bf9fa3 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Sun, 20 Mar 2016 15:33:20 -0700
+Subject: f2fs: cover large section in sanity check of super
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+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 <linux@matthiasprager.de>
+Reported-by: David Gnedt <david.gnedt@davizone.at>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..d9e552a
--- /dev/null
@@ -0,0 +1,59 @@
+From ae1086686487f13130937918ca91d920c1daafcb Mon Sep 17 00:00:00 2001
+From: Chao Yu <chao2.yu@samsung.com>
+Date: Sun, 14 Feb 2016 18:58:35 +0800
+Subject: f2fs crypto: handle unexpected lack of encryption keys
+
+From: Chao Yu <chao2.yu@samsung.com>
+
+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 <tytso@mit.edu>
+Signed-off-by: Chao Yu <chao2.yu@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..ba658d6
--- /dev/null
@@ -0,0 +1,43 @@
+From ed3360abbc0412f32c398e1c58887d74f3d04225 Mon Sep 17 00:00:00 2001
+From: Chao Yu <chao2.yu@samsung.com>
+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 <chao2.yu@samsung.com>
+
+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 <tytso@mit.edu>
+Signed-off-by: Chao Yu <chao2.yu@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..ef1317f
--- /dev/null
@@ -0,0 +1,73 @@
+From 3c082b7b5b28be606ed9ef11e4741df7c722c92e Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+Date: Sat, 23 Jan 2016 13:35:18 -0800
+Subject: f2fs: do f2fs_balance_fs when block is allocated
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+commit 3c082b7b5b28be606ed9ef11e4741df7c722c92e upstream.
+
+We should consider data block allocation to trigger f2fs_balance_fs.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..941931c
--- /dev/null
@@ -0,0 +1,43 @@
+From e3ef18762f5757d3fb86f75ca59315db6d17d719 Mon Sep 17 00:00:00 2001
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+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 <jaegeuk@kernel.org>
+
+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: [<ffffffffc025483f>] update_dirty_page+0x6f/0xd0 [f2fs]
+
+and this task is already holding:
+ (&(&q->__queue_lock)->rlock){-.-.-.}, at: [<ffffffff81396ea2>] 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 <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+               }
index 2edf17232493563151495cca46b65ad450445736..7e3066583dc244c86ce09c376ee1b8a0022292da 100644 (file)
@@ -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