Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Apr 2017 23:53:45 +0000 (16:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Apr 2017 23:53:45 +0000 (16:53 -0700)
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

1  2 
fs/btrfs/inode.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/inode.c
index a18510be76c141e5d4b4d687c2eb5498cc273c56,55ed2c4829a8b8a5b9aaf864101040876fd7d733..5e71f1ea3391b034dc8e6f55f62d82dbe76e9811
@@@ -7910,7 -7910,6 +7910,6 @@@ struct btrfs_retry_complete 
  static void btrfs_retry_endio_nocsum(struct bio *bio)
  {
        struct btrfs_retry_complete *done = bio->bi_private;
-       struct inode *inode;
        struct bio_vec *bvec;
        int i;
  
                goto end;
  
        ASSERT(bio->bi_vcnt == 1);
-       inode = bio->bi_io_vec->bv_page->mapping->host;
-       ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode));
+       ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode));
  
        done->uptodate = 1;
        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:
        complete(&done->done);
        bio_put(bio);
@@@ -7973,8 -7972,10 +7972,10 @@@ next_block_or_try_again
  
                start += sectorsize;
  
-               if (nr_sectors--) {
+               nr_sectors--;
+               if (nr_sectors) {
                        pgoff += sectorsize;
+                       ASSERT(pgoff < PAGE_SIZE);
                        goto next_block_or_try_again;
                }
        }
@@@ -7986,9 -7987,7 +7987,7 @@@ static void btrfs_retry_endio(struct bi
  {
        struct btrfs_retry_complete *done = bio->bi_private;
        struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
-       struct inode *inode;
        struct bio_vec *bvec;
-       u64 start;
        int uptodate;
        int ret;
        int i;
  
        uptodate = 1;
  
-       start = done->start;
        ASSERT(bio->bi_vcnt == 1);
-       inode = bio->bi_io_vec->bv_page->mapping->host;
-       ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode));
+       ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(done->inode));
  
        bio_for_each_segment_all(bvec, bio, i) {
                ret = __readpage_endio_check(done->inode, io_bio, i,
@@@ -8080,8 -8076,10 +8076,10 @@@ next
  
                ASSERT(nr_sectors);
  
-               if (--nr_sectors) {
+               nr_sectors--;
+               if (nr_sectors) {
                        pgoff += sectorsize;
+                       ASSERT(pgoff < PAGE_SIZE);
                        goto next_block;
                }
        }
@@@ -8908,10 -8906,10 +8906,10 @@@ again
   * beyond EOF, then the page is guaranteed safe against truncation until we
   * unlock the page.
   */
 -int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 +int btrfs_page_mkwrite(struct vm_fault *vmf)
  {
        struct page *page = vmf->page;
 -      struct inode *inode = file_inode(vma->vm_file);
 +      struct inode *inode = file_inode(vmf->vma->vm_file);
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
        struct btrfs_ordered_extent *ordered;
        ret = btrfs_delalloc_reserve_space(inode, page_start,
                                           reserved_space);
        if (!ret) {
 -              ret = file_update_time(vma->vm_file);
 +              ret = file_update_time(vmf->vma->vm_file);
                reserved = 1;
        }
        if (ret) {
@@@ -9427,11 -9425,11 +9425,11 @@@ fail
        return -ENOMEM;
  }
  
 -static int btrfs_getattr(struct vfsmount *mnt,
 -                       struct dentry *dentry, struct kstat *stat)
 +static int btrfs_getattr(const struct path *path, struct kstat *stat,
 +                       u32 request_mask, unsigned int flags)
  {
        u64 delalloc_bytes;
 -      struct inode *inode = d_inode(dentry);
 +      struct inode *inode = d_inode(path->dentry);
        u32 blocksize = inode->i_sb->s_blocksize;
  
        generic_fillattr(inode, stat);
diff --combined fs/btrfs/volumes.c
index 73d56eef5e60f311225b06ad7adccedeed54a0db,7c7e0c99360f429252cb33d330cb4056d9309f76..ab8a66d852f91cb04206361a551b8c57760c9c40
@@@ -365,7 -365,7 +365,7 @@@ static noinline void run_scheduled_bios
         */
        blk_start_plug(&plug);
  
 -      bdi = blk_get_backing_dev_info(device->bdev);
 +      bdi = device->bdev->bd_bdi;
        limit = btrfs_async_submit_limit(fs_info);
        limit = limit * 2 / 3;
  
@@@ -6213,7 -6213,7 +6213,7 @@@ int btrfs_map_bio(struct btrfs_fs_info 
        for (dev_nr = 0; dev_nr < total_devs; dev_nr++) {
                dev = bbio->stripes[dev_nr].dev;
                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);
                        continue;
                }