1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 1999 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate /* 10*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980, 1986, 1990 The Regents of the University of California. 11*7c478bd9Sstevel@tonic-gate * All rights reserved. 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 14*7c478bd9Sstevel@tonic-gate * provided that: (1) source distributions retain this entire copyright 15*7c478bd9Sstevel@tonic-gate * notice and comment, and (2) distributions including binaries display 16*7c478bd9Sstevel@tonic-gate * the following acknowledgement: ``This product includes software 17*7c478bd9Sstevel@tonic-gate * developed by the University of California, Berkeley and its contributors'' 18*7c478bd9Sstevel@tonic-gate * in the documentation or other materials provided with the distribution 19*7c478bd9Sstevel@tonic-gate * and in all advertising materials mentioning features or use of this 20*7c478bd9Sstevel@tonic-gate * software. Neither the name of the University nor the names of its 21*7c478bd9Sstevel@tonic-gate * contributors may be used to endorse or promote products derived 22*7c478bd9Sstevel@tonic-gate * from this software without specific prior written permission. 23*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 24*7c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 25*7c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 26*7c478bd9Sstevel@tonic-gate */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #include <stdio.h> 31*7c478bd9Sstevel@tonic-gate #include <strings.h> 32*7c478bd9Sstevel@tonic-gate #include <malloc.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/fs/udf_volume.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 41*7c478bd9Sstevel@tonic-gate #include "fsck.h" 42*7c478bd9Sstevel@tonic-gate #include "udfs.h" 43*7c478bd9Sstevel@tonic-gate #include <locale.h> 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * for each large file ( size > MAXOFF_T) this global counter 47*7c478bd9Sstevel@tonic-gate * gets incremented here. 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate extern unsigned int largefile_count; 51*7c478bd9Sstevel@tonic-gate extern void pwarn(char *, ...); 52*7c478bd9Sstevel@tonic-gate extern void pfatal(char *, ...); 53*7c478bd9Sstevel@tonic-gate extern void errexit(char *, ...); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate extern int32_t verifytag(struct tag *, uint32_t, struct tag *, int); 56*7c478bd9Sstevel@tonic-gate extern char *tagerrs[]; 57*7c478bd9Sstevel@tonic-gate extern void maketag(struct tag *, struct tag *); 58*7c478bd9Sstevel@tonic-gate extern void flush(int32_t, struct bufarea *); 59*7c478bd9Sstevel@tonic-gate extern void putfilentry(struct bufarea *); 60*7c478bd9Sstevel@tonic-gate extern int32_t bread(int32_t, char *, daddr_t, long); 61*7c478bd9Sstevel@tonic-gate extern void bwrite(int, char *, daddr_t, long); 62*7c478bd9Sstevel@tonic-gate extern int32_t dofix(struct inodesc *, char *); 63*7c478bd9Sstevel@tonic-gate extern int32_t reply(char *); 64*7c478bd9Sstevel@tonic-gate extern void ud_swap_short_ad(short_ad_t *); 65*7c478bd9Sstevel@tonic-gate extern void ud_swap_long_ad(long_ad_t *); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate extern void dump16(char *, char *); 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static void adjust(struct fileinfo *); 70*7c478bd9Sstevel@tonic-gate static void opndir(struct file_entry *); 71*7c478bd9Sstevel@tonic-gate static int32_t getdir(struct file_entry *, struct bufarea **, 72*7c478bd9Sstevel@tonic-gate u_offset_t *, struct file_id **); 73*7c478bd9Sstevel@tonic-gate static void ckinode(struct file_entry *); 74*7c478bd9Sstevel@tonic-gate struct bufarea *getfilentry(); 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate /* Fields for traversing an allocation extent */ 77*7c478bd9Sstevel@tonic-gate static uint32_t dir_adrsize; 78*7c478bd9Sstevel@tonic-gate static uint32_t dir_adrindx; 79*7c478bd9Sstevel@tonic-gate static uint32_t dir_naddrs; 80*7c478bd9Sstevel@tonic-gate static uint8_t *extbuf; 81*7c478bd9Sstevel@tonic-gate static uint8_t *dir_adrlist; 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate /* Keep track of where we are in the directory */ 84*7c478bd9Sstevel@tonic-gate static u_offset_t dir_baseoff; 85*7c478bd9Sstevel@tonic-gate static uint32_t dir_basesize; 86*7c478bd9Sstevel@tonic-gate static uint8_t *dirbuf; 87*7c478bd9Sstevel@tonic-gate static uint8_t *dir_fidp; 88*7c478bd9Sstevel@tonic-gate static uint32_t baseblock; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate #define MAXFIDSIZE 2048 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate static uint8_t fidbuf[MAXFIDSIZE]; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate void 95*7c478bd9Sstevel@tonic-gate pass1() 96*7c478bd9Sstevel@tonic-gate { 97*7c478bd9Sstevel@tonic-gate register struct file_entry *fp; 98*7c478bd9Sstevel@tonic-gate register struct fileinfo *fip; 99*7c478bd9Sstevel@tonic-gate register struct bufarea *bp; 100*7c478bd9Sstevel@tonic-gate struct file_id *fidp; 101*7c478bd9Sstevel@tonic-gate struct bufarea *fbp; 102*7c478bd9Sstevel@tonic-gate int err; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate (void) cachefile(rootblock, rootlen); 105*7c478bd9Sstevel@tonic-gate fip = &inphead[0]; /* The root */ 106*7c478bd9Sstevel@tonic-gate fip->fe_lseen = 0; /* Didn't get here through directory */ 107*7c478bd9Sstevel@tonic-gate n_files = n_dirs = 0; 108*7c478bd9Sstevel@tonic-gate while (fip->fe_block) { 109*7c478bd9Sstevel@tonic-gate u_offset_t offset, end; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate markbusy(fip->fe_block, fip->fe_len); 112*7c478bd9Sstevel@tonic-gate bp = getfilentry(fip->fe_block, fip->fe_len); 113*7c478bd9Sstevel@tonic-gate if (bp == NULL) { 114*7c478bd9Sstevel@tonic-gate pwarn(gettext("Unable to read file entry at %x\n"), 115*7c478bd9Sstevel@tonic-gate fip->fe_block); 116*7c478bd9Sstevel@tonic-gate goto next; 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate /* LINTED */ 119*7c478bd9Sstevel@tonic-gate fp = (struct file_entry *)bp->b_un.b_buf; 120*7c478bd9Sstevel@tonic-gate fip->fe_lcount = fp->fe_lcount; 121*7c478bd9Sstevel@tonic-gate fip->fe_type = fp->fe_icb_tag.itag_ftype; 122*7c478bd9Sstevel@tonic-gate if (fp->fe_uniq_id >= maxuniqid) 123*7c478bd9Sstevel@tonic-gate maxuniqid = fp->fe_uniq_id + 1; 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate if (fip->fe_block == rootblock && 126*7c478bd9Sstevel@tonic-gate fip->fe_type != FTYPE_DIRECTORY) 127*7c478bd9Sstevel@tonic-gate errexit(gettext("Root file entry is not a " 128*7c478bd9Sstevel@tonic-gate "directory\n")); 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate if (debug) { 131*7c478bd9Sstevel@tonic-gate (void) printf("do %x len %d type %d lcount %d" 132*7c478bd9Sstevel@tonic-gate " lseen %d end %llx\n", 133*7c478bd9Sstevel@tonic-gate fip->fe_block, fip->fe_len, 134*7c478bd9Sstevel@tonic-gate fip->fe_type, fip->fe_lcount, 135*7c478bd9Sstevel@tonic-gate fip->fe_lseen, fp->fe_info_len); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate switch (fip->fe_type) { 138*7c478bd9Sstevel@tonic-gate case FTYPE_DIRECTORY: 139*7c478bd9Sstevel@tonic-gate n_dirs++; 140*7c478bd9Sstevel@tonic-gate offset = 0; 141*7c478bd9Sstevel@tonic-gate end = fp->fe_info_len; 142*7c478bd9Sstevel@tonic-gate fbp = NULL; 143*7c478bd9Sstevel@tonic-gate opndir(fp); 144*7c478bd9Sstevel@tonic-gate for (offset = 0; offset < end; 145*7c478bd9Sstevel@tonic-gate offset += FID_LENGTH(fidp)) { 146*7c478bd9Sstevel@tonic-gate err = getdir(fp, &fbp, &offset, &fidp); 147*7c478bd9Sstevel@tonic-gate if (err) { 148*7c478bd9Sstevel@tonic-gate pwarn(gettext("Bad directory entry in " 149*7c478bd9Sstevel@tonic-gate "file %x at offset %llx\n"), 150*7c478bd9Sstevel@tonic-gate fip->fe_block, offset); 151*7c478bd9Sstevel@tonic-gate offset = end; 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate if (fidp->fid_flags & FID_DELETED) 154*7c478bd9Sstevel@tonic-gate continue; 155*7c478bd9Sstevel@tonic-gate (void) cachefile(fidp->fid_icb.lad_ext_loc, 156*7c478bd9Sstevel@tonic-gate fidp->fid_icb.lad_ext_len); 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate if (dirbuf) { 159*7c478bd9Sstevel@tonic-gate free(dirbuf); 160*7c478bd9Sstevel@tonic-gate dirbuf = NULL; 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate if (fbp) 163*7c478bd9Sstevel@tonic-gate fbp->b_flags &= ~B_INUSE; 164*7c478bd9Sstevel@tonic-gate if (debug) 165*7c478bd9Sstevel@tonic-gate (void) printf("Done %x\n", fip->fe_block); 166*7c478bd9Sstevel@tonic-gate break; 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate case FTYPE_FILE: 169*7c478bd9Sstevel@tonic-gate case FTYPE_SYMLINK: 170*7c478bd9Sstevel@tonic-gate ckinode(fp); 171*7c478bd9Sstevel@tonic-gate default: 172*7c478bd9Sstevel@tonic-gate n_files++; 173*7c478bd9Sstevel@tonic-gate break; 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate putfilentry(bp); 176*7c478bd9Sstevel@tonic-gate bp->b_flags &= ~B_INUSE; 177*7c478bd9Sstevel@tonic-gate next: 178*7c478bd9Sstevel@tonic-gate /* At end of this set of fips, get the next set */ 179*7c478bd9Sstevel@tonic-gate if ((++fip)->fe_block == (uint32_t)-1) 180*7c478bd9Sstevel@tonic-gate fip = fip->fe_nexthash; 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* Find bad link counts */ 184*7c478bd9Sstevel@tonic-gate fip = &inphead[0]; 185*7c478bd9Sstevel@tonic-gate while (fip->fe_block) { 186*7c478bd9Sstevel@tonic-gate if (fip->fe_lcount != fip->fe_lseen) 187*7c478bd9Sstevel@tonic-gate adjust(fip); 188*7c478bd9Sstevel@tonic-gate /* At end of this set of fips, get the next set */ 189*7c478bd9Sstevel@tonic-gate if ((++fip)->fe_block == (uint32_t)-1) 190*7c478bd9Sstevel@tonic-gate fip = fip->fe_nexthash; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate static void 195*7c478bd9Sstevel@tonic-gate opndir(struct file_entry *fp) 196*7c478bd9Sstevel@tonic-gate { 197*7c478bd9Sstevel@tonic-gate if (dirbuf) { 198*7c478bd9Sstevel@tonic-gate free(dirbuf); 199*7c478bd9Sstevel@tonic-gate dirbuf = NULL; 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate if (extbuf) { 202*7c478bd9Sstevel@tonic-gate free(extbuf); 203*7c478bd9Sstevel@tonic-gate extbuf = NULL; 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate dir_baseoff = 0; 207*7c478bd9Sstevel@tonic-gate dir_basesize = 0; 208*7c478bd9Sstevel@tonic-gate dir_adrindx = 0; 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate switch (fp->fe_icb_tag.itag_flags & 0x3) { 211*7c478bd9Sstevel@tonic-gate case ICB_FLAG_SHORT_AD: 212*7c478bd9Sstevel@tonic-gate dir_adrsize = sizeof (short_ad_t); 213*7c478bd9Sstevel@tonic-gate dir_naddrs = fp->fe_len_adesc / sizeof (short_ad_t); 214*7c478bd9Sstevel@tonic-gate dir_adrlist = (uint8_t *)(fp->fe_spec + fp->fe_len_ear); 215*7c478bd9Sstevel@tonic-gate break; 216*7c478bd9Sstevel@tonic-gate case ICB_FLAG_LONG_AD: 217*7c478bd9Sstevel@tonic-gate dir_adrsize = sizeof (long_ad_t); 218*7c478bd9Sstevel@tonic-gate dir_naddrs = fp->fe_len_adesc / sizeof (long_ad_t); 219*7c478bd9Sstevel@tonic-gate dir_adrlist = (uint8_t *)(fp->fe_spec + fp->fe_len_ear); 220*7c478bd9Sstevel@tonic-gate break; 221*7c478bd9Sstevel@tonic-gate case ICB_FLAG_EXT_AD: 222*7c478bd9Sstevel@tonic-gate errexit(gettext("Can't handle ext_ads in directories/n")); 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate case ICB_FLAG_ONE_AD: 225*7c478bd9Sstevel@tonic-gate dir_adrsize = 0; 226*7c478bd9Sstevel@tonic-gate dir_naddrs = 0; 227*7c478bd9Sstevel@tonic-gate dir_adrlist = NULL; 228*7c478bd9Sstevel@tonic-gate dir_basesize = fp->fe_len_adesc; 229*7c478bd9Sstevel@tonic-gate dir_fidp = (uint8_t *)(fp->fe_spec + fp->fe_len_ear); 230*7c478bd9Sstevel@tonic-gate baseblock = fp->fe_tag.tag_loc; 231*7c478bd9Sstevel@tonic-gate break; 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate /* Allocate and read in an allocation extent */ 236*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 237*7c478bd9Sstevel@tonic-gate int 238*7c478bd9Sstevel@tonic-gate getallocext(struct file_entry *fp, uint32_t loc, uint32_t len) 239*7c478bd9Sstevel@tonic-gate { 240*7c478bd9Sstevel@tonic-gate uint32_t nb; 241*7c478bd9Sstevel@tonic-gate uint8_t *ap; 242*7c478bd9Sstevel@tonic-gate int i; 243*7c478bd9Sstevel@tonic-gate int err; 244*7c478bd9Sstevel@tonic-gate struct alloc_ext_desc *aep; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate if (debug) 247*7c478bd9Sstevel@tonic-gate (void) printf(" allocext loc %x len %x\n", loc, len); 248*7c478bd9Sstevel@tonic-gate nb = roundup(len, secsize); 249*7c478bd9Sstevel@tonic-gate if (extbuf) 250*7c478bd9Sstevel@tonic-gate free(extbuf); 251*7c478bd9Sstevel@tonic-gate extbuf = (uint8_t *)malloc(nb); 252*7c478bd9Sstevel@tonic-gate if (extbuf == NULL) 253*7c478bd9Sstevel@tonic-gate errexit(gettext("Can't allocate directory extent buffer\n")); 254*7c478bd9Sstevel@tonic-gate if (bread(fsreadfd, (char *)extbuf, 255*7c478bd9Sstevel@tonic-gate fsbtodb(loc + part_start), nb) != 0) { 256*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 257*7c478bd9Sstevel@tonic-gate gettext("Can't read allocation extent\n")); 258*7c478bd9Sstevel@tonic-gate return (1); 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate /* LINTED */ 261*7c478bd9Sstevel@tonic-gate aep = (struct alloc_ext_desc *)extbuf; 262*7c478bd9Sstevel@tonic-gate err = verifytag(&aep->aed_tag, loc, &aep->aed_tag, UD_ALLOC_EXT_DESC); 263*7c478bd9Sstevel@tonic-gate if (err) { 264*7c478bd9Sstevel@tonic-gate (void) printf( 265*7c478bd9Sstevel@tonic-gate gettext("Bad tag on alloc extent: %s\n"), tagerrs[err]); 266*7c478bd9Sstevel@tonic-gate free(extbuf); 267*7c478bd9Sstevel@tonic-gate return (1); 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate dir_adrlist = (uint8_t *)(aep + 1); 270*7c478bd9Sstevel@tonic-gate dir_naddrs = aep->aed_len_aed / dir_adrsize; 271*7c478bd9Sstevel@tonic-gate dir_adrindx = 0; 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* Swap the descriptors */ 274*7c478bd9Sstevel@tonic-gate for (i = 0, ap = dir_adrlist; i < dir_naddrs; i++, ap += dir_adrsize) { 275*7c478bd9Sstevel@tonic-gate if (dir_adrsize == sizeof (short_ad_t)) { 276*7c478bd9Sstevel@tonic-gate /* LINTED */ 277*7c478bd9Sstevel@tonic-gate ud_swap_short_ad((short_ad_t *)ap); 278*7c478bd9Sstevel@tonic-gate } else if (dir_adrsize == sizeof (long_ad_t)) { 279*7c478bd9Sstevel@tonic-gate /* LINTED */ 280*7c478bd9Sstevel@tonic-gate ud_swap_long_ad((long_ad_t *)ap); 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate return (0); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate /* 288*7c478bd9Sstevel@tonic-gate * Variables used in this function and their relationships: 289*7c478bd9Sstevel@tonic-gate * *poffset - read pointer in the directory 290*7c478bd9Sstevel@tonic-gate * dir_baseoff - offset at start of dirbuf 291*7c478bd9Sstevel@tonic-gate * dir_baselen - length of valid data in current extent 292*7c478bd9Sstevel@tonic-gate * dir_adrindx - index into current allocation extent for location of 293*7c478bd9Sstevel@tonic-gate * dir_baseoff 294*7c478bd9Sstevel@tonic-gate * dir_naddrs - number of entries in current allocation extent 295*7c478bd9Sstevel@tonic-gate * dir_fidp - pointer to dirbuf or immediate data in file entry 296*7c478bd9Sstevel@tonic-gate * baseblock - block address of dir_baseoff 297*7c478bd9Sstevel@tonic-gate * newoff - *poffset - dir_baseoff 298*7c478bd9Sstevel@tonic-gate */ 299*7c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 300*7c478bd9Sstevel@tonic-gate static int32_t 301*7c478bd9Sstevel@tonic-gate getdir(struct file_entry *fp, struct bufarea **fbp, 302*7c478bd9Sstevel@tonic-gate u_offset_t *poffset, struct file_id **fidpp) 303*7c478bd9Sstevel@tonic-gate { 304*7c478bd9Sstevel@tonic-gate /* LINTED */ 305*7c478bd9Sstevel@tonic-gate register struct file_id *fidp = (struct file_id *)fidbuf; 306*7c478bd9Sstevel@tonic-gate register struct short_ad *sap; 307*7c478bd9Sstevel@tonic-gate register struct long_ad *lap; 308*7c478bd9Sstevel@tonic-gate register int i, newoff, xoff = 0; 309*7c478bd9Sstevel@tonic-gate uint32_t block = 0, nb, len, left; 310*7c478bd9Sstevel@tonic-gate u_offset_t offset; 311*7c478bd9Sstevel@tonic-gate int err, type; 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate again: 315*7c478bd9Sstevel@tonic-gate offset = *poffset; 316*7c478bd9Sstevel@tonic-gate again2: 317*7c478bd9Sstevel@tonic-gate if (debug) 318*7c478bd9Sstevel@tonic-gate (void) printf("getdir %llx\n", offset); 319*7c478bd9Sstevel@tonic-gate newoff = offset - dir_baseoff; 320*7c478bd9Sstevel@tonic-gate if (newoff >= dir_basesize) { 321*7c478bd9Sstevel@tonic-gate if (dirbuf) { 322*7c478bd9Sstevel@tonic-gate free(dirbuf); 323*7c478bd9Sstevel@tonic-gate dirbuf = NULL; 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate } else { 326*7c478bd9Sstevel@tonic-gate if (block == 0) 327*7c478bd9Sstevel@tonic-gate block = baseblock + (newoff / secsize); 328*7c478bd9Sstevel@tonic-gate goto nextone; 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate again3: 332*7c478bd9Sstevel@tonic-gate switch (fp->fe_icb_tag.itag_flags & 0x3) { 333*7c478bd9Sstevel@tonic-gate case ICB_FLAG_SHORT_AD: 334*7c478bd9Sstevel@tonic-gate /* LINTED */ 335*7c478bd9Sstevel@tonic-gate sap = &((short_ad_t *)dir_adrlist)[dir_adrindx]; 336*7c478bd9Sstevel@tonic-gate for (i = dir_adrindx; i < dir_naddrs; i++, sap++) { 337*7c478bd9Sstevel@tonic-gate len = EXTLEN(sap->sad_ext_len); 338*7c478bd9Sstevel@tonic-gate type = EXTYPE(sap->sad_ext_len); 339*7c478bd9Sstevel@tonic-gate if (type == 3) { 340*7c478bd9Sstevel@tonic-gate if (i < dir_naddrs - 1) 341*7c478bd9Sstevel@tonic-gate errexit(gettext("Allocation extent not " 342*7c478bd9Sstevel@tonic-gate "at end of list\n")); 343*7c478bd9Sstevel@tonic-gate markbusy(sap->sad_ext_loc, len); 344*7c478bd9Sstevel@tonic-gate if (getallocext(fp, sap->sad_ext_loc, len)) 345*7c478bd9Sstevel@tonic-gate return (1); 346*7c478bd9Sstevel@tonic-gate goto again3; 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate if (newoff < len) 349*7c478bd9Sstevel@tonic-gate break; 350*7c478bd9Sstevel@tonic-gate newoff -= len; 351*7c478bd9Sstevel@tonic-gate dir_baseoff += len; 352*7c478bd9Sstevel@tonic-gate if (debug) 353*7c478bd9Sstevel@tonic-gate (void) printf( 354*7c478bd9Sstevel@tonic-gate " loc %x len %x\n", sap->sad_ext_loc, 355*7c478bd9Sstevel@tonic-gate len); 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate dir_adrindx = i; 358*7c478bd9Sstevel@tonic-gate if (debug) 359*7c478bd9Sstevel@tonic-gate (void) printf(" loc %x len %x\n", sap->sad_ext_loc, 360*7c478bd9Sstevel@tonic-gate sap->sad_ext_len); 361*7c478bd9Sstevel@tonic-gate baseblock = sap->sad_ext_loc; 362*7c478bd9Sstevel@tonic-gate if (block == 0) 363*7c478bd9Sstevel@tonic-gate block = baseblock; 364*7c478bd9Sstevel@tonic-gate dir_basesize = len; 365*7c478bd9Sstevel@tonic-gate if (type < 2) 366*7c478bd9Sstevel@tonic-gate markbusy(sap->sad_ext_loc, len); 367*7c478bd9Sstevel@tonic-gate if (type != 0) { 368*7c478bd9Sstevel@tonic-gate *poffset += dir_basesize; 369*7c478bd9Sstevel@tonic-gate goto again; 370*7c478bd9Sstevel@tonic-gate } 371*7c478bd9Sstevel@tonic-gate nb = roundup(len, secsize); 372*7c478bd9Sstevel@tonic-gate dirbuf = (uint8_t *)malloc(nb); 373*7c478bd9Sstevel@tonic-gate if (dirbuf == NULL) 374*7c478bd9Sstevel@tonic-gate errexit(gettext("Can't allocate directory extent " 375*7c478bd9Sstevel@tonic-gate "buffer\n")); 376*7c478bd9Sstevel@tonic-gate if (bread(fsreadfd, (char *)dirbuf, 377*7c478bd9Sstevel@tonic-gate fsbtodb(baseblock + part_start), nb) != 0) { 378*7c478bd9Sstevel@tonic-gate errexit(gettext("Can't read directory extent\n")); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate dir_fidp = dirbuf; 381*7c478bd9Sstevel@tonic-gate break; 382*7c478bd9Sstevel@tonic-gate case ICB_FLAG_LONG_AD: 383*7c478bd9Sstevel@tonic-gate /* LINTED */ 384*7c478bd9Sstevel@tonic-gate lap = &((long_ad_t *)dir_adrlist)[dir_adrindx]; 385*7c478bd9Sstevel@tonic-gate for (i = dir_adrindx; i < dir_naddrs; i++, lap++) { 386*7c478bd9Sstevel@tonic-gate len = EXTLEN(lap->lad_ext_len); 387*7c478bd9Sstevel@tonic-gate type = EXTYPE(lap->lad_ext_len); 388*7c478bd9Sstevel@tonic-gate if (type == 3) { 389*7c478bd9Sstevel@tonic-gate if (i < dir_naddrs - 1) 390*7c478bd9Sstevel@tonic-gate errexit(gettext("Allocation extent not " 391*7c478bd9Sstevel@tonic-gate "at end of list\n")); 392*7c478bd9Sstevel@tonic-gate markbusy(lap->lad_ext_loc, len); 393*7c478bd9Sstevel@tonic-gate if (getallocext(fp, lap->lad_ext_loc, len)) 394*7c478bd9Sstevel@tonic-gate return (1); 395*7c478bd9Sstevel@tonic-gate goto again3; 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate if (newoff < len) 398*7c478bd9Sstevel@tonic-gate break; 399*7c478bd9Sstevel@tonic-gate newoff -= len; 400*7c478bd9Sstevel@tonic-gate dir_baseoff += len; 401*7c478bd9Sstevel@tonic-gate if (debug) 402*7c478bd9Sstevel@tonic-gate (void) printf( 403*7c478bd9Sstevel@tonic-gate " loc %x len %x\n", lap->lad_ext_loc, 404*7c478bd9Sstevel@tonic-gate len); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate dir_adrindx = i; 407*7c478bd9Sstevel@tonic-gate if (debug) 408*7c478bd9Sstevel@tonic-gate (void) printf(" loc %x len %x\n", lap->lad_ext_loc, 409*7c478bd9Sstevel@tonic-gate lap->lad_ext_len); 410*7c478bd9Sstevel@tonic-gate baseblock = lap->lad_ext_loc; 411*7c478bd9Sstevel@tonic-gate if (block == 0) 412*7c478bd9Sstevel@tonic-gate block = baseblock; 413*7c478bd9Sstevel@tonic-gate dir_basesize = len; 414*7c478bd9Sstevel@tonic-gate if (type < 2) 415*7c478bd9Sstevel@tonic-gate markbusy(lap->lad_ext_loc, len); 416*7c478bd9Sstevel@tonic-gate if (type != 0) { 417*7c478bd9Sstevel@tonic-gate *poffset += dir_basesize; 418*7c478bd9Sstevel@tonic-gate goto again; 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate nb = roundup(len, secsize); 421*7c478bd9Sstevel@tonic-gate dirbuf = (uint8_t *)malloc(nb); 422*7c478bd9Sstevel@tonic-gate if (dirbuf == NULL) 423*7c478bd9Sstevel@tonic-gate errexit(gettext("Can't allocate directory extent " 424*7c478bd9Sstevel@tonic-gate "buffer\n")); 425*7c478bd9Sstevel@tonic-gate if (bread(fsreadfd, (char *)dirbuf, 426*7c478bd9Sstevel@tonic-gate fsbtodb(baseblock + part_start), nb) != 0) { 427*7c478bd9Sstevel@tonic-gate errexit(gettext("Can't read directory extent\n")); 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate dir_fidp = dirbuf; 430*7c478bd9Sstevel@tonic-gate break; 431*7c478bd9Sstevel@tonic-gate case ICB_FLAG_EXT_AD: 432*7c478bd9Sstevel@tonic-gate break; 433*7c478bd9Sstevel@tonic-gate case ICB_FLAG_ONE_AD: 434*7c478bd9Sstevel@tonic-gate errexit(gettext("Logic error in getdir - at ICB_FLAG_ONE_AD " 435*7c478bd9Sstevel@tonic-gate "case\n")); 436*7c478bd9Sstevel@tonic-gate break; 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate nextone: 439*7c478bd9Sstevel@tonic-gate if (debug) 440*7c478bd9Sstevel@tonic-gate (void) printf("getdirend blk %x dir_baseoff %llx newoff %x\n", 441*7c478bd9Sstevel@tonic-gate block, dir_baseoff, newoff); 442*7c478bd9Sstevel@tonic-gate left = dir_basesize - newoff; 443*7c478bd9Sstevel@tonic-gate if (xoff + left > MAXFIDSIZE) 444*7c478bd9Sstevel@tonic-gate left = MAXFIDSIZE - xoff; 445*7c478bd9Sstevel@tonic-gate bcopy((char *)dir_fidp + newoff, (char *)fidbuf + xoff, left); 446*7c478bd9Sstevel@tonic-gate xoff += left; 447*7c478bd9Sstevel@tonic-gate /* 448*7c478bd9Sstevel@tonic-gate * If we have a fid that crosses an extent boundary, then force 449*7c478bd9Sstevel@tonic-gate * a read of the next extent, and fill up the rest of the fid. 450*7c478bd9Sstevel@tonic-gate */ 451*7c478bd9Sstevel@tonic-gate if (xoff < sizeof (fidp->fid_tag) || 452*7c478bd9Sstevel@tonic-gate xoff < sizeof (fidp->fid_tag) + SWAP16(fidp->fid_tag.tag_crc_len)) { 453*7c478bd9Sstevel@tonic-gate offset += left; 454*7c478bd9Sstevel@tonic-gate if (debug) 455*7c478bd9Sstevel@tonic-gate (void) printf("block crossing at offset %llx\n", 456*7c478bd9Sstevel@tonic-gate offset); 457*7c478bd9Sstevel@tonic-gate goto again2; 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate err = verifytag(&fidp->fid_tag, block, &fidp->fid_tag, UD_FILE_ID_DESC); 460*7c478bd9Sstevel@tonic-gate if (debug) { 461*7c478bd9Sstevel@tonic-gate dump16((char *)fidp, "\n"); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate if (err) { 464*7c478bd9Sstevel@tonic-gate pwarn(gettext("Bad directory tag: %s\n"), tagerrs[err]); 465*7c478bd9Sstevel@tonic-gate return (err); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate *fidpp = fidp; 468*7c478bd9Sstevel@tonic-gate return (0); 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate static void 472*7c478bd9Sstevel@tonic-gate ckinode(struct file_entry *fp) 473*7c478bd9Sstevel@tonic-gate { 474*7c478bd9Sstevel@tonic-gate register struct short_ad *sap; 475*7c478bd9Sstevel@tonic-gate register struct long_ad *lap; 476*7c478bd9Sstevel@tonic-gate register int i, type, len; 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate switch (fp->fe_icb_tag.itag_flags & 0x3) { 479*7c478bd9Sstevel@tonic-gate case ICB_FLAG_SHORT_AD: 480*7c478bd9Sstevel@tonic-gate dir_adrsize = sizeof (short_ad_t); 481*7c478bd9Sstevel@tonic-gate dir_naddrs = fp->fe_len_adesc / sizeof (short_ad_t); 482*7c478bd9Sstevel@tonic-gate /* LINTED */ 483*7c478bd9Sstevel@tonic-gate sap = (short_ad_t *)(fp->fe_spec + fp->fe_len_ear); 484*7c478bd9Sstevel@tonic-gate again1: 485*7c478bd9Sstevel@tonic-gate for (i = 0; i < dir_naddrs; i++, sap++) { 486*7c478bd9Sstevel@tonic-gate len = EXTLEN(sap->sad_ext_len); 487*7c478bd9Sstevel@tonic-gate type = EXTYPE(sap->sad_ext_len); 488*7c478bd9Sstevel@tonic-gate if (type < 2) 489*7c478bd9Sstevel@tonic-gate markbusy(sap->sad_ext_loc, len); 490*7c478bd9Sstevel@tonic-gate if (debug) 491*7c478bd9Sstevel@tonic-gate (void) printf( 492*7c478bd9Sstevel@tonic-gate " loc %x len %x\n", sap->sad_ext_loc, 493*7c478bd9Sstevel@tonic-gate sap->sad_ext_len); 494*7c478bd9Sstevel@tonic-gate if (type == 3) { 495*7c478bd9Sstevel@tonic-gate markbusy(sap->sad_ext_loc, len); 496*7c478bd9Sstevel@tonic-gate /* This changes dir_naddrs and dir_adrlist */ 497*7c478bd9Sstevel@tonic-gate if (getallocext(fp, sap->sad_ext_loc, len)) 498*7c478bd9Sstevel@tonic-gate break; 499*7c478bd9Sstevel@tonic-gate /* LINTED */ 500*7c478bd9Sstevel@tonic-gate sap = (short_ad_t *)dir_adrlist; 501*7c478bd9Sstevel@tonic-gate goto again1; 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate break; 505*7c478bd9Sstevel@tonic-gate case ICB_FLAG_LONG_AD: 506*7c478bd9Sstevel@tonic-gate dir_adrsize = sizeof (long_ad_t); 507*7c478bd9Sstevel@tonic-gate dir_naddrs = fp->fe_len_adesc / sizeof (long_ad_t); 508*7c478bd9Sstevel@tonic-gate /* LINTED */ 509*7c478bd9Sstevel@tonic-gate lap = (long_ad_t *)(fp->fe_spec + fp->fe_len_ear); 510*7c478bd9Sstevel@tonic-gate again2: 511*7c478bd9Sstevel@tonic-gate for (i = 0; i < dir_naddrs; i++, lap++) { 512*7c478bd9Sstevel@tonic-gate len = EXTLEN(lap->lad_ext_len); 513*7c478bd9Sstevel@tonic-gate type = EXTYPE(lap->lad_ext_len); 514*7c478bd9Sstevel@tonic-gate if (type < 2) 515*7c478bd9Sstevel@tonic-gate markbusy(lap->lad_ext_loc, len); 516*7c478bd9Sstevel@tonic-gate if (debug) 517*7c478bd9Sstevel@tonic-gate (void) printf( 518*7c478bd9Sstevel@tonic-gate " loc %x len %x\n", lap->lad_ext_loc, 519*7c478bd9Sstevel@tonic-gate lap->lad_ext_len); 520*7c478bd9Sstevel@tonic-gate if (type == 3) { 521*7c478bd9Sstevel@tonic-gate markbusy(sap->sad_ext_loc, len); 522*7c478bd9Sstevel@tonic-gate /* This changes dir_naddrs and dir_adrlist */ 523*7c478bd9Sstevel@tonic-gate if (getallocext(fp, lap->lad_ext_loc, len)) 524*7c478bd9Sstevel@tonic-gate break; 525*7c478bd9Sstevel@tonic-gate /* LINTED */ 526*7c478bd9Sstevel@tonic-gate lap = (long_ad_t *)dir_adrlist; 527*7c478bd9Sstevel@tonic-gate goto again2; 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate break; 531*7c478bd9Sstevel@tonic-gate case ICB_FLAG_EXT_AD: 532*7c478bd9Sstevel@tonic-gate break; 533*7c478bd9Sstevel@tonic-gate case ICB_FLAG_ONE_AD: 534*7c478bd9Sstevel@tonic-gate break; 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate static void 539*7c478bd9Sstevel@tonic-gate adjust(struct fileinfo *fip) 540*7c478bd9Sstevel@tonic-gate { 541*7c478bd9Sstevel@tonic-gate register struct file_entry *fp; 542*7c478bd9Sstevel@tonic-gate register struct bufarea *bp; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate bp = getfilentry(fip->fe_block, fip->fe_len); 545*7c478bd9Sstevel@tonic-gate if (bp == NULL) 546*7c478bd9Sstevel@tonic-gate errexit(gettext("Unable to read file entry at %x\n"), 547*7c478bd9Sstevel@tonic-gate fip->fe_block); 548*7c478bd9Sstevel@tonic-gate /* LINTED */ 549*7c478bd9Sstevel@tonic-gate fp = (struct file_entry *)bp->b_un.b_buf; 550*7c478bd9Sstevel@tonic-gate pwarn(gettext("LINK COUNT %s I=%x"), 551*7c478bd9Sstevel@tonic-gate fip->fe_type == FTYPE_DIRECTORY ? "DIR" : 552*7c478bd9Sstevel@tonic-gate fip->fe_type == FTYPE_SYMLINK ? "SYM" : 553*7c478bd9Sstevel@tonic-gate fip->fe_type == FTYPE_FILE ? "FILE" : "???", fip->fe_block); 554*7c478bd9Sstevel@tonic-gate (void) printf(gettext(" COUNT %d SHOULD BE %d"), 555*7c478bd9Sstevel@tonic-gate fip->fe_lcount, fip->fe_lseen); 556*7c478bd9Sstevel@tonic-gate if (preen) { 557*7c478bd9Sstevel@tonic-gate if (fip->fe_lseen > fip->fe_lcount) { 558*7c478bd9Sstevel@tonic-gate (void) printf("\n"); 559*7c478bd9Sstevel@tonic-gate pfatal(gettext("LINK COUNT INCREASING")); 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate (void) printf(gettext(" (ADJUSTED)\n")); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate if (preen || reply(gettext("ADJUST")) == 1) { 564*7c478bd9Sstevel@tonic-gate fp->fe_lcount = fip->fe_lseen; 565*7c478bd9Sstevel@tonic-gate putfilentry(bp); 566*7c478bd9Sstevel@tonic-gate dirty(bp); 567*7c478bd9Sstevel@tonic-gate flush(fswritefd, bp); 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate bp->b_flags &= ~B_INUSE; 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate void 573*7c478bd9Sstevel@tonic-gate dofreemap() 574*7c478bd9Sstevel@tonic-gate { 575*7c478bd9Sstevel@tonic-gate register int i; 576*7c478bd9Sstevel@tonic-gate register char *bp, *fp; 577*7c478bd9Sstevel@tonic-gate struct inodesc idesc; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate if (freemap == NULL) 580*7c478bd9Sstevel@tonic-gate return; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate /* Flip bits in the busy map */ 583*7c478bd9Sstevel@tonic-gate bp = busymap; 584*7c478bd9Sstevel@tonic-gate for (i = 0, bp = busymap; i < part_bmp_bytes; i++, bp++) 585*7c478bd9Sstevel@tonic-gate *bp = ~*bp; 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate /* Mark leftovers in byte as allocated */ 588*7c478bd9Sstevel@tonic-gate if (part_len % NBBY) 589*7c478bd9Sstevel@tonic-gate bp[-1] &= (unsigned)0xff >> (NBBY - part_len % NBBY); 590*7c478bd9Sstevel@tonic-gate bp = busymap; 591*7c478bd9Sstevel@tonic-gate fp = freemap; 592*7c478bd9Sstevel@tonic-gate bzero((char *)&idesc, sizeof (struct inodesc)); 593*7c478bd9Sstevel@tonic-gate idesc.id_type = ADDR; 594*7c478bd9Sstevel@tonic-gate if (bcmp(bp, fp, part_bmp_bytes) != 0 && 595*7c478bd9Sstevel@tonic-gate dofix(&idesc, gettext("BLK(S) MISSING IN FREE BITMAP"))) { 596*7c478bd9Sstevel@tonic-gate bcopy(bp, fp, part_bmp_bytes); 597*7c478bd9Sstevel@tonic-gate maketag(&spacep->sbd_tag, &spacep->sbd_tag); 598*7c478bd9Sstevel@tonic-gate bwrite(fswritefd, (char *)spacep, fsbtodb(part_bmp_loc), 599*7c478bd9Sstevel@tonic-gate part_bmp_sectors * secsize); 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate void 604*7c478bd9Sstevel@tonic-gate dolvint() 605*7c478bd9Sstevel@tonic-gate { 606*7c478bd9Sstevel@tonic-gate struct lvid_iu *lviup; 607*7c478bd9Sstevel@tonic-gate struct inodesc idesc; 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate bzero((char *)&idesc, sizeof (struct inodesc)); 610*7c478bd9Sstevel@tonic-gate idesc.id_type = ADDR; 611*7c478bd9Sstevel@tonic-gate lviup = (struct lvid_iu *)&lvintp->lvid_fst[2]; 612*7c478bd9Sstevel@tonic-gate if ((lvintp->lvid_fst[0] != part_len - n_blks || 613*7c478bd9Sstevel@tonic-gate lvintp->lvid_int_type != LVI_CLOSE || 614*7c478bd9Sstevel@tonic-gate lviup->lvidiu_nfiles != n_files || 615*7c478bd9Sstevel@tonic-gate lviup->lvidiu_ndirs != n_dirs || 616*7c478bd9Sstevel@tonic-gate lvintp->lvid_uniqid < maxuniqid) && 617*7c478bd9Sstevel@tonic-gate dofix(&idesc, gettext("LOGICAL VOLUME INTEGRITY COUNTS WRONG"))) { 618*7c478bd9Sstevel@tonic-gate lvintp->lvid_int_type = LVI_CLOSE; 619*7c478bd9Sstevel@tonic-gate lvintp->lvid_fst[0] = part_len - n_blks; 620*7c478bd9Sstevel@tonic-gate lviup->lvidiu_nfiles = n_files; 621*7c478bd9Sstevel@tonic-gate lviup->lvidiu_ndirs = n_dirs; 622*7c478bd9Sstevel@tonic-gate lvintp->lvid_uniqid = maxuniqid; 623*7c478bd9Sstevel@tonic-gate maketag(&lvintp->lvid_tag, &lvintp->lvid_tag); 624*7c478bd9Sstevel@tonic-gate bwrite(fswritefd, (char *)lvintp, fsbtodb(lvintblock), 625*7c478bd9Sstevel@tonic-gate lvintlen); 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate } 628