Merge tag 'for-4.15/dm-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 17:40:12 +0000 (09:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 17:40:12 +0000 (09:40 -0800)
Pull  more device mapper updates from Mike Snitzer:
 "Given your expected travel I figured I'd get these fixes to you sooner
  rather than later.

   - a DM multipath stable@ fix to silence an annoying error message
     that isn't _really_ an error

   - a DM core @stable fix for discard support that was enabled for an
     entire DM device despite only having partial support for discards
     due to a mix of discard capabilities across the underlying devices.

   - a couple other DM core discard fixes.

   - a DM bufio @stable fix that resolves a 32-bit overflow"

* tag 'for-4.15/dm-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm bufio: fix integer overflow when limiting maximum cache size
  dm: clear all discard attributes in queue_limits when discards are disabled
  dm: do not set 'discards_supported' in targets that do not need it
  dm: discard support requires all targets in a table support discards
  dm mpath: remove annoying message of 'blk_get_request() returned -11'

1  2 
drivers/md/dm-bufio.c
drivers/md/dm-mpath.c
drivers/md/dm-raid.c
drivers/md/dm-table.c

diff --combined drivers/md/dm-bufio.c
index 33bb074d694120a209ebac11d5e7ef93a3f445a3,8e3adcb46851e8942054f386f405f7596899cf16..b8ac591aaaa7070bfbd6d32c20993fb9130961f8
@@@ -347,7 -347,7 +347,7 @@@ static void __cache_size_refresh(void
        BUG_ON(!mutex_is_locked(&dm_bufio_clients_lock));
        BUG_ON(dm_bufio_client_count < 0);
  
 -      dm_bufio_cache_size_latch = ACCESS_ONCE(dm_bufio_cache_size);
 +      dm_bufio_cache_size_latch = READ_ONCE(dm_bufio_cache_size);
  
        /*
         * Use default if set to 0 and report the actual cache size used.
@@@ -960,7 -960,7 +960,7 @@@ static void __get_memory_limit(struct d
  {
        unsigned long buffers;
  
 -      if (unlikely(ACCESS_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch)) {
 +      if (unlikely(READ_ONCE(dm_bufio_cache_size) != dm_bufio_cache_size_latch)) {
                if (mutex_trylock(&dm_bufio_clients_lock)) {
                        __cache_size_refresh();
                        mutex_unlock(&dm_bufio_clients_lock);
                buffers = c->minimum_buffers;
  
        *limit_buffers = buffers;
-       *threshold_buffers = buffers * DM_BUFIO_WRITEBACK_PERCENT / 100;
+       *threshold_buffers = mult_frac(buffers,
+                                      DM_BUFIO_WRITEBACK_PERCENT, 100);
  }
  
  /*
@@@ -1600,7 -1601,7 +1601,7 @@@ static bool __try_evict_buffer(struct d
  
  static unsigned long get_retain_buffers(struct dm_bufio_client *c)
  {
 -        unsigned long retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
 +        unsigned long retain_bytes = READ_ONCE(dm_bufio_retain_bytes);
          return retain_bytes >> (c->sectors_per_block_bits + SECTOR_SHIFT);
  }
  
@@@ -1647,7 -1648,7 +1648,7 @@@ dm_bufio_shrink_count(struct shrinker *
  {
        struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker);
  
 -      return ACCESS_ONCE(c->n_buffers[LIST_CLEAN]) + ACCESS_ONCE(c->n_buffers[LIST_DIRTY]);
 +      return READ_ONCE(c->n_buffers[LIST_CLEAN]) + READ_ONCE(c->n_buffers[LIST_DIRTY]);
  }
  
  /*
@@@ -1818,7 -1819,7 +1819,7 @@@ EXPORT_SYMBOL_GPL(dm_bufio_set_sector_o
  
  static unsigned get_max_age_hz(void)
  {
 -      unsigned max_age = ACCESS_ONCE(dm_bufio_max_age);
 +      unsigned max_age = READ_ONCE(dm_bufio_max_age);
  
        if (max_age > UINT_MAX / HZ)
                max_age = UINT_MAX / HZ;
@@@ -1910,19 -1911,15 +1911,15 @@@ static int __init dm_bufio_init(void
        memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches);
        memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);
  
-       mem = (__u64)((totalram_pages - totalhigh_pages) *
-                     DM_BUFIO_MEMORY_PERCENT / 100) << PAGE_SHIFT;
+       mem = (__u64)mult_frac(totalram_pages - totalhigh_pages,
+                              DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT;
  
        if (mem > ULONG_MAX)
                mem = ULONG_MAX;
  
  #ifdef CONFIG_MMU
-       /*
-        * Get the size of vmalloc space the same way as VMALLOC_TOTAL
-        * in fs/proc/internal.h
-        */
-       if (mem > (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100)
-               mem = (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100;
+       if (mem > mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100))
+               mem = mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100);
  #endif
  
        dm_bufio_default_cache_size = mem;
diff --combined drivers/md/dm-mpath.c
index 204606bef9e2a15d3a91bfeefb3ee5d479506ced,e8094d8fbe0d5fb36a8e16bd2cbbbfed422423c2..c8faa2b8584268f75a8177f39677b94edba55289
@@@ -366,7 -366,7 +366,7 @@@ static struct pgpath *choose_path_in_pg
  
        pgpath = path_to_pgpath(path);
  
 -      if (unlikely(lockless_dereference(m->current_pg) != pg)) {
 +      if (unlikely(READ_ONCE(m->current_pg) != pg)) {
                /* Only update current_pgpath if pg changed */
                spin_lock_irqsave(&m->lock, flags);
                m->current_pgpath = pgpath;
@@@ -390,7 -390,7 +390,7 @@@ static struct pgpath *choose_pgpath(str
        }
  
        /* Were we instructed to switch PG? */
 -      if (lockless_dereference(m->next_pg)) {
 +      if (READ_ONCE(m->next_pg)) {
                spin_lock_irqsave(&m->lock, flags);
                pg = m->next_pg;
                if (!pg) {
  
        /* Don't change PG until it has no remaining paths */
  check_current_pg:
 -      pg = lockless_dereference(m->current_pg);
 +      pg = READ_ONCE(m->current_pg);
        if (pg) {
                pgpath = choose_path_in_pg(m, pg, nr_bytes);
                if (!IS_ERR_OR_NULL(pgpath))
@@@ -473,7 -473,7 +473,7 @@@ static int multipath_clone_and_map(stru
        struct request *clone;
  
        /* Do we need to select a new pgpath? */
 -      pgpath = lockless_dereference(m->current_pgpath);
 +      pgpath = READ_ONCE(m->current_pgpath);
        if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags))
                pgpath = choose_pgpath(m, nr_bytes);
  
        if (IS_ERR(clone)) {
                /* EBUSY, ENODEV or EWOULDBLOCK: requeue */
                bool queue_dying = blk_queue_dying(q);
-               DMERR_LIMIT("blk_get_request() returned %ld%s - requeuing",
-                           PTR_ERR(clone), queue_dying ? " (path offline)" : "");
                if (queue_dying) {
                        atomic_inc(&m->pg_init_in_progress);
                        activate_or_offline_path(pgpath);
@@@ -535,7 -533,7 +533,7 @@@ static int __multipath_map_bio(struct m
        bool queue_io;
  
        /* Do we need to select a new pgpath? */
 -      pgpath = lockless_dereference(m->current_pgpath);
 +      pgpath = READ_ONCE(m->current_pgpath);
        queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags);
        if (!pgpath || !queue_io)
                pgpath = choose_pgpath(m, nr_bytes);
@@@ -641,6 -639,14 +639,6 @@@ static void process_queued_bios(struct 
        blk_finish_plug(&plug);
  }
  
 -static void assign_bit(bool value, long nr, unsigned long *addr)
 -{
 -      if (value)
 -              set_bit(nr, addr);
 -      else
 -              clear_bit(nr, addr);
 -}
 -
  /*
   * If we run out of usable paths, should we queue I/O or error it?
   */
@@@ -650,11 -656,11 +648,11 @@@ static int queue_if_no_path(struct mult
        unsigned long flags;
  
        spin_lock_irqsave(&m->lock, flags);
 -      assign_bit((save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) ||
 -                 (!save_old_value && queue_if_no_path),
 -                 MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags);
 -      assign_bit(queue_if_no_path || dm_noflush_suspending(m->ti),
 -                 MPATHF_QUEUE_IF_NO_PATH, &m->flags);
 +      assign_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags,
 +                 (save_old_value && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) ||
 +                 (!save_old_value && queue_if_no_path));
 +      assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags,
 +                 queue_if_no_path || dm_noflush_suspending(m->ti));
        spin_unlock_irqrestore(&m->lock, flags);
  
        if (!queue_if_no_path) {
@@@ -1580,8 -1586,8 +1578,8 @@@ static void multipath_resume(struct dm_
        unsigned long flags;
  
        spin_lock_irqsave(&m->lock, flags);
 -      assign_bit(test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags),
 -                 MPATHF_QUEUE_IF_NO_PATH, &m->flags);
 +      assign_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags,
 +                 test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &m->flags));
        spin_unlock_irqrestore(&m->lock, flags);
  }
  
@@@ -1796,7 -1802,7 +1794,7 @@@ static int multipath_prepare_ioctl(stru
        struct pgpath *current_pgpath;
        int r;
  
 -      current_pgpath = lockless_dereference(m->current_pgpath);
 +      current_pgpath = READ_ONCE(m->current_pgpath);
        if (!current_pgpath)
                current_pgpath = choose_pgpath(m, 0);
  
        }
  
        if (r == -ENOTCONN) {
 -              if (!lockless_dereference(m->current_pg)) {
 +              if (!READ_ONCE(m->current_pg)) {
                        /* Path status changed, redo selection */
                        (void) choose_pgpath(m, 0);
                }
@@@ -1887,9 -1893,9 +1885,9 @@@ static int multipath_busy(struct dm_tar
                return (m->queue_mode != DM_TYPE_MQ_REQUEST_BASED);
  
        /* Guess which priority_group will be used at next mapping time */
 -      pg = lockless_dereference(m->current_pg);
 -      next_pg = lockless_dereference(m->next_pg);
 -      if (unlikely(!lockless_dereference(m->current_pgpath) && next_pg))
 +      pg = READ_ONCE(m->current_pg);
 +      next_pg = READ_ONCE(m->next_pg);
 +      if (unlikely(!READ_ONCE(m->current_pgpath) && next_pg))
                pg = next_pg;
  
        if (!pg) {
diff --combined drivers/md/dm-raid.c
index 366c625b9591f87493ca21643f517a14af13f898,ea6eb96b50121e5ccd7a93211ac270615d3cbab2..6319d846e0adb8c264f98676f0c2ddb8e85bdbb7
@@@ -12,7 -12,7 +12,7 @@@
  #include "raid1.h"
  #include "raid5.h"
  #include "raid10.h"
 -#include "bitmap.h"
 +#include "md-bitmap.h"
  
  #include <linux/device-mapper.h>
  
@@@ -2887,9 -2887,6 +2887,6 @@@ static void configure_discard_support(s
        bool raid456;
        struct dm_target *ti = rs->ti;
  
-       /* Assume discards not supported until after checks below. */
-       ti->discards_supported = false;
        /*
         * XXX: RAID level 4,5,6 require zeroing for safety.
         */
                }
        }
  
-       /* All RAID members properly support discards */
-       ti->discards_supported = true;
        /*
         * RAID1 and RAID10 personalities require bio splitting,
         * RAID0/4/5/6 don't and process large discard bios properly.
@@@ -3630,11 -3624,8 +3624,11 @@@ static void raid_postsuspend(struct dm_
  {
        struct raid_set *rs = ti->private;
  
 -      if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
 +      if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
 +              mddev_lock_nointr(&rs->md);
                mddev_suspend(&rs->md);
 +              mddev_unlock(&rs->md);
 +      }
  
        rs->md.ro = 1;
  }
@@@ -3891,11 -3882,8 +3885,11 @@@ static void raid_resume(struct dm_targe
        if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS))
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
  
 -      if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
 +      if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
 +              mddev_lock_nointr(mddev);
                mddev_resume(mddev);
 +              mddev_unlock(mddev);
 +      }
  }
  
  static struct target_type raid_target = {
diff --combined drivers/md/dm-table.c
index 433bd3f3014c9bd067215985cbee3c8589484b28,3acf8f56eb648a89e280ac2ba2dbe2589bec0b42..88130b5d95f909ead8441dec7f3fb5d80a7914c7
@@@ -1000,7 -1000,7 +1000,7 @@@ verify_rq_based
        list_for_each_entry(dd, devices, list) {
                struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev);
  
 -              if (!blk_queue_stackable(q)) {
 +              if (!queue_is_rq_based(q)) {
                        DMERR("table load rejected: including"
                              " non-request-stackable devices");
                        return -EINVAL;
@@@ -1758,13 -1758,12 +1758,12 @@@ static bool dm_table_supports_write_zer
        return true;
  }
  
- static int device_discard_capable(struct dm_target *ti, struct dm_dev *dev,
-                                 sector_t start, sector_t len, void *data)
+ static int device_not_discard_capable(struct dm_target *ti, struct dm_dev *dev,
+                                     sector_t start, sector_t len, void *data)
  {
        struct request_queue *q = bdev_get_queue(dev->bdev);
  
-       return q && blk_queue_discard(q);
+       return q && !blk_queue_discard(q);
  }
  
  static bool dm_table_supports_discards(struct dm_table *t)
        struct dm_target *ti;
        unsigned i;
  
-       /*
-        * Unless any target used by the table set discards_supported,
-        * require at least one underlying device to support discards.
-        * t->devices includes internal dm devices such as mirror logs
-        * so we need to use iterate_devices here, which targets
-        * supporting discard selectively must provide.
-        */
        for (i = 0; i < dm_table_get_num_targets(t); i++) {
                ti = dm_table_get_target(t, i);
  
                if (!ti->num_discard_bios)
-                       continue;
-               if (ti->discards_supported)
-                       return true;
+                       return false;
  
-               if (ti->type->iterate_devices &&
-                   ti->type->iterate_devices(ti, device_discard_capable, NULL))
-                       return true;
+               /*
+                * Either the target provides discard support (as implied by setting
+                * 'discards_supported') or it relies on _all_ data devices having
+                * discard support.
+                */
+               if (!ti->discards_supported &&
+                   (!ti->type->iterate_devices ||
+                    ti->type->iterate_devices(ti, device_not_discard_capable, NULL)))
+                       return false;
        }
  
-       return false;
+       return true;
  }
  
  void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
         */
        q->limits = *limits;
  
-       if (!dm_table_supports_discards(t))
+       if (!dm_table_supports_discards(t)) {
                queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
-       else
+               /* Must also clear discard limits... */
+               q->limits.max_discard_sectors = 0;
+               q->limits.max_hw_discard_sectors = 0;
+               q->limits.discard_granularity = 0;
+               q->limits.discard_alignment = 0;
+               q->limits.discard_misaligned = 0;
+       } else
                queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
  
        if (dm_table_supports_flush(t, (1UL << QUEUE_FLAG_WC))) {
         */
        if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random))
                queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
 -
 -      /*
 -       * QUEUE_FLAG_STACKABLE must be set after all queue settings are
 -       * visible to other CPUs because, once the flag is set, incoming bios
 -       * are processed by request-based dm, which refers to the queue
 -       * settings.
 -       * Until the flag set, bios are passed to bio-based dm and queued to
 -       * md->deferred where queue settings are not needed yet.
 -       * Those bios are passed to request-based dm at the resume time.
 -       */
 -      smp_mb();
 -      if (dm_table_request_based(t))
 -              queue_flag_set_unlocked(QUEUE_FLAG_STACKABLE, q);
  }
  
  unsigned int dm_table_get_num_targets(struct dm_table *t)