Commit 4b31ac48 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull btrfs fixes from Chris Mason:
 "Dave Sterba collected a few more fixes for the last rc.

  These aren't marked for stable, but I'm putting them in with a batch
  were testing/sending by hand for this release"

* 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix potential use-after-free for cloned bio
  Btrfs: fix segmentation fault when doing dio read
  Btrfs: fix invalid dereference in btrfs_retry_endio
  btrfs: drop the nossd flag when remounting with -o ssd
parents 5466f4df a967efb3
...@@ -7910,7 +7910,6 @@ struct btrfs_retry_complete { ...@@ -7910,7 +7910,6 @@ struct btrfs_retry_complete {
static void btrfs_retry_endio_nocsum(struct bio *bio) static void btrfs_retry_endio_nocsum(struct bio *bio)
{ {
struct btrfs_retry_complete *done = bio->bi_private; struct btrfs_retry_complete *done = bio->bi_private;
struct inode *inode;
struct bio_vec *bvec; struct bio_vec *bvec;
int i; int i;
...@@ -7918,12 +7917,12 @@ static void btrfs_retry_endio_nocsum(struct bio *bio) ...@@ -7918,12 +7917,12 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
goto end; goto end;
ASSERT(bio->bi_vcnt == 1); ASSERT(bio->bi_vcnt == 1);
inode = bio->bi_io_vec->bv_page->mapping->host; ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode));
ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode));
done->uptodate = 1; done->uptodate = 1;
bio_for_each_segment_all(bvec, bio, i) bio_for_each_segment_all(bvec, bio, i)
clean_io_failure(BTRFS_I(done->inode), done->start, bvec->bv_page, 0); clean_io_failure(BTRFS_I(done->inode), done->start,
bvec->bv_page, 0);
end: end:
complete(&done->done); complete(&done->done);
bio_put(bio); bio_put(bio);
...@@ -7973,8 +7972,10 @@ static int __btrfs_correct_data_nocsum(struct inode *inode, ...@@ -7973,8 +7972,10 @@ static int __btrfs_correct_data_nocsum(struct inode *inode,
start += sectorsize; start += sectorsize;
if (nr_sectors--) { nr_sectors--;
if (nr_sectors) {
pgoff += sectorsize; pgoff += sectorsize;
ASSERT(pgoff < PAGE_SIZE);
goto next_block_or_try_again; goto next_block_or_try_again;
} }
} }
...@@ -7986,9 +7987,7 @@ static void btrfs_retry_endio(struct bio *bio) ...@@ -7986,9 +7987,7 @@ static void btrfs_retry_endio(struct bio *bio)
{ {
struct btrfs_retry_complete *done = bio->bi_private; struct btrfs_retry_complete *done = bio->bi_private;
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
struct inode *inode;
struct bio_vec *bvec; struct bio_vec *bvec;
u64 start;
int uptodate; int uptodate;
int ret; int ret;
int i; int i;
...@@ -7998,11 +7997,8 @@ static void btrfs_retry_endio(struct bio *bio) ...@@ -7998,11 +7997,8 @@ static void btrfs_retry_endio(struct bio *bio)
uptodate = 1; uptodate = 1;
start = done->start;
ASSERT(bio->bi_vcnt == 1); ASSERT(bio->bi_vcnt == 1);
inode = bio->bi_io_vec->bv_page->mapping->host; ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode));
ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode));
bio_for_each_segment_all(bvec, bio, i) { bio_for_each_segment_all(bvec, bio, i) {
ret = __readpage_endio_check(done->inode, io_bio, i, ret = __readpage_endio_check(done->inode, io_bio, i,
...@@ -8080,8 +8076,10 @@ static int __btrfs_subio_endio_read(struct inode *inode, ...@@ -8080,8 +8076,10 @@ static int __btrfs_subio_endio_read(struct inode *inode,
ASSERT(nr_sectors); ASSERT(nr_sectors);
if (--nr_sectors) { nr_sectors--;
if (nr_sectors) {
pgoff += sectorsize; pgoff += sectorsize;
ASSERT(pgoff < PAGE_SIZE);
goto next_block; goto next_block;
} }
} }
......
...@@ -549,16 +549,19 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, ...@@ -549,16 +549,19 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
case Opt_ssd: case Opt_ssd:
btrfs_set_and_info(info, SSD, btrfs_set_and_info(info, SSD,
"use ssd allocation scheme"); "use ssd allocation scheme");
btrfs_clear_opt(info->mount_opt, NOSSD);
break; break;
case Opt_ssd_spread: case Opt_ssd_spread:
btrfs_set_and_info(info, SSD_SPREAD, btrfs_set_and_info(info, SSD_SPREAD,
"use spread ssd allocation scheme"); "use spread ssd allocation scheme");
btrfs_set_opt(info->mount_opt, SSD); btrfs_set_opt(info->mount_opt, SSD);
btrfs_clear_opt(info->mount_opt, NOSSD);
break; break;
case Opt_nossd: case Opt_nossd:
btrfs_set_and_info(info, NOSSD, btrfs_set_and_info(info, NOSSD,
"not using ssd allocation scheme"); "not using ssd allocation scheme");
btrfs_clear_opt(info->mount_opt, SSD); btrfs_clear_opt(info->mount_opt, SSD);
btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
break; break;
case Opt_barrier: case Opt_barrier:
btrfs_clear_and_info(info, NOBARRIER, btrfs_clear_and_info(info, NOBARRIER,
......
...@@ -6213,7 +6213,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio, ...@@ -6213,7 +6213,7 @@ int btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
for (dev_nr = 0; dev_nr < total_devs; dev_nr++) { for (dev_nr = 0; dev_nr < total_devs; dev_nr++) {
dev = bbio->stripes[dev_nr].dev; dev = bbio->stripes[dev_nr].dev;
if (!dev || !dev->bdev || if (!dev || !dev->bdev ||
(bio_op(bio) == REQ_OP_WRITE && !dev->writeable)) { (bio_op(first_bio) == REQ_OP_WRITE && !dev->writeable)) {
bbio_error(bbio, first_bio, logical); bbio_error(bbio, first_bio, logical);
continue; continue;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment