#define NAME_TABLE_SIZE 4096
-static name_ent_t **nametable;
-
-static int
-create_nametable(void)
-{
- nametable = calloc(NAME_TABLE_SIZE, sizeof(name_ent_t));
- return nametable != NULL;
-}
+static struct name_ent *nametable[NAME_TABLE_SIZE];
static void
-clear_nametable(void)
+nametable_clear(void)
{
- int i;
- name_ent_t *p;
+ int i;
+ name_ent_t *ent;
for (i = 0; i < NAME_TABLE_SIZE; i++) {
- while (nametable[i]) {
- p = nametable[i];
- nametable[i] = p->next;
- free(p);
+ while ((ent = nametable[i])) {
+ nametable[i] = ent->next;
+ free(ent);
}
}
}
+/*
+ * See if the given name is already in the name table. If so,
+ * return a pointer to its entry, otherwise return a null pointer.
+ */
+static struct name_ent *
+nametable_find(xfs_dahash_t hash, int namelen, uchar_t *name)
+{
+ struct name_ent *ent;
+
+ for (ent = nametable[hash % NAME_TABLE_SIZE]; ent; ent = ent->next) {
+ if (ent->hash == hash && ent->namelen == namelen &&
+ !memcmp(ent->name, name, namelen))
+ return ent;
+ }
+ return NULL;
+}
+
+/*
+ * Add the given name to the name table. Returns a pointer to the
+ * name's new entry, or a null pointer if an error occurs.
+ */
+static struct name_ent *
+nametable_add(xfs_dahash_t hash, int namelen, uchar_t *name)
+{
+ struct name_ent *ent;
+
+ ent = malloc(sizeof *ent + namelen);
+ if (!ent)
+ return NULL;
+
+ ent->namelen = namelen;
+ memcpy(ent->name, name, namelen);
+ ent->hash = hash;
+ ent->next = nametable[hash % NAME_TABLE_SIZE];
+
+ nametable[hash % NAME_TABLE_SIZE] = ent;
+
+ return ent;
+}
#define is_invalid_char(c) ((c) == '/' || (c) == '\0')
#define rol32(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
uchar_t *name)
{
xfs_dahash_t hash;
- name_ent_t *p;
int dup = 0;
uchar_t newname[NAME_MAX];
uchar_t *newp;
* Search the name table to be sure we don't produce
* a name that's already been used.
*/
- for (p = nametable[hash % NAME_TABLE_SIZE]; p; p = p->next) {
- if (p->hash == hash && p->namelen == namelen &&
- !memcmp(p->name, newname, namelen)) {
- dup++;
- break;
- }
- }
- } while (dup && dup < DUP_MAX);
+ if (!nametable_find(hash, namelen, newname))
+ break;
+ } while (++dup < DUP_MAX);
/*
- * Update the caller's copy with the obfuscated name. Use
- * the original name if we got too many duplicates--and if
- * so, issue a warning.
+ * Update the caller's copy with the obfuscated name.
+ *
+ * If we couldn't come up with one, just use the original
+ * name without obfuscation. Issue a warning if we managed
+ * to previously create an obfuscated name that matches the
+ * one we're working on now.
*/
if (dup < DUP_MAX)
memcpy(name, newname, namelen);
- else
+ else if (nametable_find(hash, namelen, name))
print_warning("duplicate name for inode %llu "
"in dir inode %llu\n",
(unsigned long long) ino,
(unsigned long long) cur_ino);
- /* Create an entry for the name in the name table */
-
- p = malloc(sizeof(name_ent_t) + namelen);
- if (p == NULL)
- return;
-
- p->namelen = namelen;
- memcpy(p->name, name, namelen);
- p->hash = hash;
- p->next = nametable[hash % NAME_TABLE_SIZE];
-
- nametable[hash % NAME_TABLE_SIZE] = p;
+ /*
+ * Create an entry for the name in the name table. Use the
+ * original name if we got too many dups.
+ */
+ if (!nametable_add(hash, namelen, name))
+ print_warning("unable to record name for inode %llu "
+ "in dir inode %llu\n",
+ (unsigned long long) ino,
+ (unsigned long long) cur_ino);
}
static void
break;
default: ;
}
- clear_nametable();
+ nametable_clear();
/* copy extended attributes if they exist and forkoff is valid */
if (success && XFS_DFORK_DSIZE(dip, mp) < XFS_LITINO(mp)) {
success = process_btinode(dip, TYP_ATTR);
break;
}
- clear_nametable();
+ nametable_clear();
}
return success;
}
metablock->mb_blocklog = BBSHIFT;
metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
- if (!create_nametable()) {
- print_warning("memory allocation failure");
- free(metablock);
- return 0;
- }
-
block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t));
block_buffer = (char *)metablock + BBSIZE;
num_indicies = (BBSIZE - sizeof(xfs_metablock_t)) / sizeof(__be64);
if (strcmp(argv[optind], "-") == 0) {
if (isatty(fileno(stdout))) {
print_warning("cannot write to a terminal");
- free(nametable);
free(metablock);
return 0;
}
outf = fopen(argv[optind], "wb");
if (outf == NULL) {
print_warning("cannot create dump file");
- free(nametable);
free(metablock);
return 0;
}
while (iocur_sp > start_iocur_sp)
pop_cur();
- free(nametable);
free(metablock);
return 0;