mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-23 07:31:31 +00:00
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:
parent
f183fb162c
commit
9fc5d538fc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=340411
@ -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
131
lib/libufs/getinode.3
Normal 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
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user