]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'for-3.14/drivers' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 30 Jan 2014 19:40:10 +0000 (11:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 30 Jan 2014 19:40:10 +0000 (11:40 -0800)
Pull block IO driver changes from Jens Axboe:

 - bcache update from Kent Overstreet.

 - two bcache fixes from Nicholas Swenson.

 - cciss pci init error fix from Andrew.

 - underflow fix in the parallel IDE pg_write code from Dan Carpenter.
   I'm sure the 1 (or 0) users of that are now happy.

 - two PCI related fixes for sx8 from Jingoo Han.

 - floppy init fix for first block read from Jiri Kosina.

 - pktcdvd error return miss fix from Julia Lawall.

 - removal of IRQF_SHARED from the SEGA Dreamcast CD-ROM code from
   Michael Opdenacker.

 - comment typo fix for the loop driver from Olaf Hering.

 - potential oops fix for null_blk from Raghavendra K T.

 - two fixes from Sam Bradshaw (Micron) for the mtip32xx driver, fixing
   an OOM problem and a problem with handling security locked conditions

* 'for-3.14/drivers' of git://git.kernel.dk/linux-block: (47 commits)
  mg_disk: Spelling s/finised/finished/
  null_blk: Null pointer deference problem in alloc_page_buffers
  mtip32xx: Correctly handle security locked condition
  mtip32xx: Make SGL container per-command to eliminate high order dma allocation
  drivers/block/loop.c: fix comment typo in loop_config_discard
  drivers/block/cciss.c:cciss_init_one(): use proper errnos
  drivers/block/paride/pg.c: underflow bug in pg_write()
  drivers/block/sx8.c: remove unnecessary pci_set_drvdata()
  drivers/block/sx8.c: use module_pci_driver()
  floppy: bail out in open() if drive is not responding to block0 read
  bcache: Fix auxiliary search trees for key size > cacheline size
  bcache: Don't return -EINTR when insert finished
  bcache: Improve bucket_prio() calculation
  bcache: Add bch_bkey_equal_header()
  bcache: update bch_bkey_try_merge
  bcache: Move insert_fixup() to btree_keys_ops
  bcache: Convert sorting to btree_keys
  bcache: Convert debug code to btree_keys
  bcache: Convert btree_iter to struct btree_keys
  bcache: Refactor bset_tree sysfs stats
  ...

1  2 
drivers/block/null_blk.c
drivers/md/bcache/request.c
drivers/md/raid5.c

diff --combined drivers/block/null_blk.c
index 83a598ebb65a4ab7699d1dcebe1b44b42ea8ae5a,a01d7f68fc77374e570409eeacbc887e77cd0d5d..3107282a9741f96665a2805b08217d3209c27bf7
@@@ -425,7 -425,10 +425,7 @@@ static void null_del_dev(struct nullb *
        list_del_init(&nullb->list);
  
        del_gendisk(nullb->disk);
 -      if (queue_mode == NULL_Q_MQ)
 -              blk_mq_free_queue(nullb->q);
 -      else
 -              blk_cleanup_queue(nullb->q);
 +      blk_cleanup_queue(nullb->q);
        put_disk(nullb->disk);
        kfree(nullb);
  }
@@@ -575,7 -578,10 +575,7 @@@ static int null_add_dev(void
        disk = nullb->disk = alloc_disk_node(1, home_node);
        if (!disk) {
  queue_fail:
 -              if (queue_mode == NULL_Q_MQ)
 -                      blk_mq_free_queue(nullb->q);
 -              else
 -                      blk_cleanup_queue(nullb->q);
 +              blk_cleanup_queue(nullb->q);
                cleanup_queues(nullb);
  err:
                kfree(nullb);
@@@ -616,6 -622,11 +616,11 @@@ static int __init null_init(void
                irqmode = NULL_IRQ_NONE;
        }
  #endif
+       if (bs > PAGE_SIZE) {
+               pr_warn("null_blk: invalid block size\n");
+               pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE);
+               bs = PAGE_SIZE;
+       }
  
        if (queue_mode == NULL_Q_MQ && use_per_node_hctx) {
                if (submit_queues < nr_online_nodes) {
index c906571997d7a4ab256188f05f4a8c11ea5928f8,fcdb59f9ca919a8a1baaa3c3ee3d9c79738eaa23..72cd213f213f9e806dc9a0360000ffffe6466896
@@@ -163,6 -163,7 +163,6 @@@ static struct cgroup_subsys_state *bcac
  static void bcachecg_destroy(struct cgroup *cgroup)
  {
        struct bch_cgroup *cg = cgroup_to_bcache(cgroup);
 -      free_css_id(&bcache_subsys, &cg->css);
        kfree(cg);
  }
  
@@@ -254,6 -255,24 +254,24 @@@ static void bch_data_insert_keys(struc
        closure_return(cl);
  }
  
+ static int bch_keylist_realloc(struct keylist *l, unsigned u64s,
+                              struct cache_set *c)
+ {
+       size_t oldsize = bch_keylist_nkeys(l);
+       size_t newsize = oldsize + u64s;
+       /*
+        * The journalling code doesn't handle the case where the keys to insert
+        * is bigger than an empty write: If we just return -ENOMEM here,
+        * bio_insert() and bio_invalidate() will insert the keys created so far
+        * and finish the rest when the keylist is empty.
+        */
+       if (newsize * sizeof(uint64_t) > block_bytes(c) - sizeof(struct jset))
+               return -ENOMEM;
+       return __bch_keylist_realloc(l, u64s);
+ }
  static void bch_data_invalidate(struct closure *cl)
  {
        struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
                unsigned sectors = min(bio_sectors(bio),
                                       1U << (KEY_SIZE_BITS - 1));
  
-               if (bch_keylist_realloc(&op->insert_keys, 0, op->c))
+               if (bch_keylist_realloc(&op->insert_keys, 2, op->c))
                        goto out;
  
                bio->bi_iter.bi_sector  += sectors;
@@@ -356,7 -375,7 +374,7 @@@ static void bch_data_insert_start(struc
  
                /* 1 for the device pointer and 1 for the chksum */
                if (bch_keylist_realloc(&op->insert_keys,
-                                       1 + (op->csum ? 1 : 0),
+                                       3 + (op->csum ? 1 : 0),
                                        op->c))
                        continue_at(cl, bch_data_insert_keys, bcache_wq);
  
@@@ -596,14 -615,12 +614,12 @@@ struct search 
        /* Stack frame for bio_complete */
        struct closure          cl;
  
-       struct bcache_device    *d;
        struct bbio             bio;
        struct bio              *orig_bio;
        struct bio              *cache_miss;
+       struct bcache_device    *d;
  
        unsigned                insert_bio_sectors;
        unsigned                recoverable:1;
        unsigned                write:1;
        unsigned                read_dirty_data:1;
@@@ -629,7 -646,8 +645,8 @@@ static void bch_cache_read_endio(struc
  
        if (error)
                s->iop.error = error;
-       else if (ptr_stale(s->iop.c, &b->key, 0)) {
+       else if (!KEY_DIRTY(&b->key) &&
+                ptr_stale(s->iop.c, &b->key, 0)) {
                atomic_long_inc(&s->iop.c->cache_read_races);
                s->iop.error = -EINTR;
        }
@@@ -710,10 -728,13 +727,13 @@@ static void cache_lookup(struct closur
  {
        struct search *s = container_of(cl, struct search, iop.cl);
        struct bio *bio = &s->bio.bio;
+       int ret;
+       bch_btree_op_init(&s->op, -1);
  
-       int ret = bch_btree_map_keys(&s->op, s->iop.c,
-                                    &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0),
-                                    cache_lookup_fn, MAP_END_KEY);
+       ret = bch_btree_map_keys(&s->op, s->iop.c,
+                                &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0),
+                                cache_lookup_fn, MAP_END_KEY);
        if (ret == -EAGAIN)
                continue_at(cl, cache_lookup, bcache_wq);
  
@@@ -754,12 -775,12 +774,12 @@@ static void bio_complete(struct search 
        }
  }
  
- static void do_bio_hook(struct search *s)
+ static void do_bio_hook(struct search *s, struct bio *orig_bio)
  {
        struct bio *bio = &s->bio.bio;
  
        bio_init(bio);
-       __bio_clone_fast(bio, s->orig_bio);
+       __bio_clone_fast(bio, orig_bio);
        bio->bi_end_io          = request_endio;
        bio->bi_private         = &s->cl;
  
@@@ -778,26 -799,32 +798,32 @@@ static void search_free(struct closure 
        mempool_free(s, s->d->c->search);
  }
  
- static struct search *search_alloc(struct bio *bio, struct bcache_device *d)
+ static inline struct search *search_alloc(struct bio *bio,
+                                         struct bcache_device *d)
  {
        struct search *s;
  
        s = mempool_alloc(d->c->search, GFP_NOIO);
-       memset(s, 0, offsetof(struct search, iop.insert_keys));
  
-       __closure_init(&s->cl, NULL);
+       closure_init(&s->cl, NULL);
+       do_bio_hook(s, bio);
  
-       s->iop.inode            = d->id;
-       s->iop.c                = d->c;
-       s->d                    = d;
-       s->op.lock              = -1;
-       s->iop.write_point      = hash_long((unsigned long) current, 16);
        s->orig_bio             = bio;
-       s->write                = (bio->bi_rw & REQ_WRITE) != 0;
-       s->iop.flush_journal    = (bio->bi_rw & (REQ_FLUSH|REQ_FUA)) != 0;
+       s->cache_miss           = NULL;
+       s->d                    = d;
        s->recoverable          = 1;
+       s->write                = (bio->bi_rw & REQ_WRITE) != 0;
+       s->read_dirty_data      = 0;
        s->start_time           = jiffies;
-       do_bio_hook(s);
+       s->iop.c                = d->c;
+       s->iop.bio              = NULL;
+       s->iop.inode            = d->id;
+       s->iop.write_point      = hash_long((unsigned long) current, 16);
+       s->iop.write_prio       = 0;
+       s->iop.error            = 0;
+       s->iop.flags            = 0;
+       s->iop.flush_journal    = (bio->bi_rw & (REQ_FLUSH|REQ_FUA)) != 0;
  
        return s;
  }
@@@ -843,7 -870,7 +869,7 @@@ static void cached_dev_read_error(struc
                trace_bcache_read_retry(s->orig_bio);
  
                s->iop.error = 0;
-               do_bio_hook(s);
+               do_bio_hook(s, s->orig_bio);
  
                /* XXX: invalidate cache */
  
diff --combined drivers/md/raid5.c
index 67ca9c3d2939c5e4468d51f0ea0454dfdceac731,1cfb22c025b6b5b8f02c1fe907e2810adb384a73..f1feadeb7bb2d1b68a6592d946516e4036c7e939
@@@ -675,10 -675,8 +675,10 @@@ get_active_stripe(struct r5conf *conf, 
                                         || !conf->inactive_blocked),
                                        *(conf->hash_locks + hash));
                                conf->inactive_blocked = 0;
 -                      } else
 +                      } else {
                                init_stripe(sh, sector, previous);
 +                              atomic_inc(&sh->count);
 +                      }
                } else {
                        spin_lock(&conf->device_lock);
                        if (atomic_read(&sh->count)) {
                        } else {
                                if (!test_bit(STRIPE_HANDLE, &sh->state))
                                        atomic_inc(&conf->active_stripes);
 -                              BUG_ON(list_empty(&sh->lru));
 +                              BUG_ON(list_empty(&sh->lru) &&
 +                                     !test_bit(STRIPE_EXPANDING, &sh->state));
                                list_del_init(&sh->lru);
                                if (sh->group) {
                                        sh->group->stripes_cnt--;
                                        sh->group = NULL;
                                }
                        }
 +                      atomic_inc(&sh->count);
                        spin_unlock(&conf->device_lock);
                }
        } while (sh == NULL);
  
 -      if (sh)
 -              atomic_inc(&sh->count);
 -
        spin_unlock_irq(conf->hash_locks + hash);
        return sh;
  }
@@@ -2111,7 -2110,6 +2111,7 @@@ static void raid5_end_write_request(str
                        set_bit(R5_MadeGoodRepl, &sh->dev[i].flags);
        } else {
                if (!uptodate) {
 +                      set_bit(STRIPE_DEGRADED, &sh->state);
                        set_bit(WriteErrorSeen, &rdev->flags);
                        set_bit(R5_WriteError, &sh->dev[i].flags);
                        if (!test_and_set_bit(WantReplacement, &rdev->flags))
@@@ -3610,7 -3608,7 +3610,7 @@@ static void analyse_stripe(struct strip
                         */
                        set_bit(R5_Insync, &dev->flags);
  
 -              if (rdev && test_bit(R5_WriteError, &dev->flags)) {
 +              if (test_bit(R5_WriteError, &dev->flags)) {
                        /* This flag does not apply to '.replacement'
                         * only to .rdev, so make sure to check that*/
                        struct md_rdev *rdev2 = rcu_dereference(
                        } else
                                clear_bit(R5_WriteError, &dev->flags);
                }
 -              if (rdev && test_bit(R5_MadeGood, &dev->flags)) {
 +              if (test_bit(R5_MadeGood, &dev->flags)) {
                        /* This flag does not apply to '.replacement'
                         * only to .rdev, so make sure to check that*/
                        struct md_rdev *rdev2 = rcu_dereference(
@@@ -6103,6 -6101,7 +6103,7 @@@ static int run(struct mddev *mddev
                blk_queue_io_min(mddev->queue, chunk_size);
                blk_queue_io_opt(mddev->queue, chunk_size *
                                 (conf->raid_disks - conf->max_degraded));
+               mddev->queue->limits.raid_partial_stripes_expensive = 1;
                /*
                 * We can only discard a whole stripe. It doesn't make sense to
                 * discard data disk but write parity disk