New -check_media option async_chunks=

This commit is contained in:
2012-05-01 07:49:46 +00:00
parent f0d4714db6
commit 79628f8551
7 changed files with 510 additions and 188 deletions

View File

@ -22,6 +22,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include "xorriso.h"
@ -2106,6 +2107,312 @@ int Xorriso_check_for_abort(struct XorrisO *xorriso,
}
struct xorriso_md5_state {
/* Resources */
struct XorrisO *xorriso;
void *ctx;
struct SpotlisT *spotlist;
pthread_mutex_t spot_mutex;
/* Checksum tag cursor */
uint32_t md5_start;
uint32_t next_tag;
int chain_broken;
int in_track_gap;
int was_sb_tag;
int md5_spot_value;
uint32_t md5_spot_lba;
/* Asynchronous operation */
int slave_state; /* Operated by slave
0= not yet started
1= slave is started
2= slave has reached its end
3= slave failed to start
*/
int chunk_size;
int num_chunks;
char **chunk;
int *chunk_state; /* 0= content invalid (set by boss at creation time),
1= content readable (set by boss),
2= content was read (set by MD5 slave),
3= end-of-processing (set by boss when done)
*/
int *chunk_fill; /* Actual number of valid bytes in chunk */
uint32_t *chunk_lba;
int chunk_w_idx; /* Write index. Operated by boss */
int chunk_r_idx; /* Read index. Operated by MD5 slave */
off_t w_sleeps;
off_t r_sleeps;
};
int Xorriso__add_spot(struct xorriso_md5_state *state,
int start_lba, int blocks, int quality, int flag)
{
int ret;
if(state->chunk != NULL) {
ret= pthread_mutex_lock(&(state->spot_mutex));
if(ret != 0)
return(0);
}
ret= Spotlist_add_item(state->spotlist, start_lba, blocks, quality, 0);
if(state->chunk != NULL)
pthread_mutex_unlock(&(state->spot_mutex));
return(ret);
}
int Xorriso_chunk_md5(struct XorrisO *xorriso, char *data, int to_read,
uint32_t from_lba, struct xorriso_md5_state *state, int flag)
{
int j, ret= 0, valid, tag_type;
uint32_t lba, pos, range_start, range_size;
char md5[16], tag_md5[16], *tag_type_name= "", *comparison, *sev_text;
void *cloned_ctx= NULL;
for(j= 0; j < to_read; j++) {
lba= j + from_lba;
if(lba < state->md5_start)
continue;
ret= 0;
if(lba > state->md5_start + 16 &&
(state->next_tag == 0 || state->chain_broken || lba == state->next_tag)){
ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type,
&pos, &range_start, &range_size,
&(state->next_tag), tag_md5,
!!state->chain_broken);
}
valid= (ret == 1 || ret == (int) ISO_MD5_AREA_CORRUPTED) && pos == lba;
if(valid && tag_type == 2 && (lba < state->md5_start + 32 ||
state->in_track_gap)){
tag_type_name= "superblock";
state->was_sb_tag= 1;
if(state->in_track_gap && range_start != state->md5_start &&
range_start < lba && lba - range_start <= (uint32_t) j) {
/* Looking for next session : start computing in hindsight.
Session start and superblock tag are supposed to be in the
same 64 kB chunk.
*/
iso_md5_end(&(state->ctx), md5);
ret= iso_md5_start(&(state->ctx));
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_compute(&(state->ctx), data + (j - (lba - range_start)) * 2048,
(lba - range_start) * 2048);
state->md5_start= range_start;
state->in_track_gap= 0;
}
} else if(valid && tag_type == 4 && lba < 32) {
tag_type_name= "relocated 64kB superblock";
}else if(valid && tag_type == 3 && state->was_sb_tag) {
tag_type_name= "tree";
}else if(valid && tag_type == 1) {
/* >>> ??? allow this without superblock and tree tag ? */
tag_type_name= "session";
} else {
tag_type_name= "";
}
if (tag_type_name[0]) {
if(range_start != state->md5_start) {
sprintf(xorriso->info_text,
"Found MD5 %s tag which covers different data range", tag_type_name);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
sprintf(xorriso->info_text, " Expected: %u Found: %u",
(unsigned int) state->md5_start, range_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
state->chain_broken= 1;
valid= 0;
} else {
ret= iso_md5_clone(state->ctx, &cloned_ctx);
if(ret <= 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_end(&cloned_ctx, md5);
if(ret == (int) ISO_MD5_AREA_CORRUPTED) {
comparison= "CORRUPTED";
sev_text= "WARNING";
state->md5_spot_value= Xorriso_read_quality_md5_mismatcH;
state->chain_broken= 1;
} else if(! iso_md5_match(tag_md5, md5)) {
comparison= "NON-MATCHING";
sev_text= "WARNING";
state->md5_spot_value= Xorriso_read_quality_md5_mismatcH;
state->chain_broken= 1;
} else {
comparison= "matching";
sev_text= "UPDATE";
state->md5_spot_value= Xorriso_read_quality_md5_matcH;
}
state->md5_spot_lba= lba;
sprintf(xorriso->info_text,
"Found %s MD5 %s tag: start=%d size=%d",
comparison, tag_type_name, state->md5_start,
lba - state->md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev_text, 0);
}
if(valid && (tag_type == 1 || (tag_type == 4 && pos == lba && lba < 32))){
if(state->md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Xorriso__add_spot(state, state->md5_start,
state->md5_spot_lba - state->md5_start, state->md5_spot_value, 0);
if(ret <= 0)
goto ex;
}
state->md5_spot_value= Xorriso_read_quality_untesteD;
state->md5_start = lba + 1;
if(state->md5_start % 32)
state->md5_start= state->md5_start + (32 - (state->md5_start % 32));
state->next_tag= 0;
iso_md5_end(&(state->ctx), md5);
ret= iso_md5_start(&(state->ctx));
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
if(tag_type == 1)
state->in_track_gap= 1;
continue;
}
}
iso_md5_compute(state->ctx, data + j * 2048, 2048);
}
ret= 1;
ex:;
return(ret);
}
static void *Xorriso__md5_slave(void *state_pt)
{
struct xorriso_md5_state *state;
int ret, c_state, c_idx;
static int u_wait= 1;
state= state_pt;
state->slave_state= 1;
while(1) {
c_idx= state->chunk_r_idx;
c_state= state->chunk_state[c_idx];
if(c_state == 1) {
ret= Xorriso_chunk_md5(state->xorriso, state->chunk[c_idx],
state->chunk_fill[c_idx], state->chunk_lba[c_idx],
state, 0);
if(ret <= 0)
goto ex;
state->chunk_state[c_idx]= 2;
state->chunk_r_idx= (c_idx + 1) % state->num_chunks;
} else if(c_state == 3) {
goto ex;
} else {
/* >>> have a timeout ? */;
if(u_wait > 0)
usleep(u_wait);
state->r_sleeps++;
}
}
ex:;
state->slave_state= 2;
return NULL;
}
int Xorriso_start_chunk_md5(struct XorrisO *xorriso,
struct xorriso_md5_state *state, int flag)
{
int ret, u_wait= 1000;
pthread_attr_t attr;
pthread_attr_t *attr_pt = NULL;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
attr_pt= &attr;
ret= pthread_create(&thread, attr_pt, Xorriso__md5_slave, state);
if(ret != 0) {
sprintf(xorriso->info_text,
"-check_media: Cannot create thread for MD5 computation");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
while(state->slave_state != 1) {
/* >>> have a timeout ? */;
/* >>> if this fails set state->slave_state= 3 */
usleep(u_wait);
}
ret= 1;
ex:;
return(ret);
}
int Xorriso__wait_chunk_md5(struct xorriso_md5_state *state,
int u_wait, int flag)
{
while(state->chunk_state[state->chunk_w_idx] == 1) {
/* >>> have a timeout ? */;
usleep(u_wait);
state->w_sleeps++;
}
return(1);
}
int Xorriso__wait_slave_md5_end(struct xorriso_md5_state *state,
int u_wait, int flag)
{
while(state->slave_state == 1) {
/* >>> have a timeout ? */;
usleep(u_wait);
}
return(1);
}
int Xorriso__end_slave_md5(struct xorriso_md5_state *state,
int u_wait, int flag)
{
int i, ret;
/* Tell slave thread to end */
for(i= 0; i < state->num_chunks; i++) {
ret= Xorriso__wait_chunk_md5(state, 10000, 0);
if(ret <= 0)
return(ret);
state->chunk_state[state->chunk_w_idx]= 3;
state->chunk_w_idx= (state->chunk_w_idx + 1) % state->num_chunks;
}
/* Wait for slave to end */
ret= Xorriso__wait_slave_md5_end(state, 10000, 0);
if(ret <= 0)
return(ret);
return(1);
}
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1= no pacifier messages
bit2= compute stream MD5 and look out for checksum tag
@ -2123,23 +2430,40 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
int start_lba= 0;
struct burn_drive *drive;
struct burn_drive_info *dinfo;
char *data= NULL;
char *data= NULL, *data_pt;
off_t data_count, to_read, read_count= 0, write_amount;
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0;
void *ctx= NULL, *cloned_ctx= NULL;
char md5[16], tag_md5[16];
uint32_t pos, range_start, range_size, next_tag= 0, lba, md5_spot_lba= 0;
int md5_spot_value= Xorriso_read_quality_untesteD, chain_broken= 0;
int tag_type= 0, valid, was_sb_tag= 0, in_track_gap= 0;
char *comparison= "", *sev_text= "DEBUG", *tag_type_name= "";
void *ctx= NULL;
char md5[16];
size_t data_size;
struct xorriso_md5_state state;
int num_chunks, async_md5;
static off_t chunks_limit= 256 * 1024 * 1024;
memset(&state, 0, sizeof(state));
state.chunk= NULL;
state.chunk_state= NULL;
state.chunk_fill= NULL;
state.chunk_lba= NULL;
state.spotlist= spotlist;
if(read_chunk > 1024)
read_chunk= 1024;
else if(read_chunk < 1)
read_chunk= 1;
Xorriso_alloc_meM(data, char, 2 * read_chunk * 1024);
num_chunks= job->async_chunks;
if(((off_t) num_chunks) * ((off_t) read_chunk) > chunks_limit)
num_chunks= chunks_limit / read_chunk;
async_md5= (num_chunks >= 2);
if(async_md5)
data_size= num_chunks * read_chunk * 2048;
else
data_size= read_chunk * 2048;
Xorriso_alloc_meM(data, char, data_size);
data_pt= data;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to check media readability",
@ -2171,6 +2495,50 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
}
}
state.xorriso= xorriso;
state.ctx= ctx;
state.spotlist= spotlist;
state.md5_start= md5_start;
state.next_tag= 0;
state.chain_broken= 0;
state.in_track_gap= 0;
state.was_sb_tag= 0;
state.md5_spot_value= Xorriso_read_quality_untesteD;
state.md5_spot_lba= 0;
state.slave_state= 0;
state.chunk_size= read_chunk;
if(async_md5) {
state.num_chunks= num_chunks;
Xorriso_alloc_meM(state.chunk, char *, num_chunks);
Xorriso_alloc_meM(state.chunk_state, int, num_chunks);
Xorriso_alloc_meM(state.chunk_fill, int, num_chunks);
Xorriso_alloc_meM(state.chunk_lba, uint32_t, num_chunks);
for(i= 0; i < state.num_chunks; i++) {
state.chunk[i]= data + read_chunk * i * 2048;
state.chunk_state[i]= 0;
state.chunk_fill[i]= 0;
state.chunk_lba[i]= 0;
}
ret= pthread_mutex_init(&(state.spot_mutex), NULL);
if(ret != 0) {
sprintf(xorriso->info_text,
"-check_media: Cannot initialize thread mutex");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
goto ex;
}
} else
state.num_chunks= 0;
state.chunk_w_idx= 0;
state.chunk_r_idx= 0;
state.w_sleeps= 0;
state.r_sleeps= 0;
if(async_md5) {
ret= Xorriso_start_chunk_md5(xorriso, &state, 0);
if(ret <= 0)
goto ex;
}
start_lba= from_lba;
to_read= read_chunk;
post_read_time= Sfile_microtime(0);
@ -2195,12 +2563,12 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
abort_check:;
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
ret= Xorriso__add_spot(&state, start_lba, i + from_lba - start_lba,
prev_quality, 0);
if(ret <= 0)
goto ex;
}
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i,
ret= Xorriso__add_spot(&state, i + from_lba, block_count - i,
Xorriso_read_quality_untesteD, 0);
if(ret > 0)
ret= 2;
@ -2249,8 +2617,16 @@ abort_check:;
} else {
data_count= 0;
pre_read_time= Sfile_microtime(0);
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
to_read * (off_t) 2048, &data_count, 4 * !retry);
if(async_md5) {
ret= Xorriso__wait_chunk_md5(&state, 1, 0);
if(ret <= 0)
goto ex;
data_pt= state.chunk[state.chunk_w_idx];
}
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048,
data_pt, to_read * (off_t) 2048, &data_count, 4 * !retry);
post_read_time= Sfile_microtime(0);
time_diff= post_read_time - pre_read_time;
total_time_diff+= time_diff;
@ -2260,12 +2636,12 @@ abort_check:;
if(data_count / 2048 < to_read) {
if(data_count > 0 && retry) {
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba,
ret= Xorriso__add_spot(&state, start_lba,
i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
}
ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048,
ret= Xorriso__add_spot(&state, i + from_lba, data_count / 2048,
Xorriso_read_quality_partiaL, 0);
if(ret <= 0)
goto ex;
@ -2289,120 +2665,18 @@ abort_check:;
/* MD5 checksumming */
if(ctx != NULL) {
for(j= 0; j < to_read; j++) {
lba= i + j + from_lba;
if(lba < (uint32_t) md5_start)
continue;
ret= 0;
if(lba > (uint32_t) (md5_start) + 16 &&
(next_tag == 0 || chain_broken || lba == next_tag)) {
ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type,
&pos, &range_start, &range_size,
&next_tag, tag_md5, !!chain_broken);
}
valid= (ret == 1 || ret == (int) ISO_MD5_AREA_CORRUPTED) &&
pos == lba;
if(valid && tag_type == 2 && (lba < ((uint32_t) md5_start) + 32 ||
in_track_gap)) {
tag_type_name= "superblock";
was_sb_tag= 1;
if(in_track_gap && range_start != ((uint32_t) md5_start) &&
range_start < lba && lba - range_start <= (uint32_t) j) {
/* Looking for next session : start computing in hindsight.
Session start and superblock tag are supposed to be in the
same 64 kB chunk.
*/
iso_md5_end(&ctx, md5);
ret= iso_md5_start(&ctx);
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_compute(&ctx, data + (j - (lba - range_start)) * 2048,
(lba - range_start) * 2048);
md5_start= range_start;
in_track_gap= 0;
}
} else if(valid && tag_type == 4 && lba < 32) {
tag_type_name= "relocated 64kB superblock";
}else if(valid && tag_type == 3 && was_sb_tag) {
tag_type_name= "tree";
}else if(valid && tag_type == 1) {
if(async_md5) {
state.chunk_fill[state.chunk_w_idx]= to_read;
state.chunk_lba[state.chunk_w_idx]= i + from_lba;
state.chunk_state[state.chunk_w_idx]= 1;
/* The MD5 thread will call Xorriso_chunk_md5() */
/* >>> ??? allow this without superblock and tree tag ? */
tag_type_name= "session";
} else {
tag_type_name= "";
}
if (tag_type_name[0]) {
if(range_start != (uint32_t) md5_start) {
sprintf(xorriso->info_text,
"Found MD5 %s tag which covers different data range",
tag_type_name);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
sprintf(xorriso->info_text,
" Expected: %u Found: %u",
(unsigned int) md5_start, range_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
chain_broken= 1;
valid= 0;
} else {
ret= iso_md5_clone(ctx, &cloned_ctx);
if(ret <= 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
iso_md5_end(&cloned_ctx, md5);
if(ret == (int) ISO_MD5_AREA_CORRUPTED) {
comparison= "CORRUPTED";
sev_text= "WARNING";
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
chain_broken= 1;
} else if(! iso_md5_match(tag_md5, md5)) {
comparison= "NON-MATCHING";
sev_text= "WARNING";
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
chain_broken= 1;
} else {
comparison= "matching";
sev_text= "UPDATE";
md5_spot_value= Xorriso_read_quality_md5_matcH;
}
md5_spot_lba= lba;
sprintf(xorriso->info_text,
"Found %s MD5 %s tag: start=%d size=%d",
comparison, tag_type_name, md5_start, lba - md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
sev_text, 0);
}
if(valid && (tag_type == 1 ||
(tag_type == 4 && pos == lba && lba < 32))) {
if(md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Spotlist_add_item(spotlist, md5_start,
md5_spot_lba - md5_start, md5_spot_value, 0);
if(ret <= 0)
goto ex;
}
md5_spot_value= Xorriso_read_quality_untesteD;
md5_start = lba + 1;
if (md5_start % 32)
md5_start= md5_start + (32 - (md5_start % 32));
next_tag= 0;
iso_md5_end(&ctx, md5);
ret= iso_md5_start(&ctx);
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
if(tag_type == 1)
in_track_gap= 1;
continue;
}
}
iso_md5_compute(ctx, data + j * 2048, 2048);
state.chunk_w_idx= (state.chunk_w_idx + 1) % state.num_chunks;
} else {
ret= Xorriso_chunk_md5(xorriso, data_pt, to_read,
(uint32_t) (i + from_lba), &state, 0);
if(ret <= 0)
goto ex;
}
}
@ -2426,7 +2700,7 @@ failed_to_write:;
"FAILURE", 0);
{ret= 0; goto ex;}
}
ret= write(job->data_to_fd, data, write_amount);
ret= write(job->data_to_fd, data_pt, write_amount);
if(ret == -1)
goto failed_to_write;
}
@ -2434,8 +2708,8 @@ failed_to_write:;
}
if(quality != prev_quality) {
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
prev_quality, 0);
ret= Xorriso__add_spot(&state, start_lba,
i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
}
@ -2452,7 +2726,7 @@ failed_to_write:;
}
}
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba,
ret= Xorriso__add_spot(&state, start_lba,
block_count + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
@ -2467,28 +2741,48 @@ failed_to_write:;
/* MD5 checksumming : register result */
if(async_md5) {
ret= Xorriso__end_slave_md5(&state, 10000, 0);
if(ret <= 0)
goto ex;
}
/* >>> ??? allow chain_broken to be a match ? */
if(next_tag > 0) {
if(state.next_tag > 0) {
sprintf(xorriso->info_text, "Missing announced MD5 tag: start=%d pos=%d",
md5_start, next_tag);
state.md5_start, state.next_tag);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
md5_spot_lba= next_tag;
state.md5_spot_value= Xorriso_read_quality_md5_mismatcH;
state.md5_spot_lba= state.next_tag;
}
if(md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Spotlist_add_item(spotlist, md5_start, md5_spot_lba - md5_start,
md5_spot_value, 0);
if(state.md5_spot_value != Xorriso_read_quality_untesteD) {
ret= Xorriso__add_spot(&state, state.md5_start,
state.md5_spot_lba - state.md5_start, state.md5_spot_value, 0);
if(ret <= 0)
goto ex;
}
ret= 1;
ex:
if(ctx != NULL)
iso_md5_end(&ctx, md5);
ex:;
if(async_md5) {
Xorriso__end_slave_md5(&state, 10000, 0);
sprintf(xorriso->info_text,
"async_chunks=%d , chunk_size=%d , w_sleeps: %.f , r_sleeps: %.f",
state.num_chunks, read_chunk, (double) state.w_sleeps,
(double) state.r_sleeps);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
if(state.chunk != NULL)
pthread_mutex_destroy(&(state.spot_mutex));
Xorriso_free_meM(state.chunk);
Xorriso_free_meM(state.chunk_state);
Xorriso_free_meM(state.chunk_fill);
Xorriso_free_meM(state.chunk_lba);
}
Xorriso_free_meM(data);
if(state.ctx != NULL)
iso_md5_end(&(state.ctx), md5);
return(ret);
}
@ -2519,10 +2813,11 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
if(ret<=0)
goto ex;
/* >>> determine medium type dependent blocking factor:
32 kB for CD (with 2kB retry) and DVD, 64 kB for BD
eventually adjust read_chunk
*/;
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
if(ret <= 0)
profile_no= 0;
if(profile_no >= 0x40 && profile_no <= 0x43) /* BD-ROM, BD-R, BD-RE */
read_chunk= 32;
if(job->min_block_size != 0)
read_chunk= job->min_block_size;
@ -2568,9 +2863,6 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
ret= burn_get_read_capacity(drive, &read_capacity, 0);
if(ret <= 0)
read_capacity= -1;
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
if(ret <= 0)
profile_no= 0;
if(job->max_lba >= 0) {
blocks= job->max_lba + 1 - start_lba;