diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c index 07b6bcdb21ba..7e070275c191 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 #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 @@ -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 fb02c3510c14..34257fa0212d 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 #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 @@ -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 f49188ecaac1..1fd85e30d3f9 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 8fde263e6a1e..1fc0d4aad233 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 #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 @@ -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++;