1. 10 2月, 2021 3 次提交
    • K
      bcache: Move journal work to new flush wq · afe78ab4
      Kai Krakow 提交于
      This is potentially long running and not latency sensitive, let's get
      it out of the way of other latency sensitive events.
      
      As observed in the previous commit, the `system_wq` comes easily
      congested by bcache, and this fixes a few more stalls I was observing
      every once in a while.
      
      Let's not make this `WQ_MEM_RECLAIM` as it showed to reduce performance
      of boot and file system operations in my tests. Also, without
      `WQ_MEM_RECLAIM`, I no longer see desktop stalls. This matches the
      previous behavior as `system_wq` also does no memory reclaim:
      
      > // workqueue.c:
      > system_wq = alloc_workqueue("events", 0, 0);
      
      Cc: Coly Li <colyli@suse.de>
      Cc: stable@vger.kernel.org # 5.4+
      Signed-off-by: NKai Krakow <kai@kaishome.de>
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      afe78ab4
    • K
      Revert "bcache: Kill btree_io_wq" · 9f233ffe
      Kai Krakow 提交于
      This reverts commit 56b30770.
      
      With the btree using the `system_wq`, I seem to see a lot more desktop
      latency than I should.
      
      After some more investigation, it looks like the original assumption
      of 56b30770 no longer is true, and bcache has a very high potential of
      congesting the `system_wq`. In turn, this introduces laggy desktop
      performance, IO stalls (at least with btrfs), and input events may be
      delayed.
      
      So let's revert this. It's important to note that the semantics of
      using `system_wq` previously mean that `btree_io_wq` should be created
      before and destroyed after other bcache wqs to keep the same
      assumptions.
      
      Cc: Coly Li <colyli@suse.de>
      Cc: stable@vger.kernel.org # 5.4+
      Signed-off-by: NKai Krakow <kai@kaishome.de>
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      9f233ffe
    • K
      bcache: Fix register_device_aync typo · d7fae7b4
      Kai Krakow 提交于
      Should be `register_device_async`.
      
      Cc: Coly Li <colyli@suse.de>
      Signed-off-by: NKai Krakow <kai@kaishome.de>
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      d7fae7b4
  2. 25 1月, 2021 1 次提交
  3. 10 1月, 2021 4 次提交
    • C
      bcache: set bcache device into read-only mode for BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET · 5342fd42
      Coly Li 提交于
      If BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET is set in incompat feature
      set, it means the cache device is created with obsoleted layout with
      obso_bucket_site_hi. Now bcache does not support this feature bit, a new
      BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE incompat feature bit is added
      for a better layout to support large bucket size.
      
      For the legacy compatibility purpose, if a cache device created with
      obsoleted BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET feature bit, all bcache
      devices attached to this cache set should be set to read-only. Then the
      dirty data can be written back to backing device before re-create the
      cache device with BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE feature bit
      by the latest bcache-tools.
      
      This patch checks BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET feature bit
      when running a cache set and attach a bcache device to the cache set. If
      this bit is set,
      - When run a cache set, print an error kernel message to indicate all
        following attached bcache device will be read-only.
      - When attach a bcache device, print an error kernel message to indicate
        the attached bcache device will be read-only, and ask users to update
        to latest bcache-tools.
      
      Such change is only for cache device whose bucket size >= 32MB, this is
      for the zoned SSD and almost nobody uses such large bucket size at this
      moment. If you don't explicit set a large bucket size for a zoned SSD,
      such change is totally transparent to your bcache device.
      
      Fixes: ffa47032 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket")
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      5342fd42
    • C
      bcache: introduce BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE for large bucket · b16671e8
      Coly Li 提交于
      When large bucket feature was added, BCH_FEATURE_INCOMPAT_LARGE_BUCKET
      was introduced into the incompat feature set. It used bucket_size_hi
      (which was added at the tail of struct cache_sb_disk) to extend current
      16bit bucket size to 32bit with existing bucket_size in struct
      cache_sb_disk.
      
      This is not a good idea, there are two obvious problems,
      - Bucket size is always value power of 2, if store log2(bucket size) in
        existing bucket_size of struct cache_sb_disk, it is unnecessary to add
        bucket_size_hi.
      - Macro csum_set() assumes d[SB_JOURNAL_BUCKETS] is the last member in
        struct cache_sb_disk, bucket_size_hi was added after d[] which makes
        csum_set calculate an unexpected super block checksum.
      
      To fix the above problems, this patch introduces a new incompat feature
      bit BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE, when this bit is set, it
      means bucket_size in struct cache_sb_disk stores the order of power-of-2
      bucket size value. When user specifies a bucket size larger than 32768
      sectors, BCH_FEATURE_INCOMPAT_LOG_LARGE_BUCKET_SIZE will be set to
      incompat feature set, and bucket_size stores log2(bucket size) more
      than store the real bucket size value.
      
      The obsoleted BCH_FEATURE_INCOMPAT_LARGE_BUCKET won't be used anymore,
      it is renamed to BCH_FEATURE_INCOMPAT_OBSO_LARGE_BUCKET and still only
      recognized by kernel driver for legacy compatible purpose. The previous
      bucket_size_hi is renmaed to obso_bucket_size_hi in struct cache_sb_disk
      and not used in bcache-tools anymore.
      
      For cache device created with BCH_FEATURE_INCOMPAT_LARGE_BUCKET feature,
      bcache-tools and kernel driver still recognize the feature string and
      display it as "obso_large_bucket".
      
      With this change, the unnecessary extra space extend of bcache on-disk
      super block can be avoided, and csum_set() may generate expected check
      sum as well.
      
      Fixes: ffa47032 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket")
      Signed-off-by: NColy Li <colyli@suse.de>
      Cc: stable@vger.kernel.org # 5.9+
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      b16671e8
    • C
      bcache: check unsupported feature sets for bcache register · 1dfc0686
      Coly Li 提交于
      This patch adds the check for features which is incompatible for
      current supported feature sets.
      
      Now if the bcache device created by bcache-tools has features that
      current kernel doesn't support, read_super() will fail with error
      messoage. E.g. if an unsupported incompatible feature detected,
      bcache register will fail with dmesg "bcache: register_bcache() error :
      Unsupported incompatible feature found".
      
      Fixes: d721a43f ("bcache: increase super block version for cache device and backing device")
      Fixes: ffa47032 ("bcache: add bucket_size_hi into struct cache_sb_disk for large bucket")
      Signed-off-by: NColy Li <colyli@suse.de>
      Cc: stable@vger.kernel.org # 5.9+
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      1dfc0686
    • Y
      bcache: set pdev_set_uuid before scond loop iteration · e8092707
      Yi Li 提交于
      There is no need to reassign pdev_set_uuid in the second loop iteration,
      so move it to the place before second loop.
      Signed-off-by: NYi Li <yili@winhong.com>
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      e8092707
  4. 24 12月, 2020 1 次提交
    • Y
      bcache:remove a superfluous check in register_bcache · 117ae250
      Yi Li 提交于
      There have no reassign the bdev after check It is IS_ERR.
      the double check !IS_ERR(bdev) is superfluous.
      
      After commit 4e7b5671 ("block: remove i_bdev"),
      "Switch the block device lookup interfaces to directly work with a dev_t
      so that struct block_device references are only acquired by the
      blkdev_get variants (and the blk-cgroup special case).  This means that
      we now don't need an extra reference in the inode and can generally
      simplify handling of struct block_device to keep the lookups contained
      in the core block layer code."
      
      so after lookup_bdev call, there no need to do bdput.
      
      remove a superfluous check the bdev & don't call bdput after lookup_bdev.
      
      Fixes: 4e7b5671("block: remove i_bdev")
      Signed-off-by: NYi Li <yili@winhong.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      117ae250
  5. 08 12月, 2020 1 次提交
    • D
      bcache: fix race between setting bdev state to none and new write request direct to backing · df4ad532
      Dongsheng Yang 提交于
      There is a race condition in detaching as below:
      A. detaching			B. Write request
      (1) writing back
      (2) write back done, set bdev
          state to clean.
      (3) cached_dev_put() and
          schedule_work(&dc->detach);
      				(4) write data [0 - 4K] directly
      				    into backing and ack to user.
      (5) power-failure...
      
      When we restart this bcache device, this bdev is clean but not detached,
      and read [0 - 4K], we will get unexpected old data from cache device.
      
      To fix this problem, set the bdev state to none when we writeback done
      in detaching, and then if power-failure happened as above, the data in
      cache will not be used in next bcache device starting, it's detached, we
      will read the correct data from backing derectly.
      Signed-off-by: NDongsheng Yang <dongsheng.yang@easystack.cn>
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      df4ad532
  6. 02 12月, 2020 3 次提交
  7. 03 10月, 2020 11 次提交
    • C
      bcache: remove embedded struct cache_sb from struct cache_set · 4a784266
      Coly Li 提交于
      Since bcache code was merged into mainline kerrnel, each cache set only
      as one single cache in it. The multiple caches framework is here but the
      code is far from completed. Considering the multiple copies of cached
      data can also be stored on e.g. md raid1 devices, it is unnecessary to
      support multiple caches in one cache set indeed.
      
      The previous preparation patches fix the dependencies of explicitly
      making a cache set only have single cache. Now we don't have to maintain
      an embedded partial super block in struct cache_set, the in-memory super
      block can be directly referenced from struct cache.
      
      This patch removes the embedded struct cache_sb from struct cache_set,
      and fixes all locations where the superb lock was referenced from this
      removed super block by referencing the in-memory super block of struct
      cache.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      4a784266
    • C
      bcache: check and set sync status on cache's in-memory super block · 6f9414e0
      Coly Li 提交于
      Currently the cache's sync status is checked and set on cache set's in-
      memory partial super block. After removing the embedded struct cache_sb
      from cache set and reference cache's in-memory super block from struct
      cache_set, the sync status can set and check directly on cache's super
      block.
      
      This patch checks and sets the cache sync status directly on cache's
      in-memory super block. This is a preparation for later removing embedded
      struct cache_sb from struct cache_set.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      6f9414e0
    • C
      bcache: remove can_attach_cache() · ebaa1ac1
      Coly Li 提交于
      After removing the embedded struct cache_sb from struct cache_set, cache
      set will directly reference the in-memory super block of struct cache.
      It is unnecessary to compare block_size, bucket_size and nr_in_set from
      the identical in-memory super block in can_attach_cache().
      
      This is a preparation patch for latter removing cache_set->sb from
      struct cache_set.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      ebaa1ac1
    • C
      bcache: don't check seq numbers in register_cache_set() · 08a17828
      Coly Li 提交于
      In order to update the partial super block of cache set, the seq numbers
      of cache and cache set are checked in register_cache_set(). If cache's
      seq number is larger than cache set's seq number, cache set must update
      its partial super block from cache's super block. It is unncessary when
      the embedded struct cache_sb is removed from struct cache set.
      
      This patch removed the seq numbers checking from register_cache_set(),
      because later there will be no such partial super block in struct cache
      set, the cache set will directly reference in-memory super block from
      struct cache. This is a preparation patch for removing embedded struct
      cache_sb from struct cache_set.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      08a17828
    • C
      bcache: remove useless alloc_bucket_pages() · 421cf1c5
      Coly Li 提交于
      Now no one uses alloc_bucket_pages() anymore, remove it from bcache.h.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      421cf1c5
    • C
      bcache: only use block_bytes() on struct cache · 4e1ebae3
      Coly Li 提交于
      Because struct cache_set and struct cache both have struct cache_sb,
      therefore macro block_bytes() can be used on both of them. When removing
      the embedded struct cache_sb from struct cache_set, this macro won't be
      used on struct cache_set anymore.
      
      This patch unifies all block_bytes() usage only on struct cache, this is
      one of the preparation to remove the embedded struct cache_sb from
      struct cache_set.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      4e1ebae3
    • C
      bcache: add set_uuid in struct cache_set · 1132e56e
      Coly Li 提交于
      This patch adds a separated set_uuid[16] in struct cache_set, to store
      the uuid of the cache set. This is the preparation to remove the
      embedded struct cache_sb from struct cache_set.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      1132e56e
    • C
      bcache: remove for_each_cache() · 08fdb2cd
      Coly Li 提交于
      Since now each cache_set explicitly has single cache, for_each_cache()
      is unnecessary. This patch removes this macro, and update all locations
      where it is used, and makes sure all code logic still being consistent.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      08fdb2cd
    • C
      bcache: explicitly make cache_set only have single cache · 697e2349
      Coly Li 提交于
      Currently although the bcache code has a framework for multiple caches
      in a cache set, but indeed the multiple caches never completed and users
      use md raid1 for multiple copies of the cached data.
      
      This patch does the following change in struct cache_set, to explicitly
      make a cache_set only have single cache,
      - Change pointer array "*cache[MAX_CACHES_PER_SET]" to a single pointer
        "*cache".
      - Remove pointer array "*cache_by_alloc[MAX_CACHES_PER_SET]".
      - Remove "caches_loaded".
      
      Now the code looks as exactly what it does in practic: only one cache is
      used in the cache set.
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      697e2349
    • C
      bcache: remove 'int n' from parameter list of bch_bucket_alloc_set() · 17e4aed8
      Coly Li 提交于
      The parameter 'int n' from bch_bucket_alloc_set() is not cleared
      defined. From the code comments n is the number of buckets to alloc, but
      from the code itself 'n' is the maximum cache to iterate. Indeed all the
      locations where bch_bucket_alloc_set() is called, 'n' is alwasy 1.
      
      This patch removes the confused and unnecessary 'int n' from parameter
      list of  bch_bucket_alloc_set(), and explicitly allocates only 1 bucket
      for its caller.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      17e4aed8
    • C
      bcache: share register sysfs with async register · a58e88bf
      Coly Li 提交于
      Previously the experimental async registration uses a separate sysfs
      file register_async. Now the async registration code seems working well
      for a while, we can do furtuher testing with it now.
      
      This patch changes the async bcache registration shares the same sysfs
      file /sys/fs/bcache/register (and register_quiet). Async registration
      will be default behavior if BCACHE_ASYNC_REGISTRATION is set in kernel
      configure. By default, BCACHE_ASYNC_REGISTRATION is not configured yet.
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      a58e88bf
  8. 25 9月, 2020 2 次提交
  9. 25 7月, 2020 14 次提交
    • C
      bcache: avoid extra memory consumption in struct bbio for large bucket size · 4e4d4e09
      Coly Li 提交于
      Bcache uses struct bbio to do I/Os for meta data pages like uuids,
      disk_buckets, prio_buckets, and btree nodes.
      
      Example writing a btree node onto cache device, the process is,
      - Allocate a struct bbio from mempool c->bio_meta.
      - Inside struct bbio embedded a struct bio, initialize bi_inline_vecs
        for this embedded bio.
      - Call bch_bio_map() to map each meta data page to each bv from the
        inlined  bi_io_vec table.
      - Call bch_submit_bbio() to submit the bio into underlying block layer.
      - When the I/O completed, only release the struct bbio, don't touch the
        reference counter of the meta data pages.
      
      The struct bbio is defined as,
      738 struct bbio {
      739     unsigned int            submit_time_us;
      	[snipped]
      748     struct bio              bio;
      749 };
      
      Because struct bio is embedded at the end of struct bbio, therefore the
      actual size of struct bbio is sizeof(struct bio) + size of the embedded
      bio->bi_inline_vecs.
      
      Now all the meta data bucket size are limited to meta_bucket_pages(), if
      the bucket size is large than meta_bucket_pages()*PAGE_SECTORS, rested
      space in the bucket is unused. Therefore the most used space in meta
      bucket is (1<<MAX_ORDER) pages, or (1<<CONFIG_FORCE_MAX_ZONEORDER) if it
      is configured.
      
      Therefore for large bucket size, it is unnecessary to calculate the
      allocation size of mempool c->bio_meta as,
      	mempool_init_kmalloc_pool(&c->bio_meta, 2,
      			sizeof(struct bbio) +
      			sizeof(struct bio_vec) * bucket_pages(c))
      It is too large, neither the Linux buddy allocator cannot allocate so
      much continuous pages, nor the extra allocated pages are wasted.
      
      This patch replace bucket_pages() to meta_bucket_pages() in two places,
      - In bch_cache_set_alloc(), when initialize mempool c->bio_meta, uses
        sizeof(struct bbio) + sizeof(struct bio_vec) * bucket_pages(c) to set
        the allocating object size.
      - In bch_bbio_alloc(), when calling bio_init() to set inline bvec talbe
        bi_inline_bvecs, uses meta_bucket_pages() to indicate number of the
        inline bio vencs number.
      
      Now the maximum size of embedded bio inside struct bbio exactly matches
      the limit of meta_bucket_pages(), no extra page wasted.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      4e4d4e09
    • C
      bcache: avoid extra memory allocation from mempool c->fill_iter · 6907dc49
      Coly Li 提交于
      Mempool c->fill_iter is used to allocate memory for struct btree_iter in
      bch_btree_node_read_done() to iterate all keys of a read-in btree node.
      
      The allocation size is defined in bch_cache_set_alloc() by,
        mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size))
      where iter_size is defined by a calculation,
        (sb->bucket_size / sb->block_size + 1) * sizeof(struct btree_iter_set)
      
      For 16bit width bucket_size the calculation is OK, but now the bucket
      size is extended to 32bit, the bucket size can be 2GB. By the above
      calculation, iter_size can be 2048 pages (order 11 is still accepted by
      buddy allocator).
      
      But the actual size holds the bkeys in meta data bucket is limited to
      meta_bucket_pages() already, which is 16MB. By the above calculation,
      if replace sb->bucket_size by meta_bucket_pages() * PAGE_SECTORS, the
      result is 16 pages. This is the size large enough for the mempool
      allocation to struct btree_iter.
      
      Therefore in worst case every time mempool c->fill_iter allocates, at
      most 4080 pages are wasted and won't be used. Therefore this patch uses
      meta_bucket_pages() * PAGE_SECTORS to calculate the iter size in
      bch_cache_set_alloc(), to avoid extra memory allocation from mempool
      c->fill_iter.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      6907dc49
    • C
      bcache: add bucket_size_hi into struct cache_sb_disk for large bucket · ffa47032
      Coly Li 提交于
      The large bucket feature is to extend bucket_size from 16bit to 32bit.
      
      When create cache device on zoned device (e.g. zoned NVMe SSD), making
      a single bucket cover one or more zones of the zoned device is the
      simplest way to support zoned device as cache by bcache.
      
      But current maximum bucket size is 16MB and a typical zone size of zoned
      device is 256MB, this is the major motiviation to extend bucket size to
      a larger bit width.
      
      This patch is the basic and first change to support large bucket size,
      the major changes it makes are,
      - Add BCH_FEATURE_INCOMPAT_LARGE_BUCKET for the large bucket feature,
        INCOMPAT means it introduces incompatible on-disk format change.
      - Add BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET) routines.
      - Adds __le16 bucket_size_hi into struct cache_sb_disk at offset 0x8d0
        for the on-disk super block format.
      - For the in-memory super block struct cache_sb, member bucket_size is
        extended from __u16 to __32.
      - Add get_bucket_size() to combine the bucket_size and bucket_size_hi
        from struct cache_sb_disk into an unsigned int value.
      
      Since we already have large bucket size helpers meta_bucket_pages(),
      meta_bucket_bytes() and alloc_meta_bucket_pages(), they make sure when
      bucket size > 8MB, the memory allocation for bcache meta data bucket
      won't fail no matter how large the bucket size extended. So these meta
      data buckets are handled properly when the bucket size width increase
      from 16bit to 32bit, we don't need to worry about them.
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      ffa47032
    • C
      bcache: handle btree node memory allocation properly for bucket size > 8MB · f9c32a5a
      Coly Li 提交于
      Currently the bcache internal btree node occupies a whole bucket. When
      loading the btree node from cache device into memory, mca_data_alloc()
      will call bch_btree_keys_alloc() to allocate memory for the whole bucket
      size, ilog2(b->c->btree_pages) is send to bch_btree_keys_alloc() as the
      parameter 'page_order'.
      
      c->btree_pages is set as bucket_pages() in bch_cache_set_alloc(), for
      bucket size > 8MB, ilog2(b->c->btree_pages) is 12 for 4KB page size. By
      default the maximum page order __get_free_pages() accepts is MAX_ORDER
      (11), in this condition bch_btree_keys_alloc() will always fail.
      
      Because of other over-page-order allocation failure fails the cache
      device registration, such btree node allocation failure wasn't observed
      during runtime. After other blocking page allocation failures for bucket
      size > 8MB, this btree node allocation issue may trigger potentical risk
      e.g. infinite dead-loop to retry btree node allocation after failure.
      
      This patch fixes the potential problem by setting c->btree_pages to
      meta_bucket_pages() in bch_cache_set_alloc(). In the condition that
      bucket size > 8MB, meta_bucket_pages() will always return a number which
      won't exceed the maximum page order of the buddy allocator.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      f9c32a5a
    • C
      bcache: handle cache prio_buckets and disk_buckets properly for bucket size > 8MB · c954ac8d
      Coly Li 提交于
      Similar to c->uuids, struct cache's prio_buckets and disk_buckets also
      have the potential memory allocation failure during cache registration
      if the bucket size > 8MB.
      
      ca->prio_buckets can be stored on cache device in multiple buckets, its
      in-memory space is allocated by kzalloc() interface but normally
      allocated by alloc_pages() because the size > KMALLOC_MAX_CACHE_SIZE.
      
      So allocation of ca->prio_buckets has the MAX_ORDER restriction too. If
      the bucket size > 8MB, by default the page allocator will fail because
      the page order > 11 (default MAX_ORDER value). ca->prio_buckets should
      also use meta_bucket_bytes(), meta_bucket_pages() to decide its memory
      size and use alloc_meta_bucket_pages() to allocate pages, to avoid the
      allocation failure during cache set registration when bucket size > 8MB.
      
      ca->disk_buckets is a single bucket size memory buffer, it is used to
      iterate each bucket of ca->prio_buckets, and compose the bio based on
      memory of ca->disk_buckets, then write ca->disk_buckets memory to cache
      disk one-by-one for each bucket of ca->prio_buckets. ca->disk_buckets
      should have in-memory size exact to the meta_bucket_pages(), this is the
      size that ca->prio_buckets will be stored into each on-disk bucket.
      
      This patch fixes the above issues and handle cache's prio_buckets and
      disk_buckets properly for bucket size larger than 8MB.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      c954ac8d
    • C
      bcache: handle c->uuids properly for bucket size > 8MB · 21e478dd
      Coly Li 提交于
      Bcache allocates a whole bucket to store c->uuids on cache device, and
      allocates continuous pages to store it in-memory. When the bucket size
      exceeds maximum allocable continuous pages, bch_cache_set_alloc() will
      fail and cache device registration will fail.
      
      This patch allocates c->uuids by alloc_meta_bucket_pages(), and uses
      ilog2(meta_bucket_pages(c)) to indicate order of c->uuids pages when
      free it. When writing c->uuids to cache device, its size is decided
      by meta_bucket_pages(c) * PAGE_SECTORS. Now c->uuids is properly handled
      for bucket size > 8MB.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      21e478dd
    • C
      bcache: introduce meta_bucket_pages() related helper routines · de1fafab
      Coly Li 提交于
      Currently the in-memory meta data like c->uuids or c->disk_buckets
      are allocated by alloc_bucket_pages(). The macro alloc_bucket_pages()
      calls __get_free_pages() to allocated continuous pages with order
      indicated by ilog2(bucket_pages(c)),
       #define alloc_bucket_pages(gfp, c)                      \
           ((void *) __get_free_pages(__GFP_ZERO|gfp, ilog2(bucket_pages(c))))
      
      The maximum order is defined as MAX_ORDER, the default value is 11 (and
      can be overwritten by CONFIG_FORCE_MAX_ZONEORDER). In bcache code the
      maximum bucket size width is 16bits, this is restricted both by KEY_SIZE
      size and bucket_size size from struct cache_sb_disk. The maximum 16bits
      width and power-of-2 value is (1<<15) in unit of sector (512byte). It
      means the maximum value of bucket size in bytes is (1<<24) bytes a.k.a
      4096 pages.
      
      When the bucket size is set to maximum permitted value, ilog2(4096) is
      12, which exceeds the default maximum order __get_free_pages() can
      accepted, the failed pages allocation will fail cache set registration
      procedure and print a kernel oops message for the exceeded pages order.
      
      This patch introduces meta_bucket_pages(), meta_bucket_bytes(), and
      alloc_bucket_pages() helper routines. meta_bucket_pages() indicates the
      maximum pages can be allocated to meta data bucket, meta_bucket_bytes()
      indicates the according maximum bytes, and alloc_bucket_pages() does
      the pages allocation for meta bucket. Because meta_bucket_pages()
      chooses the smaller value among the bucket size and MAX_ORDER_NR_PAGES,
      it still works when MAX_ORDER overwritten by CONFIG_FORCE_MAX_ZONEORDER.
      
      Following patches will use these helper routines to decide maximum pages
      can be allocated for different meta data buckets. If the bucket size is
      larger than meta_bucket_bytes(), the bcache registration can continue to
      success, just the space more than meta_bucket_bytes() inside the bucket
      is wasted. Comparing bcache failed for large bucket size, wasting some
      space for meta data buckets is acceptable at this moment.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      de1fafab
    • C
      bcache: move bucket related code into read_super_common() · 198efa35
      Coly Li 提交于
      Setting sb->first_bucket and checking sb->keys indeed are only for cache
      device, it does not make sense to do them in read_super() for backing
      device too.
      
      This patch moves the related code piece into read_super_common()
      explicitly for cache device and avoid the confusion.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      198efa35
    • C
      bcache: increase super block version for cache device and backing device · d721a43f
      Coly Li 提交于
      The new added super block version BCACHE_SB_VERSION_BDEV_WITH_FEATURES
      (5) BCACHE_SB_VERSION_CDEV_WITH_FEATURES value (6), is for the feature
      set bits.
      
      Devices have super block version equal to the new version will have
      three new members for feature set bits in the on-disk super block,
              __le64                  feature_compat;
              __le64                  feature_incompat;
              __le64                  feature_ro_compat;
      
      They are used for further new features which may introduce on-disk
      format change, and avoid unncessary super block version increase.
      
      The very basic features handling code skeleton is also initialized in
      this patch.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      d721a43f
    • C
      bcache: fix super block seq numbers comparision in register_cache_set() · 117f636e
      Coly Li 提交于
      In register_cache_set(), c is pointer to struct cache_set, and ca is
      pointer to struct cache, if ca->sb.seq > c->sb.seq, it means this
      registering cache has up to date version and other members, the in-
      memory version and other members should be updated to the newer value.
      
      But current implementation makes a cache set only has a single cache
      device, so the above assumption works well except for a special case.
      The execption is when a cache device new created and both ca->sb.seq and
      c->sb.seq are 0, because the super block is never flushed out yet. In
      the location for the following if() check,
      2156         if (ca->sb.seq > c->sb.seq) {
      2157                 c->sb.version           = ca->sb.version;
      2158                 memcpy(c->sb.set_uuid, ca->sb.set_uuid, 16);
      2159                 c->sb.flags             = ca->sb.flags;
      2160                 c->sb.seq               = ca->sb.seq;
      2161                 pr_debug("set version = %llu\n", c->sb.version);
      2162         }
      c->sb.version is not initialized yet and valued 0. When ca->sb.seq is 0,
      the if() check will fail (because both values are 0), and the cache set
      version, set_uuid, flags and seq won't be updated.
      
      The above problem is hiden for current code, because the bucket size is
      compatible among different super block version. And the next time when
      running cache set again, ca->sb.seq will be larger than 0 and cache set
      super block version will be updated properly.
      
      But if the large bucket feature is enabled,  sb->bucket_size is the low
      16bits of the bucket size. For a power of 2 value, when the actual
      bucket size exceeds 16bit width, sb->bucket_size will always be 0. Then
      read_super_common() will fail because the if() check to
      is_power_of_2(sb->bucket_size) is false. This is how the long time
      hidden bug is triggered.
      
      This patch modifies the if() check to the following way,
      2156         if (ca->sb.seq > c->sb.seq || c->sb.seq == 0) {
      Then cache set's version, set_uuid, flags and seq will always be updated
      corectly including for a new created cache device.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      117f636e
    • C
      bcache: disassemble the big if() checks in bch_cache_set_alloc() · a42d3c64
      Coly Li 提交于
      In bch_cache_set_alloc() there is a big if() checks combined by 11 items
      together. When this big if() statement fails, it is difficult to tell
      exactly which item fails indeed.
      
      This patch disassembles this big if() checks into 11 single if() checks,
      which makes code debug more easier.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      a42d3c64
    • C
      bcache: add more accurate error information in read_super_common() · c557a5f7
      Coly Li 提交于
      The improperly set bucket or block size will trigger error in
      read_super_common(). For large bucket size, a more accurate error message
      for invalid bucket or block size is necessary.
      
      This patch disassembles the combined if() checks into multiple single
      if() check, and provide more accurate error message for each check
      failure condition.
      Signed-off-by: NColy Li <colyli@suse.de>
      Reviewed-by: NHannes Reinecke <hare@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      c557a5f7
    • C
      bcache: add read_super_common() to read major part of super block · 5b21403c
      Coly Li 提交于
      Later patches will introduce feature set bits to on-disk super block and
      increase super block version. Current code in read_super() which reads
      common part of super block for version BCACHE_SB_VERSION_CDEV and version
      BCACHE_SB_VERSION_CDEV_WITH_UUID will be shared with the new version.
      
      Therefore this patch moves the reusable part into read_super_common(),
      this preparation patch will make later patches more simplier and only
      focus on new feature set bits.
      Signed-off-by: NColy Li <colyli@suse.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      5b21403c
    • C
      bcache: avoid nr_stripes overflow in bcache_device_init() · 65f0f017
      Coly Li 提交于
      For some block devices which large capacity (e.g. 8TB) but small io_opt
      size (e.g. 8 sectors), in bcache_device_init() the stripes number calcu-
      lated by,
      	DIV_ROUND_UP_ULL(sectors, d->stripe_size);
      might be overflow to the unsigned int bcache_device->nr_stripes.
      
      This patch uses the uint64_t variable to store DIV_ROUND_UP_ULL()
      and after the value is checked to be available in unsigned int range,
      sets it to bache_device->nr_stripes. Then the overflow is avoided.
      Reported-and-tested-by: NKen Raeburn <raeburn@redhat.com>
      Signed-off-by: NColy Li <colyli@suse.de>
      Cc: stable@vger.kernel.org
      Link: https://bugzilla.redhat.com/show_bug.cgi?id=1783075Signed-off-by: NJens Axboe <axboe@kernel.dk>
      65f0f017