Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
This commit is contained in:
parent
fe5efd7b37
commit
7e6dadeb02
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2011.08.08.121355"
|
#define Cdrskin_timestamP "2011.08.17.160854"
|
||||||
|
@ -374,6 +374,11 @@ int burn_drive_grab(struct burn_drive *d, int le)
|
|||||||
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
|
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
|
||||||
stbuf.st_size > 0) {
|
stbuf.st_size > 0) {
|
||||||
d->status = BURN_DISC_APPENDABLE;
|
d->status = BURN_DISC_APPENDABLE;
|
||||||
|
if (stbuf.st_size / (off_t) 2048
|
||||||
|
>= 0x7ffffff0) {
|
||||||
|
d->status = BURN_DISC_FULL;
|
||||||
|
d->role_5_nwa = 0x7ffffff0;
|
||||||
|
} else
|
||||||
d->role_5_nwa = stbuf.st_size / 2048 +
|
d->role_5_nwa = stbuf.st_size / 2048 +
|
||||||
!!(stbuf.st_size % 2048);
|
!!(stbuf.st_size % 2048);
|
||||||
} else
|
} else
|
||||||
@ -1464,14 +1469,15 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret,
|
|||||||
st_ret = stat(fname, &stbuf);
|
st_ret = stat(fname, &stbuf);
|
||||||
if (st_ret != -1) {
|
if (st_ret != -1) {
|
||||||
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
|
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
|
||||||
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) {
|
ret = 1;
|
||||||
|
} else if (is_rdwr)
|
||||||
ret = burn_os_stdio_capacity(fname, &read_size);
|
ret = burn_os_stdio_capacity(fname, &read_size);
|
||||||
if (ret <= 0)
|
if (ret <= 0 ||
|
||||||
|
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
|
||||||
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
|
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (is_rdwr && fd >= 0) {
|
if (is_rdwr && fd >= 0) {
|
||||||
getfl_ret = fcntl(fd, F_GETFL);
|
getfl_ret = fcntl(fd, F_GETFL);
|
||||||
@ -1614,6 +1620,11 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||||||
(burn_drive_role_4_allowed & 8)) {
|
(burn_drive_role_4_allowed & 8)) {
|
||||||
d->status = BURN_DISC_APPENDABLE;
|
d->status = BURN_DISC_APPENDABLE;
|
||||||
d->block_types[BURN_WRITE_SAO] = 0;
|
d->block_types[BURN_WRITE_SAO] = 0;
|
||||||
|
if (stbuf.st_size / (off_t) 2048
|
||||||
|
>= 0x7ffffff0) {
|
||||||
|
d->status = BURN_DISC_FULL;
|
||||||
|
d->role_5_nwa = 0x7ffffff0;
|
||||||
|
} else
|
||||||
d->role_5_nwa = stbuf.st_size / 2048 +
|
d->role_5_nwa = stbuf.st_size / 2048 +
|
||||||
!!(stbuf.st_size % 2048);
|
!!(stbuf.st_size % 2048);
|
||||||
} else {
|
} else {
|
||||||
@ -2713,11 +2724,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
size = d->media_capacity_remaining;
|
size = d->media_capacity_remaining;
|
||||||
burn_os_stdio_capacity(d->devname, &size);
|
burn_os_stdio_capacity(d->devname, &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;
|
||||||
/* >>> This looks wrong ! */
|
|
||||||
/* >>> should add file size */
|
|
||||||
o->start_range_high = size;
|
|
||||||
|
|
||||||
o->start_alignment = 2048; /* imposting a drive, not a file */
|
o->start_alignment = 2048; /* imposting a drive, not a file */
|
||||||
o->might_do_sao = 4;
|
o->might_do_sao = 4;
|
||||||
o->might_do_tao = 2;
|
o->might_do_tao = 2;
|
||||||
@ -2732,10 +2739,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
|
|
||||||
/* >>> start_range_low = file size rounded to 2048 */;
|
/* >>> start_range_low = file size rounded to 2048 */;
|
||||||
|
|
||||||
/* >>> This looks wrong ! */
|
o->start_range_high = d->media_capacity_remaining;
|
||||||
/* >>> should add file size */
|
|
||||||
o->start_range_high = size;
|
|
||||||
|
|
||||||
o->start_alignment = 2048; /* imposting a drive, not a file */
|
o->start_alignment = 2048; /* imposting a drive, not a file */
|
||||||
if (s == BURN_DISC_APPENDABLE) {
|
if (s == BURN_DISC_APPENDABLE) {
|
||||||
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
|
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
|
||||||
@ -3148,10 +3152,13 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
|||||||
*/
|
*/
|
||||||
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
||||||
{
|
{
|
||||||
|
if (value / (off_t) 2048 > (off_t) 0x7ffffff0)
|
||||||
|
value = ((off_t) 0x7ffffff0) * (off_t) 2048;
|
||||||
d->media_capacity_remaining = value;
|
d->media_capacity_remaining = value;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A81215 : API */
|
/* ts A81215 : API */
|
||||||
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
||||||
{
|
{
|
||||||
|
@ -1393,6 +1393,9 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
|||||||
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
|
subtracted from the obtained 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
|
||||||
|
device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks
|
||||||
|
= 4 TB - 32 KB.
|
||||||
@param d The drive to query.
|
@param d The drive to query.
|
||||||
@param o If not NULL: write parameters to be set on drive before query
|
@param o If not NULL: write parameters to be set on drive before query
|
||||||
@return number of most probably available free bytes
|
@return number of most probably available free bytes
|
||||||
@ -3067,6 +3070,8 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
can be read via burn_read_data() although some of them may never have been
|
can be read via burn_read_data() although some of them may never have been
|
||||||
recorded. If tracks are recognizable then it is better to only read
|
recorded. If tracks are recognizable then it is better to only read
|
||||||
LBAs which are part of some track.
|
LBAs which are part of some track.
|
||||||
|
If the drive is actually a large file or block device, then the capacity
|
||||||
|
is curbed to a maximum of 0x7ffffff0 blocks = 4 TB - 32 KB.
|
||||||
@param d The drive from which to read
|
@param d The drive from which to read
|
||||||
@param capacity Will return the result if valid
|
@param capacity Will return the result if valid
|
||||||
@param flag Bitfield for control purposes: Unused yet, submit 0.
|
@param flag Bitfield for control purposes: Unused yet, submit 0.
|
||||||
|
@ -293,7 +293,9 @@ struct burn_drive
|
|||||||
int media_lba_limit;
|
int media_lba_limit;
|
||||||
|
|
||||||
/* ts A81210 : Upper limit of readable data size,
|
/* ts A81210 : Upper limit of readable data size,
|
||||||
0x7fffffff = unknown */
|
0x7fffffff = unknown
|
||||||
|
0x7ffffff0 = 32 bit overflow, or unknown stdio size
|
||||||
|
*/
|
||||||
int media_read_capacity;
|
int media_read_capacity;
|
||||||
|
|
||||||
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
|
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
|
||||||
|
Loading…
Reference in New Issue
Block a user