116259Smckusick #ifndef lint 2*17954Smckusick static char version[] = "@(#)dir.c 3.6 (Berkeley) 02/13/85"; 316259Smckusick #endif 416259Smckusick 516259Smckusick #include <sys/param.h> 616259Smckusick #include <sys/inode.h> 716259Smckusick #include <sys/fs.h> 816259Smckusick #define KERNEL 916259Smckusick #include <sys/dir.h> 1016259Smckusick #undef KERNEL 1116259Smckusick #include "fsck.h" 1216259Smckusick 1316259Smckusick #define MINDIRSIZE (sizeof (struct dirtemplate)) 1416259Smckusick 1516259Smckusick char *endpathname = &pathname[BUFSIZ - 2]; 1616259Smckusick char *lfname = "lost+found"; 1717944Smckusick struct dirtemplate emptydir = { 0, DIRBLKSIZ }; 18*17954Smckusick struct dirtemplate dirhead = { 0, 12, 1, ".", 0, DIRBLKSIZ - 12, 2, ".." }; 1916259Smckusick 2016259Smckusick DIRECT *fsck_readdir(); 2116259Smckusick 2216259Smckusick descend(parentino, inumber) 2316259Smckusick struct inodesc *parentino; 2416259Smckusick ino_t inumber; 2516259Smckusick { 2616259Smckusick register DINODE *dp; 2716259Smckusick struct inodesc curino; 2816259Smckusick 2916259Smckusick bzero((char *)&curino, sizeof(struct inodesc)); 3017936Smckusick if (statemap[inumber] != DSTATE) 3117936Smckusick errexit("BAD INODE %d TO DESCEND", statemap[inumber]); 3217936Smckusick statemap[inumber] = DFOUND; 3317943Smckusick dp = ginode(inumber); 3416259Smckusick if (dp->di_size == 0) { 3516259Smckusick direrr(inumber, "ZERO LENGTH DIRECTORY"); 3616259Smckusick if (reply("REMOVE") == 1) 3717936Smckusick statemap[inumber] = DCLEAR; 3816259Smckusick return; 3916259Smckusick } 4016259Smckusick if (dp->di_size < MINDIRSIZE) { 4116259Smckusick direrr(inumber, "DIRECTORY TOO SHORT"); 4216259Smckusick dp->di_size = MINDIRSIZE; 4316259Smckusick if (reply("FIX") == 1) 4416259Smckusick inodirty(); 4516259Smckusick } 4616259Smckusick curino.id_type = DATA; 4716259Smckusick curino.id_func = parentino->id_func; 4816259Smckusick curino.id_parent = parentino->id_number; 4916259Smckusick curino.id_number = inumber; 5016259Smckusick curino.id_filesize = dp->di_size; 5116259Smckusick (void)ckinode(dp, &curino); 5216259Smckusick } 5316259Smckusick 5416259Smckusick dirscan(idesc) 5516259Smckusick register struct inodesc *idesc; 5616259Smckusick { 5716259Smckusick register DIRECT *dp; 5816259Smckusick int dsize, n; 5916259Smckusick long blksiz; 6016259Smckusick char dbuf[DIRBLKSIZ]; 6116259Smckusick 6216259Smckusick if (idesc->id_type != DATA) 6316259Smckusick errexit("wrong type to dirscan %d\n", idesc->id_type); 6416259Smckusick blksiz = idesc->id_numfrags * sblock.fs_fsize; 6516259Smckusick if (outrange(idesc->id_blkno, idesc->id_numfrags)) { 6616259Smckusick idesc->id_filesize -= blksiz; 6716259Smckusick return (SKIP); 6816259Smckusick } 6916259Smckusick idesc->id_loc = 0; 7016259Smckusick for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) { 7116259Smckusick dsize = dp->d_reclen; 7216259Smckusick bcopy((char *)dp, dbuf, dsize); 7316259Smckusick idesc->id_dirp = (DIRECT *)dbuf; 7416259Smckusick if ((n = (*idesc->id_func)(idesc)) & ALTERED) { 7516259Smckusick if (getblk(&fileblk, idesc->id_blkno, blksiz) != NULL) { 7616259Smckusick bcopy(dbuf, (char *)dp, dsize); 7716259Smckusick dirty(&fileblk); 7816259Smckusick sbdirty(); 7916259Smckusick } else 8016259Smckusick n &= ~ALTERED; 8116259Smckusick } 8216259Smckusick if (n & STOP) 8316259Smckusick return (n); 8416259Smckusick } 8516259Smckusick return (idesc->id_filesize > 0 ? KEEPON : STOP); 8616259Smckusick } 8716259Smckusick 8816259Smckusick /* 8916259Smckusick * get next entry in a directory. 9016259Smckusick */ 9116259Smckusick DIRECT * 9216259Smckusick fsck_readdir(idesc) 9316259Smckusick register struct inodesc *idesc; 9416259Smckusick { 9516259Smckusick register DIRECT *dp, *ndp; 9616259Smckusick long size, blksiz; 9716259Smckusick 9816259Smckusick blksiz = idesc->id_numfrags * sblock.fs_fsize; 9916259Smckusick if (getblk(&fileblk, idesc->id_blkno, blksiz) == NULL) { 10016259Smckusick idesc->id_filesize -= blksiz - idesc->id_loc; 10116259Smckusick return NULL; 10216259Smckusick } 10316259Smckusick if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 && 10416259Smckusick idesc->id_loc < blksiz) { 10516259Smckusick dp = (DIRECT *)(dirblk.b_buf + idesc->id_loc); 10616259Smckusick if (dircheck(idesc, dp)) 10716259Smckusick goto dpok; 10816259Smckusick idesc->id_loc += DIRBLKSIZ; 10916259Smckusick idesc->id_filesize -= DIRBLKSIZ; 11016259Smckusick dp->d_reclen = DIRBLKSIZ; 11116259Smckusick dp->d_ino = 0; 11216259Smckusick dp->d_namlen = 0; 11316259Smckusick dp->d_name[0] = '\0'; 11417930Smckusick if (dofix(idesc, "DIRECTORY CORRUPTED")) 11516259Smckusick dirty(&fileblk); 11616259Smckusick return (dp); 11716259Smckusick } 11816259Smckusick dpok: 11916259Smckusick if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz) 12016259Smckusick return NULL; 12116259Smckusick dp = (DIRECT *)(dirblk.b_buf + idesc->id_loc); 12216259Smckusick idesc->id_loc += dp->d_reclen; 12316259Smckusick idesc->id_filesize -= dp->d_reclen; 12416259Smckusick if ((idesc->id_loc % DIRBLKSIZ) == 0) 12516259Smckusick return (dp); 12616259Smckusick ndp = (DIRECT *)(dirblk.b_buf + idesc->id_loc); 12716259Smckusick if (idesc->id_loc < blksiz && idesc->id_filesize > 0 && 12816259Smckusick dircheck(idesc, ndp) == 0) { 12916259Smckusick size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 13016259Smckusick dp->d_reclen += size; 13116259Smckusick idesc->id_loc += size; 13216259Smckusick idesc->id_filesize -= size; 13317930Smckusick if (dofix(idesc, "DIRECTORY CORRUPTED")) 13416259Smckusick dirty(&fileblk); 13516259Smckusick } 13616259Smckusick return (dp); 13716259Smckusick } 13816259Smckusick 13916259Smckusick /* 14016259Smckusick * Verify that a directory entry is valid. 14116259Smckusick * This is a superset of the checks made in the kernel. 14216259Smckusick */ 14316259Smckusick dircheck(idesc, dp) 14416259Smckusick struct inodesc *idesc; 14516259Smckusick register DIRECT *dp; 14616259Smckusick { 14716259Smckusick register int size; 14816259Smckusick register char *cp; 14916259Smckusick int spaceleft; 15016259Smckusick 15116259Smckusick size = DIRSIZ(dp); 15216259Smckusick spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 15316259Smckusick if (dp->d_ino < imax && 15416259Smckusick dp->d_reclen != 0 && 15516259Smckusick dp->d_reclen <= spaceleft && 15616259Smckusick (dp->d_reclen & 0x3) == 0 && 15716259Smckusick dp->d_reclen >= size && 15816259Smckusick idesc->id_filesize >= size && 15916259Smckusick dp->d_namlen <= MAXNAMLEN) { 16016259Smckusick if (dp->d_ino == 0) 16116259Smckusick return (1); 16216259Smckusick for (cp = dp->d_name, size = 0; size < dp->d_namlen; size++) 16316259Smckusick if (*cp == 0 || (*cp++ & 0200)) 16416259Smckusick return (0); 16516259Smckusick if (*cp == 0) 16616259Smckusick return (1); 16716259Smckusick } 16816259Smckusick return (0); 16916259Smckusick } 17016259Smckusick 17116259Smckusick direrr(ino, s) 17216259Smckusick ino_t ino; 17316259Smckusick char *s; 17416259Smckusick { 17516259Smckusick register DINODE *dp; 17616259Smckusick 17716259Smckusick pwarn("%s ", s); 17816259Smckusick pinode(ino); 17916259Smckusick printf("\n"); 18017943Smckusick if (ino < ROOTINO || ino > imax) { 18117943Smckusick pfatal("NAME=%s\n", pathname); 18217943Smckusick return; 18317943Smckusick } 18417943Smckusick dp = ginode(ino); 18517943Smckusick if (ftypeok(dp)) 18617930Smckusick pfatal("%s=%s\n", DIRCT(dp) ? "DIR" : "FILE", pathname); 18716259Smckusick else 18816259Smckusick pfatal("NAME=%s\n", pathname); 18916259Smckusick } 19016259Smckusick 19116259Smckusick adjust(idesc, lcnt) 19216259Smckusick register struct inodesc *idesc; 19316259Smckusick short lcnt; 19416259Smckusick { 19516259Smckusick register DINODE *dp; 19616259Smckusick 19717943Smckusick dp = ginode(idesc->id_number); 19816259Smckusick if (dp->di_nlink == lcnt) { 19916259Smckusick if (linkup(idesc->id_number, (ino_t)0) == 0) 20016259Smckusick clri(idesc, "UNREF", 0); 20117936Smckusick } else { 20217930Smckusick pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname : 20317930Smckusick (DIRCT(dp) ? "DIR" : "FILE")); 20416259Smckusick pinode(idesc->id_number); 20516259Smckusick printf(" COUNT %d SHOULD BE %d", 20616259Smckusick dp->di_nlink, dp->di_nlink-lcnt); 20716259Smckusick if (preen) { 20816259Smckusick if (lcnt < 0) { 20916259Smckusick printf("\n"); 21017930Smckusick pfatal("LINK COUNT INCREASING"); 21116259Smckusick } 21216259Smckusick printf(" (ADJUSTED)\n"); 21316259Smckusick } 21416259Smckusick if (preen || reply("ADJUST") == 1) { 21516259Smckusick dp->di_nlink -= lcnt; 21616259Smckusick inodirty(); 21716259Smckusick } 21816259Smckusick } 21916259Smckusick } 22016259Smckusick 22116259Smckusick mkentry(idesc) 22216259Smckusick struct inodesc *idesc; 22316259Smckusick { 22416259Smckusick register DIRECT *dirp = idesc->id_dirp; 22516259Smckusick DIRECT newent; 22616259Smckusick int newlen, oldlen; 22716259Smckusick 22816259Smckusick newent.d_namlen = 11; 22916259Smckusick newlen = DIRSIZ(&newent); 23016259Smckusick if (dirp->d_ino != 0) 23116259Smckusick oldlen = DIRSIZ(dirp); 23216259Smckusick else 23316259Smckusick oldlen = 0; 23416259Smckusick if (dirp->d_reclen - oldlen < newlen) 23516259Smckusick return (KEEPON); 23616259Smckusick newent.d_reclen = dirp->d_reclen - oldlen; 23716259Smckusick dirp->d_reclen = oldlen; 23816259Smckusick dirp = (struct direct *)(((char *)dirp) + oldlen); 23916259Smckusick dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */ 24016259Smckusick dirp->d_reclen = newent.d_reclen; 241*17954Smckusick dirp->d_namlen = strlen(idesc->id_name); 242*17954Smckusick bcopy(idesc->id_name, dirp->d_name, dirp->d_namlen + 1); 24316259Smckusick return (ALTERED|STOP); 24416259Smckusick } 24516259Smckusick 24616259Smckusick chgdd(idesc) 24716259Smckusick struct inodesc *idesc; 24816259Smckusick { 24916259Smckusick register DIRECT *dirp = idesc->id_dirp; 25016259Smckusick 25116259Smckusick if (dirp->d_name[0] == '.' && dirp->d_name[1] == '.' && 25216259Smckusick dirp->d_name[2] == 0) { 25316259Smckusick dirp->d_ino = lfdir; 25416259Smckusick return (ALTERED|STOP); 25516259Smckusick } 25616259Smckusick return (KEEPON); 25716259Smckusick } 25816259Smckusick 25916259Smckusick linkup(orphan, pdir) 26016259Smckusick ino_t orphan; 26116259Smckusick ino_t pdir; 26216259Smckusick { 26316259Smckusick register DINODE *dp; 26416259Smckusick int lostdir, len; 265*17954Smckusick ino_t oldlfdir; 26616259Smckusick struct inodesc idesc; 267*17954Smckusick char tempname[BUFSIZ]; 26816259Smckusick 26916259Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 27017943Smckusick dp = ginode(orphan); 27117930Smckusick lostdir = DIRCT(dp); 27216259Smckusick pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); 27316259Smckusick pinode(orphan); 27416259Smckusick if (preen && dp->di_size == 0) 27516259Smckusick return (0); 27616259Smckusick if (preen) 27716259Smckusick printf(" (RECONNECTED)\n"); 27816259Smckusick else 27916259Smckusick if (reply("RECONNECT") == 0) 28016259Smckusick return (0); 28116259Smckusick pathp = pathname; 28216259Smckusick *pathp++ = '/'; 28316259Smckusick *pathp = '\0'; 28416259Smckusick if (lfdir == 0) { 28517943Smckusick dp = ginode(ROOTINO); 28617930Smckusick idesc.id_name = lfname; 28716259Smckusick idesc.id_type = DATA; 28816259Smckusick idesc.id_func = findino; 28916259Smckusick idesc.id_number = ROOTINO; 29016259Smckusick idesc.id_filesize = dp->di_size; 29116259Smckusick (void)ckinode(dp, &idesc); 292*17954Smckusick if (idesc.id_parent >= ROOTINO && idesc.id_parent < imax) { 293*17954Smckusick lfdir = idesc.id_parent; 294*17954Smckusick } else { 295*17954Smckusick pwarn("NO lost+found DIRECTORY"); 296*17954Smckusick if (preen || reply("CREATE")) { 297*17954Smckusick idesc.id_func = mkentry; 298*17954Smckusick idesc.id_parent = allocdir(ROOTINO, 0); 299*17954Smckusick idesc.id_filesize = dp->di_size; 300*17954Smckusick if (idesc.id_parent != 0) { 301*17954Smckusick if (makeentry(dp, &idesc) != 0) { 302*17954Smckusick lfdir = idesc.id_parent; 303*17954Smckusick if (preen) 304*17954Smckusick printf(" (CREATED)\n"); 305*17954Smckusick } else { 306*17954Smckusick freedir(idesc.id_parent, ROOTINO); 307*17954Smckusick if (preen) 308*17954Smckusick printf("\n"); 309*17954Smckusick } 310*17954Smckusick } 311*17954Smckusick } 312*17954Smckusick } 31317943Smckusick if (lfdir == 0) { 314*17954Smckusick pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY"); 31516259Smckusick printf("\n\n"); 31616259Smckusick return (0); 31716259Smckusick } 31816259Smckusick } 31917943Smckusick dp = ginode(lfdir); 32017943Smckusick if (!DIRCT(dp) || statemap[lfdir] != DFOUND) { 32116259Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 32216259Smckusick printf("\n\n"); 32316259Smckusick return (0); 32416259Smckusick } 32517944Smckusick if (dp->di_size % DIRBLKSIZ) { 32617944Smckusick dp->di_size = roundup(dp->di_size, DIRBLKSIZ); 32716259Smckusick inodirty(); 32816259Smckusick } 32916259Smckusick len = strlen(lfname); 33016259Smckusick bcopy(lfname, pathp, len + 1); 33116259Smckusick pathp += len; 33216259Smckusick idesc.id_type = DATA; 33316259Smckusick idesc.id_func = mkentry; 33416259Smckusick idesc.id_number = lfdir; 33516259Smckusick idesc.id_filesize = dp->di_size; 33616259Smckusick idesc.id_parent = orphan; /* this is the inode to enter */ 33716259Smckusick idesc.id_fix = DONTKNOW; 338*17954Smckusick idesc.id_name = tempname; 339*17954Smckusick len = lftempname(idesc.id_name, orphan); 34017944Smckusick if (makeentry(dp, &idesc) == 0) { 34116259Smckusick pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); 34216259Smckusick printf("\n\n"); 34316259Smckusick return (0); 34416259Smckusick } 34516259Smckusick lncntp[orphan]--; 34616259Smckusick *pathp++ = '/'; 347*17954Smckusick bcopy(idesc.id_name, pathp, len + 1); 348*17954Smckusick pathp += len; 34916259Smckusick if (lostdir) { 35016259Smckusick dp = ginode(orphan); 35116259Smckusick idesc.id_type = DATA; 35216259Smckusick idesc.id_func = chgdd; 35316259Smckusick idesc.id_number = orphan; 35416259Smckusick idesc.id_filesize = dp->di_size; 35516259Smckusick idesc.id_fix = DONTKNOW; 35616259Smckusick (void)ckinode(dp, &idesc); 35717943Smckusick dp = ginode(lfdir); 35817943Smckusick dp->di_nlink++; 35917943Smckusick inodirty(); 36017943Smckusick lncntp[lfdir]++; 36116259Smckusick pwarn("DIR I=%u CONNECTED. ", orphan); 36216259Smckusick printf("PARENT WAS I=%u\n", pdir); 36316259Smckusick if (preen == 0) 36416259Smckusick printf("\n"); 36516259Smckusick } 36616259Smckusick return (1); 36716259Smckusick } 36816259Smckusick 36916259Smckusick /* 37017944Smckusick * make an entry in a directory 37117944Smckusick */ 37217944Smckusick makeentry(dp, idesc) 37317944Smckusick DINODE *dp; 37417944Smckusick struct inodesc *idesc; 37517944Smckusick { 37617944Smckusick 37717944Smckusick if ((ckinode(dp, idesc) & ALTERED) != 0) 37817944Smckusick return (1); 37917944Smckusick if (expanddir(dp) == 0) 38017944Smckusick return (0); 38117944Smckusick idesc->id_filesize = dp->di_size; 38217944Smckusick return (ckinode(dp, idesc) & ALTERED); 38317944Smckusick } 38417944Smckusick 38517944Smckusick /* 38617944Smckusick * Attempt to expand the size of a directory 38717944Smckusick */ 38817944Smckusick expanddir(dp) 38917944Smckusick register DINODE *dp; 39017944Smckusick { 39117944Smckusick daddr_t lastbn, newblk; 39217944Smckusick char *cp, firstblk[DIRBLKSIZ]; 39317944Smckusick 39417944Smckusick lastbn = lblkno(&sblock, dp->di_size); 39517944Smckusick if (lastbn >= NDADDR - 1) 39617944Smckusick return (0); 39717944Smckusick if ((newblk = allocblk(sblock.fs_frag)) == 0) 39817944Smckusick return (0); 39917944Smckusick dp->di_db[lastbn + 1] = dp->di_db[lastbn]; 40017944Smckusick dp->di_db[lastbn] = newblk; 40117944Smckusick dp->di_size += sblock.fs_bsize; 40217944Smckusick dp->di_blocks += btodb(sblock.fs_bsize); 40317944Smckusick if (getblk(&fileblk, dp->di_db[lastbn + 1], 40417944Smckusick dblksize(&sblock, dp, lastbn + 1)) == NULL) 40517944Smckusick goto bad; 40617944Smckusick bcopy(dirblk.b_buf, firstblk, DIRBLKSIZ); 40717944Smckusick if (getblk(&fileblk, newblk, sblock.fs_bsize) == NULL) 40817944Smckusick goto bad; 40917944Smckusick bcopy(firstblk, dirblk.b_buf, DIRBLKSIZ); 41017944Smckusick for (cp = &dirblk.b_buf[DIRBLKSIZ]; 41117944Smckusick cp < &dirblk.b_buf[sblock.fs_bsize]; 41217944Smckusick cp += DIRBLKSIZ) 41317944Smckusick bcopy((char *)&emptydir, cp, sizeof emptydir); 41417944Smckusick dirty(&fileblk); 41517944Smckusick if (getblk(&fileblk, dp->di_db[lastbn + 1], 41617944Smckusick dblksize(&sblock, dp, lastbn + 1)) == NULL) 41717944Smckusick goto bad; 41817944Smckusick bcopy((char *)&emptydir, dirblk.b_buf, sizeof emptydir); 41917944Smckusick pwarn("NO SPACE LEFT IN %s", pathname); 42017944Smckusick if (preen) 42117944Smckusick printf(" (EXPANDED)\n"); 42217944Smckusick else if (reply("EXPAND") == 0) 42317944Smckusick goto bad; 42417944Smckusick dirty(&fileblk); 42517944Smckusick inodirty(); 42617944Smckusick return (1); 42717944Smckusick bad: 42817944Smckusick dp->di_db[lastbn] = dp->di_db[lastbn + 1]; 42917944Smckusick dp->di_db[lastbn + 1] = 0; 43017944Smckusick dp->di_size -= sblock.fs_bsize; 43117944Smckusick dp->di_blocks -= btodb(sblock.fs_bsize); 43217944Smckusick freeblk(newblk, sblock.fs_frag); 43317944Smckusick return (0); 43417944Smckusick } 43517944Smckusick 43617944Smckusick /* 437*17954Smckusick * allocate a new directory 438*17954Smckusick */ 439*17954Smckusick allocdir(parent, request) 440*17954Smckusick ino_t parent, request; 441*17954Smckusick { 442*17954Smckusick ino_t ino; 443*17954Smckusick char *cp; 444*17954Smckusick DINODE *dp; 445*17954Smckusick 446*17954Smckusick ino = allocino(request, IFDIR|0755); 447*17954Smckusick dirhead.dot_ino = ino; 448*17954Smckusick dirhead.dotdot_ino = parent; 449*17954Smckusick dp = ginode(ino); 450*17954Smckusick if (getblk(&fileblk, dp->di_db[0], sblock.fs_fsize) == NULL) { 451*17954Smckusick freeino(ino); 452*17954Smckusick return (0); 453*17954Smckusick } 454*17954Smckusick bcopy((char *)&dirhead, dirblk.b_buf, sizeof dirhead); 455*17954Smckusick for (cp = &dirblk.b_buf[DIRBLKSIZ]; 456*17954Smckusick cp < &dirblk.b_buf[sblock.fs_fsize]; 457*17954Smckusick cp += DIRBLKSIZ) 458*17954Smckusick bcopy((char *)&emptydir, cp, sizeof emptydir); 459*17954Smckusick dirty(&fileblk); 460*17954Smckusick dp->di_nlink = 2; 461*17954Smckusick inodirty(); 462*17954Smckusick if (ino == ROOTINO) { 463*17954Smckusick lncntp[ino] = dp->di_nlink; 464*17954Smckusick return(ino); 465*17954Smckusick } 466*17954Smckusick if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) { 467*17954Smckusick freeino(ino); 468*17954Smckusick return (0); 469*17954Smckusick } 470*17954Smckusick statemap[ino] = statemap[parent]; 471*17954Smckusick if (statemap[ino] == DSTATE) { 472*17954Smckusick lncntp[ino] = dp->di_nlink; 473*17954Smckusick lncntp[parent]++; 474*17954Smckusick } 475*17954Smckusick dp = ginode(parent); 476*17954Smckusick dp->di_nlink++; 477*17954Smckusick inodirty(); 478*17954Smckusick return (ino); 479*17954Smckusick } 480*17954Smckusick 481*17954Smckusick /* 482*17954Smckusick * free a directory inode 483*17954Smckusick */ 484*17954Smckusick freedir(ino, parent) 485*17954Smckusick ino_t ino, parent; 486*17954Smckusick { 487*17954Smckusick DINODE *dp; 488*17954Smckusick 489*17954Smckusick if (ino != parent) { 490*17954Smckusick dp = ginode(parent); 491*17954Smckusick dp->di_nlink--; 492*17954Smckusick inodirty(); 493*17954Smckusick } 494*17954Smckusick freeino(ino); 495*17954Smckusick } 496*17954Smckusick 497*17954Smckusick /* 49816259Smckusick * generate a temporary name for the lost+found directory. 49916259Smckusick */ 50016259Smckusick lftempname(bufp, ino) 50116259Smckusick char *bufp; 50216259Smckusick ino_t ino; 50316259Smckusick { 50416259Smckusick register ino_t in; 50516259Smckusick register char *cp; 50616259Smckusick int namlen; 50716259Smckusick 50816259Smckusick cp = bufp + 2; 50916259Smckusick for (in = imax; in > 0; in /= 10) 51016259Smckusick cp++; 51116259Smckusick *--cp = 0; 51216259Smckusick namlen = cp - bufp; 51316259Smckusick in = ino; 51416259Smckusick while (cp > bufp) { 51516259Smckusick *--cp = (in % 10) + '0'; 51616259Smckusick in /= 10; 51716259Smckusick } 51816259Smckusick *cp = '#'; 51916259Smckusick return (namlen); 52016259Smckusick } 521