aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-14 19:33:35 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2007-12-14 19:33:35 -0500
commit042f3cd5bd362ae05c11591810321a6fd9d5c784 (patch)
tree36c6f43b6981d25cafe5bec5b91c39d51d7a7839
parent1b0d29df12b0bd50132c9c26fda53949ce60a2ae (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.c37
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",