Skip to content

Commit 2b95550

Browse files
committed
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
2 parents 13ebfd0 + 6e78b3f commit 2b95550

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

fs/btrfs/compression.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,7 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
10241024
unsigned long buf_offset;
10251025
unsigned long current_buf_start;
10261026
unsigned long start_byte;
1027+
unsigned long prev_start_byte;
10271028
unsigned long working_bytes = total_out - buf_start;
10281029
unsigned long bytes;
10291030
char *kaddr;
@@ -1071,26 +1072,34 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
10711072
if (!bio->bi_iter.bi_size)
10721073
return 0;
10731074
bvec = bio_iter_iovec(bio, bio->bi_iter);
1074-
1075+
prev_start_byte = start_byte;
10751076
start_byte = page_offset(bvec.bv_page) - disk_start;
10761077

10771078
/*
1078-
* make sure our new page is covered by this
1079-
* working buffer
1079+
* We need to make sure we're only adjusting
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.
10801083
*/
1081-
if (total_out <= start_byte)
1082-
return 1;
1084+
if (start_byte != prev_start_byte) {
1085+
/*
1086+
* make sure our new page is covered by this
1087+
* working buffer
1088+
*/
1089+
if (total_out <= start_byte)
1090+
return 1;
10831091

1084-
/*
1085-
* the next page in the biovec might not be adjacent
1086-
* to the last page, but it might still be found
1087-
* inside this working buffer. bump our offset pointer
1088-
*/
1089-
if (total_out > start_byte &&
1090-
current_buf_start < start_byte) {
1091-
buf_offset = start_byte - buf_start;
1092-
working_bytes = total_out - start_byte;
1093-
current_buf_start = buf_start + buf_offset;
1092+
/*
1093+
* the next page in the biovec might not be adjacent
1094+
* to the last page, but it might still be found
1095+
* inside this working buffer. bump our offset pointer
1096+
*/
1097+
if (total_out > start_byte &&
1098+
current_buf_start < start_byte) {
1099+
buf_offset = start_byte - buf_start;
1100+
working_bytes = total_out - start_byte;
1101+
current_buf_start = buf_start + buf_offset;
1102+
}
10941103
}
10951104
}
10961105

fs/btrfs/ioctl.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5653,6 +5653,10 @@ long btrfs_ioctl(struct file *file, unsigned int
56535653
#ifdef CONFIG_COMPAT
56545654
long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
56555655
{
5656+
/*
5657+
* These all access 32-bit values anyway so no further
5658+
* handling is necessary.
5659+
*/
56565660
switch (cmd) {
56575661
case FS_IOC32_GETFLAGS:
56585662
cmd = FS_IOC_GETFLAGS;
@@ -5663,8 +5667,6 @@ long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
56635667
case FS_IOC32_GETVERSION:
56645668
cmd = FS_IOC_GETVERSION;
56655669
break;
5666-
default:
5667-
return -ENOIOCTLCMD;
56685670
}
56695671

56705672
return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg));

0 commit comments

Comments
 (0)