New API call iso_write_opts_set_max_ce_entries()
This commit is contained in:
parent
7109ba5675
commit
bd415402f4
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2019 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -205,17 +205,24 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
|
||||
* taking into account the continuation areas.
|
||||
*/
|
||||
static
|
||||
size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
ssize_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
{
|
||||
size_t i, len;
|
||||
ssize_t ret;
|
||||
size_t ce_len = 0;
|
||||
|
||||
/* size of "." and ".." entries */
|
||||
len = 34 + 34;
|
||||
if (t->opts->rockridge) {
|
||||
len += rrip_calc_len(t, dir, 1, 34, &ce_len, *ce);
|
||||
ret = rrip_calc_len(t, dir, 1, 34, &ce_len, *ce);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
len += ret;
|
||||
*ce += ce_len;
|
||||
len += rrip_calc_len(t, dir, 2, 34, &ce_len, *ce);
|
||||
ret = rrip_calc_len(t, dir, 2, 34, &ce_len, *ce);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
len += ret;
|
||||
*ce += ce_len;
|
||||
}
|
||||
|
||||
@ -228,8 +235,10 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
for (section = 0; section < nsections; ++section) {
|
||||
size_t dirent_len = calc_dirent_len(t, child);
|
||||
if (t->opts->rockridge) {
|
||||
dirent_len += rrip_calc_len(t, child, 0, dirent_len, &ce_len,
|
||||
*ce);
|
||||
ret = rrip_calc_len(t, child, 0, dirent_len, &ce_len, *ce);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
dirent_len += ret;
|
||||
*ce += ce_len;
|
||||
}
|
||||
remaining = BLOCK_SIZE - (len % BLOCK_SIZE);
|
||||
@ -255,14 +264,18 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
||||
}
|
||||
|
||||
static
|
||||
void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
|
||||
int calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
|
||||
{
|
||||
size_t i, len;
|
||||
ssize_t ret;
|
||||
size_t ce_len = 0;
|
||||
|
||||
t->ndirs++;
|
||||
dir->info.dir->block = t->curblock;
|
||||
len = calc_dir_size(t, dir, &ce_len);
|
||||
ret = calc_dir_size(t, dir, &ce_len);
|
||||
if (ret < 0)
|
||||
return (int) ret;
|
||||
len = ret;
|
||||
t->curblock += DIV_UP(len, BLOCK_SIZE);
|
||||
if (t->opts->rockridge) {
|
||||
t->curblock += DIV_UP(ce_len, BLOCK_SIZE);
|
||||
@ -270,9 +283,12 @@ void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
calc_dir_pos(t, child);
|
||||
ret = calc_dir_pos(t, child);
|
||||
if (ret < 0)
|
||||
return (int) ret;
|
||||
}
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -305,6 +321,7 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
Ecma119Image *target;
|
||||
uint32_t path_table_size;
|
||||
size_t ndirs;
|
||||
int ret;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
@ -315,7 +332,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
/* compute position of directories */
|
||||
iso_msg_debug(target->image->id, "Computing position of dir structure");
|
||||
target->ndirs = 0;
|
||||
calc_dir_pos(target, target->root);
|
||||
ret = calc_dir_pos(target, target->root);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* compute length of pathlist */
|
||||
iso_msg_debug(target->image->id, "Computing length of pathlist");
|
||||
@ -338,7 +357,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
/* Take into respect the second directory tree */
|
||||
ndirs = target->ndirs;
|
||||
target->ndirs = 0;
|
||||
calc_dir_pos(target, target->partition_root);
|
||||
ret = calc_dir_pos(target, target->partition_root);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (target->ndirs != ndirs) {
|
||||
iso_msg_submit(target->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Number of directories differs in ECMA-119 partiton_tree");
|
||||
@ -2737,6 +2758,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
target->filesrc_start = 0;
|
||||
target->filesrc_blocks = 0;
|
||||
|
||||
target->curr_ce_entries = 0;
|
||||
|
||||
target->joliet_ucs2_failures = 0;
|
||||
|
||||
/* If partitions get appended, then the backup GPT cannot be part of
|
||||
@ -3611,6 +3634,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->hfsp_block_size = 0;
|
||||
memset(wopts->gpt_disk_guid, 0, 16);
|
||||
wopts->gpt_disk_guid_mode = 0;
|
||||
wopts->max_ce_entries = 31; /* Linux hates >= RR_MAX_CE_ENTRIES = 32 */
|
||||
wopts->max_ce_drop_attr = 2; /* If needed drop non-isofs fattr and ACL */
|
||||
|
||||
*opts = wopts;
|
||||
return ISO_SUCCESS;
|
||||
@ -4403,6 +4428,17 @@ int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16], int mode)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_max_ce_entries(IsoWriteOpts *opts, uint32_t num,
|
||||
int flag)
|
||||
{
|
||||
if (num > 100000)
|
||||
return ISO_TOO_MANY_CE;
|
||||
if (num == 0)
|
||||
num = 1;
|
||||
opts->max_ce_entries = num;
|
||||
opts->max_ce_drop_attr = flag & 15;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param flag
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2019 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -543,6 +543,17 @@ struct iso_write_opts {
|
||||
*/
|
||||
uint8_t gpt_disk_guid[16];
|
||||
int gpt_disk_guid_mode;
|
||||
|
||||
/* Maximum number of CE entries per file */
|
||||
uint32_t max_ce_entries;
|
||||
/* Whether to try dropping AAIP data on too many CE:
|
||||
bit0-3 = Mode:
|
||||
0 = throw ISO_TOO_MANY_CE, without trying to drop anything
|
||||
1 = drop non-isofs fattr
|
||||
2 = drop ACL if dropping non-isofs fattr does not suffice
|
||||
*/
|
||||
int max_ce_drop_attr;
|
||||
|
||||
};
|
||||
|
||||
typedef struct ecma119_image Ecma119Image;
|
||||
@ -913,6 +924,8 @@ struct ecma119_image
|
||||
uint32_t filesrc_start;
|
||||
uint32_t filesrc_blocks;
|
||||
|
||||
/* Number of CE entries in currently processed node */
|
||||
uint32_t curr_ce_entries;
|
||||
};
|
||||
|
||||
#define BP(a,b) [(b) - (a) + 1]
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||
* Copyright (c) 2009-2022 Thomas Schmitt
|
||||
* Copyright (c) 2009-2023 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
|
||||
@ -2684,6 +2684,39 @@ int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
|
||||
int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16],
|
||||
int mode);
|
||||
|
||||
/**
|
||||
* Set the maximum number of SUSP CE entries and thus continuation areas.
|
||||
* Each continuation area can hold at most 2048 bytes of SUSP data (Rock Ridge
|
||||
* or AAIP). The first area can be smaller. There might be some waste at the
|
||||
* end of each area.
|
||||
* When the maximum number is exceeded during ISO filesystem production
|
||||
* then possibly xattr and ACL get removed or error ISO_TOO_MANY_CE gets
|
||||
* reported and filesystem production is prevented.
|
||||
*
|
||||
* Files with 32 or more CE entries do not show up in mounted filesystems on
|
||||
* Linux. So the default setting is 31 with drop mode 2. If a higher limit is
|
||||
* chosen and 31 gets surpassed, then a warning message gets reported.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param num
|
||||
* The maximum number of CE entries per file.
|
||||
* Not more than 100000 may be set here.
|
||||
* 0 gets silently mapped to 1, because the root directory needs one CE.
|
||||
* @param flag
|
||||
* bit0-bit3 = Drop mode: What to do with AAIP data on too many CE:
|
||||
* 0 = throw ISO_TOO_MANY_CE, without dropping anything
|
||||
* 1 = permanently drop non-isofs fattr from IsoNode and
|
||||
* retry filesystem production
|
||||
* 2 = drop ACL if dropping non-isofs fattr does not suffice
|
||||
* @return
|
||||
* ISO_SUCCESS or ISO_TOO_MANY_CE
|
||||
*
|
||||
* @since 1.5.6
|
||||
*/
|
||||
int iso_write_opts_set_max_ce_entries(IsoWriteOpts *opts, uint32_t num,
|
||||
int flag);
|
||||
|
||||
/**
|
||||
* Generate a pseudo-random GUID suitable for iso_write_opts_set_gpt_guid().
|
||||
*
|
||||
@ -9401,6 +9434,16 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
|
||||
/** Undefined IsoReadImageFeatures name (SORRY, HIGH, -426) */
|
||||
#define ISO_UNDEF_READ_FEATURE 0xE030FE56
|
||||
|
||||
/** Too many CE entries for single file (FAILURE,HIGH, -427) */
|
||||
#define ISO_TOO_MANY_CE 0xE830FE55
|
||||
|
||||
/** Too many CE entries for single file when mounted by Linux
|
||||
(WARNING,HIGH, -428) */
|
||||
#define ISO_TOO_MANY_CE_FOR_LINUX 0xD030FE54
|
||||
|
||||
/** Too many CE entries for single file, omitting attributes
|
||||
(WARNING,HIGH, -429) */
|
||||
#define ISO_CE_REMOVING_ATTR 0xD030FE53
|
||||
|
||||
|
||||
/* Internal developer note:
|
||||
|
@ -350,6 +350,7 @@ iso_write_opts_set_joliet_long_names;
|
||||
iso_write_opts_set_joliet_longer_paths;
|
||||
iso_write_opts_set_joliet_utf16;
|
||||
iso_write_opts_set_max_37_char_filenames;
|
||||
iso_write_opts_set_max_ce_entries;
|
||||
iso_write_opts_set_ms_block;
|
||||
iso_write_opts_set_no_force_dots;
|
||||
iso_write_opts_set_old_empty;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2022 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -567,6 +567,12 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Cannot obtain size of zisofs compressed stream";
|
||||
case ISO_UNDEF_READ_FEATURE:
|
||||
return "Undefined IsoReadImageFeatures name";
|
||||
case ISO_TOO_MANY_CE:
|
||||
return "Too many CE entries for single file";
|
||||
case ISO_TOO_MANY_CE_FOR_LINUX:
|
||||
return "Too many CE entries for single file when mounted by Linux";
|
||||
case ISO_CE_REMOVING_ATTR:
|
||||
return "Too many CE entries for single file, removing attributes";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2020 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -2046,9 +2046,56 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
||||
}
|
||||
ret = 1;
|
||||
ex:;
|
||||
/* Dispose eventual merged list */
|
||||
/* Dispose merged list if it was created */
|
||||
iso_node_merge_xattr(node, num_attrs, names, value_lengths, values,
|
||||
&m_num, &m_names, &m_value_lengths, &m_values, 1 << 15);
|
||||
/* Dispose ACL if saved */
|
||||
iso_node_get_acl_text(node, &a_acl, &d_acl, 1 << 15);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* @param flag
|
||||
bit0= delete ACL, too
|
||||
*/
|
||||
int iso_node_remove_fattr(IsoNode *node, int flag)
|
||||
{
|
||||
int ret;
|
||||
size_t num_attrs, *value_lengths = NULL, i, w;
|
||||
char **names = NULL, **values = NULL;
|
||||
|
||||
ret = iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,
|
||||
flag & 1);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
||||
/* Delete variables of all namespaces except isofs */
|
||||
w = 0;
|
||||
for (i = 0; i < num_attrs; i++) {
|
||||
if (strncmp(names[i], "isofs.", 6) != 0) {
|
||||
free(names[i]);
|
||||
names[i] = NULL;
|
||||
free(values[i]);
|
||||
values[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
if (w != i) {
|
||||
/* move i to w , nullify i */
|
||||
names[w] = names[i];
|
||||
names[i] = NULL;
|
||||
values[w] = values[i];
|
||||
values[i] = NULL;
|
||||
value_lengths[w] = value_lengths[i];
|
||||
}
|
||||
w++;
|
||||
}
|
||||
num_attrs = w;
|
||||
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
|
||||
(flag & 1) | 8);
|
||||
ex:;
|
||||
if (names != NULL)
|
||||
iso_node_get_attrs(NULL, &num_attrs, &names, &value_lengths, &values,
|
||||
1 << 15);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2020 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -422,6 +422,12 @@ int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs,
|
||||
int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
|
||||
size_t *value_length, char **value, int flag);
|
||||
|
||||
/**
|
||||
* Delete variables of all namespaces except isofs
|
||||
*
|
||||
* @param flag bit0= delete ACL, too
|
||||
*/
|
||||
int iso_node_remove_fattr(IsoNode *node, int flag);
|
||||
|
||||
/**
|
||||
* Function to identify and manage ZF parameters which do not stem from ZF
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2022 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -618,13 +618,15 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
|
||||
|
||||
/* @param flag bit1= care about crossing block boundaries */
|
||||
static
|
||||
int susp_calc_add_to_ce(size_t *ce, size_t base_ce, int add, int flag)
|
||||
int susp_calc_add_to_ce(Ecma119Image *t, size_t *ce, size_t base_ce, int add,
|
||||
int flag)
|
||||
{
|
||||
if (flag & 2) {
|
||||
/* Account for inserted CE before size exceeds block size */
|
||||
if ((*ce + base_ce + add + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE !=
|
||||
(*ce + base_ce) / BLOCK_SIZE) {
|
||||
/* Insert CE and padding */
|
||||
t->curr_ce_entries++;
|
||||
*ce += ISO_CE_ENTRY_SIZE;
|
||||
if ((*ce + base_ce) % BLOCK_SIZE)
|
||||
*ce += BLOCK_SIZE - ((*ce + base_ce) % BLOCK_SIZE);
|
||||
@ -658,12 +660,12 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
es_extra = 5;
|
||||
if (*sua_free < num_data + es_extra || *ce_len > 0) {
|
||||
if (es_extra > 0)
|
||||
susp_calc_add_to_ce(ce_len, ce_mem, es_extra, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce_len, ce_mem, es_extra, flag & 2);
|
||||
done = 0;
|
||||
for (aapt = *data; !done; aapt += aapt[2]) {
|
||||
done = !(aapt[4] & 1);
|
||||
len = aapt[2];
|
||||
susp_calc_add_to_ce(ce_len, ce_mem, len, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce_len, ce_mem, len, flag & 2);
|
||||
count += len;
|
||||
}
|
||||
} else {
|
||||
@ -704,7 +706,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
} else {
|
||||
ret = susp_append(t, susp, cpt);
|
||||
}
|
||||
if (ret == -1)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
free(*data);
|
||||
@ -1078,7 +1080,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
|
||||
/* Account for field size */
|
||||
if (*sua_free < 16 || *ce_len > 0) {
|
||||
susp_calc_add_to_ce(ce_len, base_ce, 16, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce_len, base_ce, 16, flag & 2);
|
||||
} else {
|
||||
*sua_free -= 16;
|
||||
}
|
||||
@ -1139,6 +1141,7 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
* <0= error:
|
||||
* -1= not enough SUA space for 28 bytes of CE entry
|
||||
* -2= out of memory
|
||||
* (int) ISO_TOO_MANY_CE
|
||||
*/
|
||||
static
|
||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
@ -1150,17 +1153,20 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
size_t num_aapt = 0, sua_free = 0;
|
||||
int ret;
|
||||
uint8_t *aapt;
|
||||
uint32_t curr_ce_entries_mem;
|
||||
|
||||
#ifdef Libisofs_ce_calc_debug_extrA
|
||||
|
||||
if (n->node->name != NULL)
|
||||
fprintf(stderr, "libburn_DEBUG: susp_calc_nm_sl_al : %.f %s \n",
|
||||
fprintf(stderr, "libburn_DEBUG: susp_calc_nm_sl_al : %u %.f %s \n",
|
||||
(unsigned int) t->curr_ce_entries,
|
||||
(double) base_ce, n->node->name);
|
||||
|
||||
#endif /* Libisofs_ce_calc_debug_extrA */
|
||||
|
||||
su_mem = *su_size;
|
||||
ce_mem = *ce;
|
||||
curr_ce_entries_mem = t->curr_ce_entries;
|
||||
if (*ce > 0 && !(flag & 1))
|
||||
goto unannounced_ca;
|
||||
|
||||
@ -1179,6 +1185,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
if (*su_size + 28 > space)
|
||||
return -1;
|
||||
*su_size += 28;
|
||||
t->curr_ce_entries++;
|
||||
}
|
||||
|
||||
/* NM entry */
|
||||
@ -1196,7 +1203,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
of the name will always fit into the directory entry.)
|
||||
*/;
|
||||
|
||||
susp_calc_add_to_ce(ce, base_ce, 5 + namelen, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce, base_ce, 5 + namelen, flag & 2);
|
||||
*su_size = space;
|
||||
}
|
||||
if (n->type == ECMA119_SYMLINK) {
|
||||
@ -1267,7 +1274,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* and another SL entry
|
||||
*/
|
||||
/* Will fill up old SL and write it */
|
||||
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce, base_ce, 255, flag & 2);
|
||||
sl_len = 5 + (clen - fit); /* Start new SL */
|
||||
} else {
|
||||
/*
|
||||
@ -1276,15 +1283,16 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* anything in this SL
|
||||
*/
|
||||
/* Will write non-full old SL */
|
||||
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce, base_ce, sl_len,
|
||||
flag & 2);
|
||||
/* Will write another full SL */
|
||||
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce, base_ce, 255, flag & 2);
|
||||
sl_len = 5 + (clen - 250) + 2; /* Start new SL */
|
||||
}
|
||||
} else {
|
||||
/* case 2, create a new SL entry */
|
||||
/* Will write non-full old SL */
|
||||
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce, base_ce, sl_len, flag & 2);
|
||||
sl_len = 5 + clen; /* Start new SL */
|
||||
}
|
||||
} else {
|
||||
@ -1307,7 +1315,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 {
|
||||
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||
susp_calc_add_to_ce(t, ce, base_ce, sl_len, flag & 2);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1367,6 +1375,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
/* Crossed a block boundary */
|
||||
*su_size = su_mem;
|
||||
*ce = ce_mem;
|
||||
t->curr_ce_entries = curr_ce_entries_mem;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1376,6 +1385,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
unannounced_ca:;
|
||||
*su_size = su_mem;
|
||||
*ce = ce_mem;
|
||||
t->curr_ce_entries = curr_ce_entries_mem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1422,6 +1432,21 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void iso_msg_too_many_ce(Ecma119Image *t, Ecma119Node *n, int err)
|
||||
{
|
||||
if (n->node->name != NULL) {
|
||||
iso_msg_submit(t->image->id, err, 0,
|
||||
"Too many CE entries for file with name: %s",
|
||||
n->node->name);
|
||||
} else {
|
||||
iso_msg_submit(t->image->id, err, 0,
|
||||
"Too many CE entries for a single file",
|
||||
n->node->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the length needed for write all RR and SUSP entries for a given
|
||||
* node.
|
||||
@ -1438,13 +1463,15 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
* @return
|
||||
* The size needed for the RR entries in the System Use Area
|
||||
*/
|
||||
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
ssize_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
size_t *ce, size_t base_ce)
|
||||
{
|
||||
size_t su_size, space;
|
||||
int ret;
|
||||
int ret, retry = 0;
|
||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||
|
||||
try_again:
|
||||
|
||||
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
|
||||
*/
|
||||
space = 254 - used_up - (used_up % 2);
|
||||
@ -1457,6 +1484,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
|
||||
*ce = 0;
|
||||
su_size = 0;
|
||||
t->curr_ce_entries = 0;
|
||||
|
||||
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10)
|
||||
@ -1506,9 +1534,18 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
if (ret == 0) /* Retry with CE but no block crossing */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 1);
|
||||
if (ret == 0) /* Retry with aligned CE and block hopping */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 1 | 2);
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce,
|
||||
1 | 2);
|
||||
if (ret == -2)
|
||||
return ISO_OUT_OF_MEM;
|
||||
/* -1 should not occur. By tradition it would not cause return */
|
||||
if (ret < -2) {
|
||||
if (n->node->name != NULL)
|
||||
iso_msg_submit(t->image->id, ret, 0,
|
||||
"SUSP planning failed for file with name: %s",
|
||||
n->node->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@ -1524,6 +1561,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
* ER needs a Continuation Area, thus we also need a CE entry
|
||||
*/
|
||||
su_size += 7 + 28; /* SP + CE */
|
||||
t->curr_ce_entries++;
|
||||
/* ER of RRIP */
|
||||
if (t->opts->rrip_version_1_10) {
|
||||
*ce = 237;
|
||||
@ -1546,6 +1584,40 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
}
|
||||
}
|
||||
|
||||
if (t->curr_ce_entries > t->opts->max_ce_entries) {
|
||||
/* If permitted by API setting: Remove non-isofs-non-ACL fattr */
|
||||
retry++;
|
||||
if (retry == 1) {
|
||||
if ((t->opts->max_ce_drop_attr & 15) >= 1) {
|
||||
ret = iso_node_remove_fattr(n->node, 0);
|
||||
if (ret > 0) {
|
||||
iso_msg_too_many_ce(t, n, ISO_CE_REMOVING_ATTR);
|
||||
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
|
||||
"Removed non-isofs attributes");
|
||||
goto try_again;
|
||||
}
|
||||
}
|
||||
} else if (retry == 2) {
|
||||
if ((t->opts->max_ce_drop_attr & 15) >= 2) {
|
||||
ret = iso_node_remove_fattr(n->node, 1);
|
||||
if (ret > 0) {
|
||||
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
|
||||
"Removed ACL");
|
||||
goto try_again;
|
||||
}
|
||||
}
|
||||
}
|
||||
iso_msg_too_many_ce(t, n, ISO_TOO_MANY_CE);
|
||||
return (ssize_t) (int) ISO_TOO_MANY_CE;
|
||||
} else if (t->curr_ce_entries >= 32) {
|
||||
if (n->node->name != NULL)
|
||||
iso_msg_submit(t->image->id, ISO_TOO_MANY_CE_FOR_LINUX, 0,
|
||||
"SUSP planning risky for file with name: %s",
|
||||
n->node->name);
|
||||
iso_msg_submit(t->image->id, ISO_TOO_MANY_CE_FOR_LINUX, 0,
|
||||
"Too many CE entries for single file when mounted by Linux");
|
||||
}
|
||||
|
||||
/*
|
||||
* The System Use field inside the directory record must be padded if
|
||||
* it is an odd number (ECMA-119, 9.1.13)
|
||||
@ -1762,6 +1834,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
/* -1 should not occur. By tradition it would not cause return */
|
||||
if (ret < -2)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
/* NM entry */
|
||||
if (5 + namelen <= sua_free) {
|
||||
@ -2064,6 +2139,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
|
||||
/* Compute length of AAIP string of root node */
|
||||
aaip_sua_free= 0;
|
||||
/* (just to give t->curr_ce_entries a defined state) */
|
||||
t->curr_ce_entries = 0;
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, ce_mem,
|
||||
1 | 2);
|
||||
if (ret < 0)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2020 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2023 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
|
||||
@ -203,7 +203,7 @@ struct susp_sys_user_entry
|
||||
* @return
|
||||
* The size needed for the RR entries in the System Use Area
|
||||
*/
|
||||
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
||||
ssize_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
||||
size_t *ce, size_t base_ce);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user