1 /* $NetBSD: inode.c,v 1.51 2013/06/18 18:18:58 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Konrad E. Schroder <perseant@hhhh.org>. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1980, 1986, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61 #include <sys/types.h> 62 #include <sys/param.h> 63 #include <sys/time.h> 64 #include <sys/buf.h> 65 #include <sys/mount.h> 66 67 #define vnode uvnode 68 #include <ufs/lfs/lfs.h> 69 #include <ufs/lfs/lfs_inode.h> 70 #undef vnode 71 72 #include <err.h> 73 #ifndef SMALL 74 #include <pwd.h> 75 #endif 76 #include <stdio.h> 77 #include <stdlib.h> 78 #include <string.h> 79 #include <util.h> 80 81 #include "bufcache.h" 82 #include "vnode.h" 83 #include "lfs_user.h" 84 85 #include "fsck.h" 86 #include "fsutil.h" 87 #include "extern.h" 88 89 extern SEGUSE *seg_table; 90 extern ulfs_daddr_t *din_table; 91 92 static int iblock(struct inodesc *, long, u_int64_t); 93 int blksreqd(struct lfs *, int); 94 int lfs_maxino(void); 95 96 /* 97 * Get a dinode of a given inum. 98 * XXX combine this function with vget. 99 */ 100 struct ulfs1_dinode * 101 ginode(ino_t ino) 102 { 103 struct uvnode *vp; 104 struct ubuf *bp; 105 IFILE *ifp; 106 107 vp = vget(fs, ino); 108 if (vp == NULL) 109 return NULL; 110 111 if (din_table[ino] == 0x0) { 112 LFS_IENTRY(ifp, fs, ino, bp); 113 din_table[ino] = ifp->if_daddr; 114 seg_table[lfs_dtosn(fs, ifp->if_daddr)].su_nbytes += LFS_DINODE1_SIZE; 115 brelse(bp, 0); 116 } 117 return (VTOI(vp)->i_din.ffs1_din); 118 } 119 120 /* 121 * Check validity of held blocks in an inode, recursing through all blocks. 122 */ 123 int 124 ckinode(struct ulfs1_dinode *dp, struct inodesc *idesc) 125 { 126 ulfs_daddr_t *ap, lbn; 127 long ret, n, ndb, offset; 128 struct ulfs1_dinode dino; 129 u_int64_t remsize, sizepb; 130 mode_t mode; 131 char pathbuf[MAXPATHLEN + 1]; 132 struct uvnode *vp, *thisvp; 133 134 if (idesc->id_fix != IGNORE) 135 idesc->id_fix = DONTKNOW; 136 idesc->id_entryno = 0; 137 idesc->id_filesize = dp->di_size; 138 mode = dp->di_mode & LFS_IFMT; 139 if (mode == LFS_IFBLK || mode == LFS_IFCHR || 140 (mode == LFS_IFLNK && (dp->di_size < fs->lfs_maxsymlinklen || 141 (fs->lfs_maxsymlinklen == 0 && 142 dp->di_blocks == 0)))) 143 return (KEEPON); 144 dino = *dp; 145 ndb = howmany(dino.di_size, fs->lfs_bsize); 146 147 thisvp = vget(fs, idesc->id_number); 148 for (lbn = 0; lbn < ULFS_NDADDR; lbn++) { 149 ap = dino.di_db + lbn; 150 if (thisvp) 151 idesc->id_numfrags = 152 lfs_numfrags(fs, VTOI(thisvp)->i_lfs_fragsize[lbn]); 153 else { 154 if (--ndb == 0 && (offset = lfs_blkoff(fs, dino.di_size)) != 0) { 155 idesc->id_numfrags = 156 lfs_numfrags(fs, lfs_fragroundup(fs, offset)); 157 } else 158 idesc->id_numfrags = fs->lfs_frag; 159 } 160 if (*ap == 0) { 161 if (idesc->id_type == DATA && ndb >= 0) { 162 /* An empty block in a directory XXX */ 163 getpathname(pathbuf, sizeof(pathbuf), 164 idesc->id_number, idesc->id_number); 165 pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [1]", 166 pathbuf, (long long)idesc->id_number); 167 if (reply("ADJUST LENGTH") == 1) { 168 vp = vget(fs, idesc->id_number); 169 dp = VTOD(vp); 170 dp->di_size = (ap - &dino.di_db[0]) * 171 fs->lfs_bsize; 172 printf( 173 "YOU MUST RERUN FSCK AFTERWARDS\n"); 174 rerun = 1; 175 inodirty(VTOI(vp)); 176 } else 177 break; 178 } 179 continue; 180 } 181 idesc->id_blkno = *ap; 182 idesc->id_lblkno = ap - &dino.di_db[0]; 183 if (idesc->id_type == ADDR) { 184 ret = (*idesc->id_func) (idesc); 185 } else 186 ret = dirscan(idesc); 187 if (ret & STOP) 188 return (ret); 189 } 190 idesc->id_numfrags = fs->lfs_frag; 191 remsize = dino.di_size - fs->lfs_bsize * ULFS_NDADDR; 192 sizepb = fs->lfs_bsize; 193 for (ap = &dino.di_ib[0], n = 1; n <= ULFS_NIADDR; ap++, n++) { 194 if (*ap) { 195 idesc->id_blkno = *ap; 196 ret = iblock(idesc, n, remsize); 197 if (ret & STOP) 198 return (ret); 199 } else { 200 if (idesc->id_type == DATA && remsize > 0) { 201 /* An empty block in a directory XXX */ 202 getpathname(pathbuf, sizeof(pathbuf), 203 idesc->id_number, idesc->id_number); 204 pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [2]", 205 pathbuf, (long long)idesc->id_number); 206 if (reply("ADJUST LENGTH") == 1) { 207 vp = vget(fs, idesc->id_number); 208 dp = VTOD(vp); 209 dp->di_size -= remsize; 210 remsize = 0; 211 printf( 212 "YOU MUST RERUN FSCK AFTERWARDS\n"); 213 rerun = 1; 214 inodirty(VTOI(vp)); 215 break; 216 } else 217 break; 218 } 219 } 220 sizepb *= LFS_NINDIR(fs); 221 remsize -= sizepb; 222 } 223 return (KEEPON); 224 } 225 226 static int 227 iblock(struct inodesc *idesc, long ilevel, u_int64_t isize) 228 { 229 ulfs_daddr_t *ap, *aplim; 230 struct ubuf *bp; 231 int i, n, (*func) (struct inodesc *), nif; 232 u_int64_t sizepb; 233 char pathbuf[MAXPATHLEN + 1], buf[BUFSIZ]; 234 struct uvnode *devvp, *vp; 235 int diddirty = 0; 236 237 if (idesc->id_type == ADDR) { 238 func = idesc->id_func; 239 n = (*func) (idesc); 240 if ((n & KEEPON) == 0) 241 return (n); 242 } else 243 func = dirscan; 244 if (chkrange(idesc->id_blkno, idesc->id_numfrags)) 245 return (SKIP); 246 247 devvp = fs->lfs_devvp; 248 bread(devvp, LFS_FSBTODB(fs, idesc->id_blkno), fs->lfs_bsize, 249 NOCRED, 0, &bp); 250 ilevel--; 251 for (sizepb = fs->lfs_bsize, i = 0; i < ilevel; i++) 252 sizepb *= LFS_NINDIR(fs); 253 if (isize > sizepb * LFS_NINDIR(fs)) 254 nif = LFS_NINDIR(fs); 255 else 256 nif = howmany(isize, sizepb); 257 if (idesc->id_func == pass1check && nif < LFS_NINDIR(fs)) { 258 aplim = ((ulfs_daddr_t *) bp->b_data) + LFS_NINDIR(fs); 259 for (ap = ((ulfs_daddr_t *) bp->b_data) + nif; ap < aplim; ap++) { 260 if (*ap == 0) 261 continue; 262 (void) sprintf(buf, "PARTIALLY TRUNCATED INODE I=%llu", 263 (unsigned long long)idesc->id_number); 264 if (dofix(idesc, buf)) { 265 *ap = 0; 266 ++diddirty; 267 } 268 } 269 } 270 aplim = ((ulfs_daddr_t *) bp->b_data) + nif; 271 for (ap = ((ulfs_daddr_t *) bp->b_data); ap < aplim; ap++) { 272 if (*ap) { 273 idesc->id_blkno = *ap; 274 if (ilevel == 0) { 275 /* 276 * dirscan needs lfs_lblkno. 277 */ 278 idesc->id_lblkno++; 279 n = (*func) (idesc); 280 } else { 281 n = iblock(idesc, ilevel, isize); 282 } 283 if (n & STOP) { 284 if (diddirty) 285 VOP_BWRITE(bp); 286 else 287 brelse(bp, 0); 288 return (n); 289 } 290 } else { 291 if (idesc->id_type == DATA && isize > 0) { 292 /* An empty block in a directory XXX */ 293 getpathname(pathbuf, sizeof(pathbuf), 294 idesc->id_number, idesc->id_number); 295 pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [3]", 296 pathbuf, (long long)idesc->id_number); 297 if (reply("ADJUST LENGTH") == 1) { 298 vp = vget(fs, idesc->id_number); 299 VTOI(vp)->i_ffs1_size -= isize; 300 isize = 0; 301 printf( 302 "YOU MUST RERUN FSCK AFTERWARDS\n"); 303 rerun = 1; 304 inodirty(VTOI(vp)); 305 if (diddirty) 306 VOP_BWRITE(bp); 307 else 308 brelse(bp, 0); 309 return (STOP); 310 } 311 } 312 } 313 isize -= sizepb; 314 } 315 if (diddirty) 316 VOP_BWRITE(bp); 317 else 318 brelse(bp, 0); 319 return (KEEPON); 320 } 321 322 /* 323 * Check that a block in a legal block number. 324 * Return 0 if in range, 1 if out of range. 325 */ 326 int 327 chkrange(daddr_t blk, int cnt) 328 { 329 if (blk < lfs_sntod(fs, 0)) { 330 return (1); 331 } 332 if (blk > maxfsblock) { 333 return (1); 334 } 335 if (blk + cnt < lfs_sntod(fs, 0)) { 336 return (1); 337 } 338 if (blk + cnt > maxfsblock) { 339 return (1); 340 } 341 return (0); 342 } 343 344 /* 345 * Routines to maintain information about directory inodes. 346 * This is built during the first pass and used during the 347 * second and third passes. 348 * 349 * Enter inodes into the cache. 350 */ 351 void 352 cacheino(struct ulfs1_dinode * dp, ino_t inumber) 353 { 354 struct inoinfo *inp; 355 struct inoinfo **inpp, **ninpsort; 356 unsigned int blks; 357 358 blks = howmany(dp->di_size, fs->lfs_bsize); 359 if (blks > ULFS_NDADDR) 360 blks = ULFS_NDADDR + ULFS_NIADDR; 361 inp = emalloc(sizeof(*inp) + (blks - 1) * sizeof(ulfs_daddr_t)); 362 inpp = &inphead[inumber % numdirs]; 363 inp->i_nexthash = *inpp; 364 *inpp = inp; 365 inp->i_child = inp->i_sibling = inp->i_parentp = 0; 366 if (inumber == ULFS_ROOTINO) 367 inp->i_parent = ULFS_ROOTINO; 368 else 369 inp->i_parent = (ino_t) 0; 370 inp->i_dotdot = (ino_t) 0; 371 inp->i_number = inumber; 372 inp->i_isize = dp->di_size; 373 374 inp->i_numblks = blks * sizeof(ulfs_daddr_t); 375 memcpy(&inp->i_blks[0], &dp->di_db[0], (size_t) inp->i_numblks); 376 if (inplast == listmax) { 377 ninpsort = erealloc(inpsort, 378 (listmax + 100) * sizeof(struct inoinfo *)); 379 inpsort = ninpsort; 380 listmax += 100; 381 } 382 inpsort[inplast++] = inp; 383 } 384 385 /* 386 * Look up an inode cache structure. 387 */ 388 struct inoinfo * 389 getinoinfo(ino_t inumber) 390 { 391 struct inoinfo *inp; 392 393 for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) { 394 if (inp->i_number != inumber) 395 continue; 396 return (inp); 397 } 398 err(EEXIT, "cannot find inode %llu\n", (unsigned long long)inumber); 399 return ((struct inoinfo *) 0); 400 } 401 402 /* 403 * Clean up all the inode cache structure. 404 */ 405 void 406 inocleanup(void) 407 { 408 struct inoinfo **inpp; 409 410 if (inphead == NULL) 411 return; 412 for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) 413 free((char *) (*inpp)); 414 free((char *) inphead); 415 free((char *) inpsort); 416 inphead = inpsort = NULL; 417 } 418 419 void 420 inodirty(struct inode *ip) 421 { 422 ip->i_flag |= IN_MODIFIED; 423 } 424 425 void 426 clri(struct inodesc * idesc, const char *type, int flag) 427 { 428 struct uvnode *vp; 429 430 vp = vget(fs, idesc->id_number); 431 if (flag & 0x1) { 432 pwarn("%s %s", type, 433 (VTOI(vp)->i_ffs1_mode & LFS_IFMT) == LFS_IFDIR ? "DIR" : "FILE"); 434 pinode(idesc->id_number); 435 } 436 if ((flag & 0x2) || preen || reply("CLEAR") == 1) { 437 if (preen && flag != 2) 438 printf(" (CLEARED)\n"); 439 n_files--; 440 (void) ckinode(VTOD(vp), idesc); 441 clearinode(idesc->id_number); 442 statemap[idesc->id_number] = USTATE; 443 vnode_destroy(vp); 444 return; 445 } 446 return; 447 } 448 449 void 450 clearinode(ino_t inumber) 451 { 452 struct ubuf *bp; 453 IFILE *ifp; 454 daddr_t daddr; 455 456 /* Send cleared inode to the free list */ 457 458 LFS_IENTRY(ifp, fs, inumber, bp); 459 daddr = ifp->if_daddr; 460 if (daddr == LFS_UNUSED_DADDR) { 461 brelse(bp, 0); 462 return; 463 } 464 ifp->if_daddr = LFS_UNUSED_DADDR; 465 ifp->if_nextfree = fs->lfs_freehd; 466 fs->lfs_freehd = inumber; 467 sbdirty(); 468 VOP_BWRITE(bp); 469 470 /* 471 * update segment usage. 472 */ 473 if (daddr != LFS_UNUSED_DADDR) { 474 SEGUSE *sup; 475 u_int32_t oldsn = lfs_dtosn(fs, daddr); 476 477 seg_table[oldsn].su_nbytes -= LFS_DINODE1_SIZE; 478 LFS_SEGENTRY(sup, fs, oldsn, bp); 479 sup->su_nbytes -= LFS_DINODE1_SIZE; 480 LFS_WRITESEGENTRY(sup, fs, oldsn, bp); /* Ifile */ 481 } 482 } 483 484 int 485 findname(struct inodesc * idesc) 486 { 487 struct lfs_direct *dirp = idesc->id_dirp; 488 size_t len; 489 char *buf; 490 491 if (dirp->d_ino != idesc->id_parent) 492 return (KEEPON); 493 if ((len = dirp->d_namlen + 1) > MAXPATHLEN) { 494 /* Truncate it but don't overflow the buffer */ 495 len = MAXPATHLEN; 496 } 497 /* this is namebuf with utils.h */ 498 buf = __UNCONST(idesc->id_name); 499 (void)memcpy(buf, dirp->d_name, len); 500 return (STOP | FOUND); 501 } 502 503 int 504 findino(struct inodesc * idesc) 505 { 506 struct lfs_direct *dirp = idesc->id_dirp; 507 508 if (dirp->d_ino == 0) 509 return (KEEPON); 510 if (strcmp(dirp->d_name, idesc->id_name) == 0 && 511 dirp->d_ino >= ULFS_ROOTINO && dirp->d_ino < maxino) { 512 idesc->id_parent = dirp->d_ino; 513 return (STOP | FOUND); 514 } 515 return (KEEPON); 516 } 517 518 void 519 pinode(ino_t ino) 520 { 521 struct ulfs1_dinode *dp; 522 struct passwd *pw; 523 524 printf(" I=%llu ", (unsigned long long)ino); 525 if (ino < ULFS_ROOTINO || ino >= maxino) 526 return; 527 dp = ginode(ino); 528 if (dp) { 529 printf(" OWNER="); 530 #ifndef SMALL 531 if (Uflag && (pw = getpwuid((int) dp->di_uid)) != 0) 532 printf("%s ", pw->pw_name); 533 else 534 #endif 535 printf("%u ", (unsigned) dp->di_uid); 536 printf("MODE=%o\n", dp->di_mode); 537 if (preen) 538 printf("%s: ", cdevname()); 539 printf("SIZE=%llu ", (unsigned long long) dp->di_size); 540 printf("MTIME=%s ", print_mtime(dp->di_mtime)); 541 } 542 } 543 544 void 545 blkerror(ino_t ino, const char *type, daddr_t blk) 546 { 547 548 pfatal("%lld %s I=%llu", (long long) blk, type, 549 (unsigned long long)ino); 550 printf("\n"); 551 if (exitonfail) 552 exit(1); 553 switch (statemap[ino]) { 554 555 case FSTATE: 556 statemap[ino] = FCLEAR; 557 return; 558 559 case DSTATE: 560 statemap[ino] = DCLEAR; 561 return; 562 563 case FCLEAR: 564 case DCLEAR: 565 return; 566 567 default: 568 err(EEXIT, "BAD STATE %d TO BLKERR\n", statemap[ino]); 569 /* NOTREACHED */ 570 } 571 } 572 573 /* 574 * allocate an unused inode 575 */ 576 ino_t 577 allocino(ino_t request, int type) 578 { 579 ino_t ino; 580 struct ulfs1_dinode *dp; 581 time_t t; 582 struct uvnode *vp; 583 struct ubuf *bp; 584 585 if (request == 0) 586 request = ULFS_ROOTINO; 587 else if (statemap[request] != USTATE) 588 return (0); 589 for (ino = request; ino < maxino; ino++) 590 if (statemap[ino] == USTATE) 591 break; 592 if (ino == maxino) 593 extend_ifile(fs); 594 595 switch (type & LFS_IFMT) { 596 case LFS_IFDIR: 597 statemap[ino] = DSTATE; 598 break; 599 case LFS_IFREG: 600 case LFS_IFLNK: 601 statemap[ino] = FSTATE; 602 break; 603 default: 604 return (0); 605 } 606 vp = lfs_valloc(fs, ino); 607 if (vp == NULL) 608 return (0); 609 dp = (VTOI(vp)->i_din.ffs1_din); 610 bp = getblk(vp, 0, fs->lfs_fsize); 611 VOP_BWRITE(bp); 612 dp->di_mode = type; 613 (void) time(&t); 614 dp->di_atime = t; 615 dp->di_mtime = dp->di_ctime = dp->di_atime; 616 dp->di_size = fs->lfs_fsize; 617 dp->di_blocks = lfs_btofsb(fs, fs->lfs_fsize); 618 n_files++; 619 inodirty(VTOI(vp)); 620 typemap[ino] = LFS_IFTODT(type); 621 return (ino); 622 } 623 624 /* 625 * deallocate an inode 626 */ 627 void 628 freeino(ino_t ino) 629 { 630 struct inodesc idesc; 631 struct uvnode *vp; 632 633 memset(&idesc, 0, sizeof(struct inodesc)); 634 idesc.id_type = ADDR; 635 idesc.id_func = pass4check; 636 idesc.id_number = ino; 637 vp = vget(fs, ino); 638 (void) ckinode(VTOD(vp), &idesc); 639 clearinode(ino); 640 statemap[ino] = USTATE; 641 vnode_destroy(vp); 642 643 n_files--; 644 } 645