diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-12-14 19:33:35 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-12-14 19:33:35 -0500 |
commit | 042f3cd5bd362ae05c11591810321a6fd9d5c784 (patch) | |
tree | 36c6f43b6981d25cafe5bec5b91c39d51d7a7839 | |
parent | 1b0d29df12b0bd50132c9c26fda53949ce60a2ae (diff) |
mkfs.jffs2.c: detect hardlinks
... with the stupidest possible algorithm for storing them and looking
them up. Optimising that is simple enough, but left as an exercise for
the user. This is userspace, after all. It's not as if I care.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | mkfs.jffs2.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/mkfs.jffs2.c b/mkfs.jffs2.c index b28f741..087f8bd 100644 --- a/mkfs.jffs2.c +++ b/mkfs.jffs2.c @@ -96,8 +96,10 @@ struct filesystem_entry { struct filesystem_entry *prev; /* Only relevant to non-directories */ struct filesystem_entry *next; /* Only relevant to non-directories */ struct filesystem_entry *files; /* Only relevant to directories */ + struct filesystem_entry *hardlink_next; }; +struct filesystem_entry *hardlinks = NULL; static int out_fd = -1; static int in_fd = -1; static char default_rootdir[] = "."; @@ -110,6 +112,24 @@ int target_endian = __BYTE_ORDER; static const char *const app_name = "mkfs.jffs2"; static const char *const memory_exhausted = "memory exhausted"; +uint32_t find_hardlink(struct filesystem_entry *e) +{ + struct filesystem_entry *f; + + for (f = hardlinks; f; f = f->hardlink_next) { + if (f->sb.st_dev == e->sb.st_dev && + f->sb.st_ino == e->sb.st_ino) { + return f->ino; + } + } + + /* Add it to the list for later */ + e->hardlink_next = hardlinks; + hardlinks = e; + + return 0; +} + static void verror_msg(const char *s, va_list p) { fflush(stdout); @@ -331,6 +351,10 @@ static struct filesystem_entry *add_host_filesystem_entry( tmp = xstrdup(name); entry->path = xstrdup(dirname(tmp)); free(tmp); + + entry->sb.st_ino = sb.st_ino; + entry->sb.st_dev = sb.st_dev; + entry->sb.st_nlink = sb.st_nlink; entry->sb.st_uid = uid; entry->sb.st_gid = gid; @@ -1278,8 +1302,17 @@ static void recursive_populate_directory(struct filesystem_entry *dir) e = dir->files; while (e) { - - switch (e->sb.st_mode & S_IFMT) { + if (e->sb.st_nlink >= 1 && + (e->ino = find_hardlink(e))) { + + write_dirent(e); + if (verbose) { + printf("\tL %04o %9lu %5d:%-3d %s\n", + e->sb.st_mode & ~S_IFMT, (unsigned long) e->ino, + (int) (e->sb.st_uid), (int) (e->sb.st_gid), + e->name); + } + } else switch (e->sb.st_mode & S_IFMT) { case S_IFDIR: if (verbose) { printf("\td %04o %9lu %5d:%-3d %s\n", |