diff options
Diffstat (limited to 'main/util-linux/libblkid-reduce-probing-area-for-crazy-CDROMs.patch')
-rw-r--r-- | main/util-linux/libblkid-reduce-probing-area-for-crazy-CDROMs.patch | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/main/util-linux/libblkid-reduce-probing-area-for-crazy-CDROMs.patch b/main/util-linux/libblkid-reduce-probing-area-for-crazy-CDROMs.patch new file mode 100644 index 0000000000..66d50082c0 --- /dev/null +++ b/main/util-linux/libblkid-reduce-probing-area-for-crazy-CDROMs.patch @@ -0,0 +1,85 @@ +From bfebe74e3babe8c188a51269acc2673f1aea283f Mon Sep 17 00:00:00 2001 +From: Karel Zak <kzak@redhat.com> +Date: Tue, 19 Apr 2016 12:39:05 +0200 +Subject: [PATCH] libblkid: reduce probing area for crazy CDROMs + +Linux kernel reports devices greater than area readable by read(2). +The readable area is usually 2-3 CD blocks smaller (CD block is +2048-bytes) than size returned by BLKGETSIZE. This patch checks for +this issues to avoid I/O errors in probing functions. + +Reported-by: Thomas Schmitt <scdbackup@gmx.net> +Signed-off-by: Karel Zak <kzak@redhat.com> +--- + libblkid/src/probe.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 49 insertions(+), 1 deletion(-) + +diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c +index 0c8625c..0455c37 100644 +--- a/libblkid/src/probe.c ++++ b/libblkid/src/probe.c +@@ -752,6 +752,51 @@ int blkid_probe_is_cdrom(blkid_probe pr) + return pr && (pr->flags & BLKID_FL_CDROM_DEV); + } + ++static int is_sector_readable(int fd, uint64_t sector) ++{ ++ char buf[512]; ++ ssize_t sz; ++ ++ if (blkid_llseek(fd, sector * 512, SEEK_SET) < 0) ++ goto failed; ++ ++ sz = read(fd, buf, sizeof(buf)); ++ if (sz != (ssize_t) sizeof(buf)) ++ goto failed; ++ ++ return 1; ++failed: ++ DBG(LOWPROBE, ul_debug("CDROM: read sector %ju failed %m", sector)); ++ errno = 0; ++ return 0; ++} ++ ++/* ++ * Linux kernel reports (BLKGETSIZE) cdrom device size greater than area ++ * readable by read(2). We have to reduce the probing area to avoid unwanted ++ * I/O errors in probing functions. It seems that unreadable are always last 2 ++ * or 3 CD blocks (CD block size is 2048 bytes, it means 12 in 512-byte ++ * sectors). ++ */ ++static void cdrom_size_correction(blkid_probe pr) ++{ ++ uint64_t n, nsectors = pr->size >> 9; ++ ++ for (n = nsectors - 12; n < nsectors; n++) { ++ if (!is_sector_readable(pr->fd, n)) ++ goto failed; ++ } ++ ++ DBG(LOWPROBE, ul_debug("CDROM: full size available")); ++ return; ++failed: ++ /* 'n' is the failed sector, reduce device size to n-1; */ ++ DBG(LOWPROBE, ul_debug("CDROM: reduce size from %ju to %ju.", ++ (uintmax_t) pr->size, ++ (uintmax_t) (n - 1) << 9)); ++ pr->size = n << 9; ++} ++ + /** + * blkid_probe_set_device: + * @pr: probe +@@ -844,8 +889,11 @@ int blkid_probe_set_device(blkid_probe pr, int fd, + else if (S_ISBLK(sb.st_mode) && + !blkid_probe_is_tiny(pr) && + blkid_probe_is_wholedisk(pr) && +- ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) ++ ioctl(fd, CDROM_GET_CAPABILITY, NULL) >= 0) { ++ + pr->flags |= BLKID_FL_CDROM_DEV; ++ cdrom_size_correction(pr); ++ } + #endif + + DBG(LOWPROBE, ul_debug("ready for low-probing, offset=%"PRIu64", size=%"PRIu64"", |