summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukem <lukem@NetBSD.org>2001-12-05 11:08:53 +0000
committerlukem <lukem@NetBSD.org>2001-12-05 11:08:53 +0000
commitebbf3dddb5a6bf5c07e5498e90c7afed7f56b8ea (patch)
tree4de1352ea6e370d3259b2505d9a428d5f1ba60db
parent20a3ef2b53d6d281b55408eebba0a05127cd597d (diff)
rework `fsnode' into two components; `fsnode' contains the name and tree
information and a link to the appropriate fsinode, and `fsinode' contains the inode information and a reference count. multiple fsnodes may point to the same fsinode. this replaces the 'dup' pointer in the previous code.
-rw-r--r--usr.sbin/makefs/ffs.c79
-rw-r--r--usr.sbin/makefs/makefs.c6
-rw-r--r--usr.sbin/makefs/makefs.h39
-rw-r--r--usr.sbin/makefs/walk.c136
4 files changed, 140 insertions, 120 deletions
diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c
index 07b6bcdb21b..7e070275c19 100644
--- a/usr.sbin/makefs/ffs.c
+++ b/usr.sbin/makefs/ffs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs.c,v 1.4 2001/11/22 02:47:26 lukem Exp $ */
+/* $NetBSD: ffs.c,v 1.5 2001/12/05 11:08:53 lukem Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -71,7 +71,7 @@
#include <sys/cdefs.h>
#ifndef __lint
-__RCSID("$NetBSD: ffs.c,v 1.4 2001/11/22 02:47:26 lukem Exp $");
+__RCSID("$NetBSD: ffs.c,v 1.5 2001/12/05 11:08:53 lukem Exp $");
#endif /* !__lint */
#include <sys/param.h>
@@ -518,14 +518,16 @@ ffs_size_dir(fsnode *root, fsinfo_t *fsopts)
assert(strcmp(node->name, ".") == 0);
ADDDIRENT("..");
}
- if (node->dup == NULL) { /* don't count duplicate names */
+ if ((node->inode->flags & FI_SIZED) == 0) {
+ /* don't count duplicate names */
+ node->inode->flags |= FI_SIZED;
if (debug & DEBUG_FS_SIZE_DIR_NODE)
printf("ffs_size_dir: %s size %lld\n",
node->name,
- (long long)node->statbuf.st_size);
+ (long long)node->inode->st.st_size);
fsopts->inodes++;
if (node->type == S_IFREG)
- ADDSIZE(node->statbuf.st_size);
+ ADDSIZE(node->inode->st.st_size);
if (node->type == S_IFLNK) {
int slen;
@@ -567,23 +569,23 @@ ffs_populate_dir(const char *dir, fsnode *root, fsinfo_t *fsopts)
* pass 1: allocate inode numbers, build directory `file'
*/
for (cur = root; cur != NULL; cur = cur->next) {
- if (cur->dup == NULL) {
- if (cur == root && cur->parent)
- cur->ino = cur->parent->ino;
+ if ((cur->inode->flags & FI_ALLOCATED) == 0) {
+ cur->inode->flags |= FI_ALLOCATED;
+ if (cur == root && cur->parent != NULL)
+ cur->inode->ino = cur->parent->inode->ino;
else {
- cur->ino = fsopts->curinode;
+ cur->inode->ino = fsopts->curinode;
fsopts->curinode++;
}
- } else
- cur->ino = cur->dup->ino;
+ }
ffs_make_dirbuf(&dirbuf, cur->name, cur, fsopts->needswap);
if (cur == root) { /* we're at "."; add ".." */
ffs_make_dirbuf(&dirbuf, "..",
cur->parent == NULL ? cur : cur->parent->first,
fsopts->needswap);
- root->nlink++; /* count my parent's link */
+ root->inode->nlink++; /* count my parent's link */
} else if (cur->child != NULL)
- root->nlink++; /* count my child's link */
+ root->inode->nlink++; /* count my child's link */
/*
* XXX possibly write file and long symlinks here,
@@ -601,8 +603,9 @@ ffs_populate_dir(const char *dir, fsnode *root, fsinfo_t *fsopts)
if (debug & DEBUG_FS_POPULATE)
printf("ffs_populate_dir: PASS 2 dir %s\n", dir);
for (cur = root; cur != NULL; cur = cur->next) {
- if (cur->dup != NULL)
+ if (cur->inode->flags & FI_WRITTEN)
continue; /* skip hard-linked entries */
+ cur->inode->flags |= FI_WRITTEN;
if (snprintf(path, sizeof(path), "%s/%s", dir, cur->name)
>= sizeof(path))
@@ -613,19 +616,19 @@ ffs_populate_dir(const char *dir, fsnode *root, fsinfo_t *fsopts)
/* build on-disk inode */
memset(&din, 0, sizeof(din));
- din.di_mode = cur->statbuf.st_mode;
- din.di_nlink = cur->nlink;
- din.di_size = cur->statbuf.st_size;
- din.di_atime = cur->statbuf.st_atime;
- din.di_atimensec = cur->statbuf.st_atimensec;
- din.di_mtime = cur->statbuf.st_mtime;
- din.di_mtimensec = cur->statbuf.st_mtimensec;
- din.di_ctime = cur->statbuf.st_ctime;
- din.di_ctimensec = cur->statbuf.st_ctimensec;
- din.di_flags = cur->statbuf.st_flags;
- din.di_gen = cur->statbuf.st_gen;
- din.di_uid = cur->statbuf.st_uid;
- din.di_gid = cur->statbuf.st_gid;
+ din.di_mode = cur->inode->st.st_mode;
+ din.di_nlink = cur->inode->nlink;
+ din.di_size = cur->inode->st.st_size;
+ din.di_atime = cur->inode->st.st_atime;
+ din.di_atimensec = cur->inode->st.st_atimensec;
+ din.di_mtime = cur->inode->st.st_mtime;
+ din.di_mtimensec = cur->inode->st.st_mtimensec;
+ din.di_ctime = cur->inode->st.st_ctime;
+ din.di_ctimensec = cur->inode->st.st_ctimensec;
+ din.di_flags = cur->inode->st.st_flags;
+ din.di_gen = cur->inode->st.st_gen;
+ din.di_uid = cur->inode->st.st_uid;
+ din.di_gid = cur->inode->st.st_gid;
/* not set: di_db, di_ib, di_blocks, di_spare */
membuf = NULL;
@@ -635,7 +638,7 @@ ffs_populate_dir(const char *dir, fsnode *root, fsinfo_t *fsopts)
} else if (S_ISBLK(cur->type) || S_ISCHR(cur->type)) {
din.di_size = 0; /* a device */
din.di_rdev =
- ufs_rw32(cur->statbuf.st_rdev, fsopts->needswap);
+ ufs_rw32(cur->inode->st.st_rdev, fsopts->needswap);
} else if (S_ISLNK(cur->type)) { /* symlink */
int slen;
@@ -649,19 +652,19 @@ ffs_populate_dir(const char *dir, fsnode *root, fsinfo_t *fsopts)
if (debug & DEBUG_FS_POPULATE_NODE) {
printf("ffs_populate_dir: writing ino %d, %s",
- cur->ino, inode_type(cur->type));
- if (cur->nlink > 1)
- printf(", nlink %d", cur->nlink);
+ cur->inode->ino, inode_type(cur->type));
+ if (cur->inode->nlink > 1)
+ printf(", nlink %d", cur->inode->nlink);
putchar('\n');
}
if (membuf != NULL) {
- ffs_write_file(&din, cur->ino, membuf, fsopts);
+ ffs_write_file(&din, cur->inode->ino, membuf, fsopts);
} else if (S_ISREG(cur->type)) {
- ffs_write_file(&din, cur->ino, path, fsopts);
+ ffs_write_file(&din, cur->inode->ino, path, fsopts);
} else {
assert (! S_ISDIR(cur->type));
- ffs_write_inode(&din, cur->ino, fsopts);
+ ffs_write_inode(&din, cur->inode->ino, fsopts);
}
}
@@ -788,7 +791,7 @@ ffs_dump_dirbuf(dirbuf_t *dbuf, const char *dir, int needswap)
{
doff_t i;
struct direct *de;
- u_int16_t reclen;
+ uint16_t reclen;
assert (dbuf != NULL);
assert (dir != NULL);
@@ -812,16 +815,16 @@ static void
ffs_make_dirbuf(dirbuf_t *dbuf, const char *name, fsnode *node, int needswap)
{
struct direct de, *dp;
- u_int16_t llen, reclen;
+ uint16_t llen, reclen;
assert (dbuf != NULL);
assert (name != NULL);
assert (node != NULL);
/* create direct entry */
(void)memset(&de, 0, sizeof(de));
- de.d_ino = ufs_rw32(node->ino, needswap);
+ de.d_ino = ufs_rw32(node->inode->ino, needswap);
de.d_type = IFTODT(node->type);
- de.d_namlen = (u_int8_t)strlen(name);
+ de.d_namlen = (uint8_t)strlen(name);
assert (de.d_namlen < (sizeof(de.d_name)));
strcpy(de.d_name, name);
reclen = DIRSIZ(0, &de, needswap);
diff --git a/usr.sbin/makefs/makefs.c b/usr.sbin/makefs/makefs.c
index fb02c3510c1..34257fa0212 100644
--- a/usr.sbin/makefs/makefs.c
+++ b/usr.sbin/makefs/makefs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: makefs.c,v 1.6 2001/11/25 11:22:09 lukem Exp $ */
+/* $NetBSD: makefs.c,v 1.7 2001/12/05 11:08:53 lukem Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#ifndef __lint
-__RCSID("$NetBSD: makefs.c,v 1.6 2001/11/25 11:22:09 lukem Exp $");
+__RCSID("$NetBSD: makefs.c,v 1.7 2001/12/05 11:08:53 lukem Exp $");
#endif /* !__lint */
#include <assert.h>
@@ -69,7 +69,7 @@ static fstype_t fstypes[] = {
{ NULL },
};
-u_int debug;
+uint debug;
struct timespec start_time;
diff --git a/usr.sbin/makefs/makefs.h b/usr.sbin/makefs/makefs.h
index f49188ecaac..1fd85e30d3f 100644
--- a/usr.sbin/makefs/makefs.h
+++ b/usr.sbin/makefs/makefs.h
@@ -1,4 +1,4 @@
-/* $NetBSD: makefs.h,v 1.3 2001/11/25 11:22:09 lukem Exp $ */
+/* $NetBSD: makefs.h,v 1.4 2001/12/05 11:08:53 lukem Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -39,10 +39,15 @@
/*
- * fsnode - a component of the tree which contains information about the
- * file system.
+ * fsnode -
+ * a component of the tree; contains a filename, a pointer to
+ * fsinode, optional symlink name, and tree pointers
*
- * A tree of these looks like this:
+ * fsinode -
+ * equivalent to an inode, containing target file system inode number,
+ * refcount (nlink), and stat buffer
+ *
+ * A tree of fsnodes looks like this:
*
* name "." "bin" "netbsd"
* type S_IFDIR S_IFDIR S_IFREG
@@ -61,22 +66,32 @@
* must be "." when the tree has been built; during build it may
* not be if "." hasn't yet been found by readdir(2).
*
- * - if dup is not NULL, it points to an fsnode that this is a
+ * - if dup is not NULL, it points to an fsent that this is a
* duplicate of; only relevant for non directories with > 1 link
*/
+
+enum fi_flags {
+ FI_SIZED = 1<<0, /* inode sized */
+ FI_ALLOCATED = 1<<1, /* fsinode->ino allocated */
+ FI_WRITTEN = 1<<2, /* inode written */
+};
+
+typedef struct {
+ uint32_t ino; /* inode number used on target fs */
+ uint32_t nlink; /* number of links to this entry */
+ enum fi_flags flags; /* flags used by fs specific code */
+ struct stat st; /* stat entry */
+} fsinode;
+
typedef struct _fsnode {
struct _fsnode *parent; /* parent (NULL if root) */
struct _fsnode *child; /* child (if type == S_IFDIR) */
struct _fsnode *next; /* next */
struct _fsnode *first; /* first node of current level (".") */
- struct stat statbuf; /* stat entry */
+ uint32_t type; /* type of entry */
+ fsinode *inode; /* actual inode data */
char *symlink; /* symlink target */
char *name; /* file name */
- struct _fsnode *dup; /* entry this is a duplicate of
- (when statbuf.st_nlink > 1) */
- uint32_t nlink; /* number of links to this entry */
- uint32_t type; /* type of entry */
- uint32_t ino; /* inode number used on target fs */
} fsnode;
@@ -151,7 +166,7 @@ void ffs_makefs(const char *, const char *, fsnode *, fsinfo_t *);
-extern u_int debug;
+extern uint debug;
extern struct timespec start_time;
#define DEBUG_TIME 0x00000001
diff --git a/usr.sbin/makefs/walk.c b/usr.sbin/makefs/walk.c
index 8fde263e6a1..1fc0d4aad23 100644
--- a/usr.sbin/makefs/walk.c
+++ b/usr.sbin/makefs/walk.c
@@ -1,4 +1,4 @@
-/* $NetBSD: walk.c,v 1.5 2001/11/02 03:12:48 lukem Exp $ */
+/* $NetBSD: walk.c,v 1.6 2001/12/05 11:08:53 lukem Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -77,7 +77,7 @@
#include <sys/cdefs.h>
#ifndef __lint
-__RCSID("$NetBSD: walk.c,v 1.5 2001/11/02 03:12:48 lukem Exp $");
+__RCSID("$NetBSD: walk.c,v 1.6 2001/12/05 11:08:53 lukem Exp $");
#endif /* !__lint */
#include <sys/param.h>
@@ -98,7 +98,8 @@ __RCSID("$NetBSD: walk.c,v 1.5 2001/11/02 03:12:48 lukem Exp $");
static void apply_specdir(const char *, NODE *, fsnode *);
static void apply_specentry(const char *, NODE *, fsnode *);
static fsnode *create_fsnode(const char *, struct stat *);
-static fsnode *link_check(fsnode *);
+static fsinode *create_fsinode(struct stat *);
+static fsinode *link_check(fsinode *);
/*
@@ -141,6 +142,7 @@ walk_dir(const char *dir, fsnode *parent)
}
cur = create_fsnode(dent->d_name, &stbuf);
+ cur->inode = create_fsinode(&stbuf);
cur->parent = parent;
if (strcmp(dent->d_name, ".") == 0) {
/* ensure "." is at the start of the list */
@@ -159,10 +161,15 @@ walk_dir(const char *dir, fsnode *parent)
continue;
}
}
- if (cur->statbuf.st_nlink > 1) {
- cur->dup = link_check(cur);
- if (cur->dup)
- cur->dup->nlink++;
+ if (stbuf.st_nlink > 1) {
+ fsinode *curino;
+
+ curino = link_check(cur->inode);
+ if (curino != NULL) {
+ free(cur->inode);
+ cur->inode = curino;
+ cur->inode->nlink++;
+ }
}
if (S_ISLNK(cur->type)) {
char slink[PATH_MAX+1];
@@ -184,19 +191,28 @@ walk_dir(const char *dir, fsnode *parent)
}
static fsnode *
-create_fsnode(const char *name, struct stat *statbuf)
+create_fsnode(const char *name, struct stat *stbuf)
{
fsnode *cur;
if ((cur = calloc(1, sizeof(fsnode))) == NULL ||
(cur->name = strdup(name)) == NULL)
err(1, "Memory allocation error");
- cur->statbuf = *statbuf;
- cur->type = (cur->statbuf.st_mode & S_IFMT);
- cur->nlink = 1;
+ cur->type = stbuf->st_mode & S_IFMT;
return (cur);
}
+static fsinode *
+create_fsinode(struct stat *statbuf)
+{
+ fsinode *cur;
+
+ if ((cur = calloc(1, sizeof(fsinode))) == NULL)
+ err(1, "Memory allocation error");
+ cur->nlink = 1;
+ cur->st = *statbuf;
+ return (cur);
+}
/*
* apply_specfile --
@@ -301,6 +317,7 @@ apply_specdir(const char *dir, NODE *specnode, fsnode *dirnode)
/* build minimal fsnode */
memset(&stbuf, 0, sizeof(stbuf));
stbuf.st_mode = nodetoino(curnode->type);
+ stbuf.st_nlink = 1;
stbuf.st_mtime = stbuf.st_atime =
stbuf.st_ctime = start_time.tv_sec;
stbuf.st_mtimensec = stbuf.st_atimensec =
@@ -353,16 +370,6 @@ apply_specentry(const char *dir, NODE *specnode, fsnode *dirnode)
if (debug & DEBUG_APPLY_SPECENTRY)
printf("apply_specentry: %s/%s\n", dir, dirnode->name);
- /*
- * if this is a duplicate (i.e, an existing hardlink),
- * change the actual settings.
- */
- if (dirnode->dup != NULL) {
- if (debug & DEBUG_APPLY_SPECENTRY)
- printf("\t\t\thard-linked to %s\n", dirnode->dup->name);
- dirnode = dirnode->dup;
- }
-
#define ASEPRINT(t, b, o, n) \
if (debug & DEBUG_APPLY_SPECENTRY) \
printf("\t\t\tchanging %s from " b " to " b "\n", \
@@ -370,21 +377,21 @@ apply_specentry(const char *dir, NODE *specnode, fsnode *dirnode)
if (specnode->flags & (F_GID | F_GNAME)) {
ASEPRINT("gid", "%d",
- dirnode->statbuf.st_gid, specnode->st_gid);
- dirnode->statbuf.st_gid = specnode->st_gid;
+ dirnode->inode->st.st_gid, specnode->st_gid);
+ dirnode->inode->st.st_gid = specnode->st_gid;
}
if (specnode->flags & F_MODE) {
ASEPRINT("mode", "%#o",
- dirnode->statbuf.st_mode & ALLPERMS, specnode->st_mode);
- dirnode->statbuf.st_mode &= ~ALLPERMS;
- dirnode->statbuf.st_mode |= (specnode->st_mode & ALLPERMS);
+ dirnode->inode->st.st_mode & ALLPERMS, specnode->st_mode);
+ dirnode->inode->st.st_mode &= ~ALLPERMS;
+ dirnode->inode->st.st_mode |= (specnode->st_mode & ALLPERMS);
}
/* XXX: ignoring F_NLINK for now */
if (specnode->flags & F_SIZE) {
ASEPRINT("size", "%lld",
- (long long)dirnode->statbuf.st_size,
+ (long long)dirnode->inode->st.st_size,
(long long)specnode->st_size);
- dirnode->statbuf.st_size = specnode->st_size;
+ dirnode->inode->st.st_size = specnode->st_size;
}
if (specnode->flags & F_SLINK) {
assert(dirnode->symlink != NULL);
@@ -396,29 +403,30 @@ apply_specentry(const char *dir, NODE *specnode, fsnode *dirnode)
}
if (specnode->flags & F_TIME) {
ASEPRINT("time", "%ld",
- (long)dirnode->statbuf.st_mtime, (long)specnode->st_mtime);
- dirnode->statbuf.st_mtime = specnode->st_mtime;
- dirnode->statbuf.st_mtimensec = specnode->st_mtimensec;
- dirnode->statbuf.st_atime = specnode->st_mtime;
- dirnode->statbuf.st_atimensec = specnode->st_mtimensec;
- dirnode->statbuf.st_ctime = start_time.tv_sec;
- dirnode->statbuf.st_ctimensec = start_time.tv_nsec;
+ (long)dirnode->inode->st.st_mtime,
+ (long)specnode->st_mtime);
+ dirnode->inode->st.st_mtime = specnode->st_mtime;
+ dirnode->inode->st.st_mtimensec = specnode->st_mtimensec;
+ dirnode->inode->st.st_atime = specnode->st_mtime;
+ dirnode->inode->st.st_atimensec = specnode->st_mtimensec;
+ dirnode->inode->st.st_ctime = start_time.tv_sec;
+ dirnode->inode->st.st_ctimensec = start_time.tv_nsec;
}
if (specnode->flags & (F_UID | F_UNAME)) {
ASEPRINT("uid", "%d",
- dirnode->statbuf.st_uid, specnode->st_uid);
- dirnode->statbuf.st_uid = specnode->st_uid;
+ dirnode->inode->st.st_uid, specnode->st_uid);
+ dirnode->inode->st.st_uid = specnode->st_uid;
}
if (specnode->flags & F_FLAGS) {
ASEPRINT("flags", "%#lX",
- (u_long)dirnode->statbuf.st_flags,
- (u_long)specnode->st_flags);
- dirnode->statbuf.st_flags = specnode->st_flags;
+ (ulong)dirnode->inode->st.st_flags,
+ (ulong)specnode->st_flags);
+ dirnode->inode->st.st_flags = specnode->st_flags;
}
if (specnode->flags & F_DEV) {
ASEPRINT("rdev", "%#x",
- dirnode->statbuf.st_rdev, specnode->st_rdev);
- dirnode->statbuf.st_rdev = specnode->st_rdev;
+ dirnode->inode->st.st_rdev, specnode->st_rdev);
+ dirnode->inode->st.st_rdev = specnode->st_rdev;
}
#undef ASEPRINT
}
@@ -451,11 +459,8 @@ dump_fsnodes(const char *dir, fsnode *root)
} else {
assert (cur->symlink == NULL);
}
- if (cur->dup != NULL) {
- printf(", hard-linked to %s", cur->dup->name);
- }
- if (cur->nlink > 1)
- printf(", nlinks=%d", cur->nlink);
+ if (cur->inode->nlink > 1)
+ printf(", nlinks=%d", cur->inode->nlink);
putchar('\n');
if (cur->child) {
@@ -482,21 +487,19 @@ inode_type(mode_t mode)
}
-typedef struct {
- int32_t dev;
- int32_t ino;
- fsnode *dup;
-} dupnode;
-
/*
* link_check --
* return pointer to fsnode matching `entry's st_ino & st_dev if it exists,
* otherwise add `entry' to table and return NULL
*/
-static fsnode *
-link_check(fsnode *entry)
+static fsinode *
+link_check(fsinode *entry)
{
- static dupnode *dups;
+ static struct dupnode {
+ uint32_t dev;
+ uint32_t ino;
+ fsinode *dup;
+ } *dups;
static int ndups, maxdups;
int i;
@@ -505,27 +508,26 @@ link_check(fsnode *entry)
/* XXX; maybe traverse in reverse for speed? */
for (i = 0; i < ndups; i++) {
- if (dups[i].dev == entry->statbuf.st_dev &&
- dups[i].ino == entry->statbuf.st_ino) {
+ if (dups[i].dev == entry->st.st_dev &&
+ dups[i].ino == entry->st.st_ino) {
if (debug & DEBUG_WALK_DIR_LINKCHECK)
- printf(
- "link_check: %s (%d,%d) linked to %s\n",
- entry->name, entry->statbuf.st_dev,
- entry->statbuf.st_ino, dups[i].dup->name);
+ printf("link_check: found [%d,%d]\n",
+ entry->st.st_dev, entry->st.st_ino);
return (dups[i].dup);
}
}
if (debug & DEBUG_WALK_DIR_LINKCHECK)
- printf("link_check: no match for %s (%d, %d)\n",
- entry->name, entry->statbuf.st_dev, entry->statbuf.st_ino);
+ printf("link_check: no match for [%d, %d]\n",
+ entry->st.st_dev, entry->st.st_ino);
if (ndups == maxdups) {
maxdups += 128;
- if ((dups = realloc(dups, sizeof(dupnode) * maxdups)) == NULL)
+ if ((dups = realloc(dups, sizeof(struct dupnode) * maxdups))
+ == NULL)
err(1, "Memory allocation error");
}
- dups[ndups].dev = entry->statbuf.st_dev;
- dups[ndups].ino = entry->statbuf.st_ino;
+ dups[ndups].dev = entry->st.st_dev;
+ dups[ndups].ino = entry->st.st_ino;
dups[ndups].dup = entry;
ndups++;