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
This commit is contained in:
Kirk McKusick 2018-11-13 21:40:56 +00:00
parent f183fb162c
commit 9fc5d538fc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=340411
23 changed files with 448 additions and 295 deletions

View File

@ -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

131
lib/libufs/getinode.3 Normal file
View File

@ -0,0 +1,131 @@
.\" Author: Marshall Kirk McKusick <mckusick@freebsd.org>
.\" 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 <sys/stat.h>
#include <err.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <libufs.h>
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

View File

@ -49,18 +49,16 @@ __FBSDID("$FreeBSD$");
#include <libufs.h>
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;

View File

@ -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

View File

@ -62,11 +62,6 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <unistd.h>
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);

View File

@ -262,7 +262,7 @@ main(int argc, char **argv)
dbg_csp = fscs;
/* ... and dump it */
for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) {
for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) {
snprintf(dbg_line, sizeof(dbg_line),
"%d. csum in fscs", dbg_csc);
DBG_DUMP_CSUM(&sblock,
@ -342,8 +342,8 @@ void
dump_whole_ufs1_inode(ino_t inode, int level)
{
DBG_FUNC("dump_whole_ufs1_inode")
struct ufs1_dinode *ino;
int rb, mode;
union dinodep dp;
int rb;
unsigned int ind2ctr, ind3ctr;
ufs1_daddr_t *ind2ptr, *ind3ptr;
char comment[80];
@ -353,10 +353,10 @@ dump_whole_ufs1_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.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; ((ind3ctr<howmany(sblock.fs_bsize,
sizeof(ufs1_daddr_t)))&&(rb>0)); 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),

View File

@ -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) {

View File

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

View File

@ -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;

View File

@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <pwd.h>
#include <string.h>
#include <time.h>
#include <libufs.h>
#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);

View File

@ -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

View File

@ -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)

View File

@ -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++;
}
}

View File

@ -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;

View File

@ -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);
}
/*

View File

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

View File

@ -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 *);

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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 */

View File

@ -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

View File

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