Skip to content

Commit 3413efa

Browse files
committed
Merge tag 'pull-bd_flags-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull bdev flags update from Al Viro: "Compactifying bdev flags. We can easily have up to 24 flags with sane atomicity, _without_ pushing anything out of the first cacheline of struct block_device" * tag 'pull-bd_flags-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: bdev: move ->bd_make_it_fail to ->__bd_flags bdev: move ->bd_ro_warned to ->__bd_flags bdev: move ->bd_has_subit_bio to ->__bd_flags bdev: move ->bd_write_holder into ->__bd_flags bdev: move ->bd_read_only to ->__bd_flags bdev: infrastructure for flags wrapper for access to ->bd_partno Use bdev_is_paritition() instead of open-coding it
2 parents 2a8120d + 811ba89 commit 3413efa

File tree

12 files changed

+77
-46
lines changed

12 files changed

+77
-46
lines changed

block/bdev.c

+8-9
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,11 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
422422
mutex_init(&bdev->bd_fsfreeze_mutex);
423423
spin_lock_init(&bdev->bd_size_lock);
424424
mutex_init(&bdev->bd_holder_lock);
425-
bdev->bd_partno = partno;
425+
atomic_set(&bdev->__bd_flags, partno);
426426
bdev->bd_mapping = &inode->i_data;
427427
bdev->bd_queue = disk->queue;
428-
if (partno)
429-
bdev->bd_has_submit_bio = disk->part0->bd_has_submit_bio;
430-
else
431-
bdev->bd_has_submit_bio = false;
428+
if (partno && bdev_test_flag(disk->part0, BD_HAS_SUBMIT_BIO))
429+
bdev_set_flag(bdev, BD_HAS_SUBMIT_BIO);
432430
bdev->bd_stats = alloc_percpu(struct disk_stats);
433431
if (!bdev->bd_stats) {
434432
iput(inode);
@@ -642,7 +640,7 @@ static void bd_end_claim(struct block_device *bdev, void *holder)
642640
bdev->bd_holder = NULL;
643641
bdev->bd_holder_ops = NULL;
644642
mutex_unlock(&bdev->bd_holder_lock);
645-
if (bdev->bd_write_holder)
643+
if (bdev_test_flag(bdev, BD_WRITE_HOLDER))
646644
unblock = true;
647645
}
648646
if (!whole->bd_holders)
@@ -655,7 +653,7 @@ static void bd_end_claim(struct block_device *bdev, void *holder)
655653
*/
656654
if (unblock) {
657655
disk_unblock_events(bdev->bd_disk);
658-
bdev->bd_write_holder = false;
656+
bdev_clear_flag(bdev, BD_WRITE_HOLDER);
659657
}
660658
}
661659

@@ -922,9 +920,10 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
922920
* writeable reference is too fragile given the way @mode is
923921
* used in blkdev_get/put().
924922
*/
925-
if ((mode & BLK_OPEN_WRITE) && !bdev->bd_write_holder &&
923+
if ((mode & BLK_OPEN_WRITE) &&
924+
!bdev_test_flag(bdev, BD_WRITE_HOLDER) &&
926925
(disk->event_flags & DISK_EVENT_FLAG_BLOCK_ON_EXCL_WRITE)) {
927-
bdev->bd_write_holder = true;
926+
bdev_set_flag(bdev, BD_WRITE_HOLDER);
928927
unblock_events = false;
929928
}
930929
}

block/blk-core.c

+10-7
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,8 @@ __setup("fail_make_request=", setup_fail_make_request);
496496

497497
bool should_fail_request(struct block_device *part, unsigned int bytes)
498498
{
499-
return part->bd_make_it_fail && should_fail(&fail_make_request, bytes);
499+
return bdev_test_flag(part, BD_MAKE_IT_FAIL) &&
500+
should_fail(&fail_make_request, bytes);
500501
}
501502

502503
static int __init fail_make_request_debugfs(void)
@@ -516,10 +517,11 @@ static inline void bio_check_ro(struct bio *bio)
516517
if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
517518
return;
518519

519-
if (bio->bi_bdev->bd_ro_warned)
520+
if (bdev_test_flag(bio->bi_bdev, BD_RO_WARNED))
520521
return;
521522

522-
bio->bi_bdev->bd_ro_warned = true;
523+
bdev_set_flag(bio->bi_bdev, BD_RO_WARNED);
524+
523525
/*
524526
* Use ioctl to set underlying disk of raid/dm to read-only
525527
* will trigger this.
@@ -616,7 +618,7 @@ static void __submit_bio(struct bio *bio)
616618
if (unlikely(!blk_crypto_bio_prep(&bio)))
617619
return;
618620

619-
if (!bio->bi_bdev->bd_has_submit_bio) {
621+
if (!bdev_test_flag(bio->bi_bdev, BD_HAS_SUBMIT_BIO)) {
620622
blk_mq_submit_bio(bio);
621623
} else if (likely(bio_queue_enter(bio) == 0)) {
622624
struct gendisk *disk = bio->bi_bdev->bd_disk;
@@ -730,7 +732,7 @@ void submit_bio_noacct_nocheck(struct bio *bio)
730732
*/
731733
if (current->bio_list)
732734
bio_list_add(&current->bio_list[0], bio);
733-
else if (!bio->bi_bdev->bd_has_submit_bio)
735+
else if (!bdev_test_flag(bio->bi_bdev, BD_HAS_SUBMIT_BIO))
734736
__submit_bio_noacct_mq(bio);
735737
else
736738
__submit_bio_noacct(bio);
@@ -766,7 +768,8 @@ void submit_bio_noacct(struct bio *bio)
766768
if (!bio_flagged(bio, BIO_REMAPPED)) {
767769
if (unlikely(bio_check_eod(bio)))
768770
goto end_io;
769-
if (bdev->bd_partno && unlikely(blk_partition_remap(bio)))
771+
if (bdev_is_partition(bdev) &&
772+
unlikely(blk_partition_remap(bio)))
770773
goto end_io;
771774
}
772775

@@ -991,7 +994,7 @@ void update_io_ticks(struct block_device *part, unsigned long now, bool end)
991994
(end || part_in_flight(part)))
992995
__part_stat_add(part, io_ticks, now - stamp);
993996

994-
if (part->bd_partno) {
997+
if (bdev_is_partition(part)) {
995998
part = bdev_whole(part);
996999
goto again;
9971000
}

block/blk-mq.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static bool blk_mq_check_inflight(struct request *rq, void *priv)
9393
struct mq_inflight *mi = priv;
9494

9595
if (rq->part && blk_do_io_stat(rq) &&
96-
(!mi->part->bd_partno || rq->part == mi->part) &&
96+
(!bdev_is_partition(mi->part) || rq->part == mi->part) &&
9797
blk_mq_rq_state(rq) == MQ_RQ_IN_FLIGHT)
9898
mi->inflight[rq_data_dir(rq)]++;
9999

block/blk-zoned.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,7 @@ void blk_zone_write_plug_bio_endio(struct bio *bio)
12571257
* is not called. So we need to schedule execution of the next
12581258
* plugged BIO here.
12591259
*/
1260-
if (bio->bi_bdev->bd_has_submit_bio)
1260+
if (bdev_test_flag(bio->bi_bdev, BD_HAS_SUBMIT_BIO))
12611261
disk_zone_wplug_unplug_bio(disk, zwplug);
12621262

12631263
/* Drop the reference we took when entering this function. */
@@ -1326,7 +1326,7 @@ static void blk_zone_wplug_bio_work(struct work_struct *work)
13261326
* path for BIO-based devices will not do that. So drop this extra
13271327
* reference here.
13281328
*/
1329-
if (bdev->bd_has_submit_bio)
1329+
if (bdev_test_flag(bdev, BD_HAS_SUBMIT_BIO))
13301330
blk_queue_exit(bdev->bd_disk->queue);
13311331

13321332
put_zwplug:

block/early-lookup.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static int __init devt_from_partuuid(const char *uuid_str, dev_t *devt)
7878
* to the partition number found by UUID.
7979
*/
8080
*devt = part_devt(dev_to_disk(dev),
81-
dev_to_bdev(dev)->bd_partno + offset);
81+
bdev_partno(dev_to_bdev(dev)) + offset);
8282
} else {
8383
*devt = dev->devt;
8484
}

block/genhd.c

+10-5
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
411411
elevator_init_mq(disk->queue);
412412

413413
/* Mark bdev as having a submit_bio, if needed */
414-
disk->part0->bd_has_submit_bio = disk->fops->submit_bio != NULL;
414+
if (disk->fops->submit_bio)
415+
bdev_set_flag(disk->part0, BD_HAS_SUBMIT_BIO);
415416

416417
/*
417418
* If the driver provides an explicit major number it also must provide
@@ -1064,7 +1065,8 @@ static DEVICE_ATTR(partscan, 0444, partscan_show, NULL);
10641065
ssize_t part_fail_show(struct device *dev,
10651066
struct device_attribute *attr, char *buf)
10661067
{
1067-
return sprintf(buf, "%d\n", dev_to_bdev(dev)->bd_make_it_fail);
1068+
return sprintf(buf, "%d\n",
1069+
bdev_test_flag(dev_to_bdev(dev), BD_MAKE_IT_FAIL));
10681070
}
10691071

10701072
ssize_t part_fail_store(struct device *dev,
@@ -1073,9 +1075,12 @@ ssize_t part_fail_store(struct device *dev,
10731075
{
10741076
int i;
10751077

1076-
if (count > 0 && sscanf(buf, "%d", &i) > 0)
1077-
dev_to_bdev(dev)->bd_make_it_fail = i;
1078-
1078+
if (count > 0 && sscanf(buf, "%d", &i) > 0) {
1079+
if (i)
1080+
bdev_set_flag(dev_to_bdev(dev), BD_MAKE_IT_FAIL);
1081+
else
1082+
bdev_clear_flag(dev_to_bdev(dev), BD_MAKE_IT_FAIL);
1083+
}
10791084
return count;
10801085
}
10811086

block/ioctl.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,10 @@ static int blkdev_roset(struct block_device *bdev, unsigned cmd,
431431
if (ret)
432432
return ret;
433433
}
434-
bdev->bd_read_only = n;
434+
if (n)
435+
bdev_set_flag(bdev, BD_READ_ONLY);
436+
else
437+
bdev_clear_flag(bdev, BD_READ_ONLY);
435438
return 0;
436439
}
437440

block/partitions/core.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ static struct parsed_partitions *check_partition(struct gendisk *hd)
173173
static ssize_t part_partition_show(struct device *dev,
174174
struct device_attribute *attr, char *buf)
175175
{
176-
return sprintf(buf, "%d\n", dev_to_bdev(dev)->bd_partno);
176+
return sprintf(buf, "%d\n", bdev_partno(dev_to_bdev(dev)));
177177
}
178178

179179
static ssize_t part_start_show(struct device *dev,
@@ -250,7 +250,7 @@ static int part_uevent(const struct device *dev, struct kobj_uevent_env *env)
250250
{
251251
const struct block_device *part = dev_to_bdev(dev);
252252

253-
add_uevent_var(env, "PARTN=%u", part->bd_partno);
253+
add_uevent_var(env, "PARTN=%u", bdev_partno(part));
254254
if (part->bd_meta_info && part->bd_meta_info->volname[0])
255255
add_uevent_var(env, "PARTNAME=%s", part->bd_meta_info->volname);
256256
return 0;
@@ -267,7 +267,7 @@ void drop_partition(struct block_device *part)
267267
{
268268
lockdep_assert_held(&part->bd_disk->open_mutex);
269269

270-
xa_erase(&part->bd_disk->part_tbl, part->bd_partno);
270+
xa_erase(&part->bd_disk->part_tbl, bdev_partno(part));
271271
kobject_put(part->bd_holder_dir);
272272

273273
device_del(&part->bd_device);
@@ -338,8 +338,8 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
338338
pdev->parent = ddev;
339339

340340
/* in consecutive minor range? */
341-
if (bdev->bd_partno < disk->minors) {
342-
devt = MKDEV(disk->major, disk->first_minor + bdev->bd_partno);
341+
if (bdev_partno(bdev) < disk->minors) {
342+
devt = MKDEV(disk->major, disk->first_minor + bdev_partno(bdev));
343343
} else {
344344
err = blk_alloc_ext_minor();
345345
if (err < 0)
@@ -404,7 +404,7 @@ static bool partition_overlaps(struct gendisk *disk, sector_t start,
404404

405405
rcu_read_lock();
406406
xa_for_each_start(&disk->part_tbl, idx, part, 1) {
407-
if (part->bd_partno != skip_partno &&
407+
if (bdev_partno(part) != skip_partno &&
408408
start < part->bd_start_sect + bdev_nr_sectors(part) &&
409409
start + length > part->bd_start_sect) {
410410
overlap = true;

include/linux/blk_types.h

+9-8
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,15 @@ struct block_device {
4545
struct request_queue * bd_queue;
4646
struct disk_stats __percpu *bd_stats;
4747
unsigned long bd_stamp;
48-
bool bd_read_only; /* read-only policy */
49-
u8 bd_partno;
50-
bool bd_write_holder;
51-
bool bd_has_submit_bio;
48+
atomic_t __bd_flags; // partition number + flags
49+
#define BD_PARTNO 255 // lower 8 bits; assign-once
50+
#define BD_READ_ONLY (1u<<8) // read-only policy
51+
#define BD_WRITE_HOLDER (1u<<9)
52+
#define BD_HAS_SUBMIT_BIO (1u<<10)
53+
#define BD_RO_WARNED (1u<<11)
54+
#ifdef CONFIG_FAIL_MAKE_REQUEST
55+
#define BD_MAKE_IT_FAIL (1u<<12)
56+
#endif
5257
dev_t bd_dev;
5358
struct address_space *bd_mapping; /* page cache */
5459

@@ -65,10 +70,6 @@ struct block_device {
6570
struct mutex bd_fsfreeze_mutex; /* serialize freeze/thaw */
6671

6772
struct partition_meta_info *bd_meta_info;
68-
#ifdef CONFIG_FAIL_MAKE_REQUEST
69-
bool bd_make_it_fail;
70-
#endif
71-
bool bd_ro_warned;
7273
int bd_writers;
7374
/*
7475
* keep this out-of-line as it's both big and not needed in the fast

include/linux/blkdev.h

+23-3
Original file line numberDiff line numberDiff line change
@@ -718,15 +718,35 @@ void invalidate_disk(struct gendisk *disk);
718718
void set_disk_ro(struct gendisk *disk, bool read_only);
719719
void disk_uevent(struct gendisk *disk, enum kobject_action action);
720720

721+
static inline u8 bdev_partno(const struct block_device *bdev)
722+
{
723+
return atomic_read(&bdev->__bd_flags) & BD_PARTNO;
724+
}
725+
726+
static inline bool bdev_test_flag(const struct block_device *bdev, unsigned flag)
727+
{
728+
return atomic_read(&bdev->__bd_flags) & flag;
729+
}
730+
731+
static inline void bdev_set_flag(struct block_device *bdev, unsigned flag)
732+
{
733+
atomic_or(flag, &bdev->__bd_flags);
734+
}
735+
736+
static inline void bdev_clear_flag(struct block_device *bdev, unsigned flag)
737+
{
738+
atomic_andnot(flag, &bdev->__bd_flags);
739+
}
740+
721741
static inline int get_disk_ro(struct gendisk *disk)
722742
{
723-
return disk->part0->bd_read_only ||
743+
return bdev_test_flag(disk->part0, BD_READ_ONLY) ||
724744
test_bit(GD_READ_ONLY, &disk->state);
725745
}
726746

727747
static inline int bdev_read_only(struct block_device *bdev)
728748
{
729-
return bdev->bd_read_only || get_disk_ro(bdev->bd_disk);
749+
return bdev_test_flag(bdev, BD_READ_ONLY) || get_disk_ro(bdev->bd_disk);
730750
}
731751

732752
bool set_capacity_and_notify(struct gendisk *disk, sector_t size);
@@ -1086,7 +1106,7 @@ static inline int sb_issue_zeroout(struct super_block *sb, sector_t block,
10861106

10871107
static inline bool bdev_is_partition(struct block_device *bdev)
10881108
{
1089-
return bdev->bd_partno;
1109+
return bdev_partno(bdev) != 0;
10901110
}
10911111

10921112
enum blk_default_limits {

include/linux/part_stat.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static inline void part_stat_set_all(struct block_device *part, int value)
5959

6060
#define part_stat_add(part, field, addnd) do { \
6161
__part_stat_add((part), field, addnd); \
62-
if ((part)->bd_partno) \
62+
if (bdev_is_partition(part)) \
6363
__part_stat_add(bdev_whole(part), field, addnd); \
6464
} while (0)
6565

lib/vsprintf.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -966,13 +966,13 @@ char *bdev_name(char *buf, char *end, struct block_device *bdev,
966966

967967
hd = bdev->bd_disk;
968968
buf = string(buf, end, hd->disk_name, spec);
969-
if (bdev->bd_partno) {
969+
if (bdev_is_partition(bdev)) {
970970
if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) {
971971
if (buf < end)
972972
*buf = 'p';
973973
buf++;
974974
}
975-
buf = number(buf, end, bdev->bd_partno, spec);
975+
buf = number(buf, end, bdev_partno(bdev), spec);
976976
}
977977
return buf;
978978
}

0 commit comments

Comments
 (0)