diff --git a/libisofs/fs_image.c b/libisofs/fs_image.c index cf15ae4..9dc9a6a 100644 --- a/libisofs/fs_image.c +++ b/libisofs/fs_image.c @@ -6298,25 +6298,46 @@ int iso_file_get_old_image_sections(IsoFile *file, int *section_count, /* Rank two IsoFileSource by their eventual old image LBAs. Other IsoFileSource classes will be ranked only roughly. */ -int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag) +int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret, + int flag) { int i; ImageFileSourceData *d1, *d2; - if (s1->class != s2->class) - return (s1->class < s2->class ? -1 : 1); - if (s1->class != &ifs_class) - return(0); - - d1= s1->data; - d2= s2->data; - for (i = 0; i < d1->nsections; i++) { - if (i >= d2->nsections) - return 1; - if (d1->sections[i].block != d2->sections[i].block) - return (d1->sections[i].block < d2->sections[i].block ? -1 : 1); - if (d1->sections[i].size != d2->sections[i].size) - return (d1->sections[i].size < d2->sections[i].size ? -1 : 1); + if (s1->class != s2->class) { + *cmp_ret = (s1->class < s2->class ? -1 : 1); + return 0; } - return(0); + if (s1->class != &ifs_class) { + *cmp_ret = 0; + return 0; + } + + d1 = s1->data; + d2 = s2->data; + if (d1->nsections < 1) + return 0; + if (d1->sections[0].size < 1) + return 0; + for (i = 0; i < d1->nsections; i++) { + if (i >= d2->nsections) { + *cmp_ret = 1; + return 1; + } + if (d1->sections[i].block != d2->sections[i].block) { + *cmp_ret = (d1->sections[i].block < d2->sections[i].block ? -1 : 1); + return 1; + } + if (d1->sections[i].size != d2->sections[i].size) { + *cmp_ret = (d1->sections[i].size < d2->sections[i].size ? -1 : 1); + return 1; + } + } + if (i < d2->nsections) { + *cmp_ret = -1; + return 1; + } + *cmp_ret = 0; + return 1; } + diff --git a/libisofs/fsource.h b/libisofs/fsource.h index 1640c90..dfb6a45 100644 --- a/libisofs/fsource.h +++ b/libisofs/fsource.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2009 - 2011 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 @@ -34,9 +34,13 @@ int iso_local_filesystem_new(IsoFilesystem **fs); /* Rank two IsoFileSource of ifs_class by their eventual old image LBAs. - Other IsoFileSource classes will be ranked only roughly. + * @param cmp_ret will return the reply value -1, 0, or 1. + * @return 1= *cmp_ret is a valid reply + * 0= not both streams are of ifs_class, + * *cmp_ret is only a rough estimation. */ -int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag); +int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret, + int flag); /* Create an independent copy of an ifs_class IsoFileSource. diff --git a/libisofs/stream.c b/libisofs/stream.c index d450393..0bd67ed 100644 --- a/libisofs/stream.c +++ b/libisofs/stream.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * Copyright (c) 2009 - 2011 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 @@ -957,6 +957,23 @@ int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag) return 0; } +int iso_stream_cmp_ifs_sections(IsoStream *s1, IsoStream *s2, int *cmp_ret, + int flag) +{ + int ret; + FSrcStreamData *fssd1, *fssd2; + + if (s1->class != &fsrc_stream_class || s2->class != &fsrc_stream_class) + return 0; + /* Compare eventual image data section LBA and sizes */ + fssd1= (FSrcStreamData *) s1->data; + fssd2= (FSrcStreamData *) s2->data; + ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, cmp_ret, 0); + if (ret <= 0) + return 0; + return 1; +} + /* API */ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag) { @@ -965,8 +982,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag) dev_t dev_id1, dev_id2; ino_t ino_id1, ino_id2; off_t size1, size2; - FSrcStreamData *fssd1, *fssd2; - /* #define Libisofs_stream_cmp_ino_debuG 1 @@ -983,6 +998,9 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag) if (s2 == NULL) return 1; + if (iso_stream_cmp_ifs_sections(s1, s2, &ret, 0) > 0) + return ret; /* Both are unfiltered from loaded ISO filesystem */ + if (s1->class->version >= 3 && !(flag & 1)) { /* Filters may have smarter methods to compare themselves with others */ ret = s1->class->cmp_ino(s1, s2); @@ -1042,14 +1060,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag) if (s1->class != s2->class) return (s1->class < s2->class ? -1 : 1); - if (s1->class == &fsrc_stream_class) { - /* Compare eventual image data section LBA and sizes */ - fssd1= (FSrcStreamData *) s1->data; - fssd2= (FSrcStreamData *) s2->data; - ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, 0); - if (ret != 0) - return ret; - } if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0) { return (s1 < s2 ? -1 : 1); }