Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140008574
D13360.id36182.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D13360.id36182.diff
View Options
Index: sys/cam/cam_ccb.h
===================================================================
--- sys/cam/cam_ccb.h
+++ sys/cam/cam_ccb.h
@@ -1268,6 +1268,7 @@
#define CDAI_TYPE_EXT_INQ 5
#define CDAI_TYPE_NVME_CNTRL 6 /* NVMe Identify Controller data */
#define CDAI_TYPE_NVME_NS 7 /* NVMe Identify Namespace data */
+#define CDAI_TYPE_MODE_DEV_SPEC 8 /* Device specific byte of mode header */
off_t bufsiz; /* IN: Size of external buffer */
#define CAM_SCSI_DEVID_MAXLEN 65536 /* length in buffer is an uint16_t */
off_t provsiz; /* OUT: Size required/used */
Index: sys/cam/cam_xpt_internal.h
===================================================================
--- sys/cam/cam_xpt_internal.h
+++ sys/cam/cam_xpt_internal.h
@@ -133,6 +133,7 @@
* queuing for a device.
*/
u_int8_t queue_flags; /* Queue flags from the control page */
+ u_int8_t dev_spec; /* Device specific byte of mode header */
u_int8_t serial_num_len;
u_int8_t *serial_num;
u_int32_t flags;
Index: sys/cam/scsi/scsi_da.c
===================================================================
--- sys/cam/scsi/scsi_da.c
+++ sys/cam/scsi/scsi_da.c
@@ -5596,6 +5596,34 @@
softc->disk->d_devstat->block_size = softc->params.secsize;
softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
+ /* Refresh the write protect status as well. */
+ {
+ struct ccb_dev_advinfo cdai;
+ uint8_t dev_spec;
+
+ xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+ cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
+ cdai.buftype = CDAI_TYPE_MODE_DEV_SPEC;
+ cdai.flags = 0;
+ cdai.bufsiz = 1;
+ cdai.buf = &dev_spec;
+ xpt_action((union ccb *)&cdai);
+ if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
+ cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
+ if (cdai.ccb_h.status != CAM_REQ_CMP) {
+ xpt_print(periph->path, "%s: failed to get dev_spec\n",
+ __func__);
+ /* Use cam_error_print() to decode the status */
+ cam_error_print((union ccb *)&cdai, CAM_ESF_CAM_STATUS,
+ CAM_EPF_ALL);
+ } else {
+ if ((dev_spec & 0x80) != 0)
+ softc->disk->d_flags |= DISKFLAG_WRITE_PROTECT;
+ else
+ softc->disk->d_flags &= ~DISKFLAG_WRITE_PROTECT;
+ }
+ }
+
error = disk_resize(softc->disk, M_NOWAIT);
if (error != 0)
xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error);
Index: sys/cam/scsi/scsi_xpt.c
===================================================================
--- sys/cam/scsi/scsi_xpt.c
+++ sys/cam/scsi/scsi_xpt.c
@@ -1423,6 +1423,7 @@
+ mode_hdr->blk_desc_len;
page = (struct scsi_control_page *)offset;
path->device->queue_flags = page->queue_flags;
+ path->device->dev_spec = mode_hdr->dev_spec;
} else if (cam_periph_error(done_ccb, 0,
SF_RETRY_UA|SF_NO_PRINT,
&softc->saved_ccb) == ERESTART) {
@@ -2615,6 +2616,18 @@
amt = cdai->bufsiz;
memcpy(cdai->buf, device->ext_inq, amt);
break;
+ case CDAI_TYPE_MODE_DEV_SPEC:
+ /*
+ * We fetch mode parameter header during probe.
+ * We don't allow changing it.
+ */
+ if (cdai->flags & CDAI_FLAG_STORE)
+ return;
+ cdai->provsiz = 1;
+ if (cdai->bufsiz == 0)
+ break;
+ cdai->buf[0] = device->dev_spec;
+ break;
default:
return;
}
Index: sys/geom/geom_disk.h
===================================================================
--- sys/geom/geom_disk.h
+++ sys/geom/geom_disk.h
@@ -124,13 +124,14 @@
LIST_HEAD(,disk_alias) d_aliases;
};
-#define DISKFLAG_RESERVED 0x1 /* Was NEEDSGIANT */
-#define DISKFLAG_OPEN 0x2
-#define DISKFLAG_CANDELETE 0x4
-#define DISKFLAG_CANFLUSHCACHE 0x8
-#define DISKFLAG_UNMAPPED_BIO 0x10
-#define DISKFLAG_DIRECT_COMPLETION 0x20
-#define DISKFLAG_CANZONE 0x80
+#define DISKFLAG_RESERVED 0x0001 /* Was NEEDSGIANT */
+#define DISKFLAG_OPEN 0x0002
+#define DISKFLAG_CANDELETE 0x0004
+#define DISKFLAG_CANFLUSHCACHE 0x0008
+#define DISKFLAG_UNMAPPED_BIO 0x0010
+#define DISKFLAG_DIRECT_COMPLETION 0x0020
+#define DISKFLAG_CANZONE 0x0080
+#define DISKFLAG_WRITE_PROTECT 0x0100
struct disk *disk_alloc(void);
void disk_create(struct disk *disk, int version);
Index: sys/geom/geom_disk.c
===================================================================
--- sys/geom/geom_disk.c
+++ sys/geom/geom_disk.c
@@ -120,14 +120,18 @@
e += pp->ace;
error = 0;
if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
- if (dp->d_open != NULL) {
+ /*
+ * It would be better to defer this decision to d_open if
+ * it was able to take flags.
+ */
+ if (w > 0 && (dp->d_flags & DISKFLAG_WRITE_PROTECT) != 0)
+ error = ENODEV;
+ if (error == 0 && dp->d_open != NULL)
error = dp->d_open(dp);
- if (bootverbose && error != 0)
- printf("Opened disk %s -> %d\n",
- pp->name, error);
- if (error != 0)
- return (error);
- }
+ if (bootverbose && error != 0)
+ printf("Opened disk %s -> %d\n", pp->name, error);
+ if (error != 0)
+ return (error);
pp->sectorsize = dp->d_sectorsize;
if (dp->d_maxsize == 0) {
printf("WARNING: Disk drive %s%d has no d_maxsize\n",
@@ -1041,7 +1045,8 @@
"\4CANFLUSHCACHE"
"\5UNMAPPEDBIO"
"\6DIRECTCOMPLETION"
- "\10CANZONE");
+ "\10CANZONE"
+ "\11WRITEPROTECT");
sbuf_finish(sb);
error = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 19, 11:25 PM (5 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27088996
Default Alt Text
D13360.id36182.diff (5 KB)
Attached To
Mode
D13360: geom_disk / scsi_da: deny opening write-protected disks for writing
Attached
Detach File
Event Timeline
Log In to Comment