From: Pali Rohár Date: Thu, 5 Nov 2020 18:16:27 +0000 (+0100) Subject: libblkid: detect CD/DVD discs in packet writing mode X-Git-Tag: v2.37-rc1~266^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b88a410ae0473d622454680fdf8166c8e174f8d;p=thirdparty%2Futil-linux.git libblkid: detect CD/DVD discs in packet writing mode Packet writing mode for CD and DVD discs is provided by kernel module pktcdvd.ko which exports block devices /dev/pktcdvd/pktcdvd*. These block devices do not accept CDROM_DRIVE_STATUS ioctl, therefore current blkid code does not detect them as BLKID_FL_CDROM_DEV and also does not do necessary size correction. Extend detection of CD/DVD discs by additional CDROM_LAST_WRITTEN ioctl which is accepted also by pktcdvd.ko. Signed-off-by: Pali Rohár --- diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 093fad1b64..ab88efc724 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -864,6 +864,9 @@ int blkid_probe_set_device(blkid_probe pr, int fd, struct stat sb; uint64_t devsiz = 0; char *dm_uuid = NULL; +#ifdef CDROM_GET_CAPABILITY + long last_written = 0; +#endif blkid_reset_probe(pr); blkid_probe_reset_buffers(pr); @@ -945,19 +948,38 @@ int blkid_probe_set_device(blkid_probe pr, int fd, else if (S_ISBLK(sb.st_mode) && !blkid_probe_is_tiny(pr) && !dm_uuid && - blkid_probe_is_wholedisk(pr) && - ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) { + blkid_probe_is_wholedisk(pr)) { + + /** + * pktcdvd.ko accepts only these ioctls: + * CDROMEJECT CDROMMULTISESSION CDROMREADTOCENTRY + * CDROM_LAST_WRITTEN CDROM_SEND_PACKET SCSI_IOCTL_SEND_COMMAND + * So CDROM_GET_CAPABILITY cannot be used for detecting pktcdvd + * devices. But CDROM_GET_CAPABILITY and CDROM_DRIVE_STATUS are + * fast so use them for detecting if medium is present. In any + * case use last written block form CDROM_LAST_WRITTEN. + */ + if (ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) { # ifdef CDROM_DRIVE_STATUS - switch (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) { - case CDS_TRAY_OPEN: - case CDS_NO_DISC: - errno = ENOMEDIUM; - goto err; + switch (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) { + case CDS_TRAY_OPEN: + case CDS_NO_DISC: + errno = ENOMEDIUM; + goto err; + } +# endif + pr->flags |= BLKID_FL_CDROM_DEV; } + +# ifdef CDROM_LAST_WRITTEN + if (ioctl(fd, CDROM_LAST_WRITTEN, &last_written) == 0) + pr->flags |= BLKID_FL_CDROM_DEV; # endif - pr->flags |= BLKID_FL_CDROM_DEV; - cdrom_size_correction(pr); + + if (pr->flags & BLKID_FL_CDROM_DEV) { + cdrom_size_correction(pr); + } } #endif free(dm_uuid);