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); }