Changeset View
Changeset View
Standalone View
Standalone View
sbin/fsck_ffs/inode.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | ckinode(union dinode *dp, struct inodesc *idesc) | ||||
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && | if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && | ||||
DIP(dp, di_size) < (unsigned)sblock.fs_maxsymlinklen)) | DIP(dp, di_size) < (unsigned)sblock.fs_maxsymlinklen)) | ||||
return (KEEPON); | return (KEEPON); | ||||
if (sblock.fs_magic == FS_UFS1_MAGIC) | if (sblock.fs_magic == FS_UFS1_MAGIC) | ||||
dino.dp1 = dp->dp1; | dino.dp1 = dp->dp1; | ||||
else | else | ||||
dino.dp2 = dp->dp2; | dino.dp2 = dp->dp2; | ||||
ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize); | ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize); | ||||
for (i = 0; i < NDADDR; i++) { | for (i = 0; i < UFS_NDADDR; i++) { | ||||
idesc->id_lbn++; | idesc->id_lbn++; | ||||
if (--ndb == 0 && | if (--ndb == 0 && | ||||
(offset = blkoff(&sblock, DIP(&dino, di_size))) != 0) | (offset = blkoff(&sblock, DIP(&dino, di_size))) != 0) | ||||
idesc->id_numfrags = | idesc->id_numfrags = | ||||
numfrags(&sblock, fragroundup(&sblock, offset)); | numfrags(&sblock, fragroundup(&sblock, offset)); | ||||
else | else | ||||
idesc->id_numfrags = sblock.fs_frag; | idesc->id_numfrags = sblock.fs_frag; | ||||
if (DIP(&dino, di_db[i]) == 0) { | if (DIP(&dino, di_db[i]) == 0) { | ||||
Show All 20 Lines | for (i = 0; i < UFS_NDADDR; i++) { | ||||
if (idesc->id_type != DATA) | if (idesc->id_type != DATA) | ||||
ret = (*idesc->id_func)(idesc); | ret = (*idesc->id_func)(idesc); | ||||
else | else | ||||
ret = dirscan(idesc); | ret = dirscan(idesc); | ||||
if (ret & STOP) | if (ret & STOP) | ||||
return (ret); | return (ret); | ||||
} | } | ||||
idesc->id_numfrags = sblock.fs_frag; | idesc->id_numfrags = sblock.fs_frag; | ||||
remsize = DIP(&dino, di_size) - sblock.fs_bsize * NDADDR; | remsize = DIP(&dino, di_size) - sblock.fs_bsize * UFS_NDADDR; | ||||
sizepb = sblock.fs_bsize; | sizepb = sblock.fs_bsize; | ||||
for (i = 0; i < NIADDR; i++) { | for (i = 0; i < UFS_NIADDR; i++) { | ||||
sizepb *= NINDIR(&sblock); | sizepb *= NINDIR(&sblock); | ||||
if (DIP(&dino, di_ib[i])) { | if (DIP(&dino, di_ib[i])) { | ||||
idesc->id_blkno = DIP(&dino, di_ib[i]); | idesc->id_blkno = DIP(&dino, di_ib[i]); | ||||
ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i); | ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i); | ||||
if (ret & STOP) | if (ret & STOP) | ||||
return (ret); | return (ret); | ||||
} else { | } else { | ||||
idesc->id_lbn += sizepb / sblock.fs_bsize; | idesc->id_lbn += sizepb / sblock.fs_bsize; | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* General purpose interface for reading inodes. | * General purpose interface for reading inodes. | ||||
*/ | */ | ||||
union dinode * | union dinode * | ||||
ginode(ino_t inumber) | ginode(ino_t inumber) | ||||
{ | { | ||||
ufs2_daddr_t iblk; | ufs2_daddr_t iblk; | ||||
if (inumber < ROOTINO || inumber > maxino) | if (inumber < UFS_ROOTINO || inumber > maxino) | ||||
errx(EEXIT, "bad inode number %ju to ginode", | errx(EEXIT, "bad inode number %ju to ginode", | ||||
(uintmax_t)inumber); | (uintmax_t)inumber); | ||||
if (startinum == 0 || | if (startinum == 0 || | ||||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) { | inumber < startinum || inumber >= startinum + INOPB(&sblock)) { | ||||
iblk = ino_to_fsba(&sblock, inumber); | iblk = ino_to_fsba(&sblock, inumber); | ||||
if (pbp != NULL) | if (pbp != NULL) | ||||
pbp->b_flags &= ~B_INUSE; | pbp->b_flags &= ~B_INUSE; | ||||
pbp = getdatablk(iblk, sblock.fs_bsize, BT_INODES); | pbp = getdatablk(iblk, sblock.fs_bsize, BT_INODES); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | getnextinode(ino_t inumber, int rebuildcg) | ||||
if (rebuildcg && nextinop == inobuf.b_un.b_buf) { | if (rebuildcg && nextinop == inobuf.b_un.b_buf) { | ||||
/* | /* | ||||
* Try to determine if we have reached the end of the | * Try to determine if we have reached the end of the | ||||
* allocated inodes. | * allocated inodes. | ||||
*/ | */ | ||||
mode = DIP(dp, di_mode) & IFMT; | mode = DIP(dp, di_mode) & IFMT; | ||||
if (mode == 0) { | if (mode == 0) { | ||||
if (memcmp(dp->dp2.di_db, ufs2_zino.di_db, | if (memcmp(dp->dp2.di_db, ufs2_zino.di_db, | ||||
NDADDR * sizeof(ufs2_daddr_t)) || | UFS_NDADDR * sizeof(ufs2_daddr_t)) || | ||||
memcmp(dp->dp2.di_ib, ufs2_zino.di_ib, | memcmp(dp->dp2.di_ib, ufs2_zino.di_ib, | ||||
NIADDR * sizeof(ufs2_daddr_t)) || | UFS_NIADDR * sizeof(ufs2_daddr_t)) || | ||||
dp->dp2.di_mode || dp->dp2.di_size) | dp->dp2.di_mode || dp->dp2.di_size) | ||||
return (NULL); | return (NULL); | ||||
goto inodegood; | goto inodegood; | ||||
} | } | ||||
if (!ftypeok(dp)) | if (!ftypeok(dp)) | ||||
return (NULL); | return (NULL); | ||||
ndb = howmany(DIP(dp, di_size), sblock.fs_bsize); | ndb = howmany(DIP(dp, di_size), sblock.fs_bsize); | ||||
if (ndb < 0) | if (ndb < 0) | ||||
return (NULL); | return (NULL); | ||||
if (mode == IFBLK || mode == IFCHR) | if (mode == IFBLK || mode == IFCHR) | ||||
ndb++; | ndb++; | ||||
if (mode == IFLNK) { | if (mode == IFLNK) { | ||||
/* | /* | ||||
* Fake ndb value so direct/indirect block checks below | * Fake ndb value so direct/indirect block checks below | ||||
* will detect any garbage after symlink string. | * will detect any garbage after symlink string. | ||||
*/ | */ | ||||
if (DIP(dp, di_size) < (off_t)sblock.fs_maxsymlinklen) { | if (DIP(dp, di_size) < (off_t)sblock.fs_maxsymlinklen) { | ||||
ndb = howmany(DIP(dp, di_size), | ndb = howmany(DIP(dp, di_size), | ||||
sizeof(ufs2_daddr_t)); | sizeof(ufs2_daddr_t)); | ||||
if (ndb > NDADDR) { | if (ndb > UFS_NDADDR) { | ||||
j = ndb - NDADDR; | j = ndb - UFS_NDADDR; | ||||
for (ndb = 1; j > 1; j--) | for (ndb = 1; j > 1; j--) | ||||
ndb *= NINDIR(&sblock); | ndb *= NINDIR(&sblock); | ||||
ndb += NDADDR; | ndb += UFS_NDADDR; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
for (j = ndb; ndb < NDADDR && j < NDADDR; j++) | for (j = ndb; ndb < UFS_NDADDR && j < UFS_NDADDR; j++) | ||||
if (DIP(dp, di_db[j]) != 0) | if (DIP(dp, di_db[j]) != 0) | ||||
return (NULL); | return (NULL); | ||||
for (j = 0, ndb -= NDADDR; ndb > 0; j++) | for (j = 0, ndb -= UFS_NDADDR; ndb > 0; j++) | ||||
ndb /= NINDIR(&sblock); | ndb /= NINDIR(&sblock); | ||||
for (; j < NIADDR; j++) | for (; j < UFS_NIADDR; j++) | ||||
if (DIP(dp, di_ib[j]) != 0) | if (DIP(dp, di_ib[j]) != 0) | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
inodegood: | inodegood: | ||||
if (sblock.fs_magic == FS_UFS1_MAGIC) | if (sblock.fs_magic == FS_UFS1_MAGIC) | ||||
nextinop += sizeof(struct ufs1_dinode); | nextinop += sizeof(struct ufs1_dinode); | ||||
else | else | ||||
nextinop += sizeof(struct ufs2_dinode); | nextinop += sizeof(struct ufs2_dinode); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
* Enter inodes into the cache. | * Enter inodes into the cache. | ||||
*/ | */ | ||||
void | void | ||||
cacheino(union dinode *dp, ino_t inumber) | cacheino(union dinode *dp, ino_t inumber) | ||||
{ | { | ||||
struct inoinfo *inp, **inpp; | struct inoinfo *inp, **inpp; | ||||
int i, blks; | int i, blks; | ||||
if (howmany(DIP(dp, di_size), sblock.fs_bsize) > NDADDR) | if (howmany(DIP(dp, di_size), sblock.fs_bsize) > UFS_NDADDR) | ||||
blks = NDADDR + NIADDR; | blks = UFS_NDADDR + UFS_NIADDR; | ||||
else | else | ||||
blks = howmany(DIP(dp, di_size), sblock.fs_bsize); | blks = howmany(DIP(dp, di_size), sblock.fs_bsize); | ||||
inp = (struct inoinfo *) | inp = (struct inoinfo *) | ||||
Malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t)); | Malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t)); | ||||
if (inp == NULL) | if (inp == NULL) | ||||
errx(EEXIT, "cannot increase directory list"); | errx(EEXIT, "cannot increase directory list"); | ||||
inpp = &inphead[inumber % dirhash]; | inpp = &inphead[inumber % dirhash]; | ||||
inp->i_nexthash = *inpp; | inp->i_nexthash = *inpp; | ||||
*inpp = inp; | *inpp = inp; | ||||
inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0; | inp->i_parent = inumber == UFS_ROOTINO ? UFS_ROOTINO : (ino_t)0; | ||||
inp->i_dotdot = (ino_t)0; | inp->i_dotdot = (ino_t)0; | ||||
inp->i_number = inumber; | inp->i_number = inumber; | ||||
inp->i_isize = DIP(dp, di_size); | inp->i_isize = DIP(dp, di_size); | ||||
inp->i_numblks = blks; | inp->i_numblks = blks; | ||||
for (i = 0; i < MIN(blks, NDADDR); i++) | for (i = 0; i < MIN(blks, UFS_NDADDR); i++) | ||||
inp->i_blks[i] = DIP(dp, di_db[i]); | inp->i_blks[i] = DIP(dp, di_db[i]); | ||||
if (blks > NDADDR) | if (blks > UFS_NDADDR) | ||||
for (i = 0; i < NIADDR; i++) | for (i = 0; i < UFS_NIADDR; i++) | ||||
inp->i_blks[NDADDR + i] = DIP(dp, di_ib[i]); | inp->i_blks[UFS_NDADDR + i] = DIP(dp, di_ib[i]); | ||||
if (inplast == listmax) { | if (inplast == listmax) { | ||||
listmax += 100; | listmax += 100; | ||||
inpsort = (struct inoinfo **)realloc((char *)inpsort, | inpsort = (struct inoinfo **)realloc((char *)inpsort, | ||||
(unsigned)listmax * sizeof(struct inoinfo *)); | (unsigned)listmax * sizeof(struct inoinfo *)); | ||||
if (inpsort == NULL) | if (inpsort == NULL) | ||||
errx(EEXIT, "cannot increase directory list"); | errx(EEXIT, "cannot increase directory list"); | ||||
} | } | ||||
inpsort[inplast++] = inp; | inpsort[inplast++] = inp; | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
findino(struct inodesc *idesc) | findino(struct inodesc *idesc) | ||||
{ | { | ||||
struct direct *dirp = idesc->id_dirp; | struct direct *dirp = idesc->id_dirp; | ||||
if (dirp->d_ino == 0) | if (dirp->d_ino == 0) | ||||
return (KEEPON); | return (KEEPON); | ||||
if (strcmp(dirp->d_name, idesc->id_name) == 0 && | if (strcmp(dirp->d_name, idesc->id_name) == 0 && | ||||
dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) { | dirp->d_ino >= UFS_ROOTINO && dirp->d_ino <= maxino) { | ||||
idesc->id_parent = dirp->d_ino; | idesc->id_parent = dirp->d_ino; | ||||
return (STOP|FOUND); | return (STOP|FOUND); | ||||
} | } | ||||
return (KEEPON); | return (KEEPON); | ||||
} | } | ||||
int | int | ||||
clearentry(struct inodesc *idesc) | clearentry(struct inodesc *idesc) | ||||
Show All 12 Lines | |||||
pinode(ino_t ino) | pinode(ino_t ino) | ||||
{ | { | ||||
union dinode *dp; | union dinode *dp; | ||||
char *p; | char *p; | ||||
struct passwd *pw; | struct passwd *pw; | ||||
time_t t; | time_t t; | ||||
printf(" I=%lu ", (u_long)ino); | printf(" I=%lu ", (u_long)ino); | ||||
if (ino < ROOTINO || ino > maxino) | if (ino < UFS_ROOTINO || ino > maxino) | ||||
return; | return; | ||||
dp = ginode(ino); | dp = ginode(ino); | ||||
printf(" OWNER="); | printf(" OWNER="); | ||||
if ((pw = getpwuid((int)DIP(dp, di_uid))) != NULL) | if ((pw = getpwuid((int)DIP(dp, di_uid))) != NULL) | ||||
printf("%s ", pw->pw_name); | printf("%s ", pw->pw_name); | ||||
else | else | ||||
printf("%u ", (unsigned)DIP(dp, di_uid)); | printf("%u ", (unsigned)DIP(dp, di_uid)); | ||||
printf("MODE=%o\n", DIP(dp, di_mode)); | printf("MODE=%o\n", DIP(dp, di_mode)); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
ino_t ino; | ino_t ino; | ||||
union dinode *dp; | union dinode *dp; | ||||
struct bufarea *cgbp; | struct bufarea *cgbp; | ||||
struct cg *cgp; | struct cg *cgp; | ||||
int cg; | int cg; | ||||
if (request == 0) | if (request == 0) | ||||
request = ROOTINO; | request = UFS_ROOTINO; | ||||
else if (inoinfo(request)->ino_state != USTATE) | else if (inoinfo(request)->ino_state != USTATE) | ||||
return (0); | return (0); | ||||
for (ino = request; ino < maxino; ino++) | for (ino = request; ino < maxino; ino++) | ||||
if (inoinfo(ino)->ino_state == USTATE) | if (inoinfo(ino)->ino_state == USTATE) | ||||
break; | break; | ||||
if (ino == maxino) | if (ino == maxino) | ||||
return (0); | return (0); | ||||
cg = ino_to_cg(&sblock, ino); | cg = ino_to_cg(&sblock, ino); | ||||
▲ Show 20 Lines • Show All 61 Lines • Show Last 20 Lines |