]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Dec 2013 23:33:27 +0000 (15:33 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Dec 2013 23:33:27 +0000 (15:33 -0800)
Pull block layer fixes from Jens Axboe:
 "A small collection of fixes for the current series. It contains:

   - A fix for a use-after-free of a request in blk-mq.  From Ming Lei

   - A fix for a blk-mq bug that could attempt to dereference a NULL rq
     if allocation failed

   - Two xen-blkfront small fixes

   - Cleanup of submit_bio_wait() type uses in the kernel, unifying
     that.  From Kent

   - A fix for 32-bit blkg_rwstat reading.  I apologize for this one
     looking mangled in the shortlog, it's entirely my fault for missing
     an empty line between the description and body of the text"

* 'for-linus' of git://git.kernel.dk/linux-block:
  blk-mq: fix use-after-free of request
  blk-mq: fix dereference of rq->mq_ctx if allocation fails
  block: xen-blkfront: Fix possible NULL ptr dereference
  xen-blkfront: Silence pfn maybe-uninitialized warning
  block: submit_bio_wait() conversions
  Update of blkg_stat and blkg_rwstat may happen in bh context

1  2 
drivers/md/md.c
fs/btrfs/check-integrity.c
fs/btrfs/extent_io.c
fs/btrfs/scrub.c

diff --combined drivers/md/md.c
index e60cebf3f519841d81726f1aee6ef97df6e8da6b,8700de376876f36000720d80bcb62bd77e43ae01..21f4d7ff0da22ee16e7556958502a2fb9ea74502
@@@ -776,16 -776,10 +776,10 @@@ void md_super_wait(struct mddev *mddev
        finish_wait(&mddev->sb_wait, &wq);
  }
  
- static void bi_complete(struct bio *bio, int error)
- {
-       complete((struct completion*)bio->bi_private);
- }
  int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
                 struct page *page, int rw, bool metadata_op)
  {
        struct bio *bio = bio_alloc_mddev(GFP_NOIO, 1, rdev->mddev);
-       struct completion event;
        int ret;
  
        rw |= REQ_SYNC;
        else
                bio->bi_sector = sector + rdev->data_offset;
        bio_add_page(bio, page, size, 0);
-       init_completion(&event);
-       bio->bi_private = &event;
-       bio->bi_end_io = bi_complete;
-       submit_bio(rw, bio);
-       wait_for_completion(&event);
+       submit_bio_wait(rw, bio);
  
        ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
        bio_put(bio);
@@@ -7777,7 -7767,7 +7767,7 @@@ void md_check_recovery(struct mddev *md
        if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
                return;
        if ( ! (
 -              (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) ||
 +              (mddev->flags & MD_UPDATE_SB_FLAGS & ~ (1<<MD_CHANGE_PENDING)) ||
                test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
                test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
                (mddev->external == 0 && mddev->safemode == 1) ||
index b50764bef1410c2750b17d943ae3597899b3ee9e,f85b1c4090038d16a82e4aa6512f282b3d389c79..131d82800b3af45778cb8651f5c559bd57cec437
   * the integrity of (super)-block write requests, do not
   * enable the config option BTRFS_FS_CHECK_INTEGRITY to
   * include and compile the integrity check tool.
 + *
 + * Expect millions of lines of information in the kernel log with an
 + * enabled check_int_print_mask. Therefore set LOG_BUF_SHIFT in the
 + * kernel config to at least 26 (which is 64MB). Usually the value is
 + * limited to 21 (which is 2MB) in init/Kconfig. The file needs to be
 + * changed like this before LOG_BUF_SHIFT can be set to a high value:
 + * config LOG_BUF_SHIFT
 + *       int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
 + *       range 12 30
   */
  
  #include <linux/sched.h>
  #define BTRFSIC_PRINT_MASK_INITIAL_DATABASE                   0x00000400
  #define BTRFSIC_PRINT_MASK_NUM_COPIES                         0x00000800
  #define BTRFSIC_PRINT_MASK_TREE_WITH_ALL_MIRRORS              0x00001000
 +#define BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE              0x00002000
  
  struct btrfsic_dev_state;
  struct btrfsic_state;
@@@ -333,7 -323,6 +333,6 @@@ static void btrfsic_release_block_ctx(s
  static int btrfsic_read_block(struct btrfsic_state *state,
                              struct btrfsic_block_data_ctx *block_ctx);
  static void btrfsic_dump_database(struct btrfsic_state *state);
- static void btrfsic_complete_bio_end_io(struct bio *bio, int err);
  static int btrfsic_test_for_metadata(struct btrfsic_state *state,
                                     char **datav, unsigned int num_pages);
  static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state,
@@@ -1687,7 -1676,6 +1686,6 @@@ static int btrfsic_read_block(struct bt
        for (i = 0; i < num_pages;) {
                struct bio *bio;
                unsigned int j;
-               DECLARE_COMPLETION_ONSTACK(complete);
  
                bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i);
                if (!bio) {
                }
                bio->bi_bdev = block_ctx->dev->bdev;
                bio->bi_sector = dev_bytenr >> 9;
-               bio->bi_end_io = btrfsic_complete_bio_end_io;
-               bio->bi_private = &complete;
  
                for (j = i; j < num_pages; j++) {
                        ret = bio_add_page(bio, block_ctx->pagev[j],
                               "btrfsic: error, failed to add a single page!\n");
                        return -1;
                }
-               submit_bio(READ, bio);
-               /* this will also unplug the queue */
-               wait_for_completion(&complete);
-               if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+               if (submit_bio_wait(READ, bio)) {
                        printk(KERN_INFO
                               "btrfsic: read error at logical %llu dev %s!\n",
                               block_ctx->start, block_ctx->dev->name);
        return block_ctx->len;
  }
  
- static void btrfsic_complete_bio_end_io(struct bio *bio, int err)
- {
-       complete((struct completion *)bio->bi_private);
- }
  static void btrfsic_dump_database(struct btrfsic_state *state)
  {
        struct list_head *elem_all;
@@@ -3008,14 -2984,12 +2994,12 @@@ int btrfsic_submit_bh(int rw, struct bu
        return submit_bh(rw, bh);
  }
  
void btrfsic_submit_bio(int rw, struct bio *bio)
static void __btrfsic_submit_bio(int rw, struct bio *bio)
  {
        struct btrfsic_dev_state *dev_state;
  
-       if (!btrfsic_is_initialized) {
-               submit_bio(rw, bio);
+       if (!btrfsic_is_initialized)
                return;
-       }
  
        mutex_lock(&btrfsic_mutex);
        /* since btrfsic_submit_bio() is also called before
            (rw & WRITE) && NULL != bio->bi_io_vec) {
                unsigned int i;
                u64 dev_bytenr;
 +              u64 cur_bytenr;
                int bio_is_patched;
                char **mapped_datav;
  
                                       GFP_NOFS);
                if (!mapped_datav)
                        goto leave;
 +              cur_bytenr = dev_bytenr;
                for (i = 0; i < bio->bi_vcnt; i++) {
                        BUG_ON(bio->bi_io_vec[i].bv_len != PAGE_CACHE_SIZE);
                        mapped_datav[i] = kmap(bio->bi_io_vec[i].bv_page);
                                kfree(mapped_datav);
                                goto leave;
                        }
 -                      if ((BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH |
 -                           BTRFSIC_PRINT_MASK_VERBOSE) ==
 -                          (dev_state->state->print_mask &
 -                           (BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH |
 -                            BTRFSIC_PRINT_MASK_VERBOSE)))
 +                      if (dev_state->state->print_mask &
 +                          BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH_VERBOSE)
                                printk(KERN_INFO
 -                                     "#%u: page=%p, len=%u, offset=%u\n",
 -                                     i, bio->bi_io_vec[i].bv_page,
 -                                     bio->bi_io_vec[i].bv_len,
 +                                     "#%u: bytenr=%llu, len=%u, offset=%u\n",
 +                                     i, cur_bytenr, bio->bi_io_vec[i].bv_len,
                                       bio->bi_io_vec[i].bv_offset);
 +                      cur_bytenr += bio->bi_io_vec[i].bv_len;
                }
                btrfsic_process_written_block(dev_state, dev_bytenr,
                                              mapped_datav, bio->bi_vcnt,
        }
  leave:
        mutex_unlock(&btrfsic_mutex);
+ }
  
+ void btrfsic_submit_bio(int rw, struct bio *bio)
+ {
+       __btrfsic_submit_bio(rw, bio);
        submit_bio(rw, bio);
  }
  
+ int btrfsic_submit_bio_wait(int rw, struct bio *bio)
+ {
+       __btrfsic_submit_bio(rw, bio);
+       return submit_bio_wait(rw, bio);
+ }
  int btrfsic_mount(struct btrfs_root *root,
                  struct btrfs_fs_devices *fs_devices,
                  int including_extent_data, u32 print_mask)
diff --combined fs/btrfs/extent_io.c
index 8e457fca0a0ba5c04afb84414ccd640821a640d1,014beaa9458c236cc35f9b205e6e2a42fb003ebd..ff43802a7c886088e37c5c1c16427f2b522cad30
@@@ -1952,11 -1952,6 +1952,6 @@@ static int free_io_failure(struct inod
        return err;
  }
  
- static void repair_io_failure_callback(struct bio *bio, int err)
- {
-       complete(bio->bi_private);
- }
  /*
   * this bypasses the standard btrfs submit functions deliberately, as
   * the standard behavior is to write all copies in a raid setup. here we only
@@@ -1973,14 -1968,12 +1968,13 @@@ int repair_io_failure(struct btrfs_fs_i
  {
        struct bio *bio;
        struct btrfs_device *dev;
-       DECLARE_COMPLETION_ONSTACK(compl);
        u64 map_length = 0;
        u64 sector;
        struct btrfs_bio *bbio = NULL;
        struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
        int ret;
  
 +      ASSERT(!(fs_info->sb->s_flags & MS_RDONLY));
        BUG_ON(!mirror_num);
  
        /* we can't repair anything in raid56 yet */
        bio = btrfs_io_bio_alloc(GFP_NOFS, 1);
        if (!bio)
                return -EIO;
-       bio->bi_private = &compl;
-       bio->bi_end_io = repair_io_failure_callback;
        bio->bi_size = 0;
        map_length = length;
  
        }
        bio->bi_bdev = dev->bdev;
        bio_add_page(bio, page, length, start - page_offset(page));
-       btrfsic_submit_bio(WRITE_SYNC, bio);
-       wait_for_completion(&compl);
  
-       if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
+       if (btrfsic_submit_bio_wait(WRITE_SYNC, bio)) {
                /* try to remap that extent elsewhere? */
                bio_put(bio);
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
@@@ -2037,9 -2026,6 +2027,9 @@@ int repair_eb_io_failure(struct btrfs_r
        unsigned long i, num_pages = num_extent_pages(eb->start, eb->len);
        int ret = 0;
  
 +      if (root->fs_info->sb->s_flags & MS_RDONLY)
 +              return -EROFS;
 +
        for (i = 0; i < num_pages; i++) {
                struct page *p = extent_buffer_page(eb, i);
                ret = repair_io_failure(root->fs_info, start, PAGE_CACHE_SIZE,
@@@ -2061,12 -2047,12 +2051,12 @@@ static int clean_io_failure(u64 start, 
        u64 private;
        u64 private_failure;
        struct io_failure_record *failrec;
 -      struct btrfs_fs_info *fs_info;
 +      struct inode *inode = page->mapping->host;
 +      struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
        struct extent_state *state;
        int num_copies;
        int did_repair = 0;
        int ret;
 -      struct inode *inode = page->mapping->host;
  
        private = 0;
        ret = count_range_bits(&BTRFS_I(inode)->io_failure_tree, &private,
                did_repair = 1;
                goto out;
        }
 +      if (fs_info->sb->s_flags & MS_RDONLY)
 +              goto out;
  
        spin_lock(&BTRFS_I(inode)->io_tree.lock);
        state = find_first_extent_bit_state(&BTRFS_I(inode)->io_tree,
  
        if (state && state->start <= failrec->start &&
            state->end >= failrec->start + failrec->len - 1) {
 -              fs_info = BTRFS_I(inode)->root->fs_info;
                num_copies = btrfs_num_copies(fs_info, failrec->logical,
                                              failrec->len);
                if (num_copies > 1)  {
diff --combined fs/btrfs/scrub.c
index 561e2f16ba3e3ff3b0be72b12b4a052b86082d2a,3214ebe593bdb51334044ccd4bb8dd4fc25b2246..1fd3f33c330abe930fbd03de1deb5968e32fd7b5
@@@ -208,7 -208,6 +208,6 @@@ static void scrub_recheck_block_checksu
                                         int is_metadata, int have_csum,
                                         const u8 *csum, u64 generation,
                                         u16 csum_size);
- static void scrub_complete_bio_end_io(struct bio *bio, int err);
  static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
                                             struct scrub_block *sblock_good,
                                             int force_write);
@@@ -938,10 -937,8 +937,10 @@@ static int scrub_handle_errored_block(s
                                BTRFS_DEV_STAT_CORRUPTION_ERRS);
        }
  
 -      if (sctx->readonly && !sctx->is_dev_replace)
 -              goto did_not_correct_error;
 +      if (sctx->readonly) {
 +              ASSERT(!sctx->is_dev_replace);
 +              goto out;
 +      }
  
        if (!is_metadata && !have_csum) {
                struct scrub_fixup_nodatasum *fixup_nodatasum;
@@@ -1294,7 -1291,6 +1293,6 @@@ static void scrub_recheck_block(struct 
        for (page_num = 0; page_num < sblock->page_count; page_num++) {
                struct bio *bio;
                struct scrub_page *page = sblock->pagev[page_num];
-               DECLARE_COMPLETION_ONSTACK(complete);
  
                if (page->dev->bdev == NULL) {
                        page->io_error = 1;
                }
                bio->bi_bdev = page->dev->bdev;
                bio->bi_sector = page->physical >> 9;
-               bio->bi_end_io = scrub_complete_bio_end_io;
-               bio->bi_private = &complete;
  
                bio_add_page(bio, page->page, PAGE_SIZE, 0);
-               btrfsic_submit_bio(READ, bio);
-               /* this will also unplug the queue */
-               wait_for_completion(&complete);
-               page->io_error = !test_bit(BIO_UPTODATE, &bio->bi_flags);
-               if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+               if (btrfsic_submit_bio_wait(READ, bio))
                        sblock->no_io_error_seen = 0;
                bio_put(bio);
        }
  
@@@ -1391,11 -1380,6 +1382,6 @@@ static void scrub_recheck_block_checksu
                sblock->checksum_error = 1;
  }
  
- static void scrub_complete_bio_end_io(struct bio *bio, int err)
- {
-       complete((struct completion *)bio->bi_private);
- }
  static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad,
                                             struct scrub_block *sblock_good,
                                             int force_write)
@@@ -1430,7 -1414,6 +1416,6 @@@ static int scrub_repair_page_from_good_
            sblock_bad->checksum_error || page_bad->io_error) {
                struct bio *bio;
                int ret;
-               DECLARE_COMPLETION_ONSTACK(complete);
  
                if (!page_bad->dev->bdev) {
                        printk_ratelimited(KERN_WARNING
                        return -EIO;
                bio->bi_bdev = page_bad->dev->bdev;
                bio->bi_sector = page_bad->physical >> 9;
-               bio->bi_end_io = scrub_complete_bio_end_io;
-               bio->bi_private = &complete;
  
                ret = bio_add_page(bio, page_good->page, PAGE_SIZE, 0);
                if (PAGE_SIZE != ret) {
                        bio_put(bio);
                        return -EIO;
                }
-               btrfsic_submit_bio(WRITE, bio);
  
-               /* this will also unplug the queue */
-               wait_for_completion(&complete);
-               if (!bio_flagged(bio, BIO_UPTODATE)) {
+               if (btrfsic_submit_bio_wait(WRITE, bio)) {
                        btrfs_dev_stat_inc_and_print(page_bad->dev,
                                BTRFS_DEV_STAT_WRITE_ERRS);
                        btrfs_dev_replace_stats_inc(
@@@ -3375,7 -3353,6 +3355,6 @@@ static int write_page_nocow(struct scru
        struct bio *bio;
        struct btrfs_device *dev;
        int ret;
-       DECLARE_COMPLETION_ONSTACK(compl);
  
        dev = sctx->wr_ctx.tgtdev;
        if (!dev)
                spin_unlock(&sctx->stat_lock);
                return -ENOMEM;
        }
-       bio->bi_private = &compl;
-       bio->bi_end_io = scrub_complete_bio_end_io;
        bio->bi_size = 0;
        bio->bi_sector = physical_for_dev_replace >> 9;
        bio->bi_bdev = dev->bdev;
@@@ -3404,10 -3379,8 +3381,8 @@@ leave_with_eio
                btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_WRITE_ERRS);
                return -EIO;
        }
-       btrfsic_submit_bio(WRITE_SYNC, bio);
-       wait_for_completion(&compl);
  
-       if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+       if (btrfsic_submit_bio_wait(WRITE_SYNC, bio))
                goto leave_with_eio;
  
        bio_put(bio);