aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-11 12:15:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-11 12:15:58 -0500
commit2b95550a4323e501e133dac1c9c9cad6ff17f4c1 (patch)
treec68b793cfc897e003d08164cb3f03db274766e6f
parent13ebfd0601228fbbd92707ce4944ab1a09a4d821 (diff)
parent6e78b3f7a193546b1c00a6d084596e774f147169 (diff)
Merge branch 'for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "This has two last minute fixes. The highest priority here is a regression fix for the decompression code, but we also fixed up a problem with the 32-bit compat ioctls. The decompression bug could hand back the wrong data on big reads when zlib was used. I have a larger cleanup to make the math here less error prone, but at this stage in the release Omar's patch is the best choice" * 'for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: btrfs: fix btrfs_decompress_buf2page() btrfs: fix btrfs_compat_ioctl failures on non-compat ioctls
-rw-r--r--fs/btrfs/compression.c39
-rw-r--r--fs/btrfs/ioctl.c6
2 files changed, 28 insertions, 17 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 7f390849343b..c4444d6f439f 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -1024,6 +1024,7 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
1024 unsigned long buf_offset; 1024 unsigned long buf_offset;
1025 unsigned long current_buf_start; 1025 unsigned long current_buf_start;
1026 unsigned long start_byte; 1026 unsigned long start_byte;
1027 unsigned long prev_start_byte;
1027 unsigned long working_bytes = total_out - buf_start; 1028 unsigned long working_bytes = total_out - buf_start;
1028 unsigned long bytes; 1029 unsigned long bytes;
1029 char *kaddr; 1030 char *kaddr;
@@ -1071,26 +1072,34 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
1071 if (!bio->bi_iter.bi_size) 1072 if (!bio->bi_iter.bi_size)
1072 return 0; 1073 return 0;
1073 bvec = bio_iter_iovec(bio, bio->bi_iter); 1074 bvec = bio_iter_iovec(bio, bio->bi_iter);
1074 1075 prev_start_byte = start_byte;
1075 start_byte = page_offset(bvec.bv_page) - disk_start; 1076 start_byte = page_offset(bvec.bv_page) - disk_start;
1076 1077
1077 /* 1078 /*
1078 * make sure our new page is covered by this 1079 * We need to make sure we're only adjusting
1079 * working buffer 1080 * our offset into compression working buffer when
1081 * we're switching pages. Otherwise we can incorrectly
1082 * keep copying when we were actually done.
1080 */ 1083 */
1081 if (total_out <= start_byte) 1084 if (start_byte != prev_start_byte) {
1082 return 1; 1085 /*
1086 * make sure our new page is covered by this
1087 * working buffer
1088 */
1089 if (total_out <= start_byte)
1090 return 1;
1083 1091
1084 /* 1092 /*
1085 * the next page in the biovec might not be adjacent 1093 * the next page in the biovec might not be adjacent
1086 * to the last page, but it might still be found 1094 * to the last page, but it might still be found
1087 * inside this working buffer. bump our offset pointer 1095 * inside this working buffer. bump our offset pointer
1088 */ 1096 */
1089 if (total_out > start_byte && 1097 if (total_out > start_byte &&
1090 current_buf_start < start_byte) { 1098 current_buf_start < start_byte) {
1091 buf_offset = start_byte - buf_start; 1099 buf_offset = start_byte - buf_start;
1092 working_bytes = total_out - start_byte; 1100 working_bytes = total_out - start_byte;
1093 current_buf_start = buf_start + buf_offset; 1101 current_buf_start = buf_start + buf_offset;
1102 }
1094 } 1103 }
1095 } 1104 }
1096 1105
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 33f967d30b2a..21e51b0ba188 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -5653,6 +5653,10 @@ long btrfs_ioctl(struct file *file, unsigned int
5653#ifdef CONFIG_COMPAT 5653#ifdef CONFIG_COMPAT
5654long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 5654long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
5655{ 5655{
5656 /*
5657 * These all access 32-bit values anyway so no further
5658 * handling is necessary.
5659 */
5656 switch (cmd) { 5660 switch (cmd) {
5657 case FS_IOC32_GETFLAGS: 5661 case FS_IOC32_GETFLAGS:
5658 cmd = FS_IOC_GETFLAGS; 5662 cmd = FS_IOC_GETFLAGS;
@@ -5663,8 +5667,6 @@ long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
5663 case FS_IOC32_GETVERSION: 5667 case FS_IOC32_GETVERSION:
5664 cmd = FS_IOC_GETVERSION; 5668 cmd = FS_IOC_GETVERSION;
5665 break; 5669 break;
5666 default:
5667 return -ENOIOCTLCMD;
5668 } 5670 }
5669 5671
5670 return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); 5672 return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg));