static inline bool bio_check_ro(struct bio *bio, struct block_device *part)
 {
-       const int op = bio_op(bio);
-
-       if (part->bd_read_only && op_is_write(op)) {
+       if (op_is_write(bio_op(bio)) && bdev_read_only(part)) {
                char b[BDEVNAME_SIZE];
 
                if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
 
        kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
 }
 
-void set_disk_ro(struct gendisk *disk, int flag)
+/**
+ * set_disk_ro - set a gendisk read-only
+ * @disk:      gendisk to operate on
+ * @ready_only:        %true to set the disk read-only, %false set the disk read/write
+ *
+ * This function is used to indicate whether a given disk device should have its
+ * read-only flag set. set_disk_ro() is typically used by device drivers to
+ * indicate whether the underlying physical device is write-protected.
+ */
+void set_disk_ro(struct gendisk *disk, bool read_only)
 {
-       struct disk_part_iter piter;
-       struct block_device *part;
-
-       if (disk->part0->bd_read_only != flag) {
-               set_disk_ro_uevent(disk, flag);
-               disk->part0->bd_read_only = flag;
+       if (read_only) {
+               if (test_and_set_bit(GD_READ_ONLY, &disk->state))
+                       return;
+       } else {
+               if (!test_and_clear_bit(GD_READ_ONLY, &disk->state))
+                       return;
        }
-
-       disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
-       while ((part = disk_part_iter_next(&piter)))
-               part->bd_read_only = flag;
-       disk_part_iter_exit(&piter);
+       set_disk_ro_uevent(disk, read_only);
 }
-
 EXPORT_SYMBOL(set_disk_ro);
 
 int bdev_read_only(struct block_device *bdev)
 {
-       return bdev->bd_read_only;
+       return bdev->bd_read_only ||
+               test_bit(GD_READ_ONLY, &bdev->bd_disk->state);
 }
 EXPORT_SYMBOL(bdev_read_only);
 
 
 static ssize_t part_ro_show(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
-       return sprintf(buf, "%d\n", dev_to_bdev(dev)->bd_read_only);
+       return sprintf(buf, "%d\n", bdev_read_only(dev_to_bdev(dev)));
 }
 
 static ssize_t part_alignment_offset_show(struct device *dev,
 
        bdev->bd_start_sect = start;
        bdev_set_nr_sectors(bdev, len);
-       bdev->bd_read_only = get_disk_ro(disk);
 
        if (info) {
                err = -ENOMEM;
 
        int flags;
        unsigned long state;
 #define GD_NEED_PART_SCAN              0
+#define GD_READ_ONLY                   1
        struct kobject *slave_dir;
 
        struct timer_rand_state *random;
 extern void del_gendisk(struct gendisk *gp);
 extern struct block_device *bdget_disk(struct gendisk *disk, int partno);
 
-extern void set_disk_ro(struct gendisk *disk, int flag);
+void set_disk_ro(struct gendisk *disk, bool read_only);
 
 static inline int get_disk_ro(struct gendisk *disk)
 {
-       return disk->part0->bd_read_only;
+       return disk->part0->bd_read_only ||
+               test_bit(GD_READ_ONLY, &disk->state);
 }
 
 extern void disk_block_events(struct gendisk *disk);