inode.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/sysmacros.h>
#include <pwd.h>
#include "fsck.h"
extern uint_t largefile_count;
{
int n, ndb;
int ret;
idesc->id_entryno = 0;
return (KEEPON);
if (--ndb == 0 &&
idesc->id_numfrags =
else
if (*ap == 0)
continue;
else
return (ret);
}
/*
* indir_data_blks determine the no. of data blocks
* in the previous levels. ie., at level 3 it
* is the number of data blocks at level 2, 1, and 0.
*/
if (n == 1) {
/* SINGLE */
} else if (n == 2) {
/* DOUBLE */
} else if (n == 3) {
/* TRIPLE */
}
if (*ap) {
return (ret);
} else {
}
}
return (KEEPON);
}
int ilevel;
{
int i, n, (*func)();
return (n);
return (STOP);
} else { /* DATA, ie a directory */
return (SKIP);
}
ilevel--;
}
/*
* nif indicates the next "free" pointer (as an array index) in this
* indirect block, based on counting the blocks remaining in the
* file after subtracting all previously processed blocks.
* This figure is based on the size field of the inode.
*
* Note that in normal operation, nif may initially calculated to
* be larger than the number of pointers in this block; if that is
* the case, nif is limited to the max number of pointers per
* indirect block.
*
* Also note that if an inode is inconsistant (has more blocks
* allocated to it than the size field would indicate), the sweep
* through any indirect blocks directly pointed at by the inode
* continues. Since the block offset of any data blocks referenced
* by these indirect blocks is greater than the size of the file,
* the index nif may be computed as a negative value.
* In this case, we reset nif to indicate that all pointers in
* this retrieval block should be zeroed and the resulting
* through garbage collection later.
*/
else if (nif < 0)
nif = 0;
/*
* first pass: all "free" retrieval pointers (from [nif] thru
* the end of the indirect block) should be zero. (This
* assertion does not hold for directories, which may be
* truncated without releasing their allocated space)
*/
if (*ap == 0)
continue;
*ap = 0;
}
}
}
/*
* second pass: all retrieval pointers refering to blocks within
* a valid range [0..filesize] (both indirect and data blocks)
* are respectively examined the same manner as the direct blocks
* in the inode are checked in chkinode(). Sweep through
* the first pointer in this retrieval block to [nif-1].
*/
if (*ap) {
if (ilevel > 0) {
/*
* each iteration decrease "remaining block
* count" by however many blocks were accessible
* by a pointer at this indirect block level.
*/
iblks -= fsbperindirb;
} else {
if (!idesc->id_hasholes) {
/*
* Increment logical block count here.
* In the case of direct blocks, it is
* done in pass1().
*/
}
}
if (n & STOP) {
return (n);
}
} else {
}
}
return (KEEPON);
}
/*
* Check that a block is a legal block number.
* Return 0 if in range, 1 if out of range.
*/
int cnt;
{
int c;
return (1);
if (debug) {
printf("blk %d < cgdmin %d;",
printf(" blk + cnt %d > cgsbase %d\n",
}
return (1);
}
} else {
if (debug) {
printf("blk %d >= cgdmin %d;",
printf(" blk + cnt %d > sblock.fs_fpg %d\n",
}
return (1);
}
}
return (0);
}
/*
* General purpose interface for reading inodes.
*/
struct dinode *
{
if (startinum == 0 ||
if (pbp != 0) {
}
}
return (dp);
}
/*
* Special purpose version of ginode used to optimize first pass
* over all the inodes in numerical order.
*/
struct dinode *
{
readcnt++;
size = partialsize;
lastinum += partialcnt;
} else {
size = inobufsize;
}
}
return (dp++);
}
{
startinum = 0;
nextino = 0;
lastinum = 0;
readcnt = 0;
if (partialcnt != 0) {
readpercg++;
} else {
}
errexit("Cannot allocate space for inode buffer\n");
while (nextino < UFSROOTINO)
(void) getnextinode(nextino);
}
{
}
/*
* Routines to maintain information about directory inodes.
* This is built during the first pass and used during the
* second and third passes.
*
* Enter inodes into the cache.
*/
{
return;
listmax += 100;
errexit("cannot increase directory list");
}
}
/*
* Look up an inode cache structure.
*/
struct inoinfo *
{
continue;
return (inp);
}
return ((struct inoinfo *)0);
}
/*
* Determine whether inode is in cache.
*/
{
continue;
return (1);
}
return (0);
}
/*
* Clean up all the inode cache structure.
*/
{
return;
}
/*
* Routines to maintain information about acl inodes.
* This is built during the first pass and used during the
* second and third passes.
*
* Enter acl inodes into the cache.
*/
{
return;
aclmax += 100;
errexit("cannot increase acl list");
}
}
/*
* Look up an acl inode cache structure.
*/
struct aclinfo *
{
continue;
return (aclp);
}
return ((struct aclinfo *)0);
}
/*
* Determine whether acl inode is in cache.
*/
{
continue;
return (1);
}
return (0);
}
inodirty()
{
}
char *type;
int flag;
{
if (flag == 1) {
}
if (preen)
printf(" (CLEARED)\n");
n_files--;
if (debug)
printf("clearing file: size %d,count %d\n",
}
clearinode(dp);
inodirty();
}
}
{
return (KEEPON);
}
{
return (KEEPON);
}
return (KEEPON);
}
{
char *p;
time_t t;
return;
printf(" OWNER=");
else
if (preen)
p = ctime(&t);
}
char *type;
{
printf("\n");
case FSTATE:
return;
case DSTATE:
return;
case SSTATE:
return;
case FCLEAR:
case DCLEAR:
case SCLEAR:
return;
default:
/* NOTREACHED */
}
}
/*
* allocate an unused inode
*/
int type;
{
time_t t;
if (request == 0)
return (0);
break;
return (0);
case IFDIR:
break;
case IFREG:
case IFLNK:
break;
default:
return (0);
}
return (0);
}
time(&t);
n_files++;
inodirty();
return (ino);
}
/*
* deallocate an inode
*/
{
extern int pass4check();
clearinode(dp);
inodirty();
n_files--;
}