@@ -585,6 +585,11 @@ static void register_disk(struct device *parent, struct gendisk *disk)
585585 */
586586 pm_runtime_set_memalloc_noio (ddev , true);
587587
588+ if (disk -> flags & GENHD_FL_HIDDEN ) {
589+ dev_set_uevent_suppress (ddev , 0 );
590+ return ;
591+ }
592+
588593 disk -> part0 .holder_dir = kobject_create_and_add ("holders" , & ddev -> kobj );
589594 disk -> slave_dir = kobject_create_and_add ("slaves" , & ddev -> kobj );
590595
@@ -616,6 +621,11 @@ static void register_disk(struct device *parent, struct gendisk *disk)
616621 while ((part = disk_part_iter_next (& piter )))
617622 kobject_uevent (& part_to_dev (part )-> kobj , KOBJ_ADD );
618623 disk_part_iter_exit (& piter );
624+
625+ err = sysfs_create_link (& ddev -> kobj ,
626+ & disk -> queue -> backing_dev_info -> dev -> kobj ,
627+ "bdi" );
628+ WARN_ON (err );
619629}
620630
621631/**
@@ -630,7 +640,6 @@ static void register_disk(struct device *parent, struct gendisk *disk)
630640 */
631641void device_add_disk (struct device * parent , struct gendisk * disk )
632642{
633- struct backing_dev_info * bdi ;
634643 dev_t devt ;
635644 int retval ;
636645
@@ -639,7 +648,8 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
639648 * parameters make sense.
640649 */
641650 WARN_ON (disk -> minors && !(disk -> major || disk -> first_minor ));
642- WARN_ON (!disk -> minors && !(disk -> flags & GENHD_FL_EXT_DEVT ));
651+ WARN_ON (!disk -> minors &&
652+ !(disk -> flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN )));
643653
644654 disk -> flags |= GENHD_FL_UP ;
645655
@@ -648,18 +658,26 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
648658 WARN_ON (1 );
649659 return ;
650660 }
651- disk_to_dev (disk )-> devt = devt ;
652661 disk -> major = MAJOR (devt );
653662 disk -> first_minor = MINOR (devt );
654663
655664 disk_alloc_events (disk );
656665
657- /* Register BDI before referencing it from bdev */
658- bdi = disk -> queue -> backing_dev_info ;
659- bdi_register_owner (bdi , disk_to_dev (disk ));
660-
661- blk_register_region (disk_devt (disk ), disk -> minors , NULL ,
662- exact_match , exact_lock , disk );
666+ if (disk -> flags & GENHD_FL_HIDDEN ) {
667+ /*
668+ * Don't let hidden disks show up in /proc/partitions,
669+ * and don't bother scanning for partitions either.
670+ */
671+ disk -> flags |= GENHD_FL_SUPPRESS_PARTITION_INFO ;
672+ disk -> flags |= GENHD_FL_NO_PART_SCAN ;
673+ } else {
674+ /* Register BDI before referencing it from bdev */
675+ disk_to_dev (disk )-> devt = devt ;
676+ bdi_register_owner (disk -> queue -> backing_dev_info ,
677+ disk_to_dev (disk ));
678+ blk_register_region (disk_devt (disk ), disk -> minors , NULL ,
679+ exact_match , exact_lock , disk );
680+ }
663681 register_disk (parent , disk );
664682 blk_register_queue (disk );
665683
@@ -669,10 +687,6 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
669687 */
670688 WARN_ON_ONCE (!blk_get_queue (disk -> queue ));
671689
672- retval = sysfs_create_link (& disk_to_dev (disk )-> kobj , & bdi -> dev -> kobj ,
673- "bdi" );
674- WARN_ON (retval );
675-
676690 disk_add_events (disk );
677691 blk_integrity_add (disk );
678692}
@@ -701,7 +715,8 @@ void del_gendisk(struct gendisk *disk)
701715 set_capacity (disk , 0 );
702716 disk -> flags &= ~GENHD_FL_UP ;
703717
704- sysfs_remove_link (& disk_to_dev (disk )-> kobj , "bdi" );
718+ if (!(disk -> flags & GENHD_FL_HIDDEN ))
719+ sysfs_remove_link (& disk_to_dev (disk )-> kobj , "bdi" );
705720 if (disk -> queue ) {
706721 /*
707722 * Unregister bdi before releasing device numbers (as they can
@@ -712,13 +727,15 @@ void del_gendisk(struct gendisk *disk)
712727 } else {
713728 WARN_ON (1 );
714729 }
715- blk_unregister_region (disk_devt (disk ), disk -> minors );
730+
731+ if (!(disk -> flags & GENHD_FL_HIDDEN )) {
732+ blk_unregister_region (disk_devt (disk ), disk -> minors );
733+ kobject_put (disk -> part0 .holder_dir );
734+ kobject_put (disk -> slave_dir );
735+ }
716736
717737 part_stat_set_all (& disk -> part0 , 0 );
718738 disk -> part0 .stamp = 0 ;
719-
720- kobject_put (disk -> part0 .holder_dir );
721- kobject_put (disk -> slave_dir );
722739 if (!sysfs_deprecated )
723740 sysfs_remove_link (block_depr , dev_name (disk_to_dev (disk )));
724741 pm_runtime_set_memalloc_noio (disk_to_dev (disk ), false);
@@ -781,6 +798,10 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
781798 spin_unlock_bh (& ext_devt_lock );
782799 }
783800
801+ if (unlikely (disk -> flags & GENHD_FL_HIDDEN )) {
802+ put_disk (disk );
803+ disk = NULL ;
804+ }
784805 return disk ;
785806}
786807EXPORT_SYMBOL (get_gendisk );
@@ -1024,6 +1045,15 @@ static ssize_t disk_removable_show(struct device *dev,
10241045 (disk -> flags & GENHD_FL_REMOVABLE ? 1 : 0 ));
10251046}
10261047
1048+ static ssize_t disk_hidden_show (struct device * dev ,
1049+ struct device_attribute * attr , char * buf )
1050+ {
1051+ struct gendisk * disk = dev_to_disk (dev );
1052+
1053+ return sprintf (buf , "%d\n" ,
1054+ (disk -> flags & GENHD_FL_HIDDEN ? 1 : 0 ));
1055+ }
1056+
10271057static ssize_t disk_ro_show (struct device * dev ,
10281058 struct device_attribute * attr , char * buf )
10291059{
@@ -1061,6 +1091,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
10611091static DEVICE_ATTR (range , S_IRUGO , disk_range_show , NULL) ;
10621092static DEVICE_ATTR (ext_range , S_IRUGO , disk_ext_range_show , NULL) ;
10631093static DEVICE_ATTR (removable , S_IRUGO , disk_removable_show , NULL) ;
1094+ static DEVICE_ATTR (hidden , S_IRUGO , disk_hidden_show , NULL) ;
10641095static DEVICE_ATTR (ro , S_IRUGO , disk_ro_show , NULL) ;
10651096static DEVICE_ATTR (size , S_IRUGO , part_size_show , NULL) ;
10661097static DEVICE_ATTR (alignment_offset , S_IRUGO , disk_alignment_offset_show , NULL) ;
@@ -1085,6 +1116,7 @@ static struct attribute *disk_attrs[] = {
10851116 & dev_attr_range .attr ,
10861117 & dev_attr_ext_range .attr ,
10871118 & dev_attr_removable .attr ,
1119+ & dev_attr_hidden .attr ,
10881120 & dev_attr_ro .attr ,
10891121 & dev_attr_size .attr ,
10901122 & dev_attr_alignment_offset .attr ,
0 commit comments