scsi: sd: Keep disk read-only when re-reading partition
[sfrench/cifs-2.6.git] / drivers / scsi / sd.c
index d175c5c5ccf87eba361aa1bad5d84b56ce64d5b0..3b45f7fc562017c8f626c46153e343a1f675cdfb 100644 (file)
@@ -231,11 +231,15 @@ manage_start_stop_store(struct device *dev, struct device_attribute *attr,
 {
        struct scsi_disk *sdkp = to_scsi_disk(dev);
        struct scsi_device *sdp = sdkp->device;
+       bool v;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       sdp->manage_start_stop = simple_strtoul(buf, NULL, 10);
+       if (kstrtobool(buf, &v))
+               return -EINVAL;
+
+       sdp->manage_start_stop = v;
 
        return count;
 }
@@ -253,6 +257,7 @@ static ssize_t
 allow_restart_store(struct device *dev, struct device_attribute *attr,
                    const char *buf, size_t count)
 {
+       bool v;
        struct scsi_disk *sdkp = to_scsi_disk(dev);
        struct scsi_device *sdp = sdkp->device;
 
@@ -262,7 +267,10 @@ allow_restart_store(struct device *dev, struct device_attribute *attr,
        if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
                return -EINVAL;
 
-       sdp->allow_restart = simple_strtoul(buf, NULL, 10);
+       if (kstrtobool(buf, &v))
+               return -EINVAL;
+
+       sdp->allow_restart = v;
 
        return count;
 }
@@ -906,6 +914,26 @@ static void sd_config_write_same(struct scsi_disk *sdkp)
        else
                sdkp->zeroing_mode = SD_ZERO_WRITE;
 
+       if (sdkp->max_ws_blocks &&
+           sdkp->physical_block_size > logical_block_size) {
+               /*
+                * Reporting a maximum number of blocks that is not aligned
+                * on the device physical size would cause a large write same
+                * request to be split into physically unaligned chunks by
+                * __blkdev_issue_write_zeroes() and __blkdev_issue_write_same()
+                * even if the caller of these functions took care to align the
+                * large request. So make sure the maximum reported is aligned
+                * to the device physical block size. This is only an optional
+                * optimization for regular disks, but this is mandatory to
+                * avoid failure of large write same requests directed at
+                * sequential write required zones of host-managed ZBC disks.
+                */
+               sdkp->max_ws_blocks =
+                       round_down(sdkp->max_ws_blocks,
+                                  bytes_to_logical(sdkp->device,
+                                                   sdkp->physical_block_size));
+       }
+
 out:
        blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
                                         (logical_block_size >> 9));
@@ -2142,7 +2170,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
                        }
                        /* Wait 1 second for next try */
                        msleep(1000);
-                       printk(".");
+                       printk(KERN_CONT ".");
 
                /*
                 * Wait for USB flash devices with slow firmware.
@@ -2172,9 +2200,9 @@ sd_spinup_disk(struct scsi_disk *sdkp)
 
        if (spintime) {
                if (scsi_status_is_good(the_result))
-                       printk("ready\n");
+                       printk(KERN_CONT "ready\n");
                else
-                       printk("not responding...\n");
+                       printk(KERN_CONT "not responding...\n");
        }
 }
 
@@ -2596,6 +2624,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
        int res;
        struct scsi_device *sdp = sdkp->device;
        struct scsi_mode_data data;
+       int disk_ro = get_disk_ro(sdkp->disk);
        int old_wp = sdkp->write_prot;
 
        set_disk_ro(sdkp->disk, 0);
@@ -2636,7 +2665,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
                          "Test WP failed, assume Write Enabled\n");
        } else {
                sdkp->write_prot = ((data.device_specific & 0x80) != 0);
-               set_disk_ro(sdkp->disk, sdkp->write_prot);
+               set_disk_ro(sdkp->disk, sdkp->write_prot || disk_ro);
                if (sdkp->first_scan || old_wp != sdkp->write_prot) {
                        sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n",
                                  sdkp->write_prot ? "on" : "off");