diff options
| -rw-r--r-- | fs/iomap.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/iomap.c b/fs/iomap.c index d51e7a2ae641..3ffb776fbebe 100644 --- a/fs/iomap.c +++ b/fs/iomap.c | |||
| @@ -142,13 +142,14 @@ static void | |||
| 142 | iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop, | 142 | iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop, |
| 143 | loff_t *pos, loff_t length, unsigned *offp, unsigned *lenp) | 143 | loff_t *pos, loff_t length, unsigned *offp, unsigned *lenp) |
| 144 | { | 144 | { |
| 145 | loff_t orig_pos = *pos; | ||
| 146 | loff_t isize = i_size_read(inode); | ||
| 145 | unsigned block_bits = inode->i_blkbits; | 147 | unsigned block_bits = inode->i_blkbits; |
| 146 | unsigned block_size = (1 << block_bits); | 148 | unsigned block_size = (1 << block_bits); |
| 147 | unsigned poff = offset_in_page(*pos); | 149 | unsigned poff = offset_in_page(*pos); |
| 148 | unsigned plen = min_t(loff_t, PAGE_SIZE - poff, length); | 150 | unsigned plen = min_t(loff_t, PAGE_SIZE - poff, length); |
| 149 | unsigned first = poff >> block_bits; | 151 | unsigned first = poff >> block_bits; |
| 150 | unsigned last = (poff + plen - 1) >> block_bits; | 152 | unsigned last = (poff + plen - 1) >> block_bits; |
| 151 | unsigned end = offset_in_page(i_size_read(inode)) >> block_bits; | ||
| 152 | 153 | ||
| 153 | /* | 154 | /* |
| 154 | * If the block size is smaller than the page size we need to check the | 155 | * If the block size is smaller than the page size we need to check the |
| @@ -183,8 +184,12 @@ iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop, | |||
| 183 | * handle both halves separately so that we properly zero data in the | 184 | * handle both halves separately so that we properly zero data in the |
| 184 | * page cache for blocks that are entirely outside of i_size. | 185 | * page cache for blocks that are entirely outside of i_size. |
| 185 | */ | 186 | */ |
| 186 | if (first <= end && last > end) | 187 | if (orig_pos <= isize && orig_pos + length > isize) { |
| 187 | plen -= (last - end) * block_size; | 188 | unsigned end = offset_in_page(isize - 1) >> block_bits; |
| 189 | |||
| 190 | if (first <= end && last > end) | ||
| 191 | plen -= (last - end) * block_size; | ||
| 192 | } | ||
| 188 | 193 | ||
| 189 | *offp = poff; | 194 | *offp = poff; |
| 190 | *lenp = plen; | 195 | *lenp = plen; |
