From 8d934ee7b856cda57c43676964c5e0d6ae2840ca Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 22 Aug 2020 15:22:11 +0200 Subject: [PATCH] Testing use of experimental ioctl CDROM_REVALIDATE after media state changes --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 5 ++- libburn/sg-linux.c | 62 ++++++++++++++++++++++++++++++++++++- libburn/transport.h | 6 +++- libburn/write.c | 4 +++ 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index fe8bcfc..f5c8340 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2020.04.15.185125" +#define Cdrskin_timestamP "2020.08.22.132046" diff --git a/libburn/drive.c b/libburn/drive.c index bbb709d..1300a7f 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2017 Thomas Schmitt + Copyright (c) 2006 - 2020 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -556,6 +556,7 @@ struct burn_drive *burn_drive_register(struct burn_drive *d) d->thread_pid = 0; d->thread_pid_valid = 0; memset(&(d->thread_tid), 0, sizeof(d->thread_tid)); + d->medium_state_changed = 0; d->toc_entries = 0; d->toc_entry = NULL; d->disc = NULL; @@ -883,6 +884,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast) d->progress.sector = 0; #endif /* Libburn_reset_progress_asynC */ + d->medium_state_changed = 1; d->erase(d, fast); d->busy = BURN_DRIVE_ERASING; @@ -972,6 +974,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag) stages = 1 + ((flag & 1) && size > 1024 * 1024); d->cancel = 0; d->busy = BURN_DRIVE_FORMATTING; + d->medium_state_changed = 1; ret = d->format_unit(d, size, flag & 0xfff6); /* forward bits */ if (ret <= 0) diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index c74e999..b3d5cea 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2019 Thomas Schmitt + Copyright (c) 2006 - 2020 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -820,6 +820,63 @@ static int sg_release_siblings(int sibling_fds[], } +/* ts C00806 */ +/** Urges the operating system to re-assess drive and medium state +*/ +static int sg_os_revalidate_disc(struct burn_drive *d) +{ + +/* <<< only for compiler tests */ +/* # def ine BURN_CDROM_REVALIDATE 0x5332 */ + +/* >>> if ioctl CDROM_REVALIDATE is accepted in the kernel: + #i fdef CDROM_REVALIDATE + #d efine BURN_CDROM_REVALIDATE CDROM_REVALIDATE + #e ndif +*/ + +#ifdef BURN_CDROM_REVALIDATE + + int i, ioctl_ret, reval_n_wait= 3, ret, os_errno; + char *msg = NULL; + + BURN_ALLOC_MEM(msg, char, 161); + + for(i = 0; i < reval_n_wait; i++) { + os_errno = 0; + ioctl_ret = ioctl(d->fd, BURN_CDROM_REVALIDATE, 0); + if(ioctl_ret == 0) + break; + os_errno = errno; + if(errno != EBUSY) + break; + if(i < reval_n_wait - 1) + usleep(2000000); + } + if(ioctl_ret == 0) { + sprintf(msg, + "ioctl(CDROM_REVALIDATE) succeeded in try #%d", i); + ret = 1; + } else { + sprintf(msg, "ioctl(CDROM_REVALIDATE) failed"); + ret = 0; + } + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + msg, os_errno, 0); +ex: + BURN_FREE_MEM(msg); + return ret; + +#else + + return 0; + +#endif /* CDROM_REVALIDATE */ + +} + + /* ts A60926 */ static int sg_close_drive(struct burn_drive *d) { @@ -829,6 +886,9 @@ static int sg_close_drive(struct burn_drive *d) return 0; sg_release_siblings(d->sibling_fds, d->sibling_fnames, &(d->sibling_count)); + if(d->medium_state_changed > 0) + sg_os_revalidate_disc(d); + d->medium_state_changed = -1; ret = sg_close_drive_fd(d->devname, d->global_index, &(d->fd), 0); return ret; } diff --git a/libburn/transport.h b/libburn/transport.h index b77001d..86ec7d9 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2016 Thomas Schmitt + Copyright (c) 2006 - 2020 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -438,6 +438,10 @@ struct burn_drive /* ts B90513 */ unsigned int write_retry_count; + /* ts C00806 */ + /* 0=no change, 1=change, -1=already urged OS to revalidate medium */ + int medium_state_changed; + /* transport functions */ int (*grab) (struct burn_drive *); int (*release) (struct burn_drive *); diff --git a/libburn/write.c b/libburn/write.c index c4ac5a9..d011813 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -1904,6 +1904,9 @@ int burn_dvd_write_track(struct burn_write_opts *o, /* ts A70213 : eventually expand size of track to max */ burn_track_apply_fillup(t, d->media_capacity_remaining, 0); + /* ts C00806 : Consider the track state changed by try to open */ + d->medium_state_changed = 1; + if (d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15) { /* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */ @@ -3074,6 +3077,7 @@ return crap. so we send the command, then ignore the result. /* goto fail_wo_sync; */ #endif /* Libburn_write_with_function_print_cuE */ + d->medium_state_changed = 1; ret = 1; if (o->write_type == BURN_WRITE_SAO) ret = d->send_cue_sheet(d, sheet);