Improved drive capacity estimation for sparse regular files

This commit is contained in:
Thomas Schmitt 2014-06-10 07:37:40 +00:00
parent b9d52d07e9
commit 8e0db7c63e
13 changed files with 78 additions and 26 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2014.05.03.103448" #define Cdrskin_timestamP "2014.06.09.183251"

View File

@ -393,7 +393,7 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret,
if (S_ISREG(stbuf.st_mode)) if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size; read_size = stbuf.st_size;
else if (is_rdwr) else if (is_rdwr)
ret = burn_os_stdio_capacity(fname, &read_size); ret = burn_os_stdio_capacity(fname, 0, &read_size);
if (ret <= 0 || if (ret <= 0 ||
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0) read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048; read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
@ -450,7 +450,7 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag)
d->media_read_capacity = d->media_read_capacity =
read_size / 2048 - !(read_size % 2048); read_size / 2048 - !(read_size % 2048);
if ((stat_ret == -1 || is_rdwr) && d->devname[0]) { if ((stat_ret == -1 || is_rdwr) && d->devname[0]) {
ret = burn_os_stdio_capacity(d->devname, &size); ret = burn_os_stdio_capacity(d->devname, 0, &size);
if (ret > 0) if (ret > 0)
burn_drive_set_media_capacity_remaining(d, burn_drive_set_media_capacity_remaining(d,
size); size);
@ -1722,7 +1722,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf, is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf,
&read_size, 1 | 2); &read_size, 1 | 2);
if (stat_ret == -1 || is_rdwr) { if (stat_ret == -1 || is_rdwr) {
ret = burn_os_stdio_capacity(fname, &size); ret = burn_os_stdio_capacity(fname, 0, &size);
if (ret == -1) { if (ret == -1) {
libdax_msgs_submit(libdax_messenger, -1, libdax_msgs_submit(libdax_messenger, -1,
0x00020009, 0x00020009,
@ -2637,7 +2637,8 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start)
off_t burn_disc_available_space(struct burn_drive *d, off_t burn_disc_available_space(struct burn_drive *d,
struct burn_write_opts *o) struct burn_write_opts *o)
{ {
int lba, nwa; int lba, nwa, ret;
off_t bytes;
if (burn_drive_is_released(d)) if (burn_drive_is_released(d))
return 0; return 0;
@ -2646,9 +2647,13 @@ off_t burn_disc_available_space(struct burn_drive *d,
if (d->drive_role == 0) if (d->drive_role == 0)
return 0; return 0;
if (d->drive_role != 1) { if (d->drive_role != 1) {
if (d->media_capacity_remaining <= 0) ret = burn_os_stdio_capacity(d->devname, o->start_byte, &bytes);
burn_drive_set_media_capacity_remaining(d, if (ret != 1)
(off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); bytes = d->media_capacity_remaining;
if (bytes <= 0)
bytes = (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048;
if (bytes != d->media_capacity_remaining)
burn_drive_set_media_capacity_remaining(d, bytes);
} else { } else {
if (o != NULL) if (o != NULL)
d->send_write_parameters(d, NULL, -1, o); d->send_write_parameters(d, NULL, -1, o);
@ -2897,7 +2902,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
/* stdio file drive : random access read-write */ /* stdio file drive : random access read-write */
o->start_adr = 1; o->start_adr = 1;
size = d->media_capacity_remaining; size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, &size); burn_os_stdio_capacity(d->devname, 0, &size);
burn_drive_set_media_capacity_remaining(d, size); burn_drive_set_media_capacity_remaining(d, size);
o->start_range_high = d->media_capacity_remaining; o->start_range_high = d->media_capacity_remaining;
o->start_alignment = 2048; /* imposting a drive, not a file */ o->start_alignment = 2048; /* imposting a drive, not a file */
@ -2909,7 +2914,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
/* stdio file drive : random access write-only */ /* stdio file drive : random access write-only */
o->start_adr = 1; o->start_adr = 1;
size = d->media_capacity_remaining; size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, &size); burn_os_stdio_capacity(d->devname, 0, &size);
burn_drive_set_media_capacity_remaining(d, size); burn_drive_set_media_capacity_remaining(d, size);
/* >>> start_range_low = file size rounded to 2048 */; /* >>> start_range_low = file size rounded to 2048 */;

View File

@ -1478,7 +1478,7 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value
from the most recent automatic inquiry (e.g. during last drive grabbing). from the most recent automatic inquiry (e.g. during last drive grabbing).
An eventual start address from burn_write_opts_set_start_byte() will be An eventual start address from burn_write_opts_set_start_byte() will be
subtracted from the obtained capacity estimation. Negative results get taken into respect with the capacity estimation. Negative results get
defaulted to 0. defaulted to 0.
If the drive is actually a file in a large filesystem or a large block If the drive is actually a file in a large filesystem or a large block
device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks

View File

@ -244,7 +244,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
@ -289,7 +289,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#endif /* Libburn_if_this_was_linuX */ #endif /* Libburn_if_this_was_linuX */
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -716,7 +716,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
struct statvfs vfsbuf; struct statvfs vfsbuf;
@ -769,7 +769,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
{ret = -2; goto ex;} {ret = -2; goto ex;}
*bytes = add_size; *bytes = add_size;
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -1051,7 +1051,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
struct statvfs vfsbuf; struct statvfs vfsbuf;
@ -1104,7 +1104,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
{ret = -2; goto ex;} {ret = -2; goto ex;}
*bytes = add_size; *bytes = add_size;
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -865,7 +865,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
@ -944,7 +944,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#endif /* Libburn_is_on_solariS */ #endif /* Libburn_is_on_solariS */
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -2169,6 +2169,24 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->end_time = burn_get_time(0); c->end_time = burn_get_time(0);
/*
# de fine Libburn_ff_netbsd_mockuP
*/
#ifdef Libburn_ff_netbsd_mockuP
if (c->opcode[0] == 0x5a) {
sprintf(msg, "Libburn_ff_netbsd_mockuP : Emulating zero reply from SCSI command 5A");
if (burn_sg_log_scsi & 3)
scsi_log_message(d, fp, msg, 0);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
memset(c->page->data, 0, c->page->bytes);
c->error = 1;
c->dxfer_len = 0;
}
#endif
/* ts A61010 */ /* ts A61010 */
/* a ssert(err != -1); */ /* a ssert(err != -1); */
if (err == -1) { if (err == -1) {
@ -2353,7 +2371,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
struct statvfs vfsbuf; struct statvfs vfsbuf;
@ -2386,7 +2404,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
{ret = -2; goto ex;} {ret = -2; goto ex;}
*bytes = ((off_t) blocks) * (off_t) 512; *bytes = ((off_t) blocks) * (off_t) 512;
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -787,7 +787,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
int ret; int ret;
@ -830,7 +830,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
} }
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -785,7 +785,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
0 = could not estimate size capacity of file object 0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set 1 = estimation has been made, bytes was set
*/ */
int burn_os_stdio_capacity(char *path, off_t *bytes) int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ {
struct stat stbuf; struct stat stbuf;
int ret; int ret;
@ -826,7 +826,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
} }
} else if(S_ISREG(stbuf.st_mode)) { } else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512; add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path); strcpy(testpath, path);
} else } else
{ret = 0; goto ex;} {ret = 0; goto ex;}

View File

@ -36,7 +36,7 @@ int sg_drive_is_open(struct burn_drive * d);
int burn_os_is_2k_seekrw(char *path, int flag); int burn_os_is_2k_seekrw(char *path, int flag);
int burn_os_stdio_capacity(char *path, off_t *bytes); int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes);
/* ts A91227 */ /* ts A91227 */
/** Returns the id string of the SCSI transport adapter and eventually /** Returns the id string of the SCSI transport adapter and eventually

View File

@ -17,6 +17,8 @@
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
@ -377,4 +379,23 @@ double burn_get_time(int flag)
return (double) time(NULL); return (double) time(NULL);
} }
/* ts B40609 */
off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf)
{
off_t add_size;
add_size = stbuf->st_blocks * (off_t) 512;
if (add_size < stbuf->st_size) {
/* Sparse file */
if (write_start < stbuf->st_size) {
/* Might write into sparse gaps */
if (write_start > add_size)
add_size = write_start;
} else {
/* Will not write into sparse area */
add_size = stbuf->st_size;
}
}
return add_size;
}

View File

@ -1,6 +1,11 @@
#ifndef __UTIL #ifndef __UTIL
#define __UTIL #define __UTIL
/* for struct stat */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/* ts A90905 */ /* ts A90905 */
int burn_util_make_printable_word(char **text, int flag); int burn_util_make_printable_word(char **text, int flag);
@ -14,4 +19,7 @@ void burn_int_to_lsb(int val, char *target);
/* ts B30609 */ /* ts B30609 */
double burn_get_time(int flag); double burn_get_time(int flag);
/* ts B40609 */
off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf);
#endif #endif