Skip to content

Commit ffa4703

Browse files
Coly Liaxboe
authored andcommitted
bcache: add bucket_size_hi into struct cache_sb_disk for large bucket
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: Coly Li <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent f9c32a5 commit ffa4703

File tree

6 files changed

+52
-11
lines changed

6 files changed

+52
-11
lines changed

drivers/md/bcache/alloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ void bch_rescale_priorities(struct cache_set *c, int sectors)
8787
{
8888
struct cache *ca;
8989
struct bucket *b;
90-
unsigned int next = c->nbuckets * c->sb.bucket_size / 1024;
90+
unsigned long next = c->nbuckets * c->sb.bucket_size / 1024;
9191
unsigned int i;
9292
int r;
9393

drivers/md/bcache/features.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Feature set bits and string conversion.
4+
* Inspired by ext4's features compat/incompat/ro_compat related code.
5+
*
6+
* Copyright 2020 Coly Li <[email protected]>
7+
*
8+
*/
9+
#include <linux/bcache.h>
10+
#include "bcache.h"
11+
12+
struct feature {
13+
int compat;
14+
unsigned int mask;
15+
const char *string;
16+
};
17+
18+
static struct feature feature_list[] = {
19+
{BCH_FEATURE_INCOMPAT, BCH_FEATURE_INCOMPAT_LARGE_BUCKET,
20+
"large_bucket"},
21+
{0, 0, 0 },
22+
};

drivers/md/bcache/features.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
#define BCH_FEATURE_INCOMPAT 2
1212
#define BCH_FEATURE_TYPE_MASK 0x03
1313

14+
/* Feature set definition */
15+
/* Incompat feature set */
16+
#define BCH_FEATURE_INCOMPAT_LARGE_BUCKET 0x0001 /* 32bit bucket size */
17+
1418
#define BCH_FEATURE_COMPAT_SUUP 0
1519
#define BCH_FEATURE_RO_COMPAT_SUUP 0
16-
#define BCH_FEATURE_INCOMPAT_SUUP 0
20+
#define BCH_FEATURE_INCOMPAT_SUUP BCH_FEATURE_INCOMPAT_LARGE_BUCKET
1721

1822
#define BCH_HAS_COMPAT_FEATURE(sb, mask) \
1923
((sb)->feature_compat & (mask))
@@ -22,8 +26,6 @@
2226
#define BCH_HAS_INCOMPAT_FEATURE(sb, mask) \
2327
((sb)->feature_incompat & (mask))
2428

25-
/* Feature set definition */
26-
2729
#define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \
2830
static inline int bch_has_feature_##name(struct cache_sb *sb) \
2931
{ \
@@ -75,4 +77,5 @@ static inline void bch_clear_feature_##name(struct cache_sb *sb) \
7577
~BCH##_FEATURE_INCOMPAT_##flagname; \
7678
}
7779

80+
BCH_FEATURE_INCOMPAT_FUNCS(large_bucket, LARGE_BUCKET);
7881
#endif

drivers/md/bcache/movinggc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ void bch_moving_gc(struct cache_set *c)
206206
mutex_lock(&c->bucket_lock);
207207

208208
for_each_cache(ca, c, i) {
209-
unsigned int sectors_to_move = 0;
210-
unsigned int reserve_sectors = ca->sb.bucket_size *
209+
unsigned long sectors_to_move = 0;
210+
unsigned long reserve_sectors = ca->sb.bucket_size *
211211
fifo_used(&ca->free[RESERVE_MOVINGGC]);
212212

213213
ca->heap.used = 0;

drivers/md/bcache/super.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ struct workqueue_struct *bch_journal_wq;
6060

6161
/* Superblock */
6262

63+
static unsigned int get_bucket_size(struct cache_sb *sb, struct cache_sb_disk *s)
64+
{
65+
unsigned int bucket_size = le16_to_cpu(s->bucket_size);
66+
67+
if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES &&
68+
bch_has_feature_large_bucket(sb))
69+
bucket_size |= le16_to_cpu(s->bucket_size_hi) << 16;
70+
71+
return bucket_size;
72+
}
73+
6374
static const char *read_super_common(struct cache_sb *sb, struct block_device *bdev,
6475
struct cache_sb_disk *s)
6576
{
@@ -68,7 +79,7 @@ static const char *read_super_common(struct cache_sb *sb, struct block_device *
6879

6980
sb->first_bucket= le16_to_cpu(s->first_bucket);
7081
sb->nbuckets = le64_to_cpu(s->nbuckets);
71-
sb->bucket_size = le16_to_cpu(s->bucket_size);
82+
sb->bucket_size = get_bucket_size(sb, s);
7283

7384
sb->nr_in_set = le16_to_cpu(s->nr_in_set);
7485
sb->nr_this_dev = le16_to_cpu(s->nr_this_dev);
@@ -210,12 +221,16 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
210221
goto err;
211222
break;
212223
case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
213-
err = read_super_common(sb, bdev, s);
214-
if (err)
215-
goto err;
224+
/*
225+
* Feature bits are needed in read_super_common(),
226+
* convert them firstly.
227+
*/
216228
sb->feature_compat = le64_to_cpu(s->feature_compat);
217229
sb->feature_incompat = le64_to_cpu(s->feature_incompat);
218230
sb->feature_ro_compat = le64_to_cpu(s->feature_ro_compat);
231+
err = read_super_common(sb, bdev, s);
232+
if (err)
233+
goto err;
219234
break;
220235
default:
221236
err = "Unsupported superblock version";

include/uapi/linux/bcache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ struct cache_sb_disk {
213213
__le16 keys;
214214
};
215215
__le64 d[SB_JOURNAL_BUCKETS]; /* journal buckets */
216+
__le16 bucket_size_hi;
216217
};
217218

218219
/*
@@ -247,9 +248,9 @@ struct cache_sb {
247248
__u64 nbuckets; /* device size */
248249

249250
__u16 block_size; /* sectors */
250-
__u16 bucket_size; /* sectors */
251251
__u16 nr_in_set;
252252
__u16 nr_this_dev;
253+
__u32 bucket_size; /* sectors */
253254
};
254255
struct {
255256
/* Backing devices */

0 commit comments

Comments
 (0)