pass1.c revision 98888
18871Srgrimes/* 21558Srgrimes * Copyright (c) 1980, 1986, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 3541477Sjulian#if 0 3623675Speterstatic const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; 3741477Sjulian#endif 3841477Sjulianstatic const char rcsid[] = 3950476Speter "$FreeBSD: head/sbin/fsck_ffs/pass1.c 98888 2002-06-26 18:34:51Z iedowse $"; 401558Srgrimes#endif /* not lint */ 411558Srgrimes 421558Srgrimes#include <sys/param.h> 4362668Smckusick#include <sys/stat.h> 4474556Smckusick#include <sys/sysctl.h> 4523675Speter 461558Srgrimes#include <ufs/ufs/dinode.h> 471558Srgrimes#include <ufs/ufs/dir.h> 481558Srgrimes#include <ufs/ffs/fs.h> 4923675Speter 5023675Speter#include <err.h> 511558Srgrimes#include <string.h> 5223675Speter 531558Srgrimes#include "fsck.h" 541558Srgrimes 5598542Smckusickstatic ufs2_daddr_t badblk; 5698542Smckusickstatic ufs2_daddr_t dupblk; 5741474Sjulianstatic ino_t lastino; /* last inode in use */ 581558Srgrimes 5992839Simpstatic void checkinode(ino_t inumber, struct inodesc *); 607585Sbde 617585Sbdevoid 6292839Simppass1(void) 631558Srgrimes{ 6441474Sjulian struct inostat *info; 651558Srgrimes struct inodesc idesc; 6698542Smckusick ino_t inumber, inosused; 6798542Smckusick ufs2_daddr_t i, cgd; 6898542Smckusick u_int8_t *cp; 6998542Smckusick int c; 701558Srgrimes 711558Srgrimes /* 7296707Strhodes * Set filesystem reserved blocks in used block map. 731558Srgrimes */ 741558Srgrimes for (c = 0; c < sblock.fs_ncg; c++) { 751558Srgrimes cgd = cgdmin(&sblock, c); 761558Srgrimes if (c == 0) { 771558Srgrimes i = cgbase(&sblock, c); 781558Srgrimes } else 791558Srgrimes i = cgsblock(&sblock, c); 801558Srgrimes for (; i < cgd; i++) 811558Srgrimes setbmap(i); 821558Srgrimes } 8369800Stomsoft i = sblock.fs_csaddr; 8469800Stomsoft cgd = i + howmany(sblock.fs_cssize, sblock.fs_fsize); 8569800Stomsoft for (; i < cgd; i++) 8669800Stomsoft setbmap(i); 8769800Stomsoft 881558Srgrimes /* 891558Srgrimes * Find all allocated blocks. 901558Srgrimes */ 9123675Speter memset(&idesc, 0, sizeof(struct inodesc)); 921558Srgrimes idesc.id_func = pass1check; 931558Srgrimes n_files = n_blks = 0; 941558Srgrimes for (c = 0; c < sblock.fs_ncg; c++) { 9541474Sjulian inumber = c * sblock.fs_ipg; 9641474Sjulian setinodebuf(inumber); 9798542Smckusick getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); 9898542Smckusick if (sblock.fs_magic == FS_UFS2_MAGIC) 9998542Smckusick inosused = cgrp.cg_initediblk; 10098542Smckusick else 10198542Smckusick inosused = sblock.fs_ipg; 10270050Siedowse if (got_siginfo) { 10370050Siedowse printf("%s: phase 1: cyl group %d of %d (%d%%)\n", 10470050Siedowse cdevname, c, sblock.fs_ncg, 10570050Siedowse c * 100 / sblock.fs_ncg); 10670050Siedowse got_siginfo = 0; 10770050Siedowse } 10841474Sjulian /* 10941474Sjulian * If we are using soft updates, then we can trust the 11041474Sjulian * cylinder group inode allocation maps to tell us which 11141474Sjulian * inodes are allocated. We will scan the used inode map 11241474Sjulian * to find the inodes that are really in use, and then 11341474Sjulian * read only those inodes in from disk. 11441474Sjulian */ 11541474Sjulian if (preen && usedsoftdep) { 11641474Sjulian if (!cg_chkmagic(&cgrp)) 11741474Sjulian pfatal("CG %d: BAD MAGIC NUMBER\n", c); 11898542Smckusick cp = &cg_inosused(&cgrp)[(inosused - 1) / NBBY]; 11941474Sjulian for ( ; inosused > 0; inosused -= NBBY, cp--) { 12041474Sjulian if (*cp == 0) 12141474Sjulian continue; 12241474Sjulian for (i = 1 << (NBBY - 1); i > 0; i >>= 1) { 12341474Sjulian if (*cp & i) 12441474Sjulian break; 12541474Sjulian inosused--; 12641474Sjulian } 12741474Sjulian break; 12841474Sjulian } 12941474Sjulian if (inosused < 0) 13041474Sjulian inosused = 0; 13141474Sjulian } 13241474Sjulian /* 13341474Sjulian * Allocate inoinfo structures for the allocated inodes. 13441474Sjulian */ 13541474Sjulian inostathead[c].il_numalloced = inosused; 13641474Sjulian if (inosused == 0) { 13741474Sjulian inostathead[c].il_stat = 0; 13841474Sjulian continue; 13941474Sjulian } 14041474Sjulian info = calloc((unsigned)inosused, sizeof(struct inostat)); 14141474Sjulian if (info == NULL) 14241474Sjulian pfatal("cannot alloc %u bytes for inoinfo\n", 14341474Sjulian (unsigned)(sizeof(struct inostat) * inosused)); 14441474Sjulian inostathead[c].il_stat = info; 14541474Sjulian /* 14641474Sjulian * Scan the allocated inodes. 14741474Sjulian */ 14841474Sjulian for (i = 0; i < inosused; i++, inumber++) { 14941474Sjulian if (inumber < ROOTINO) { 15041474Sjulian (void)getnextinode(inumber); 1511558Srgrimes continue; 15241474Sjulian } 1531558Srgrimes checkinode(inumber, &idesc); 1541558Srgrimes } 15541474Sjulian lastino += 1; 15641474Sjulian if (inosused < sblock.fs_ipg || inumber == lastino) 15741474Sjulian continue; 15841474Sjulian /* 15941474Sjulian * If we were not able to determine in advance which inodes 16041474Sjulian * were in use, then reduce the size of the inoinfo structure 16141474Sjulian * to the size necessary to describe the inodes that we 16241474Sjulian * really found. 16341474Sjulian */ 16498542Smckusick if (lastino < (c * sblock.fs_ipg)) 16541474Sjulian inosused = 0; 16698542Smckusick else 16798542Smckusick inosused = lastino - (c * sblock.fs_ipg); 16841474Sjulian inostathead[c].il_numalloced = inosused; 16941474Sjulian if (inosused == 0) { 17041474Sjulian free(inostathead[c].il_stat); 17141474Sjulian inostathead[c].il_stat = 0; 17241474Sjulian continue; 17341474Sjulian } 17441474Sjulian info = calloc((unsigned)inosused, sizeof(struct inostat)); 17541474Sjulian if (info == NULL) 17641474Sjulian pfatal("cannot alloc %u bytes for inoinfo\n", 17741474Sjulian (unsigned)(sizeof(struct inostat) * inosused)); 17841474Sjulian memmove(info, inostathead[c].il_stat, inosused * sizeof(*info)); 17941474Sjulian free(inostathead[c].il_stat); 18041474Sjulian inostathead[c].il_stat = info; 1811558Srgrimes } 1821558Srgrimes freeinodebuf(); 1831558Srgrimes} 1841558Srgrimes 18523675Speterstatic void 18692839Simpcheckinode(ino_t inumber, struct inodesc *idesc) 1871558Srgrimes{ 18898542Smckusick union dinode *dp; 1891558Srgrimes struct zlncnt *zlnp; 19098542Smckusick off_t kernmaxfilesize; 19198542Smckusick ufs2_daddr_t ndb; 1921558Srgrimes mode_t mode; 1932603Sdg char *symbuf; 19498542Smckusick int j; 1951558Srgrimes 1961558Srgrimes dp = getnextinode(inumber); 19798542Smckusick mode = DIP(dp, di_mode) & IFMT; 1981558Srgrimes if (mode == 0) { 19998542Smckusick if ((sblock.fs_magic == FS_UFS1_MAGIC && 20098542Smckusick (memcmp(dp->dp1.di_db, ufs1_zino.di_db, 20198542Smckusick NDADDR * sizeof(ufs1_daddr_t)) || 20298542Smckusick memcmp(dp->dp1.di_ib, ufs1_zino.di_ib, 20398542Smckusick NIADDR * sizeof(ufs1_daddr_t)) || 20498542Smckusick dp->dp1.di_mode || dp->dp1.di_size)) || 20598542Smckusick (sblock.fs_magic == FS_UFS2_MAGIC && 20698542Smckusick (memcmp(dp->dp2.di_db, ufs2_zino.di_db, 20798542Smckusick NDADDR * sizeof(ufs2_daddr_t)) || 20898542Smckusick memcmp(dp->dp2.di_ib, ufs2_zino.di_ib, 20998542Smckusick NIADDR * sizeof(ufs2_daddr_t)) || 21098542Smckusick dp->dp2.di_mode || dp->dp2.di_size))) { 21186514Siedowse pfatal("PARTIALLY ALLOCATED INODE I=%lu", 21286514Siedowse (u_long)inumber); 2131558Srgrimes if (reply("CLEAR") == 1) { 2141558Srgrimes dp = ginode(inumber); 2151558Srgrimes clearinode(dp); 2161558Srgrimes inodirty(); 2171558Srgrimes } 2181558Srgrimes } 21941474Sjulian inoinfo(inumber)->ino_state = USTATE; 2201558Srgrimes return; 2211558Srgrimes } 2221558Srgrimes lastino = inumber; 22371884Siedowse /* This should match the file size limit in ffs_mountfs(). */ 22498888Siedowse if (sblock.fs_magic == FS_UFS1_MAGIC) 22598888Siedowse kernmaxfilesize = (off_t)0x40000000 * sblock.fs_bsize - 1; 22698888Siedowse else 22798888Siedowse kernmaxfilesize = sblock.fs_maxfilesize; 22898542Smckusick if (DIP(dp, di_size) > kernmaxfilesize || 22998542Smckusick DIP(dp, di_size) > sblock.fs_maxfilesize || 23098542Smckusick (mode == IFDIR && DIP(dp, di_size) > MAXDIRSIZE)) { 2311558Srgrimes if (debug) 23298542Smckusick printf("bad size %qu:", DIP(dp, di_size)); 2331558Srgrimes goto unknown; 2341558Srgrimes } 2351558Srgrimes if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { 2361558Srgrimes dp = ginode(inumber); 23798542Smckusick DIP(dp, di_size) = sblock.fs_fsize; 23898542Smckusick DIP(dp, di_mode) = IFREG|0600; 2391558Srgrimes inodirty(); 2401558Srgrimes } 24163003Smckusick if ((mode == IFBLK || mode == IFCHR || mode == IFIFO || 24298542Smckusick mode == IFSOCK) && DIP(dp, di_size) != 0) { 24363003Smckusick if (debug) 24498542Smckusick printf("bad special-file size %qu:", DIP(dp, di_size)); 24563003Smckusick goto unknown; 24663003Smckusick } 24798542Smckusick if ((mode == IFBLK || mode == IFCHR) && 24898542Smckusick (dev_t)DIP(dp, di_rdev) == NODEV) { 24972525Stegge if (debug) 25072525Stegge printf("bad special-file rdev NODEV:"); 25172525Stegge goto unknown; 25272525Stegge } 25398542Smckusick ndb = howmany(DIP(dp, di_size), sblock.fs_bsize); 2541558Srgrimes if (ndb < 0) { 2551558Srgrimes if (debug) 25698542Smckusick printf("bad size %qu ndb %qu:", 25798542Smckusick DIP(dp, di_size), ndb); 2581558Srgrimes goto unknown; 2591558Srgrimes } 2601558Srgrimes if (mode == IFBLK || mode == IFCHR) 2611558Srgrimes ndb++; 2621558Srgrimes if (mode == IFLNK) { 2631558Srgrimes /* 2641558Srgrimes * Fake ndb value so direct/indirect block checks below 2651558Srgrimes * will detect any garbage after symlink string. 2661558Srgrimes */ 26798542Smckusick if (DIP(dp, di_size) < (off_t)sblock.fs_maxsymlinklen) { 26898542Smckusick if (sblock.fs_magic == FS_UFS1_MAGIC) 26998542Smckusick ndb = howmany(DIP(dp, di_size), 27098542Smckusick sizeof(ufs1_daddr_t)); 27198542Smckusick else 27298542Smckusick ndb = howmany(DIP(dp, di_size), 27398542Smckusick sizeof(ufs2_daddr_t)); 2741558Srgrimes if (ndb > NDADDR) { 2751558Srgrimes j = ndb - NDADDR; 2761558Srgrimes for (ndb = 1; j > 1; j--) 2771558Srgrimes ndb *= NINDIR(&sblock); 2781558Srgrimes ndb += NDADDR; 2791558Srgrimes } 2801558Srgrimes } 2811558Srgrimes } 28298879Siedowse for (j = ndb; ndb < NDADDR && j < NDADDR; j++) 28398542Smckusick if (DIP(dp, di_db[j]) != 0) { 2841558Srgrimes if (debug) 28598542Smckusick printf("bad direct addr[%d]: %qu\n", j, 28698542Smckusick (ufs2_daddr_t)DIP(dp, di_db[j])); 2871558Srgrimes goto unknown; 2881558Srgrimes } 2891558Srgrimes for (j = 0, ndb -= NDADDR; ndb > 0; j++) 2901558Srgrimes ndb /= NINDIR(&sblock); 2911558Srgrimes for (; j < NIADDR; j++) 29298542Smckusick if (DIP(dp, di_ib[j]) != 0) { 2931558Srgrimes if (debug) 29498542Smckusick printf("bad indirect addr: %qu\n", 29598542Smckusick DIP(dp, di_ib[j])); 2961558Srgrimes goto unknown; 2971558Srgrimes } 2981558Srgrimes if (ftypeok(dp) == 0) 2991558Srgrimes goto unknown; 3001558Srgrimes n_files++; 30198542Smckusick inoinfo(inumber)->ino_linkcnt = DIP(dp, di_nlink); 30298542Smckusick if (DIP(dp, di_nlink) <= 0) { 3031558Srgrimes zlnp = (struct zlncnt *)malloc(sizeof *zlnp); 3041558Srgrimes if (zlnp == NULL) { 3051558Srgrimes pfatal("LINK COUNT TABLE OVERFLOW"); 30634266Sjulian if (reply("CONTINUE") == 0) { 30734266Sjulian ckfini(0); 30823675Speter exit(EEXIT); 30934266Sjulian } 3101558Srgrimes } else { 3111558Srgrimes zlnp->zlncnt = inumber; 3121558Srgrimes zlnp->next = zlnhead; 3131558Srgrimes zlnhead = zlnp; 3141558Srgrimes } 3151558Srgrimes } 3161558Srgrimes if (mode == IFDIR) { 31798542Smckusick if (DIP(dp, di_size) == 0) 31841474Sjulian inoinfo(inumber)->ino_state = DCLEAR; 3191558Srgrimes else 32041474Sjulian inoinfo(inumber)->ino_state = DSTATE; 3211558Srgrimes cacheino(dp, inumber); 32241474Sjulian countdirs++; 3231558Srgrimes } else 32441474Sjulian inoinfo(inumber)->ino_state = FSTATE; 32541474Sjulian inoinfo(inumber)->ino_type = IFTODT(mode); 3261558Srgrimes badblk = dupblk = 0; 3271558Srgrimes idesc->id_number = inumber; 32898542Smckusick if (DIP(dp, di_flags) & SF_SNAPSHOT) 32962668Smckusick idesc->id_type = SNAP; 33062668Smckusick else 33162668Smckusick idesc->id_type = ADDR; 3321558Srgrimes (void)ckinode(dp, idesc); 3331558Srgrimes idesc->id_entryno *= btodb(sblock.fs_fsize); 33498542Smckusick if (DIP(dp, di_blocks) != idesc->id_entryno) { 33598542Smckusick pwarn("INCORRECT BLOCK COUNT I=%lu (%qu should be %qu)", 33698542Smckusick (u_long)inumber, DIP(dp, di_blocks), 33798542Smckusick idesc->id_entryno); 3381558Srgrimes if (preen) 3391558Srgrimes printf(" (CORRECTED)\n"); 3401558Srgrimes else if (reply("CORRECT") == 0) 3411558Srgrimes return; 34274556Smckusick if (bkgrdflag == 0) { 34374556Smckusick dp = ginode(inumber); 34498542Smckusick DIP(dp, di_blocks) = idesc->id_entryno; 34574556Smckusick inodirty(); 34674556Smckusick } else { 34774556Smckusick cmd.value = idesc->id_number; 34898542Smckusick cmd.size = idesc->id_entryno - DIP(dp, di_blocks); 34974556Smckusick if (debug) 35098542Smckusick printf("adjblkcnt ino %qu amount %ld\n", 35198542Smckusick cmd.value, cmd.size); 35274556Smckusick if (sysctl(adjblkcnt, MIBSIZE, 0, 0, 35374556Smckusick &cmd, sizeof cmd) == -1) 35474556Smckusick rwerror("ADJUST INODE BLOCK COUNT", cmd.value); 35574556Smckusick } 3561558Srgrimes } 3571558Srgrimes return; 3581558Srgrimesunknown: 35986514Siedowse pfatal("UNKNOWN FILE TYPE I=%lu", (u_long)inumber); 36041474Sjulian inoinfo(inumber)->ino_state = FCLEAR; 3611558Srgrimes if (reply("CLEAR") == 1) { 36241474Sjulian inoinfo(inumber)->ino_state = USTATE; 3631558Srgrimes dp = ginode(inumber); 3641558Srgrimes clearinode(dp); 3651558Srgrimes inodirty(); 3661558Srgrimes } 3671558Srgrimes} 3681558Srgrimes 3697585Sbdeint 37092839Simppass1check(struct inodesc *idesc) 3711558Srgrimes{ 3721558Srgrimes int res = KEEPON; 3731558Srgrimes int anyout, nfrags; 37498542Smckusick ufs2_daddr_t blkno = idesc->id_blkno; 37592806Sobrien struct dups *dlp; 3761558Srgrimes struct dups *new; 3771558Srgrimes 37862668Smckusick if (idesc->id_type == SNAP) { 37962668Smckusick if (blkno == BLK_NOCOPY) 38062668Smckusick return (KEEPON); 38162668Smckusick if (idesc->id_number == cursnapshot) { 38262668Smckusick if (blkno == blkstofrags(&sblock, idesc->id_lbn)) 38362668Smckusick return (KEEPON); 38462668Smckusick if (blkno == BLK_SNAP) { 38562668Smckusick blkno = blkstofrags(&sblock, idesc->id_lbn); 38662668Smckusick idesc->id_entryno -= idesc->id_numfrags; 38762668Smckusick } 38862668Smckusick } else { 38962668Smckusick if (blkno == BLK_SNAP) 39062668Smckusick return (KEEPON); 39162668Smckusick } 39262668Smckusick } 3931558Srgrimes if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { 3941558Srgrimes blkerror(idesc->id_number, "BAD", blkno); 3951558Srgrimes if (badblk++ >= MAXBAD) { 3961558Srgrimes pwarn("EXCESSIVE BAD BLKS I=%lu", 39786514Siedowse (u_long)idesc->id_number); 3981558Srgrimes if (preen) 3991558Srgrimes printf(" (SKIPPING)\n"); 40034266Sjulian else if (reply("CONTINUE") == 0) { 40134266Sjulian ckfini(0); 40223675Speter exit(EEXIT); 40334266Sjulian } 4041558Srgrimes return (STOP); 4051558Srgrimes } 4061558Srgrimes } 4071558Srgrimes for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 4081558Srgrimes if (anyout && chkrange(blkno, 1)) { 4091558Srgrimes res = SKIP; 4101558Srgrimes } else if (!testbmap(blkno)) { 4111558Srgrimes n_blks++; 4121558Srgrimes setbmap(blkno); 4131558Srgrimes } else { 4141558Srgrimes blkerror(idesc->id_number, "DUP", blkno); 4151558Srgrimes if (dupblk++ >= MAXDUP) { 4161558Srgrimes pwarn("EXCESSIVE DUP BLKS I=%lu", 41786514Siedowse (u_long)idesc->id_number); 4181558Srgrimes if (preen) 4191558Srgrimes printf(" (SKIPPING)\n"); 42034266Sjulian else if (reply("CONTINUE") == 0) { 42134266Sjulian ckfini(0); 42223675Speter exit(EEXIT); 42334266Sjulian } 4241558Srgrimes return (STOP); 4251558Srgrimes } 4261558Srgrimes new = (struct dups *)malloc(sizeof(struct dups)); 4271558Srgrimes if (new == NULL) { 4281558Srgrimes pfatal("DUP TABLE OVERFLOW."); 42934266Sjulian if (reply("CONTINUE") == 0) { 43034266Sjulian ckfini(0); 43123675Speter exit(EEXIT); 43234266Sjulian } 4331558Srgrimes return (STOP); 4341558Srgrimes } 4351558Srgrimes new->dup = blkno; 4361558Srgrimes if (muldup == 0) { 4371558Srgrimes duplist = muldup = new; 4381558Srgrimes new->next = 0; 4391558Srgrimes } else { 4401558Srgrimes new->next = muldup->next; 4411558Srgrimes muldup->next = new; 4421558Srgrimes } 4431558Srgrimes for (dlp = duplist; dlp != muldup; dlp = dlp->next) 4441558Srgrimes if (dlp->dup == blkno) 4451558Srgrimes break; 4461558Srgrimes if (dlp == muldup && dlp->dup != blkno) 4471558Srgrimes muldup = new; 4481558Srgrimes } 4491558Srgrimes /* 4501558Srgrimes * count the number of blocks found in id_entryno 4511558Srgrimes */ 4521558Srgrimes idesc->id_entryno++; 4531558Srgrimes } 4541558Srgrimes return (res); 4551558Srgrimes} 456