Working around a Linux kernel bug, which hides files of which the
Rock Ridge CE entry points to a range that crosses a block boundary, or of which the byte offset is larger than the block size of 2048. Thanks to Joerg Meyer.
This commit is contained in:
parent
527b613607
commit
8e55195edc
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -32,10 +32,16 @@
|
||||
#define ISO_ROCKRIDGE_IN_DIR_REC 124
|
||||
#endif
|
||||
|
||||
#define ISO_CE_ENTRY_SIZE 28
|
||||
|
||||
|
||||
static
|
||||
int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno);
|
||||
|
||||
static
|
||||
int susp_make_CE(Ecma119Image *t, uint8_t **CE,
|
||||
uint32_t block_offset, uint32_t byte_offset, uint32_t size);
|
||||
|
||||
|
||||
static
|
||||
int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||
@ -54,14 +60,66 @@ int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||
static
|
||||
int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||
{
|
||||
susp->n_ce_susp_fields++;
|
||||
susp->ce_susp_fields = realloc(susp->ce_susp_fields, sizeof(void*)
|
||||
* susp->n_ce_susp_fields);
|
||||
if (susp->ce_susp_fields == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
int to_alloc = 1, ret;
|
||||
unsigned char *pad;
|
||||
uint8_t *CE;
|
||||
size_t next_alloc;
|
||||
|
||||
if (data[0] &&
|
||||
(susp->ce_len + data[2] + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE !=
|
||||
susp->ce_len / BLOCK_SIZE) {
|
||||
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE.
|
||||
So this Continuation Area needs to end by a CE which points
|
||||
to the start of the next block.
|
||||
*/
|
||||
to_alloc = 2;
|
||||
if ((susp->ce_len + ISO_CE_ENTRY_SIZE) % BLOCK_SIZE)
|
||||
to_alloc = 3; /* need a PAD pseudo entry */
|
||||
}
|
||||
|
||||
if (susp->ce_susp_fields == NULL)
|
||||
susp->alloc_ce_susp_fields = 0;
|
||||
if (susp->n_ce_susp_fields + to_alloc > susp->alloc_ce_susp_fields) {
|
||||
next_alloc = susp->alloc_ce_susp_fields;
|
||||
while (susp->n_ce_susp_fields + to_alloc > next_alloc)
|
||||
next_alloc += ISO_SUSP_CE_ALLOC_STEP;
|
||||
susp->ce_susp_fields = realloc(susp->ce_susp_fields,
|
||||
sizeof(uint8_t *) * next_alloc);
|
||||
if (susp->ce_susp_fields == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
susp->alloc_ce_susp_fields = next_alloc;
|
||||
}
|
||||
|
||||
if (to_alloc >= 2) {
|
||||
/* Insert CE entry (actual CE size later by susp_update_CE_sizes) */
|
||||
ret = susp_make_CE(t, &CE, (uint32_t) (susp->ce_block +
|
||||
susp->ce_len / BLOCK_SIZE + 1),
|
||||
(uint32_t) 0, (uint32_t) 2048);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields] = CE;
|
||||
susp->ce_len += ISO_CE_ENTRY_SIZE;
|
||||
susp->n_ce_susp_fields++;
|
||||
}
|
||||
if (to_alloc >= 3) {
|
||||
pad = malloc(1);
|
||||
if (pad == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
pad[0] = 0;
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields] = pad;
|
||||
if (susp->ce_len % BLOCK_SIZE)
|
||||
susp->ce_len += BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE);
|
||||
susp->n_ce_susp_fields++;
|
||||
}
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields] = data;
|
||||
susp->n_ce_susp_fields++;
|
||||
|
||||
if (data[0] == 0) {
|
||||
if (susp->ce_len % BLOCK_SIZE)
|
||||
susp->ce_len += BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE);
|
||||
} else {
|
||||
susp->ce_len += data[2];
|
||||
}
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields - 1] = data;
|
||||
susp->ce_len += data[2];
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -547,9 +605,24 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int susp_calc_add_to_ce(size_t *ce, int add, int flag)
|
||||
{
|
||||
/* Account for inserted CE before size exceeds block size */
|
||||
if ((*ce + add + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE != *ce / BLOCK_SIZE) {
|
||||
/* Insert CE and padding */
|
||||
*ce += ISO_CE_ENTRY_SIZE;
|
||||
if (*ce % BLOCK_SIZE)
|
||||
*ce += BLOCK_SIZE - (*ce % BLOCK_SIZE);
|
||||
}
|
||||
*ce += add;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@param flag bit0= only account sizes in sua_free resp. ce_len
|
||||
parameters susp and data may be NULL in this case
|
||||
@param flag bit0= only account sizes in sua_free resp. ce_len.
|
||||
Parameter susp may be NULL in this case
|
||||
*/
|
||||
static
|
||||
int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
@ -558,11 +631,20 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
{
|
||||
int ret, done = 0, len, es_extra = 0;
|
||||
uint8_t *aapt, *cpt;
|
||||
size_t count = 0;
|
||||
|
||||
if (!t->opts->aaip_susp_1_10)
|
||||
es_extra = 5;
|
||||
if (*sua_free < num_data + es_extra || *ce_len > 0) {
|
||||
*ce_len += num_data + es_extra;
|
||||
if (es_extra > 0)
|
||||
susp_calc_add_to_ce(ce_len, es_extra, 0);
|
||||
done = 0;
|
||||
for (aapt = *data; !done; aapt += aapt[2]) {
|
||||
done = !(aapt[4] & 1);
|
||||
len = aapt[2];
|
||||
susp_calc_add_to_ce(ce_len, len, 0);
|
||||
count += len;
|
||||
}
|
||||
} else {
|
||||
*sua_free -= num_data + es_extra;
|
||||
}
|
||||
@ -588,6 +670,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
}
|
||||
|
||||
/* Multiple fields have to be handed over as single field copies */
|
||||
done = 0;
|
||||
for (aapt = *data; !done; aapt += aapt[2]) {
|
||||
done = !(aapt[4] & 1);
|
||||
len = aapt[2];
|
||||
@ -722,6 +805,35 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the byte representation of a CE entry.
|
||||
* (SUSP, 5.1).
|
||||
*/
|
||||
static
|
||||
int susp_make_CE(Ecma119Image *t, uint8_t **CE,
|
||||
uint32_t block_offset, uint32_t byte_offset, uint32_t size)
|
||||
{
|
||||
uint8_t *data;
|
||||
|
||||
*CE = NULL;
|
||||
data = calloc(1, 28);
|
||||
if (data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
*CE = data;
|
||||
|
||||
data[0] = 'C';
|
||||
data[1] = 'E';
|
||||
data[2] = 28;
|
||||
data[3] = 1;
|
||||
|
||||
iso_bb(&data[4], block_offset - t->eff_partition_offset, 4);
|
||||
iso_bb(&data[12], byte_offset, 4);
|
||||
iso_bb(&data[20], size, 4);
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a CE System Use Entry to the given tree node. A "CE" is used to add
|
||||
* a continuation area, where additional System Use Entry can be written.
|
||||
@ -730,20 +842,18 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
|
||||
static
|
||||
int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
|
||||
{
|
||||
uint8_t *CE = malloc(28);
|
||||
if (CE == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
CE[0] = 'C';
|
||||
CE[1] = 'E';
|
||||
CE[2] = 28;
|
||||
CE[3] = 1;
|
||||
|
||||
iso_bb(&CE[4], susp->ce_block - t->eff_partition_offset, 4);
|
||||
iso_bb(&CE[12], susp->ce_len, 4);
|
||||
iso_bb(&CE[20], (uint32_t) ce_len, 4);
|
||||
uint32_t block_offset, byte_offset;
|
||||
uint8_t *CE;
|
||||
int ret;
|
||||
|
||||
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE
|
||||
* Here the byte_offset is reduced to the minimum.
|
||||
*/
|
||||
block_offset = susp->ce_block + susp->ce_len / BLOCK_SIZE;
|
||||
byte_offset = susp->ce_len % BLOCK_SIZE;
|
||||
ret = susp_make_CE(t, &CE, block_offset, byte_offset, (uint32_t) ce_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return susp_append(t, susp, CE);
|
||||
}
|
||||
|
||||
@ -799,6 +909,27 @@ int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A field beginning by 0 causes rrip_write_ce_fields() to pad up to the
|
||||
* next block.
|
||||
*/
|
||||
static
|
||||
int pseudo_susp_add_PAD(Ecma119Image *t, struct susp_info *susp)
|
||||
{
|
||||
unsigned char *pad;
|
||||
int ret;
|
||||
|
||||
pad = malloc(1);
|
||||
if (pad == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
pad[0] = 0;
|
||||
ret = susp_append_ce(t, susp, pad);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* see doc/zisofs_format.txt : "ZF System Use Entry Format"
|
||||
*/
|
||||
@ -922,7 +1053,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
|
||||
/* Account for field size */
|
||||
if (*sua_free < 16 || *ce_len > 0) {
|
||||
*ce_len += 16;
|
||||
susp_calc_add_to_ce(ce_len, 16, 0);
|
||||
} else {
|
||||
*sua_free -= 16;
|
||||
}
|
||||
@ -988,6 +1119,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
void *xipt;
|
||||
size_t num_aapt = 0, sua_free = 0;
|
||||
int ret;
|
||||
uint8_t *aapt;
|
||||
|
||||
su_mem = *su_size;
|
||||
ce_mem = *ce;
|
||||
@ -1020,7 +1152,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
of the name will always fit into the directory entry.)
|
||||
*/;
|
||||
|
||||
*ce = 5 + namelen;
|
||||
susp_calc_add_to_ce(ce, 5 + namelen, 0);
|
||||
*su_size = space;
|
||||
}
|
||||
if (n->type == ECMA119_SYMLINK) {
|
||||
@ -1090,21 +1222,26 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* the component can be divided between this
|
||||
* and another SL entry
|
||||
*/
|
||||
*ce += 255; /* this SL, full */
|
||||
sl_len = 5 + (clen - fit);
|
||||
/* Will fill up old SL and write it */
|
||||
susp_calc_add_to_ce(ce, 255, 0);
|
||||
sl_len = 5 + (clen - fit); /* Start new SL */
|
||||
} else {
|
||||
/*
|
||||
* the component will need a 2rd SL entry in
|
||||
* any case, so we prefer to don't write
|
||||
* anything in this SL
|
||||
*/
|
||||
*ce += sl_len + 255;
|
||||
sl_len = 5 + (clen - 250) + 2;
|
||||
/* Will write non-full old SL */
|
||||
susp_calc_add_to_ce(ce, sl_len , 0);
|
||||
/* Will write another full SL */
|
||||
susp_calc_add_to_ce(ce, 255, 0);
|
||||
sl_len = 5 + (clen - 250) + 2; /* Start new SL */
|
||||
}
|
||||
} else {
|
||||
/* case 2, create a new SL entry */
|
||||
*ce += sl_len;
|
||||
sl_len = 5 + clen;
|
||||
/* Will write non-full old SL */
|
||||
susp_calc_add_to_ce(ce, sl_len, 0);
|
||||
sl_len = 5 + clen; /* Start new SL */
|
||||
}
|
||||
} else {
|
||||
sl_len += clen;
|
||||
@ -1126,7 +1263,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
/* the whole SL fits into the SUA */
|
||||
*su_size += sl_len;
|
||||
} else {
|
||||
*ce += sl_len;
|
||||
susp_calc_add_to_ce(ce, sl_len, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1150,7 +1287,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
/* let the expert decide where to add num_aapt */
|
||||
if (num_aapt > 0) {
|
||||
sua_free = space - *su_size;
|
||||
aaip_add_AL(t, NULL, NULL, num_aapt, &sua_free, ce, 1);
|
||||
aapt = (uint8_t *) xipt;
|
||||
aaip_add_AL(t, NULL, &aapt, num_aapt, &sua_free, ce, 1);
|
||||
*su_size = space - sua_free;
|
||||
if (*ce > 0 && !(flag & 1))
|
||||
goto unannounced_ca;
|
||||
@ -1185,7 +1323,9 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||
if (num_aapt > 0) {
|
||||
if (flag & 1) {
|
||||
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
||||
aapt = (unsigned char *) xipt;
|
||||
ret = aaip_add_AL(t, NULL, &aapt, num_aapt, sua_free, ce_len,
|
||||
1);
|
||||
} else {
|
||||
aapt = malloc(num_aapt);
|
||||
if (aapt == NULL)
|
||||
@ -1193,10 +1333,10 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
memcpy(aapt, xipt, num_aapt);
|
||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
||||
0);
|
||||
/* aapt is NULL now and the memory is owned by t */
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* aapt is NULL now and the memory is owned by t */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -1393,6 +1533,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
/* Mark start index of node's continuation area for later update */
|
||||
info->current_ce_start = info->n_ce_susp_fields;
|
||||
|
||||
if (type == 2 && n->parent != NULL) {
|
||||
node = n->parent;
|
||||
} else {
|
||||
@ -1699,6 +1842,16 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
|
||||
if (ce_is_predicted) {
|
||||
if ((info->ce_len % BLOCK_SIZE) &&
|
||||
(info->ce_len + ce_len_pd - 1 ) / BLOCK_SIZE !=
|
||||
info->ce_len / BLOCK_SIZE) {
|
||||
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE
|
||||
* Insert padding to shift CE offset to next block start
|
||||
*/
|
||||
ret = pseudo_susp_add_PAD(t, info);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
/* Add the CE entry */
|
||||
ret = susp_add_CE(t, ce_len_pd, info);
|
||||
if (ret < 0) {
|
||||
@ -1854,6 +2007,51 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Update the sizes of CE fields at end of info->susp_fields and in
|
||||
single node range of info->ce_susp_fields.
|
||||
*/
|
||||
static
|
||||
int susp_update_CE_sizes(Ecma119Image *t, struct susp_info *info, int flag)
|
||||
{
|
||||
size_t i, curr_pos;
|
||||
uint8_t *curr_ce;
|
||||
uint32_t size;
|
||||
|
||||
if (info->n_susp_fields == 0 ||
|
||||
info->n_ce_susp_fields - info->current_ce_start == 0)
|
||||
return ISO_SUCCESS;
|
||||
if (info->susp_fields[info->n_susp_fields - 1][0] != 'C' ||
|
||||
info->susp_fields[info->n_susp_fields - 1][1] != 'E') {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Last System Use Area field is not CE, but there are fileds in Continuation Area");
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
curr_ce = info->susp_fields[info->n_susp_fields - 1];
|
||||
curr_pos = 0;
|
||||
for (i = info->current_ce_start; i < info->n_ce_susp_fields; i++) {
|
||||
if (info->ce_susp_fields[i][0] == 0) {
|
||||
curr_pos = 0; /* pseudo SUSP PAD */
|
||||
continue;
|
||||
}
|
||||
if (info->ce_susp_fields[i][0] == 'C' &&
|
||||
info->ce_susp_fields[i][1] == 'E') {
|
||||
size = (curr_pos + info->ce_susp_fields[i][2]) % BLOCK_SIZE;
|
||||
if (size == 0)
|
||||
size = BLOCK_SIZE;
|
||||
iso_bb(curr_ce + 20, size, 4);
|
||||
curr_ce = info->ce_susp_fields[i];
|
||||
}
|
||||
curr_pos = (curr_pos + info->ce_susp_fields[i][2]) % 2048;
|
||||
}
|
||||
if (curr_pos > 0) {
|
||||
size = curr_pos % BLOCK_SIZE;
|
||||
iso_bb(curr_ce + 20, size, 4);
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the given SUSP fields into buf. Note that Continuation Area
|
||||
* fields are not written.
|
||||
@ -1866,11 +2064,16 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
||||
{
|
||||
size_t i;
|
||||
size_t pos = 0;
|
||||
int ret;
|
||||
|
||||
if (info->n_susp_fields == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = susp_update_CE_sizes(t, info, 0);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < info->n_susp_fields; i++) {
|
||||
memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]);
|
||||
pos += info->susp_fields[i][2];
|
||||
@ -1896,6 +2099,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
size_t i;
|
||||
uint8_t *padding = NULL;
|
||||
int ret= ISO_SUCCESS;
|
||||
uint64_t written = 0, pad_size;
|
||||
|
||||
if (info->n_ce_susp_fields == 0) {
|
||||
goto ex;
|
||||
@ -1903,11 +2107,24 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
|
||||
|
||||
for (i = 0; i < info->n_ce_susp_fields; i++) {
|
||||
if (info->ce_susp_fields[i][0] == 0) {
|
||||
/* Pseudo field: pad up to next block boundary */
|
||||
pad_size = BLOCK_SIZE - (written % BLOCK_SIZE);
|
||||
if (pad_size == BLOCK_SIZE)
|
||||
continue;
|
||||
memset(padding, 0, pad_size);
|
||||
ret = iso_write(t, padding, pad_size);
|
||||
if (ret < 0)
|
||||
goto write_ce_field_cleanup;
|
||||
written += pad_size;
|
||||
continue;
|
||||
}
|
||||
ret = iso_write(t, info->ce_susp_fields[i],
|
||||
info->ce_susp_fields[i][2]);
|
||||
if (ret < 0) {
|
||||
goto write_ce_field_cleanup;
|
||||
}
|
||||
written += info->ce_susp_fields[i][2];
|
||||
}
|
||||
|
||||
/* pad continuation area until block size */
|
||||
@ -1915,6 +2132,9 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
if (i > 0 && i < BLOCK_SIZE) {
|
||||
memset(padding, 0, i);
|
||||
ret = iso_write(t, padding, i);
|
||||
if (ret < 0)
|
||||
goto write_ce_field_cleanup;
|
||||
written += i;
|
||||
}
|
||||
|
||||
write_ce_field_cleanup: ;
|
||||
@ -1925,6 +2145,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
free(info->ce_susp_fields);
|
||||
info->ce_susp_fields = NULL;
|
||||
info->n_ce_susp_fields = 0;
|
||||
info->alloc_ce_susp_fields = 0;
|
||||
info->ce_len = 0;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(padding);
|
||||
|
@ -63,10 +63,22 @@ struct susp_info
|
||||
uint32_t ce_block;
|
||||
uint32_t ce_len;
|
||||
|
||||
/* Storage for Continuation Area for a whole directory */
|
||||
size_t n_ce_susp_fields;
|
||||
uint8_t **ce_susp_fields;
|
||||
|
||||
/* The number of allocated members in ce_susp_fields */
|
||||
size_t alloc_ce_susp_fields;
|
||||
|
||||
/* Marks the start index in ce_susp_fields of the current node */
|
||||
size_t current_ce_start;
|
||||
|
||||
};
|
||||
|
||||
/* Step to increase allocated size of susp_info.ce_susp_fields */
|
||||
#define ISO_SUSP_CE_ALLOC_STEP 16
|
||||
|
||||
|
||||
/* SUSP 5.1 */
|
||||
struct susp_CE {
|
||||
uint8_t block[8];
|
||||
|
Loading…
Reference in New Issue
Block a user