From 9fc5d538fc57f438ca860e07db191b946b4768c9 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 13 Nov 2018 21:40:56 +0000 Subject: [PATCH] In preparation for adding inode check-hashes, clean up and document the libufs interface for fetching and storing inodes. The undocumented getino / putino interface has been replaced with a new getinode / putinode interface. Convert the utilities that had been using the undocumented interface to use the new documented interface. No functional change (as for now the libufs library does not do inode check-hashes). Reviewed by: kib Tested by: Peter Holm Sponsored by: Netflix --- lib/libufs/Makefile | 5 +- lib/libufs/getinode.3 | 131 +++++++++++++++++++++++++++++ lib/libufs/inode.c | 30 +++---- lib/libufs/libufs.h | 9 +- sbin/clri/clri.c | 11 +-- sbin/ffsinfo/ffsinfo.c | 103 +++++++++++------------ sbin/fsck_ffs/dir.c | 13 +-- sbin/fsck_ffs/fsck.h | 2 +- sbin/fsck_ffs/gjournal.c | 32 +++---- sbin/fsck_ffs/inode.c | 21 +++-- sbin/fsck_ffs/main.c | 22 +++-- sbin/fsck_ffs/pass5.c | 5 +- sbin/fsirand/fsirand.c | 33 ++++---- sbin/growfs/growfs.c | 44 +++++++--- sbin/newfs/mkfs.c | 17 ++-- sbin/tunefs/tunefs.c | 161 ++++++++++++++++-------------------- sys/ufs/ffs/ffs_extern.h | 2 +- sys/ufs/ffs/ffs_inode.c | 10 ++- sys/ufs/ffs/ffs_snapshot.c | 4 +- sys/ufs/ffs/ffs_softdep.c | 16 ++-- sys/ufs/ffs/ffs_subr.c | 42 +++++----- sys/ufs/ffs/ffs_vfsops.c | 20 +++-- tools/diag/prtblknos/main.c | 10 +-- 23 files changed, 448 insertions(+), 295 deletions(-) create mode 100644 lib/libufs/getinode.3 diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile index 16487bebc957..2685f7318ac1 100644 --- a/lib/libufs/Makefile +++ b/lib/libufs/Makefile @@ -3,12 +3,12 @@ PACKAGE=lib${LIB} LIB= ufs SHLIBDIR?= /lib -SHLIB_MAJOR= 6 +SHLIB_MAJOR= 7 SRCS= block.c cgroup.c crc32.c inode.c sblock.c type.c ffs_subr.c ffs_tables.c INCS= libufs.h -MAN= bread.3 cgread.3 libufs.3 sbread.3 ufs_disk_close.3 +MAN= bread.3 cgread.3 getinode.3 libufs.3 sbread.3 ufs_disk_close.3 MLINKS+= bread.3 bwrite.3 MLINKS+= bread.3 berase.3 MLINKS+= cgread.3 cgread1.3 @@ -16,6 +16,7 @@ MLINKS+= cgread.3 cgget.3 MLINKS+= cgread.3 cgwrite.3 MLINKS+= cgread.3 cgwrite1.3 MLINKS+= cgread.3 cgput.3 +MLINKS+= getinode.3 putinode.3 MLINKS+= sbread.3 sbwrite.3 MLINKS+= sbread.3 sbget.3 MLINKS+= sbread.3 sbput.3 diff --git a/lib/libufs/getinode.3 b/lib/libufs/getinode.3 new file mode 100644 index 000000000000..6aa5388cbd6d --- /dev/null +++ b/lib/libufs/getinode.3 @@ -0,0 +1,131 @@ +.\" Author: Marshall Kirk McKusick +.\" Date: January 19, 2018 +.\" Description: +.\" Manual page for libufs functions: +.\" getinode(3) +.\" putinode(3) +.\" +.\" This file is in the public domain. +.\" +.\" $FreeBSD$ +.\" +.Dd November 10, 2018 +.Dt GETINODE 3 +.Os +.Sh NAME +.Nm getinode , putinode +.Nd fetch and store inodes on a UFS file system +.Sh LIBRARY +.Lb libufs +.Sh SYNOPSIS +.In ufs/ufs/dinode.h +.In ufs/ffs/fs.h +.In libufs.h +.Ft int +.Fn getinode "struct uufsd *disk" "union dinodep *dp" "ino_t inumber" +.Ft int +.Fn putinode "struct uufsd *disk" +.Sh DESCRIPTION +The +.Fn getinode +and +.Fn putinode +functions provide an inode fetch and store API for +.Xr libufs 3 +consumers. +They operate on a userland UFS disk structure. +The +.Fn getinode +function fetches the specified inode from the filesystem. +The +.Fn putinode +function stores the most recently fetched inode to the filesystem. +.Pp +The +.Va dinodep +union is defined as: +.Bd -literal -offset indent +union dinodep { + struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; +}; +.Ed +.Pp +Sample code to clear write permissions for inode number +.Fa inumber +stored on the filesystem described by +.Fa diskp . +.Bd -literal -offset indent +#include +#include + +#include +#include +#include + +void +clearwrite(struct uufsd *diskp, ino_t inumber) +{ + union dinodep dp; + + if (getinode(diskp, &dp, inumber) == -1) + err(1, "getinode: %s", diskp->d_error); + switch (diskp->d_ufs) { + case 1: /* UFS 1 filesystem */ + dp.dp1->di_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + break; + case 2: /* UFS 2 filesystem */ + dp.dp2->di_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + break; + default: + errx(1, "unknown filesystem type"); + } + if (putinode(diskp) == -1) + err(1, "putinode: %s", diskp->d_error); +} +.Ed +.Sh RETURN VALUES +The +.Fn getinode +and +.Fn putinode +functions return 0 on success, or \-1 in case of any error. +A string describing the error is stored in +.Fa diskp->d_error . +The global +.Fa errno +often provides additional information. +.Sh ERRORS +The function +.Fn getinode +may fail and set +.Va errno +for any of the errors specified for the library function +.Xr pread 2 . +It can also fail if the inode number is out of the range of inodes +in the filesystem. +.Pp +The function +.Fn putinode +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr ufs_disk_write 3 +or +.Xr pwrite 2 . +.Pp +Additionally both functions may follow the +.Xr libufs 3 +error methodologies in case of a device error. +.Sh SEE ALSO +.Xr pread 2 , +.Xr pwrite 2 , +.Xr libufs 3 , +.Xr ufs_disk_write 3 +.Sh HISTORY +These functions first appeared as part of +.Xr libufs 3 +in +.Fx 13.0 . +.Sh AUTHORS +.An Marshall Kirk McKusick Aq Mt mckusick@freebsd.org diff --git a/lib/libufs/inode.c b/lib/libufs/inode.c index 83a6cf0e36c7..11e263f08ad5 100644 --- a/lib/libufs/inode.c +++ b/lib/libufs/inode.c @@ -49,18 +49,16 @@ __FBSDID("$FreeBSD$"); #include int -getino(struct uufsd *disk, void **dino, ino_t inode, int *mode) +getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) { ino_t min, max; caddr_t inoblock; - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; struct fs *fs; ERROR(disk, NULL); fs = &disk->d_fs; - if (inode >= (ino_t)fs->fs_ipg * fs->fs_ncg) { + if (inum >= (ino_t)fs->fs_ipg * fs->fs_ncg) { ERROR(disk, "inode number out of range"); return (-1); } @@ -76,26 +74,22 @@ getino(struct uufsd *disk, void **dino, ino_t inode, int *mode) } disk->d_inoblock = inoblock; } - if (inode >= min && inode < max) + if (inum >= min && inum < max) goto gotit; - bread(disk, fsbtodb(fs, ino_to_fsba(fs, inode)), inoblock, + bread(disk, fsbtodb(fs, ino_to_fsba(fs, inum)), inoblock, fs->fs_bsize); - disk->d_inomin = min = inode - (inode % INOPB(fs)); + disk->d_inomin = min = inum - (inum % INOPB(fs)); disk->d_inomax = max = min + INOPB(fs); gotit: switch (disk->d_ufs) { case 1: - dp1 = &((struct ufs1_dinode *)inoblock)[inode - min]; - if (mode != NULL) - *mode = dp1->di_mode & IFMT; - if (dino != NULL) - *dino = dp1; + disk->d_dp.dp1 = &((struct ufs1_dinode *)inoblock)[inum - min]; + if (dp != NULL) + *dp = disk->d_dp; return (0); case 2: - dp2 = &((struct ufs2_dinode *)inoblock)[inode - min]; - if (mode != NULL) - *mode = dp2->di_mode & IFMT; - if (dino != NULL) - *dino = dp2; + disk->d_dp.dp2 = &((struct ufs2_dinode *)inoblock)[inum - min]; + if (dp != NULL) + *dp = disk->d_dp; return (0); default: break; @@ -105,7 +99,7 @@ gotit: switch (disk->d_ufs) { } int -putino(struct uufsd *disk) +putinode(struct uufsd *disk) { struct fs *fs; diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h index 4598a9999ce2..dbd378949877 100644 --- a/lib/libufs/libufs.h +++ b/lib/libufs/libufs.h @@ -35,6 +35,10 @@ /* * libufs structures. */ +union dinodep { + struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; +}; /* * userland ufs disk. @@ -49,6 +53,7 @@ struct uufsd { caddr_t d_inoblock; /* inode block */ uint32_t d_inomin; /* low inode (not ino_t for ABI compat) */ uint32_t d_inomax; /* high inode (not ino_t for ABI compat) */ + union dinodep d_dp; /* pointer to currently active inode */ union { struct fs d_fs; /* filesystem information */ char d_sb[MAXBSIZE]; @@ -135,8 +140,8 @@ int cgwrite1(struct uufsd *, int); /* * inode.c */ -int getino(struct uufsd *, void **, ino_t, int *); -int putino(struct uufsd *); +int getinode(struct uufsd *, union dinodep *, ino_t); +int putinode(struct uufsd *); /* * sblock.c diff --git a/sbin/clri/clri.c b/sbin/clri/clri.c index 0c0f8f0947a3..7f9a4f09bfe0 100644 --- a/sbin/clri/clri.c +++ b/sbin/clri/clri.c @@ -62,11 +62,6 @@ __FBSDID("$FreeBSD$"); #include #include -union dinodep { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; -}; - static void usage(void) { @@ -104,8 +99,8 @@ main(int argc, char *argv[]) } (void)printf("clearing %d\n", inonum); - if (getino(&disk, (void **)&dp, inonum, NULL) == -1) { - printf("getino: %s\n", disk.d_error); + if (getinode(&disk, &dp, inonum) == -1) { + printf("getinode: %s\n", disk.d_error); exitval = 1; continue; } @@ -119,7 +114,7 @@ main(int argc, char *argv[]) memset(dp.dp2, 0, sizeof(*dp.dp2)); dp.dp2->di_gen = generation; } - putino(&disk); + putinode(&disk); (void)fsync(disk.d_fd); } (void)ufs_disk_close(&disk); diff --git a/sbin/ffsinfo/ffsinfo.c b/sbin/ffsinfo/ffsinfo.c index 5e08d35e5d91..9bd3210986a9 100644 --- a/sbin/ffsinfo/ffsinfo.c +++ b/sbin/ffsinfo/ffsinfo.c @@ -262,7 +262,7 @@ main(int argc, char **argv) dbg_csp = fscs; /* ... and dump it */ - for(dbg_csc=0; dbg_cscdi_nlink==0) { + if (dp.dp1->di_nlink == 0) { DBG_LEAVE; return; /* inode not in use */ } @@ -368,7 +368,7 @@ dump_whole_ufs1_inode(ino_t inode, int level) if (level & 0x100) { DBG_DUMP_INO(&sblock, comment, - ino); + dp.dp1); } if (!(level & 0x200)) { @@ -379,13 +379,13 @@ dump_whole_ufs1_inode(ino_t inode, int level) /* * Ok, now prepare for dumping all direct and indirect pointers. */ - rb = howmany(ino->di_size, sblock.fs_bsize) - UFS_NDADDR; - if(rb>0) { + rb = howmany(dp.dp1->di_size, sblock.fs_bsize) - UFS_NDADDR; + if (rb > 0) { /* * Dump single indirect block. */ - if (bread(&disk, fsbtodb(&sblock, ino->di_ib[0]), (void *)&i1blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, dp.dp1->di_ib[0]), + (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 0", @@ -394,14 +394,14 @@ dump_whole_ufs1_inode(ino_t inode, int level) comment, i1blk, (size_t)rb); - rb-=howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)); + rb -= howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)); } - if(rb>0) { + if (rb > 0) { /* * Dump double indirect blocks. */ - if (bread(&disk, fsbtodb(&sblock, ino->di_ib[1]), (void *)&i2blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, dp.dp1->di_ib[1]), + (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 1", @@ -410,12 +410,12 @@ dump_whole_ufs1_inode(ino_t inode, int level) comment, i2blk, howmany(rb, howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)))); - for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize, - sizeof(ufs1_daddr_t))) && (rb>0)); ind2ctr++) { - ind2ptr=&((ufs1_daddr_t *)(void *)&i2blk)[ind2ctr]; + for (ind2ctr = 0; ((ind2ctr < howmany(sblock.fs_bsize, + sizeof(ufs1_daddr_t))) && (rb > 0)); ind2ctr++) { + ind2ptr = &((ufs1_daddr_t *)(void *)&i2blk)[ind2ctr]; - if (bread(&disk, fsbtodb(&sblock, *ind2ptr), (void *)&i1blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, *ind2ptr), + (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), @@ -425,15 +425,15 @@ dump_whole_ufs1_inode(ino_t inode, int level) comment, i1blk, (size_t)rb); - rb-=howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)); + rb -= howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)); } } - if(rb>0) { + if (rb > 0) { /* * Dump triple indirect blocks. */ - if (bread(&disk, fsbtodb(&sblock, ino->di_ib[2]), (void *)&i3blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, dp.dp1->di_ib[2]), + (void *)&i3blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 2", @@ -445,12 +445,12 @@ dump_whole_ufs1_inode(ino_t inode, int level) howmany(rb, SQUARE(howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t))))); #undef SQUARE - for(ind3ctr=0; ((ind3ctr0)); ind3ctr++) { - ind3ptr=&((ufs1_daddr_t *)(void *)&i3blk)[ind3ctr]; + for (ind3ctr = 0; ((ind3ctr < howmany(sblock.fs_bsize, + sizeof(ufs1_daddr_t))) && (rb > 0)); ind3ctr++) { + ind3ptr = &((ufs1_daddr_t *)(void *)&i3blk)[ind3ctr]; - if (bread(&disk, fsbtodb(&sblock, *ind3ptr), (void *)&i2blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, *ind3ptr), + (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), @@ -461,8 +461,8 @@ dump_whole_ufs1_inode(ino_t inode, int level) i2blk, howmany(rb, howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)))); - for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize, - sizeof(ufs1_daddr_t)))&&(rb>0)); ind2ctr++) { + for (ind2ctr = 0; ((ind2ctr < howmany(sblock.fs_bsize, + sizeof(ufs1_daddr_t))) && (rb > 0)); ind2ctr++) { ind2ptr=&((ufs1_daddr_t *)(void *)&i2blk) [ind2ctr]; if (bread(&disk, fsbtodb(&sblock, *ind2ptr), @@ -477,7 +477,7 @@ dump_whole_ufs1_inode(ino_t inode, int level) comment, i1blk, (size_t)rb); - rb-=howmany(sblock.fs_bsize, + rb -= howmany(sblock.fs_bsize, sizeof(ufs1_daddr_t)); } } @@ -496,8 +496,8 @@ void dump_whole_ufs2_inode(ino_t inode, int level) { DBG_FUNC("dump_whole_ufs2_inode") - struct ufs2_dinode *ino; - int rb, mode; + union dinodep dp; + int rb; unsigned int ind2ctr, ind3ctr; ufs2_daddr_t *ind2ptr, *ind3ptr; char comment[80]; @@ -507,10 +507,10 @@ dump_whole_ufs2_inode(ino_t inode, int level) /* * Read the inode from disk/cache. */ - if (getino(&disk, (void **)&ino, inode, &mode) == -1) - err(1, "getino: %s", disk.d_error); + if (getinode(&disk, &dp, inode) == -1) + err(1, "getinode: %s", disk.d_error); - if (ino->di_nlink == 0) { + if (dp.dp2->di_nlink == 0) { DBG_LEAVE; return; /* inode not in use */ } @@ -520,7 +520,7 @@ dump_whole_ufs2_inode(ino_t inode, int level) */ snprintf(comment, sizeof(comment), "Inode 0x%08jx", (uintmax_t)inode); if (level & 0x100) { - DBG_DUMP_INO(&sblock, comment, ino); + DBG_DUMP_INO(&sblock, comment, dp.dp2); } if (!(level & 0x200)) { @@ -531,13 +531,13 @@ dump_whole_ufs2_inode(ino_t inode, int level) /* * Ok, now prepare for dumping all direct and indirect pointers. */ - rb = howmany(ino->di_size, sblock.fs_bsize) - UFS_NDADDR; + rb = howmany(dp.dp2->di_size, sblock.fs_bsize) - UFS_NDADDR; if (rb > 0) { /* * Dump single indirect block. */ - if (bread(&disk, fsbtodb(&sblock, ino->di_ib[0]), (void *)&i1blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, dp.dp2->di_ib[0]), + (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 0", @@ -549,8 +549,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) /* * Dump double indirect blocks. */ - if (bread(&disk, fsbtodb(&sblock, ino->di_ib[1]), (void *)&i2blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, dp.dp2->di_ib[1]), + (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 1", @@ -563,8 +563,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) sizeof(ufs2_daddr_t))) && (rb>0)); ind2ctr++) { ind2ptr = &((ufs2_daddr_t *)(void *)&i2blk)[ind2ctr]; - if (bread(&disk, fsbtodb(&sblock, *ind2ptr), (void *)&i1blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, *ind2ptr), + (void *)&i1blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), @@ -578,8 +578,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) /* * Dump triple indirect blocks. */ - if (bread(&disk, fsbtodb(&sblock, ino->di_ib[2]), (void *)&i3blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, dp.dp2->di_ib[2]), + (void *)&i3blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), "Inode 0x%08jx: indirect 2", @@ -595,8 +595,8 @@ dump_whole_ufs2_inode(ino_t inode, int level) sizeof(ufs2_daddr_t))) && (rb > 0)); ind3ctr++) { ind3ptr = &((ufs2_daddr_t *)(void *)&i3blk)[ind3ctr]; - if (bread(&disk, fsbtodb(&sblock, *ind3ptr), (void *)&i2blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, *ind3ptr), + (void *)&i2blk, (size_t)sblock.fs_bsize) == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), @@ -610,8 +610,9 @@ dump_whole_ufs2_inode(ino_t inode, int level) for (ind2ctr = 0; ((ind2ctr < howmany(sblock.fs_bsize, sizeof(ufs2_daddr_t))) && (rb > 0)); ind2ctr++) { ind2ptr = &((ufs2_daddr_t *)(void *)&i2blk) [ind2ctr]; - if (bread(&disk, fsbtodb(&sblock, *ind2ptr), (void *)&i1blk, - (size_t)sblock.fs_bsize) == -1) { + if (bread(&disk, fsbtodb(&sblock, *ind2ptr), + (void *)&i1blk, (size_t)sblock.fs_bsize) + == -1) { err(1, "bread: %s", disk.d_error); } snprintf(comment, sizeof(comment), diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index a590ee74227b..e923714c3c72 100644 --- a/sbin/fsck_ffs/dir.c +++ b/sbin/fsck_ffs/dir.c @@ -254,14 +254,14 @@ fileerror(ino_t cwd, ino_t ino, const char *errmesg) char pathbuf[MAXPATHLEN + 1]; pwarn("%s ", errmesg); - pinode(ino); - printf("\n"); - getpathname(pathbuf, cwd, ino); if (ino < UFS_ROOTINO || ino > maxino) { - pfatal("NAME=%s\n", pathbuf); + pfatal("out-of-range inode number %ju", (uintmax_t)ino); return; } dp = ginode(ino); + prtinode(ino, dp); + printf("\n"); + getpathname(pathbuf, cwd, ino); if (ftypeok(dp)) pfatal("%s=%s\n", (DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE", @@ -309,7 +309,7 @@ adjust(struct inodesc *idesc, int lcnt) if (lcnt != 0) { pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : ((DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE")); - pinode(idesc->id_number); + prtinode(idesc->id_number, dp); printf(" COUNT %d SHOULD BE %d", DIP(dp, di_nlink), DIP(dp, di_nlink) - lcnt); if (preen || usedsoftdep) { @@ -390,7 +390,8 @@ linkup(ino_t orphan, ino_t parentdir, char *name) dp = ginode(orphan); lostdir = (DIP(dp, di_mode) & IFMT) == IFDIR; pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); - pinode(orphan); + prtinode(orphan, dp); + printf("\n"); if (preen && DIP(dp, di_size) == 0) return (0); if (cursnapshot != 0) { diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index cfac25bdfe3d..ffe41be6cf3b 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -463,8 +463,8 @@ void pass4(void); int pass4check(struct inodesc *); void pass5(void); void pfatal(const char *fmt, ...) __printflike(1, 2); -void pinode(ino_t ino); void propagate(void); +void prtinode(ino_t ino, union dinode *dp); void pwarn(const char *fmt, ...) __printflike(1, 2); int readsb(int listerr); int reply(const char *question); diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c index 79f670c00567..17361f78a058 100644 --- a/sbin/fsck_ffs/gjournal.c +++ b/sbin/fsck_ffs/gjournal.c @@ -392,13 +392,12 @@ clear_inode(struct ufs2_dinode *dino) void gjournal_check(const char *filesys) { - struct ufs2_dinode *dino; - void *p; + union dinodep dp; struct cgchain *cgc; struct cg *cgp; uint8_t *inosused; ino_t cino, ino; - int cg, mode; + int cg; devnam = filesys; opendisk(); @@ -444,19 +443,20 @@ gjournal_check(const char *filesys) /* Unallocated? Skip it. */ if (isclr(inosused, cino)) continue; - if (getino(diskp, &p, ino, &mode) == -1) - err(1, "getino(cg=%d ino=%ju)", - cg, (uintmax_t)ino); - dino = p; + if (getinode(diskp, &dp, ino) == -1) + err(1, "getinode (cg=%d ino=%ju) %s", + cg, (uintmax_t)ino, diskp->d_error); /* Not a regular file nor directory? Skip it. */ - if (!S_ISREG(dino->di_mode) && !S_ISDIR(dino->di_mode)) + if (!S_ISREG(dp.dp2->di_mode) && + !S_ISDIR(dp.dp2->di_mode)) continue; /* Has reference(s)? Skip it. */ - if (dino->di_nlink > 0) + if (dp.dp2->di_nlink > 0) continue; - //printf("Clearing inode=%d (size=%jd)\n", ino, (intmax_t)dino->di_size); + /* printf("Clearing inode=%d (size=%jd)\n", ino, + (intmax_t)dp.dp2->di_size); */ /* Free inode's blocks. */ - clear_inode(dino); + clear_inode(dp.dp2); /* Deallocate it. */ clrbit(inosused, cino); /* Update position of last used inode. */ @@ -469,17 +469,17 @@ gjournal_check(const char *filesys) cgp->cg_unrefs--; fs->fs_unrefs--; /* If this is directory, update related statistics. */ - if (S_ISDIR(dino->di_mode)) { + if (S_ISDIR(dp.dp2->di_mode)) { cgp->cg_cs.cs_ndir--; fs->fs_cs(fs, cg).cs_ndir--; fs->fs_cstotal.cs_ndir--; } /* Zero-fill the inode. */ - *dino = ufs2_zino; + *dp.dp2 = ufs2_zino; /* Write the inode back. */ - if (putino(diskp) == -1) - err(1, "putino(cg=%d ino=%ju)", - cg, (uintmax_t)ino); + if (putinode(diskp) == -1) + err(1, "putinode (cg=%d ino=%ju) %s", + cg, (uintmax_t)ino, diskp->d_error); if (cgp->cg_unrefs == 0) { //printf("No more unreferenced inodes in cg=%d.\n", cg); break; diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c index 7cce44953a69..3f1cab8b3bd5 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "fsck.h" @@ -342,7 +343,11 @@ getnextinode(ino_t inumber, int rebuildcg) nextinop = inobuf.b_un.b_buf; } dp = (union dinode *)nextinop; - if (rebuildcg && nextinop == inobuf.b_un.b_buf) { + if (sblock.fs_magic == FS_UFS1_MAGIC) + nextinop += sizeof(struct ufs1_dinode); + else + nextinop += sizeof(struct ufs2_dinode); + if (rebuildcg && (char *)dp == inobuf.b_un.b_buf) { /* * Try to determine if we have reached the end of the * allocated inodes. @@ -355,7 +360,7 @@ getnextinode(ino_t inumber, int rebuildcg) UFS_NIADDR * sizeof(ufs2_daddr_t)) || dp->dp2.di_mode || dp->dp2.di_size) return (NULL); - goto inodegood; + return (dp); } if (!ftypeok(dp)) return (NULL); @@ -389,11 +394,6 @@ getnextinode(ino_t inumber, int rebuildcg) if (DIP(dp, di_ib[j]) != 0) return (NULL); } -inodegood: - if (sblock.fs_magic == FS_UFS1_MAGIC) - nextinop += sizeof(struct ufs1_dinode); - else - nextinop += sizeof(struct ufs2_dinode); return (dp); } @@ -534,7 +534,8 @@ clri(struct inodesc *idesc, const char *type, int flag) if (flag == 1) { pwarn("%s %s", type, (DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"); - pinode(idesc->id_number); + prtinode(idesc->id_number, dp); + printf("\n"); } if (preen || reply("CLEAR") == 1) { if (preen) @@ -600,9 +601,8 @@ clearentry(struct inodesc *idesc) } void -pinode(ino_t ino) +prtinode(ino_t ino, union dinode *dp) { - union dinode *dp; char *p; struct passwd *pw; time_t t; @@ -610,7 +610,6 @@ pinode(ino_t ino) printf(" I=%lu ", (u_long)ino); if (ino < UFS_ROOTINO || ino > maxino) return; - dp = ginode(ino); printf(" OWNER="); if ((pw = getpwuid((int)DIP(dp, di_uid))) != NULL) printf("%s ", pw->pw_name); diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index e5118619475b..ce4d0a89a36a 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -458,30 +458,40 @@ checkfilesys(char *filesys) if (preen == 0 && yflag == 0 && sblock.fs_magic != FS_UFS1_MAGIC && fswritefd != -1 && getosreldate() >= P_OSREL_CK_CYLGRP) { if ((sblock.fs_metackhash & CK_CYLGRP) == 0 && - reply("ADD CYLINDER GROUP CHECK-HASH PROTECTION") != 0) + reply("ADD CYLINDER GROUP CHECK-HASH PROTECTION") != 0) { ckhashadd |= CK_CYLGRP; + sblock.fs_metackhash |= CK_CYLGRP; + } if ((sblock.fs_metackhash & CK_SUPERBLOCK) == 0 && getosreldate() >= P_OSREL_CK_SUPERBLOCK && reply("ADD SUPERBLOCK CHECK-HASH PROTECTION") != 0) { + ckhashadd |= CK_SUPERBLOCK; sblock.fs_metackhash |= CK_SUPERBLOCK; - sbdirty(); } #ifdef notyet if ((sblock.fs_metackhash & CK_INODE) == 0 && getosreldate() >= P_OSREL_CK_INODE && - reply("ADD INODE CHECK-HASH PROTECTION") != 0) + reply("ADD INODE CHECK-HASH PROTECTION") != 0) { ckhashadd |= CK_INODE; + sblock.fs_metackhash |= CK_INODE; + } if ((sblock.fs_metackhash & CK_INDIR) == 0 && getosreldate() >= P_OSREL_CK_INDIR && - reply("ADD INDIRECT BLOCK CHECK-HASH PROTECTION") != 0) + reply("ADD INDIRECT BLOCK CHECK-HASH PROTECTION") != 0) { ckhashadd |= CK_INDIR; + sblock.fs_metackhash |= CK_INDIR; + } if ((sblock.fs_metackhash & CK_DIR) == 0 && getosreldate() >= P_OSREL_CK_DIR && - reply("ADD DIRECTORY CHECK-HASH PROTECTION") != 0) + reply("ADD DIRECTORY CHECK-HASH PROTECTION") != 0) { ckhashadd |= CK_DIR; + sblock.fs_metackhash |= CK_DIR; + } #endif /* notyet */ - if (ckhashadd != 0) + if (ckhashadd != 0) { sblock.fs_flags |= FS_METACKHASH; + sbdirty(); + } } /* * Cleared if any questions answered no. Used to decide if diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index 71e3eda74c1b..436d184c327b 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -74,11 +74,8 @@ pass5(void) memset(newcg, 0, (size_t)fs->fs_cgsize); newcg->cg_niblk = fs->fs_ipg; /* check to see if we are to add a cylinder group check hash */ - if ((ckhashadd & CK_CYLGRP) != 0) { - fs->fs_metackhash |= CK_CYLGRP; + if ((ckhashadd & CK_CYLGRP) != 0) rewritecg = 1; - sbdirty(); - } if (cvtlevel >= 3) { if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { if (preen) diff --git a/sbin/fsirand/fsirand.c b/sbin/fsirand/fsirand.c index bb0f27a59301..f5e26571f903 100644 --- a/sbin/fsirand/fsirand.c +++ b/sbin/fsirand/fsirand.c @@ -175,7 +175,7 @@ fsirand(char *device) } /* For each cylinder group, randomize inodes and update backup sblock */ - for (cg = 0, inumber = 0; cg < (int)sblock->fs_ncg; cg++) { + for (cg = 0, inumber = UFS_ROOTINO; cg < (int)sblock->fs_ncg; cg++) { /* Read in inodes, then print or randomize generation nums */ dblk = fsbtodb(sblock, ino_to_fsba(sblock, inumber)); if (lseek(devfd, (off_t)dblk * bsize, SEEK_SET) < 0) { @@ -187,21 +187,22 @@ fsirand(char *device) return (1); } - for (n = 0; n < (int)sblock->fs_ipg; n++, inumber++) { - if (sblock->fs_magic == FS_UFS1_MAGIC) - dp1 = &((struct ufs1_dinode *)inodebuf)[n]; - else - dp2 = &((struct ufs2_dinode *)inodebuf)[n]; - if (inumber >= UFS_ROOTINO) { - if (printonly) - (void)printf("ino %ju gen %08x\n", - (uintmax_t)inumber, - sblock->fs_magic == FS_UFS1_MAGIC ? - dp1->di_gen : dp2->di_gen); - else if (sblock->fs_magic == FS_UFS1_MAGIC) - dp1->di_gen = random(); - else - dp2->di_gen = random(); + dp1 = (struct ufs1_dinode *)(void *)inodebuf; + dp2 = (struct ufs2_dinode *)(void *)inodebuf; + for (n = cg > 0 ? 0 : UFS_ROOTINO; + n < (int)sblock->fs_ipg; + n++, inumber++) { + if (printonly) { + (void)printf("ino %ju gen %08x\n", + (uintmax_t)inumber, + sblock->fs_magic == FS_UFS1_MAGIC ? + dp1->di_gen : dp2->di_gen); + } else if (sblock->fs_magic == FS_UFS1_MAGIC) { + dp1->di_gen = arc4random(); + dp1++; + } else { + dp2->di_gen = arc4random(); + dp2++; } } diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index 61f90de7ea68..b75f377841ef 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -301,16 +301,21 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag) { DBG_FUNC("initcg") static caddr_t iobuf; + static long iobufsize; long blkno, start; ino_t ino; ufs2_daddr_t i, cbase, dmax; struct ufs1_dinode *dp1; + struct ufs2_dinode *dp2; struct csum *cs; uint j, d, dupper, dlower; - if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize * 3)) == NULL) - errx(37, "panic: cannot allocate I/O buffer"); - + if (iobuf == NULL) { + iobufsize = 2 * sblock.fs_bsize; + if ((iobuf = malloc(iobufsize)) == NULL) + errx(37, "panic: cannot allocate I/O buffer"); + memset(iobuf, '\0', iobufsize); + } /* * Determine block bounds for cylinder group. * Allow space for super block summary information in first @@ -374,13 +379,30 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag) setbit(cg_inosused(&acg), ino); acg.cg_cs.cs_nifree--; } + /* + * Initialize the initial inode blocks. + */ + dp1 = (struct ufs1_dinode *)(void *)iobuf; + dp2 = (struct ufs2_dinode *)(void *)iobuf; + for (i = 0; i < acg.cg_initediblk; i++) { + if (sblock.fs_magic == FS_UFS1_MAGIC) { + dp1->di_gen = arc4random(); + dp1++; + } else { + dp2->di_gen = arc4random(); + dp2++; + } + } + wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), iobufsize, iobuf, + fso, Nflag); /* * For the old file system, we have to initialize all the inodes. */ - if (sblock.fs_magic == FS_UFS1_MAGIC) { - bzero(iobuf, sblock.fs_bsize); - for (i = 0; i < sblock.fs_ipg / INOPF(&sblock); - i += sblock.fs_frag) { + if (sblock.fs_magic == FS_UFS1_MAGIC && + sblock.fs_ipg > 2 * INOPB(&sblock)) { + for (i = 2 * sblock.fs_frag; + i < sblock.fs_ipg / INOPF(&sblock); + i += sblock.fs_frag) { dp1 = (struct ufs1_dinode *)(void *)iobuf; for (j = 0; j < INOPB(&sblock); j++) { dp1->di_gen = arc4random(); @@ -463,12 +485,8 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag) *cs = acg.cg_cs; cgckhash(&acg); - memcpy(iobuf, &acg, sblock.fs_cgsize); - memset(iobuf + sblock.fs_cgsize, '\0', - sblock.fs_bsize * 3 - sblock.fs_cgsize); - - wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), - sblock.fs_bsize * 3, iobuf, fso, Nflag); + wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, &acg, + fso, Nflag); DBG_DUMP_CG(&sblock, "new cg", &acg); DBG_LEAVE; diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c index 74a0f9511a85..2bea89cf2bc9 100644 --- a/sbin/newfs/mkfs.c +++ b/sbin/newfs/mkfs.c @@ -1029,7 +1029,7 @@ alloc(int size, int mode) void iput(union dinode *ip, ino_t ino) { - ufs2_daddr_t d; + union dinodep dp; bread(&disk, part_ofs + fsbtodb(&sblock, cgtod(&sblock, 0)), (char *)&acg, sblock.fs_cgsize); @@ -1043,20 +1043,15 @@ iput(union dinode *ip, ino_t ino) err(1, "iput: cgput: %s", disk.d_error); sblock.fs_cstotal.cs_nifree--; fscs[0].cs_nifree--; - if (ino >= (unsigned long)sblock.fs_ipg * sblock.fs_ncg) { - printf("fsinit: inode value out of range (%ju).\n", - (uintmax_t)ino); + if (getinode(&disk, &dp, ino) == -1) { + printf("iput: %s\n", disk.d_error); exit(32); } - d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino)); - bread(&disk, part_ofs + d, (char *)iobuf, sblock.fs_bsize); if (sblock.fs_magic == FS_UFS1_MAGIC) - ((struct ufs1_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)] = - ip->dp1; + *dp.dp1 = ip->dp1; else - ((struct ufs2_dinode *)iobuf)[ino_to_fsbo(&sblock, ino)] = - ip->dp2; - wtfs(d, sblock.fs_bsize, (char *)iobuf); + *dp.dp2 = ip->dp2; + putinode(&disk); } /* diff --git a/sbin/tunefs/tunefs.c b/sbin/tunefs/tunefs.c index ef27b60f6bef..6a6b7f767ede 100644 --- a/sbin/tunefs/tunefs.c +++ b/sbin/tunefs/tunefs.c @@ -679,41 +679,36 @@ dir_search(ufs2_daddr_t blk, int bytes) static ino_t journal_findfile(void) { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; + union dinodep dp; ino_t ino; - int mode; - void *ip; int i; - if (getino(&disk, &ip, UFS_ROOTINO, &mode) != 0) { - warn("Failed to get root inode"); + if (getinode(&disk, &dp, UFS_ROOTINO) != 0) { + warn("Failed to get root inode: %s", disk.d_error); return (-1); } - dp2 = ip; - dp1 = ip; if (sblock.fs_magic == FS_UFS1_MAGIC) { - if ((off_t)dp1->di_size >= lblktosize(&sblock, UFS_NDADDR)) { + if ((off_t)dp.dp1->di_size >= lblktosize(&sblock, UFS_NDADDR)) { warnx("UFS_ROOTINO extends beyond direct blocks."); return (-1); } for (i = 0; i < UFS_NDADDR; i++) { - if (dp1->di_db[i] == 0) + if (dp.dp1->di_db[i] == 0) break; - if ((ino = dir_search(dp1->di_db[i], - sblksize(&sblock, (off_t)dp1->di_size, i))) != 0) + if ((ino = dir_search(dp.dp1->di_db[i], + sblksize(&sblock, (off_t)dp.dp1->di_size, i))) != 0) return (ino); } } else { - if ((off_t)dp2->di_size >= lblktosize(&sblock, UFS_NDADDR)) { + if ((off_t)dp.dp2->di_size >= lblktosize(&sblock, UFS_NDADDR)) { warnx("UFS_ROOTINO extends beyond direct blocks."); return (-1); } for (i = 0; i < UFS_NDADDR; i++) { - if (dp2->di_db[i] == 0) + if (dp.dp2->di_db[i] == 0) break; - if ((ino = dir_search(dp2->di_db[i], - sblksize(&sblock, (off_t)dp2->di_size, i))) != 0) + if ((ino = dir_search(dp.dp2->di_db[i], + sblksize(&sblock, (off_t)dp.dp2->di_size, i))) != 0) return (ino); } } @@ -795,23 +790,18 @@ dir_extend(ufs2_daddr_t blk, ufs2_daddr_t nblk, off_t size, ino_t ino) static int journal_insertfile(ino_t ino) { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; - void *ip; + union dinodep dp; ufs2_daddr_t nblk; ufs2_daddr_t blk; ufs_lbn_t lbn; int size; - int mode; int off; - if (getino(&disk, &ip, UFS_ROOTINO, &mode) != 0) { - warn("Failed to get root inode"); + if (getinode(&disk, &dp, UFS_ROOTINO) != 0) { + warn("Failed to get root inode: %s", disk.d_error); sbdirty(); return (-1); } - dp2 = ip; - dp1 = ip; blk = 0; size = 0; nblk = journal_balloc(); @@ -824,15 +814,15 @@ journal_insertfile(ino_t ino) * have to free them and extend the block. */ if (sblock.fs_magic == FS_UFS1_MAGIC) { - lbn = lblkno(&sblock, dp1->di_size); - off = blkoff(&sblock, dp1->di_size); - blk = dp1->di_db[lbn]; - size = sblksize(&sblock, (off_t)dp1->di_size, lbn); + lbn = lblkno(&sblock, dp.dp1->di_size); + off = blkoff(&sblock, dp.dp1->di_size); + blk = dp.dp1->di_db[lbn]; + size = sblksize(&sblock, (off_t)dp.dp1->di_size, lbn); } else { - lbn = lblkno(&sblock, dp2->di_size); - off = blkoff(&sblock, dp2->di_size); - blk = dp2->di_db[lbn]; - size = sblksize(&sblock, (off_t)dp2->di_size, lbn); + lbn = lblkno(&sblock, dp.dp2->di_size); + off = blkoff(&sblock, dp.dp2->di_size); + blk = dp.dp2->di_db[lbn]; + size = sblksize(&sblock, (off_t)dp.dp2->di_size, lbn); } if (off != 0) { if (dir_extend(blk, nblk, off, ino) == -1) @@ -843,16 +833,16 @@ journal_insertfile(ino_t ino) return (-1); } if (sblock.fs_magic == FS_UFS1_MAGIC) { - dp1->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE; - dp1->di_db[lbn] = nblk; - dp1->di_size = lblktosize(&sblock, lbn+1); + dp.dp1->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE; + dp.dp1->di_db[lbn] = nblk; + dp.dp1->di_size = lblktosize(&sblock, lbn+1); } else { - dp2->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE; - dp2->di_db[lbn] = nblk; - dp2->di_size = lblktosize(&sblock, lbn+1); + dp.dp2->di_blocks += (sblock.fs_bsize - size) / DEV_BSIZE; + dp.dp2->di_db[lbn] = nblk; + dp.dp2->di_size = lblktosize(&sblock, lbn+1); } - if (putino(&disk) < 0) { - warn("Failed to write root inode"); + if (putinode(&disk) < 0) { + warn("Failed to write root inode: %s", disk.d_error); return (-1); } if (cgwrite(&disk) < 0) { @@ -916,11 +906,8 @@ indir_fill(ufs2_daddr_t blk, int level, int *resid) static void journal_clear(void) { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; + union dinodep dp; ino_t ino; - int mode; - void *ip; ino = journal_findfile(); if (ino == (ino_t)-1 || ino == 0) { @@ -928,18 +915,16 @@ journal_clear(void) return; } printf("Clearing journal flags from inode %ju\n", (uintmax_t)ino); - if (getino(&disk, &ip, ino, &mode) != 0) { - warn("Failed to get journal inode"); + if (getinode(&disk, &dp, ino) != 0) { + warn("Failed to get journal inode: %s", disk.d_error); return; } - dp2 = ip; - dp1 = ip; if (sblock.fs_magic == FS_UFS1_MAGIC) - dp1->di_flags = 0; + dp.dp1->di_flags = 0; else - dp2->di_flags = 0; - if (putino(&disk) < 0) { - warn("Failed to write journal inode"); + dp.dp2->di_flags = 0; + if (putinode(&disk) < 0) { + warn("Failed to write journal inode: %s", disk.d_error); return; } } @@ -947,15 +932,12 @@ journal_clear(void) static int journal_alloc(int64_t size) { - struct ufs1_dinode *dp1; - struct ufs2_dinode *dp2; + union dinodep dp; ufs2_daddr_t blk; - void *ip; struct cg *cgp; int resid; ino_t ino; int blks; - int mode; time_t utime; int i; @@ -1007,8 +989,8 @@ journal_alloc(int64_t size) break; printf("Using inode %ju in cg %d for %jd byte journal\n", (uintmax_t)ino, cgp->cg_cgx, size); - if (getino(&disk, &ip, ino, &mode) != 0) { - warn("Failed to get allocated inode"); + if (getinode(&disk, &dp, ino) != 0) { + warn("Failed to get allocated inode: %s", disk.d_error); sbdirty(); goto out; } @@ -1017,39 +999,39 @@ journal_alloc(int64_t size) * blocks and size uninitialized. This causes legacy * fsck implementations to clear the inode. */ - dp2 = ip; - dp1 = ip; time(&utime); if (sblock.fs_magic == FS_UFS1_MAGIC) { - bzero(dp1, sizeof(*dp1)); - dp1->di_size = size; - dp1->di_mode = IFREG | IREAD; - dp1->di_nlink = 1; - dp1->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP; - dp1->di_atime = utime; - dp1->di_mtime = utime; - dp1->di_ctime = utime; + bzero(dp.dp1, sizeof(*dp.dp1)); + dp.dp1->di_size = size; + dp.dp1->di_mode = IFREG | IREAD; + dp.dp1->di_nlink = 1; + dp.dp1->di_flags = + SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP; + dp.dp1->di_atime = utime; + dp.dp1->di_mtime = utime; + dp.dp1->di_ctime = utime; } else { - bzero(dp2, sizeof(*dp2)); - dp2->di_size = size; - dp2->di_mode = IFREG | IREAD; - dp2->di_nlink = 1; - dp2->di_flags = SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP; - dp2->di_atime = utime; - dp2->di_mtime = utime; - dp2->di_ctime = utime; - dp2->di_birthtime = utime; + bzero(dp.dp2, sizeof(*dp.dp2)); + dp.dp2->di_size = size; + dp.dp2->di_mode = IFREG | IREAD; + dp.dp2->di_nlink = 1; + dp.dp2->di_flags = + SF_IMMUTABLE | SF_NOUNLINK | UF_NODUMP; + dp.dp2->di_atime = utime; + dp.dp2->di_mtime = utime; + dp.dp2->di_ctime = utime; + dp.dp2->di_birthtime = utime; } for (i = 0; i < UFS_NDADDR && resid; i++, resid--) { blk = journal_balloc(); if (blk <= 0) goto out; if (sblock.fs_magic == FS_UFS1_MAGIC) { - dp1->di_db[i] = blk; - dp1->di_blocks++; + dp.dp1->di_db[i] = blk; + dp.dp1->di_blocks++; } else { - dp2->di_db[i] = blk; - dp2->di_blocks++; + dp.dp2->di_db[i] = blk; + dp.dp2->di_blocks++; } } for (i = 0; i < UFS_NIADDR && resid; i++) { @@ -1062,19 +1044,20 @@ journal_alloc(int64_t size) goto out; } if (sblock.fs_magic == FS_UFS1_MAGIC) { - dp1->di_ib[i] = blk; - dp1->di_blocks += blks; + dp.dp1->di_ib[i] = blk; + dp.dp1->di_blocks += blks; } else { - dp2->di_ib[i] = blk; - dp2->di_blocks += blks; + dp.dp2->di_ib[i] = blk; + dp.dp2->di_blocks += blks; } } if (sblock.fs_magic == FS_UFS1_MAGIC) - dp1->di_blocks *= sblock.fs_bsize / disk.d_bsize; + dp.dp1->di_blocks *= sblock.fs_bsize / disk.d_bsize; else - dp2->di_blocks *= sblock.fs_bsize / disk.d_bsize; - if (putino(&disk) < 0) { - warn("Failed to write inode"); + dp.dp2->di_blocks *= sblock.fs_bsize / disk.d_bsize; + if (putinode(&disk) < 0) { + warn("Failed to write allocated inode: %s", + disk.d_error); sbdirty(); return (-1); } diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index 6b8e708f7371..c2f6c91bcc4b 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -82,7 +82,7 @@ int ffs_getcg(struct fs *, struct vnode *, u_int, struct buf **, struct cg **); int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t); int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t); -void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t); +int ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t); void ffs_oldfscompat_write(struct fs *, struct ufsmount *); int ffs_own_mount(const struct mount *mp); int ffs_reallocblks(struct vop_reallocblks_args *); diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index a1be71511434..d146d14980c3 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -148,12 +148,18 @@ ffs_update(vp, waitfor) if (I_IS_UFS1(ip)) { *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1; - /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */ + /* + * XXX: FIX? The entropy here is desirable, + * but the harvesting may be expensive + */ random_harvest_queue(&(ip->i_din1), sizeof(ip->i_din1), RANDOM_FS_ATIME); } else { *((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2; - /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */ + /* + * XXX: FIX? The entropy here is desirable, + * but the harvesting may be expensive + */ random_harvest_queue(&(ip->i_din2), sizeof(ip->i_din2), RANDOM_FS_ATIME); } if (waitfor) diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index 4453c59517df..09b1d4982c49 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -1333,12 +1333,12 @@ expunge_ufs2(snapvp, cancelip, fs, acctfunc, expungetype, clearmode) */ dip = (struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, cancelip->i_number); - if (clearmode || cancelip->i_effnlink == 0) - dip->di_mode = 0; dip->di_size = 0; dip->di_blocks = 0; dip->di_flags &= ~SF_SNAPSHOT; bzero(&dip->di_db[0], (UFS_NDADDR + UFS_NIADDR) * sizeof(ufs2_daddr_t)); + if (clearmode || cancelip->i_effnlink == 0) + dip->di_mode = 0; bdwrite(bp); /* * Now go through and expunge all the blocks in the file diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index dcc72b2fdfd3..3fe9e205f858 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -6698,12 +6698,13 @@ softdep_journal_freeblocks(ip, cred, length, flags) if (bp->b_bufsize == fs->fs_bsize) bp->b_flags |= B_CLUSTEROK; softdep_update_inodeblock(ip, bp, 0); - if (ump->um_fstype == UFS1) + if (ump->um_fstype == UFS1) { *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1; - else + } else { *((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2; + } ACQUIRE_LOCK(ump); (void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep); if ((inodedep->id_state & IOSTARTED) != 0) @@ -9640,6 +9641,7 @@ static void clear_unlinked_inodedep(inodedep) struct inodedep *inodedep; { + struct ufs2_dinode *dip; struct ufsmount *ump; struct inodedep *idp; struct inodedep *idn; @@ -9743,12 +9745,14 @@ clear_unlinked_inodedep(inodedep) ffs_oldfscompat_write((struct fs *)bp->b_data, ump); softdep_setup_sbupdate(ump, (struct fs *)bp->b_data, bp); - } else if (fs->fs_magic == FS_UFS1_MAGIC) + } else if (fs->fs_magic == FS_UFS1_MAGIC) { ((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, pino))->di_freelink = nino; - else - ((struct ufs2_dinode *)bp->b_data + - ino_to_fsbo(fs, pino))->di_freelink = nino; + } else { + dip = (struct ufs2_dinode *)bp->b_data + + ino_to_fsbo(fs, pino); + dip->di_freelink = nino; + } /* * If the bwrite fails we have no recourse to recover. The * filesystem is corrupted already. diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c index de70a3f84283..541d44c887db 100644 --- a/sys/ufs/ffs/ffs_subr.c +++ b/sys/ufs/ffs/ffs_subr.c @@ -108,31 +108,35 @@ ffs_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp) * Load up the contents of an inode and copy the appropriate pieces * to the incore copy. */ -void +int ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino) { + struct ufs1_dinode *dip1; + struct ufs2_dinode *dip2; if (I_IS_UFS1(ip)) { - *ip->i_din1 = + dip1 = ip->i_din1; + *dip1 = *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); - ip->i_mode = ip->i_din1->di_mode; - ip->i_nlink = ip->i_din1->di_nlink; - ip->i_size = ip->i_din1->di_size; - ip->i_flags = ip->i_din1->di_flags; - ip->i_gen = ip->i_din1->di_gen; - ip->i_uid = ip->i_din1->di_uid; - ip->i_gid = ip->i_din1->di_gid; - } else { - *ip->i_din2 = - *((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); - ip->i_mode = ip->i_din2->di_mode; - ip->i_nlink = ip->i_din2->di_nlink; - ip->i_size = ip->i_din2->di_size; - ip->i_flags = ip->i_din2->di_flags; - ip->i_gen = ip->i_din2->di_gen; - ip->i_uid = ip->i_din2->di_uid; - ip->i_gid = ip->i_din2->di_gid; + ip->i_mode = dip1->di_mode; + ip->i_nlink = dip1->di_nlink; + ip->i_size = dip1->di_size; + ip->i_flags = dip1->di_flags; + ip->i_gen = dip1->di_gen; + ip->i_uid = dip1->di_uid; + ip->i_gid = dip1->di_gid; + return (0); } + dip2 = ip->i_din2; + *dip2 = *((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); + ip->i_mode = dip2->di_mode; + ip->i_nlink = dip2->di_nlink; + ip->i_size = dip2->di_size; + ip->i_flags = dip2->di_flags; + ip->i_gen = dip2->di_gen; + ip->i_uid = dip2->di_uid; + ip->i_gid = dip2->di_gid; + return (0); } #endif /* KERNEL */ diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index b69dd20da113..7ecaae231f07 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -740,16 +740,19 @@ ffs_reload(struct mount *mp, struct thread *td, int flags) bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), (int)fs->fs_bsize, NOCRED, &bp); if (error) { - VOP_UNLOCK(vp, 0); - vrele(vp); + vput(vp); + MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); + return (error); + } + if ((error = ffs_load_inode(bp, ip, fs, ip->i_number)) != 0) { + brelse(bp); + vput(vp); MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); return (error); } - ffs_load_inode(bp, ip, fs, ip->i_number); ip->i_effnlink = ip->i_nlink; brelse(bp); - VOP_UNLOCK(vp, 0); - vrele(vp); + vput(vp); } return (0); } @@ -1729,7 +1732,12 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags) ip->i_din1 = uma_zalloc(uma_ufs1, M_WAITOK); else ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK); - ffs_load_inode(bp, ip, fs, ino); + if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) { + bqrelse(bp); + vput(vp); + *vpp = NULL; + return (error); + } if (DOINGSOFTDEP(vp)) softdep_load_inodeblock(ip); else diff --git a/tools/diag/prtblknos/main.c b/tools/diag/prtblknos/main.c index 51d5b135a5ea..c3abb2babad1 100644 --- a/tools/diag/prtblknos/main.c +++ b/tools/diag/prtblknos/main.c @@ -47,7 +47,7 @@ main(argc, argv) char *argv[]; { struct uufsd disk; - union dinode *dp; + union dinodep dp; struct fs *fs; struct stat sb; struct statfs sfb; @@ -98,11 +98,11 @@ main(argc, argv) (void)printf("%s (inode #%jd): ", filename, (intmax_t)inonum); - if ((error = getino(&disk, (void **)&dp, inonum, NULL)) < 0) - warn("Read of inode %jd on %s failed", - (intmax_t)inonum, fsname); + if ((error = getinode(&disk, &dp, inonum)) < 0) + warn("Read of inode %jd on %s failed: %s", + (intmax_t)inonum, fsname, disk.d_error); - prtblknos(&disk, dp); + prtblknos(&disk, (union dinode *)dp.dp1); } exit(0); }