Transfering inode numbers from PX entries to IsoNode during image import
and using these numbers in PX entries during next image generation. This also answers the concerns about PX without ino in RRIP 1.12 and PX with ino in RRIP 1.10 images produced by mkisofs.
This commit is contained in:
@ -88,6 +88,14 @@ struct iso_read_opts
|
||||
* attribute "isofs.cs" of root directory
|
||||
*/
|
||||
int auto_input_charset;
|
||||
|
||||
/* ts A90425 */
|
||||
/**
|
||||
* Hand out new inode numbers and overwrite eventually read PX inode
|
||||
* numbers. This will split apart any hardlinks.
|
||||
*/
|
||||
int make_new_ino : 1 ;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -137,6 +145,7 @@ enum read_rr_ext {
|
||||
RR_EXT_112 = 2 /*< RR extensions conforming version 1.12 */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private data for the image IsoFilesystem
|
||||
*/
|
||||
@ -264,6 +273,15 @@ typedef struct
|
||||
/* Inode number generator counter */
|
||||
ino_t inode_counter;
|
||||
|
||||
/* ts A90425 */
|
||||
/* PX inode number status
|
||||
bit0= there were nodes with PX inode numbers
|
||||
bit1= there were nodes with PX but without inode numbers
|
||||
bit2= there were nodes without PX
|
||||
bit3= there were nodes with faulty PX
|
||||
*/
|
||||
int px_ino_status;
|
||||
|
||||
} _ImageFsData;
|
||||
|
||||
typedef struct image_fs_data ImageFileSourceData;
|
||||
@ -1070,6 +1088,8 @@ char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
|
||||
}
|
||||
|
||||
|
||||
#ifndef Libisofs_hardlink_prooF
|
||||
|
||||
/**
|
||||
* A global counter for default inode numbers for the ISO image filesystem.
|
||||
* @param fs The filesystem where the number shall be used
|
||||
@ -1087,11 +1107,13 @@ ino_t fs_give_ino_number(IsoImageFilesystem *fs, int flag)
|
||||
if (fsdata->inode_counter == 0) {
|
||||
|
||||
/* >>> raise alert because of inode rollover */;
|
||||
|
||||
|
||||
}
|
||||
return fsdata->inode_counter;
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_hardlink_prooF */
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@ -1135,6 +1157,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
size_t cs_value_length = 0;
|
||||
char msg[160];
|
||||
|
||||
int has_px = 0;
|
||||
|
||||
#ifdef Libisofs_with_zliB
|
||||
uint8_t zisofs_alg[2], zisofs_hs4 = 0, zisofs_bsl2 = 0;
|
||||
uint32_t zisofs_usize = 0;
|
||||
@ -1147,6 +1171,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
fsdata = (_ImageFsData*)fs->data;
|
||||
|
||||
memset(&atts, 0, sizeof(struct stat));
|
||||
atts.st_nlink = 1;
|
||||
|
||||
/*
|
||||
* First of all, check for unsupported ECMA-119 features
|
||||
@ -1275,12 +1300,23 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
continue;
|
||||
|
||||
if (SUSP_SIG(sue, 'P', 'X')) {
|
||||
/* ts A90426 */
|
||||
has_px = 1;
|
||||
ret = read_rr_PX(sue, &atts);
|
||||
if (ret < 0) {
|
||||
/* notify and continue */
|
||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
||||
"Invalid PX entry");
|
||||
fsdata->px_ino_status |= 8;
|
||||
} if (ret == 2) {
|
||||
if (fsdata->inode_counter < atts.st_ino)
|
||||
fsdata->inode_counter = atts.st_ino;
|
||||
fsdata->px_ino_status |= 1;
|
||||
|
||||
} else {
|
||||
fsdata->px_ino_status |= 2;
|
||||
}
|
||||
|
||||
} else if (SUSP_SIG(sue, 'T', 'F')) {
|
||||
ret = read_rr_TF(sue, &atts);
|
||||
if (ret < 0) {
|
||||
@ -1536,6 +1572,11 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
}
|
||||
}
|
||||
|
||||
/* ts A90426 */
|
||||
if (!has_px) {
|
||||
fsdata->px_ino_status |= 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we haven't RR extensions, or no NM entry is present,
|
||||
* we use the name in directory record
|
||||
@ -1596,12 +1637,29 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
/* but the real name is the name of the placeholder */
|
||||
ifsdata = (ImageFileSourceData*) (*src)->data;
|
||||
ifsdata->name = name;
|
||||
|
||||
/* >>> ts A90427 : What about final treatment ?
|
||||
How does directory relocation relate to inode
|
||||
numbers and hard links ?
|
||||
*/
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_hardlink_prooF
|
||||
|
||||
/* ts A90426 :
|
||||
Production of missing inode numbers is delayed until the image is
|
||||
complete. Then all nodes which shall get a new inode number will
|
||||
be served.
|
||||
*/
|
||||
|
||||
#else /* Libisofs_hardlink_prooF */
|
||||
|
||||
#ifdef Libisofs_new_fs_image_inO
|
||||
|
||||
/* >>> ts A90426 : this ifdef shall become a read option */
|
||||
|
||||
if (fsdata->rr != RR_EXT_112) {
|
||||
if (fsdata->rr == 0) {
|
||||
atts.st_nlink = 1;
|
||||
@ -1611,6 +1669,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
|
||||
#else /* Libisofs_new_fs_image_inO */
|
||||
|
||||
|
||||
/* ts Nov 25 2008: TODO
|
||||
This seems not fully consistent with read_rr_PX() which decides
|
||||
by (px->len_sue[0] == 44) whether an inode number is present or not.
|
||||
@ -1642,7 +1701,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
/* Ticket 144: This produces duplicate numbers with empty files.
|
||||
*/
|
||||
atts.st_ino = (ino_t) iso_read_bb(record->block, 4, NULL);
|
||||
#endif
|
||||
#endif /* ! Libisofs_patch_ticket_144 */
|
||||
|
||||
if (fsdata->rr == 0) {
|
||||
atts.st_nlink = 1;
|
||||
}
|
||||
@ -1650,6 +1710,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
|
||||
#endif /* ! Libisofs_new_fs_image_inO */
|
||||
|
||||
#endif /* ! Libisofs_hardlink_prooF */
|
||||
|
||||
/*
|
||||
* if we haven't RR extensions, or a needed TF time stamp is not present,
|
||||
* we use plain iso recording time
|
||||
@ -1974,7 +2036,6 @@ void ifs_fs_free(IsoFilesystem *fs)
|
||||
free(data->copyright_file_id);
|
||||
free(data->abstract_file_id);
|
||||
free(data->biblio_file_id);
|
||||
|
||||
free(data->input_charset);
|
||||
free(data->local_charset);
|
||||
free(data);
|
||||
@ -2273,6 +2334,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
data->msgid = msgid;
|
||||
data->aaip_load = !opts->noaaip;
|
||||
data->aaip_version = -1;
|
||||
data->inode_counter = 0;
|
||||
data->px_ino_status = 0;
|
||||
|
||||
#ifndef Libisofs_setlocale_in_iniT
|
||||
/* ??? ts Nov 25 2008 :
|
||||
@ -2718,15 +2781,35 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
|
||||
ret = src_aa_to_node(src, new, 0);
|
||||
if (ret < 0) {
|
||||
/* todo: stuff any possible memory leak here */
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
free(new);
|
||||
return ret;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_hardlink_prooF
|
||||
|
||||
/* ts A90428 */
|
||||
/* Attach ino as xinfo if valid and no IsoStream is involved */
|
||||
if (info.st_ino != 0 && (info.st_mode & S_IFMT) != S_IFREG
|
||||
&& (info.st_mode & S_IFMT) != S_IFDIR) {
|
||||
|
||||
/* >>> ??? is there any sense in equipping directories with
|
||||
persistent inode numbers ? */
|
||||
|
||||
ret = iso_node_set_ino(new, info.st_ino, 0);
|
||||
if (ret < 0)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_hardlink_prooF */
|
||||
|
||||
*node = new;
|
||||
return ISO_SUCCESS;
|
||||
|
||||
failure:;
|
||||
/* todo: stuff any possible memory leak here */
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
free(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2763,7 +2846,8 @@ int iso_image_builder_new(IsoNodeBuilder *old, IsoNodeBuilder **builder)
|
||||
* accessible from the ISO filesystem.
|
||||
*/
|
||||
static
|
||||
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src)
|
||||
int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoImage *image,
|
||||
IsoFileSource **src)
|
||||
{
|
||||
int ret;
|
||||
struct stat atts;
|
||||
@ -2780,18 +2864,25 @@ int create_boot_img_filesrc(IsoImageFilesystem *fs, IsoFileSource **src)
|
||||
memset(&atts, 0, sizeof(struct stat));
|
||||
atts.st_mode = S_IFREG;
|
||||
|
||||
#ifdef Libisofs_hardlink_prooF
|
||||
|
||||
/* ts A90427 : img_give_ino_number() is coordinated with existing inos */
|
||||
atts.st_ino = img_give_ino_number(image, 0);
|
||||
|
||||
#else /* Libisofs_hardlink_prooF */
|
||||
|
||||
#ifdef Libisofs_new_fs_image_inO
|
||||
|
||||
atts.st_ino = fs_give_ino_number(fs, 0);
|
||||
|
||||
#else /* Libisofs_new_fs_image_inO */
|
||||
|
||||
/* ts A90426 : >>> need a unique inode for El-Torito boot image */
|
||||
|
||||
atts.st_ino = fsdata->imgblock; /* not the best solution, but... */
|
||||
|
||||
#endif /* ! Libisofs_new_fs_image_inO */
|
||||
|
||||
#endif /* ! Libisofs_hardlink_prooF */
|
||||
|
||||
atts.st_nlink = 1;
|
||||
|
||||
/*
|
||||
@ -2953,12 +3044,40 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
goto import_revert;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_hardlink_prooF
|
||||
|
||||
/* ts A90428 */
|
||||
/* Take over inode management from IsoImageFilesystem.
|
||||
data->inode_counter is supposed to hold the maximum PX inode number.
|
||||
*/
|
||||
image->inode_counter = data->inode_counter;
|
||||
|
||||
/* ts A90426 */
|
||||
if ((data->px_ino_status & (2 | 4 | 8)) || opts->make_new_ino) {
|
||||
|
||||
/* >>> ??? is there any benefit with stable ino for directories ?
|
||||
if so: add 4 to img_make_inos(flag)
|
||||
*/
|
||||
ret = img_make_inos(image, image->root, 8 | 2 | !!opts->make_new_ino);
|
||||
if (ret < 0) {
|
||||
iso_node_builder_unref(image->builder);
|
||||
goto import_revert;
|
||||
}
|
||||
|
||||
/* <<< debugging */
|
||||
} else {
|
||||
/* <<< just for the duplicate inode check */
|
||||
img_collect_inos(image, image->root, 0);
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_hardlink_prooF */
|
||||
|
||||
if (data->eltorito) {
|
||||
/* if catalog and image nodes were not filled, we create them here */
|
||||
if (image->bootcat->image->image == NULL) {
|
||||
IsoFileSource *src;
|
||||
IsoNode *node;
|
||||
ret = create_boot_img_filesrc(fs, &src);
|
||||
ret = create_boot_img_filesrc(fs, image, &src);
|
||||
if (ret < 0) {
|
||||
iso_node_builder_unref(image->builder);
|
||||
goto import_revert;
|
||||
|
Reference in New Issue
Block a user