1 /* 2 * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs_vnops.c 7.66 (Berkeley) 09/20/91 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "namei.h" 13 #include "resourcevar.h" 14 #include "kernel.h" 15 #include "file.h" 16 #include "stat.h" 17 #include "buf.h" 18 #include "proc.h" 19 #include "conf.h" 20 #include "mount.h" 21 #include "vnode.h" 22 #include "specdev.h" 23 #include "fifo.h" 24 #include "malloc.h" 25 26 #include "../ufs/lockf.h" 27 #include "../ufs/quota.h" 28 #include "../ufs/inode.h" 29 #include "../ufs/dir.h" 30 #include "lfs.h" 31 #include "lfs_extern.h" 32 33 static int chmod1 __P((struct vnode *, int, struct proc *)); 34 static int chown1 __P((struct vnode *, uid_t, gid_t, struct proc *)); 35 static int maknode __P((int, struct nameidata *, struct inode **)); 36 37 /* 38 * Create a regular file 39 */ 40 lfs_create(ndp, vap, p) 41 struct nameidata *ndp; 42 struct vattr *vap; 43 struct proc *p; 44 { 45 struct inode *ip; 46 int error; 47 48 printf("lfs_create\n"); 49 if (error = maknode(MAKEIMODE(vap->va_type, vap->va_mode), ndp, &ip)) 50 return (error); 51 ndp->ni_vp = ITOV(ip); 52 return (0); 53 } 54 55 /* 56 * Mknod vnode call 57 */ 58 /* ARGSUSED */ 59 lfs_mknod(ndp, vap, cred, p) 60 struct nameidata *ndp; 61 struct ucred *cred; 62 struct vattr *vap; 63 struct proc *p; 64 { 65 register struct vnode *vp; 66 struct inode *ip; 67 int error; 68 69 printf("lfs_mknod\n"); 70 if (error = maknode(MAKEIMODE(vap->va_type, vap->va_mode), ndp, &ip)) 71 return (error); 72 ip->i_flag |= IACC|IUPD|ICHG; 73 if (vap->va_rdev != VNOVAL) { 74 /* 75 * Want to be able to use this to make badblock 76 * inodes, so don't truncate the dev number. 77 */ 78 ip->i_rdev = vap->va_rdev; 79 } 80 /* 81 * Remove inode so that it will be reloaded by iget and 82 * checked to see if it is an alias of an existing entry 83 * in the inode cache. 84 */ 85 vp = ITOV(ip); 86 vput(vp); 87 vp->v_type = VNON; 88 vgone(vp); 89 return (0); 90 } 91 92 /* ARGSUSED */ 93 lfs_getattr(vp, vap, cred, p) 94 struct vnode *vp; 95 register struct vattr *vap; 96 struct ucred *cred; 97 struct proc *p; 98 { 99 register struct inode *ip = VTOI(vp); 100 101 printf("lfs_getattr\n"); 102 ITIMES(ip, &time, &time); 103 /* 104 * Copy from inode table 105 */ 106 vap->va_fsid = ip->i_dev; 107 vap->va_fileid = ip->i_number; 108 vap->va_mode = ip->i_mode & ~IFMT; 109 vap->va_nlink = ip->i_nlink; 110 vap->va_uid = ip->i_uid; 111 vap->va_gid = ip->i_gid; 112 vap->va_rdev = (dev_t)ip->i_rdev; 113 #ifdef tahoe 114 vap->va_size = ip->i_size; 115 vap->va_size_rsv = 0; 116 #else 117 vap->va_qsize = ip->i_din.di_qsize; 118 #endif 119 vap->va_atime.tv_sec = ip->i_atime; 120 vap->va_atime.tv_usec = 0; 121 vap->va_mtime.tv_sec = ip->i_mtime; 122 vap->va_mtime.tv_usec = 0; 123 vap->va_ctime.tv_sec = ip->i_ctime; 124 vap->va_ctime.tv_usec = 0; 125 vap->va_flags = ip->i_flags; 126 vap->va_gen = ip->i_gen; 127 /* this doesn't belong here */ 128 if (vp->v_type == VBLK) 129 vap->va_blocksize = BLKDEV_IOSIZE; 130 else if (vp->v_type == VCHR) 131 vap->va_blocksize = MAXBSIZE; 132 else 133 vap->va_blocksize = ip->i_lfs->lfs_bsize; /* LFS */ 134 vap->va_bytes = dbtob(ip->i_blocks); 135 vap->va_bytes_rsv = 0; 136 vap->va_type = vp->v_type; 137 return (0); 138 } 139 140 /* 141 * Set attribute vnode op. called from several syscalls 142 */ 143 lfs_setattr(vp, vap, cred, p) 144 register struct vnode *vp; 145 register struct vattr *vap; 146 register struct ucred *cred; 147 struct proc *p; 148 { 149 register struct inode *ip = VTOI(vp); 150 int error = 0; 151 152 printf("lfs_setattr\n"); 153 /* 154 * Check for unsettable attributes. 155 */ 156 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 157 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 158 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 159 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 160 return (EINVAL); 161 } 162 /* 163 * Go through the fields and update iff not VNOVAL. 164 */ 165 if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL) 166 if (error = chown1(vp, vap->va_uid, vap->va_gid, p)) 167 return (error); 168 if (vap->va_size != VNOVAL) { 169 if (vp->v_type == VDIR) 170 return (EISDIR); /* LFS */ 171 if (error = lfs_itrunc(ip, vap->va_size, 0)) /* XXX IO_SYNC? */ 172 return (error); 173 } 174 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 175 if (cred->cr_uid != ip->i_uid && 176 (error = suser(cred, &p->p_acflag))) 177 return (error); 178 if (vap->va_atime.tv_sec != VNOVAL) 179 ip->i_flag |= IACC; 180 if (vap->va_mtime.tv_sec != VNOVAL) 181 ip->i_flag |= IUPD; 182 ip->i_flag |= ICHG; /* LFS */ 183 if (error = lfs_iupdat(ip, &vap->va_atime, &vap->va_mtime, 1)) 184 return (error); 185 } 186 if (vap->va_mode != (u_short)VNOVAL) 187 error = chmod1(vp, (int)vap->va_mode, p); 188 if (vap->va_flags != VNOVAL) { 189 if (cred->cr_uid != ip->i_uid && 190 (error = suser(cred, &p->p_acflag))) 191 return (error); 192 if (cred->cr_uid == 0) { 193 ip->i_flags = vap->va_flags; 194 } else { 195 ip->i_flags &= 0xffff0000; 196 ip->i_flags |= (vap->va_flags & 0xffff); 197 } 198 ip->i_flag |= ICHG; 199 } 200 return (error); 201 } 202 203 /* 204 * Vnode op for reading. 205 */ 206 /* ARGSUSED */ 207 lfs_read(vp, uio, ioflag, cred) 208 struct vnode *vp; 209 register struct uio *uio; 210 int ioflag; 211 struct ucred *cred; 212 { 213 register struct inode *ip = VTOI(vp); 214 register LFS *fs; /* LFS */ 215 struct buf *bp; 216 daddr_t lbn, bn, rablock; 217 int size, diff, error = 0; 218 long n, on, type; 219 220 printf("lfs_read: ino %d\n", ip->i_number); 221 #ifdef DIAGNOSTIC 222 if (uio->uio_rw != UIO_READ) 223 panic("ufs_read mode"); 224 type = ip->i_mode & IFMT; 225 if (type != IFDIR && type != IFREG && type != IFLNK) 226 panic("ufs_read type"); 227 #endif 228 if (uio->uio_resid == 0) 229 return (0); 230 if (uio->uio_offset < 0) 231 return (EINVAL); 232 ip->i_flag |= IACC; 233 234 fs = ip->i_lfs; /* LFS */ 235 do { 236 lbn = lblkno(fs, uio->uio_offset); 237 on = blkoff(fs, uio->uio_offset); 238 n = MIN((unsigned)(fs->lfs_bsize - on), uio->uio_resid); 239 diff = ip->i_size - uio->uio_offset; 240 if (diff <= 0) 241 return (0); 242 if (diff < n) 243 n = diff; 244 size = blksize(fs); /* LFS */ 245 rablock = lbn + 1; 246 if (vp->v_lastr + 1 == lbn && 247 lblktosize(fs, rablock) < ip->i_size) 248 error = breada(ITOV(ip), lbn, size, rablock, 249 blksize(fs), NOCRED, &bp); 250 else 251 error = bread(ITOV(ip), lbn, size, NOCRED, &bp); 252 vp->v_lastr = lbn; 253 n = MIN(n, size - bp->b_resid); 254 if (error) { 255 brelse(bp); 256 return (error); 257 } 258 error = uiomove(bp->b_un.b_addr + on, (int)n, uio); 259 if (n + on == fs->lfs_bsize || uio->uio_offset == ip->i_size) 260 bp->b_flags |= B_AGE; 261 brelse(bp); 262 } while (error == 0 && uio->uio_resid > 0 && n != 0); 263 return (error); 264 } 265 266 /* 267 * Vnode op for writing. 268 */ 269 lfs_write(vp, uio, ioflag, cred) 270 register struct vnode *vp; 271 struct uio *uio; 272 int ioflag; 273 struct ucred *cred; 274 { 275 struct proc *p = uio->uio_procp; 276 register struct inode *ip = VTOI(vp); 277 register struct fs *fs; 278 struct buf *bp; 279 daddr_t lbn, bn; 280 u_long osize; 281 int n, on, flags; 282 int size, resid, error = 0; 283 284 printf("lfs_write ino %d\n", ip->i_number); 285 #ifdef DIAGNOSTIC 286 if (uio->uio_rw != UIO_WRITE) 287 panic("ufs_write mode"); 288 #endif 289 switch (vp->v_type) { 290 case VREG: 291 if (ioflag & IO_APPEND) 292 uio->uio_offset = ip->i_size; 293 /* fall through */ 294 case VLNK: 295 break; 296 297 case VDIR: 298 if ((ioflag & IO_SYNC) == 0) 299 panic("ufs_write nonsync dir write"); 300 break; 301 302 default: 303 panic("ufs_write type"); 304 } 305 if (uio->uio_offset < 0) 306 return (EINVAL); 307 if (uio->uio_resid == 0) 308 return (0); 309 /* 310 * Maybe this should be above the vnode op call, but so long as 311 * file servers have no limits, i don't think it matters 312 */ 313 if (vp->v_type == VREG && p && 314 uio->uio_offset + uio->uio_resid > 315 p->p_rlimit[RLIMIT_FSIZE].rlim_cur) { 316 psignal(p, SIGXFSZ); 317 return (EFBIG); 318 } 319 resid = uio->uio_resid; 320 osize = ip->i_size; 321 #ifdef NOTLFS /* LFS */ 322 fs = ip->i_fs; 323 flags = 0; 324 if (ioflag & IO_SYNC) 325 flags = B_SYNC; 326 do { 327 lbn = lblkno(fs, uio->uio_offset); 328 on = blkoff(fs, uio->uio_offset); 329 n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid); 330 if (n < fs->fs_bsize) 331 flags |= B_CLRBUF; 332 else 333 flags &= ~B_CLRBUF; 334 if (error = balloc(ip, lbn, (int)(on + n), &bp, flags)) 335 break; 336 bn = bp->b_blkno; 337 if (uio->uio_offset + n > ip->i_size) { 338 ip->i_size = uio->uio_offset + n; 339 vnode_pager_setsize(vp, ip->i_size); 340 } 341 size = blksize(fs, ip, lbn); 342 (void) vnode_pager_uncache(vp); 343 n = MIN(n, size - bp->b_resid); 344 error = uiomove(bp->b_un.b_addr + on, n, uio); 345 if (ioflag & IO_SYNC) 346 (void) bwrite(bp); 347 else if (n + on == fs->fs_bsize) { 348 bp->b_flags |= B_AGE; 349 bawrite(bp); 350 } else 351 bdwrite(bp); 352 ip->i_flag |= IUPD|ICHG; 353 if (cred->cr_uid != 0) 354 ip->i_mode &= ~(ISUID|ISGID); 355 } while (error == 0 && uio->uio_resid > 0 && n != 0); 356 #else 357 /* LFS IMPLEMENT -- write call */ 358 panic("lfs_write not implemented"); 359 #endif 360 if (error && (ioflag & IO_UNIT)) { 361 (void) lfs_itrunc(ip, osize, ioflag & IO_SYNC); 362 uio->uio_offset -= resid - uio->uio_resid; 363 uio->uio_resid = resid; 364 } 365 if (!error && (ioflag & IO_SYNC)) 366 error = lfs_iupdat(ip, &time, &time, 1); 367 return (error); 368 } 369 370 /* 371 * Synch an open file. 372 */ 373 /* ARGSUSED */ 374 lfs_fsync(vp, fflags, cred, waitfor, p) 375 struct vnode *vp; 376 int fflags; 377 struct ucred *cred; 378 int waitfor; 379 struct proc *p; 380 { 381 struct inode *ip = VTOI(vp); 382 383 printf("lfs_sync: ino %d\n", ip->i_number); 384 if (fflags & FWRITE) 385 ip->i_flag |= ICHG; 386 vflushbuf(vp, waitfor == MNT_WAIT ? B_SYNC : 0); /* LFS */ 387 return (lfs_iupdat(ip, &time, &time, waitfor == MNT_WAIT)); 388 } 389 390 /* 391 * ufs remove 392 * Hard to avoid races here, especially 393 * in unlinking directories. 394 */ 395 lfs_remove(ndp, p) 396 struct nameidata *ndp; 397 struct proc *p; 398 { 399 register struct inode *ip, *dp; 400 int error; 401 402 printf("lfs_remove\n"); 403 ip = VTOI(ndp->ni_vp); 404 dp = VTOI(ndp->ni_dvp); 405 error = lfs_dirremove(ndp); /* LFS */ 406 if (!error) { 407 ip->i_nlink--; 408 ip->i_flag |= ICHG; 409 } 410 if (dp == ip) 411 vrele(ITOV(ip)); 412 else 413 iput(ip); 414 iput(dp); 415 return (error); 416 } 417 /* 418 * link vnode call 419 */ 420 lfs_link(vp, ndp, p) 421 register struct vnode *vp; 422 register struct nameidata *ndp; 423 struct proc *p; 424 { 425 register struct inode *ip = VTOI(vp); 426 int error; 427 428 printf("lfs_link\n"); 429 #ifdef DIANOSTIC 430 if ((ndp->ni_nameiop & HASBUF) == 0) 431 panic("ufs_link: no name"); 432 #endif 433 if ((unsigned short)ip->i_nlink >= LINK_MAX) { 434 free(ndp->ni_pnbuf, M_NAMEI); 435 return (EMLINK); 436 } 437 if (ndp->ni_dvp != vp) 438 ILOCK(ip); 439 ip->i_nlink++; 440 ip->i_flag |= ICHG; 441 error = lfs_iupdat(ip, &time, &time, 1); /* LFS */ 442 if (!error) 443 error = lfs_direnter(ip, ndp); /* LFS */ 444 if (ndp->ni_dvp != vp) 445 IUNLOCK(ip); 446 FREE(ndp->ni_pnbuf, M_NAMEI); 447 vput(ndp->ni_dvp); 448 if (error) { 449 ip->i_nlink--; 450 ip->i_flag |= ICHG; 451 } 452 return (error); 453 } 454 455 /* 456 * Rename system call. 457 * rename("foo", "bar"); 458 * is essentially 459 * unlink("bar"); 460 * link("foo", "bar"); 461 * unlink("foo"); 462 * but ``atomically''. Can't do full commit without saving state in the 463 * inode on disk which isn't feasible at this time. Best we can do is 464 * always guarantee the target exists. 465 * 466 * Basic algorithm is: 467 * 468 * 1) Bump link count on source while we're linking it to the 469 * target. This also ensure the inode won't be deleted out 470 * from underneath us while we work (it may be truncated by 471 * a concurrent `trunc' or `open' for creation). 472 * 2) Link source to destination. If destination already exists, 473 * delete it first. 474 * 3) Unlink source reference to inode if still around. If a 475 * directory was moved and the parent of the destination 476 * is different from the source, patch the ".." entry in the 477 * directory. 478 */ 479 lfs_rename(fndp, tndp, p) 480 register struct nameidata *fndp, *tndp; 481 struct proc *p; 482 { 483 register struct inode *ip, *xp, *dp; 484 struct dirtemplate dirbuf; 485 int doingdirectory = 0, oldparent = 0, newparent = 0; 486 int error = 0; 487 488 printf("lfs_rename\n"); 489 #ifdef DIANOSTIC 490 if ((tndp->ni_nameiop & HASBUF) == 0 || 491 (fndp->ni_nameiop & HASBUF) == 0) 492 panic("ufs_rename: no name"); 493 #endif 494 dp = VTOI(fndp->ni_dvp); 495 ip = VTOI(fndp->ni_vp); 496 /* 497 * Check if just deleting a link name. 498 */ 499 if (fndp->ni_vp == tndp->ni_vp) { 500 VOP_ABORTOP(tndp); 501 vput(tndp->ni_dvp); 502 vput(tndp->ni_vp); 503 vrele(fndp->ni_dvp); 504 if ((ip->i_mode&IFMT) == IFDIR) { 505 VOP_ABORTOP(fndp); 506 vrele(fndp->ni_vp); 507 return (EINVAL); 508 } 509 doingdirectory = 0; 510 goto unlinkit; 511 } 512 ILOCK(ip); 513 if ((ip->i_mode&IFMT) == IFDIR) { 514 /* 515 * Avoid ".", "..", and aliases of "." for obvious reasons. 516 */ 517 if ((fndp->ni_namelen == 1 && fndp->ni_ptr[0] == '.') || 518 dp == ip || fndp->ni_isdotdot || (ip->i_flag & IRENAME)) { 519 VOP_ABORTOP(tndp); 520 vput(tndp->ni_dvp); 521 if (tndp->ni_vp) 522 vput(tndp->ni_vp); 523 VOP_ABORTOP(fndp); 524 vrele(fndp->ni_dvp); 525 vput(fndp->ni_vp); 526 return (EINVAL); 527 } 528 ip->i_flag |= IRENAME; 529 oldparent = dp->i_number; 530 doingdirectory++; 531 } 532 vrele(fndp->ni_dvp); 533 534 /* 535 * 1) Bump link count while we're moving stuff 536 * around. If we crash somewhere before 537 * completing our work, the link count 538 * may be wrong, but correctable. 539 */ 540 ip->i_nlink++; 541 ip->i_flag |= ICHG; 542 error = lfs_iupdat(ip, &time, &time, 1); /* LFS */ 543 IUNLOCK(ip); 544 545 /* 546 * When the target exists, both the directory 547 * and target vnodes are returned locked. 548 */ 549 dp = VTOI(tndp->ni_dvp); 550 xp = NULL; 551 if (tndp->ni_vp) 552 xp = VTOI(tndp->ni_vp); 553 /* 554 * If ".." must be changed (ie the directory gets a new 555 * parent) then the source directory must not be in the 556 * directory heirarchy above the target, as this would 557 * orphan everything below the source directory. Also 558 * the user must have write permission in the source so 559 * as to be able to change "..". We must repeat the call 560 * to namei, as the parent directory is unlocked by the 561 * call to checkpath(). 562 */ 563 if (oldparent != dp->i_number) 564 newparent = dp->i_number; 565 if (doingdirectory && newparent) { 566 VOP_LOCK(fndp->ni_vp); 567 error = ufs_access(fndp->ni_vp, VWRITE, tndp->ni_cred, p); 568 VOP_UNLOCK(fndp->ni_vp); 569 if (error) 570 goto bad; 571 if (xp != NULL) 572 iput(xp); /* LFS */ 573 if (error = lfs_checkpath(ip, dp, tndp->ni_cred)) 574 goto out; 575 if ((tndp->ni_nameiop & SAVESTART) == 0) 576 panic("ufs_rename: lost to startdir"); 577 if (error = lookup(tndp, p)) 578 goto out; 579 dp = VTOI(tndp->ni_dvp); 580 xp = NULL; 581 if (tndp->ni_vp) 582 xp = VTOI(tndp->ni_vp); 583 } 584 /* 585 * 2) If target doesn't exist, link the target 586 * to the source and unlink the source. 587 * Otherwise, rewrite the target directory 588 * entry to reference the source inode and 589 * expunge the original entry's existence. 590 */ 591 if (xp == NULL) { 592 if (dp->i_dev != ip->i_dev) 593 panic("rename: EXDEV"); 594 /* 595 * Account for ".." in new directory. 596 * When source and destination have the same 597 * parent we don't fool with the link count. 598 */ 599 if (doingdirectory && newparent) { 600 if ((unsigned short)dp->i_nlink >= LINK_MAX) { 601 error = EMLINK; 602 goto bad; 603 } 604 dp->i_nlink++; 605 dp->i_flag |= ICHG; /* LFS */ 606 if (error = lfs_iupdat(dp, &time, &time, 1)) 607 goto bad; 608 } 609 if (error = lfs_direnter(ip, tndp)) { 610 if (doingdirectory && newparent) { 611 dp->i_nlink--; 612 dp->i_flag |= ICHG; /* LFS */ 613 (void) lfs_iupdat(dp, &time, &time, 1); 614 } 615 goto bad; 616 } 617 iput(dp); 618 } else { 619 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) 620 panic("rename: EXDEV"); 621 /* 622 * Short circuit rename(foo, foo). 623 */ 624 if (xp->i_number == ip->i_number) 625 panic("rename: same file"); 626 /* 627 * If the parent directory is "sticky", then the user must 628 * own the parent directory, or the destination of the rename, 629 * otherwise the destination may not be changed (except by 630 * root). This implements append-only directories. 631 */ 632 if ((dp->i_mode & ISVTX) && tndp->ni_cred->cr_uid != 0 && 633 tndp->ni_cred->cr_uid != dp->i_uid && 634 xp->i_uid != tndp->ni_cred->cr_uid) { 635 error = EPERM; 636 goto bad; 637 } 638 /* 639 * Target must be empty if a directory and have no links 640 * to it. Also, ensure source and target are compatible 641 * (both directories, or both not directories). 642 */ 643 if ((xp->i_mode&IFMT) == IFDIR) { 644 if (!dirempty(xp, dp->i_number, tndp->ni_cred) || 645 xp->i_nlink > 2) { 646 error = ENOTEMPTY; 647 goto bad; 648 } 649 if (!doingdirectory) { 650 error = ENOTDIR; 651 goto bad; 652 } 653 cache_purge(ITOV(dp)); 654 } else if (doingdirectory) { 655 error = EISDIR; 656 goto bad; 657 } 658 if (error = dirrewrite(dp, ip, tndp)) 659 goto bad; 660 /* 661 * If the target directory is in the same 662 * directory as the source directory, 663 * decrement the link count on the parent 664 * of the target directory. 665 */ 666 if (doingdirectory && !newparent) { 667 dp->i_nlink--; 668 dp->i_flag |= ICHG; 669 } 670 vput(ITOV(dp)); 671 /* 672 * Adjust the link count of the target to 673 * reflect the dirrewrite above. If this is 674 * a directory it is empty and there are 675 * no links to it, so we can squash the inode and 676 * any space associated with it. We disallowed 677 * renaming over top of a directory with links to 678 * it above, as the remaining link would point to 679 * a directory without "." or ".." entries. 680 */ 681 xp->i_nlink--; 682 if (doingdirectory) { 683 if (--xp->i_nlink != 0) /* LFS */ 684 panic("rename: linked directory"); 685 error = lfs_itrunc(xp, (u_long)0, IO_SYNC); 686 } 687 xp->i_flag |= ICHG; 688 iput(xp); 689 xp = NULL; 690 } 691 692 /* 693 * 3) Unlink the source. 694 */ 695 unlinkit: 696 fndp->ni_nameiop &= ~MODMASK; 697 fndp->ni_nameiop |= LOCKPARENT | LOCKLEAF; 698 if ((fndp->ni_nameiop & SAVESTART) == 0) 699 panic("ufs_rename: lost from startdir"); 700 (void) lookup(fndp, p); 701 if (fndp->ni_vp != NULL) { 702 xp = VTOI(fndp->ni_vp); 703 dp = VTOI(fndp->ni_dvp); 704 } else { 705 /* 706 * From name has disappeared. 707 */ 708 if (doingdirectory) 709 panic("rename: lost dir entry"); 710 vrele(ITOV(ip)); 711 return (0); 712 } 713 /* 714 * Ensure that the directory entry still exists and has not 715 * changed while the new name has been entered. If the source is 716 * a file then the entry may have been unlinked or renamed. In 717 * either case there is no further work to be done. If the source 718 * is a directory then it cannot have been rmdir'ed; its link 719 * count of three would cause a rmdir to fail with ENOTEMPTY. 720 * The IRENAME flag ensures that it cannot be moved by another 721 * rename. 722 */ 723 if (xp != ip) { 724 if (doingdirectory) 725 panic("rename: lost dir entry"); 726 } else { 727 /* 728 * If the source is a directory with a 729 * new parent, the link count of the old 730 * parent directory must be decremented 731 * and ".." set to point to the new parent. 732 */ 733 if (doingdirectory && newparent) { 734 dp->i_nlink--; 735 dp->i_flag |= ICHG; 736 error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf, 737 sizeof (struct dirtemplate), (off_t)0, 738 UIO_SYSSPACE, IO_NODELOCKED, 739 tndp->ni_cred, (int *)0, (struct proc *)0); 740 if (error == 0) { 741 if (dirbuf.dotdot_namlen != 2 || 742 dirbuf.dotdot_name[0] != '.' || 743 dirbuf.dotdot_name[1] != '.') { 744 lfs_dirbad(xp, 12, 745 "rename: mangled dir"); 746 } else { 747 dirbuf.dotdot_ino = newparent; 748 (void) vn_rdwr(UIO_WRITE, ITOV(xp), 749 (caddr_t)&dirbuf, 750 sizeof (struct dirtemplate), 751 (off_t)0, UIO_SYSSPACE, 752 IO_NODELOCKED|IO_SYNC, 753 tndp->ni_cred, (int *)0, 754 (struct proc *)0); 755 cache_purge(ITOV(dp)); 756 } 757 } 758 } 759 error = lfs_dirremove(fndp); /* LFS */ 760 if (!error) { 761 xp->i_nlink--; 762 xp->i_flag |= ICHG; 763 } 764 xp->i_flag &= ~IRENAME; 765 } 766 if (dp) 767 vput(ITOV(dp)); 768 if (xp) 769 vput(ITOV(xp)); 770 vrele(ITOV(ip)); 771 return (error); 772 773 bad: 774 if (xp) 775 vput(ITOV(xp)); 776 vput(ITOV(dp)); 777 out: 778 ip->i_nlink--; 779 ip->i_flag |= ICHG; 780 vrele(ITOV(ip)); 781 return (error); 782 } 783 784 /* 785 * A virgin directory (no blushing please). 786 */ 787 static struct dirtemplate mastertemplate = { 788 0, 12, 1, ".", 789 0, DIRBLKSIZ - 12, 2, ".." 790 }; 791 792 /* 793 * Mkdir system call 794 */ 795 lfs_mkdir(ndp, vap, p) 796 struct nameidata *ndp; 797 struct vattr *vap; 798 struct proc *p; 799 { 800 register struct inode *ip, *dp; 801 struct inode *tip; 802 struct vnode *dvp; 803 struct dirtemplate dirtemplate; 804 int error; 805 int dmode; 806 807 printf("lfs_mkdir\n"); 808 #ifdef DIANOSTIC 809 if ((ndp->ni_nameiop & HASBUF) == 0) 810 panic("ufs_mkdir: no name"); 811 #endif 812 dvp = ndp->ni_dvp; 813 dp = VTOI(dvp); 814 if ((unsigned short)dp->i_nlink >= LINK_MAX) { 815 free(ndp->ni_pnbuf, M_NAMEI); 816 iput(dp); 817 return (EMLINK); 818 } 819 dmode = vap->va_mode&0777; 820 dmode |= IFDIR; 821 /* 822 * Must simulate part of maknode here to acquire the inode, but 823 * not have it entered in the parent directory. The entry is made 824 * later after writing "." and ".." entries. 825 */ 826 #ifdef NOTLFS /* LFS */ 827 if (error = ialloc(dp, dirpref(dp->i_fs), dmode, ndp->ni_cred, &tip)) { 828 #else 829 if (error = lfs_ialloc(dp->i_lfs, dp, &tip, ndp->ni_cred)) { 830 #endif 831 free(ndp->ni_pnbuf, M_NAMEI); 832 iput(dp); 833 return (error); 834 } 835 ip = tip; 836 ip->i_uid = ndp->ni_cred->cr_uid; 837 ip->i_gid = dp->i_gid; 838 #ifdef QUOTA 839 if ((error = getinoquota(ip)) || 840 (error = chkiq(ip, 1, ndp->ni_cred, 0))) { 841 free(ndp->ni_pnbuf, M_NAMEI); 842 #ifdef NOTLFS /* LFS */ 843 ifree(ip, ip->i_number, dmode); 844 #else 845 lfs_ifree(ip); 846 #endif 847 iput(ip); 848 iput(dp); 849 return (error); 850 } 851 #endif 852 ip->i_flag |= IACC|IUPD|ICHG; 853 ip->i_mode = dmode; 854 ITOV(ip)->v_type = VDIR; /* Rest init'd in iget() */ 855 ip->i_nlink = 2; 856 error = lfs_iupdat(ip, &time, &time, 1); /* LFS */ 857 858 /* 859 * Bump link count in parent directory 860 * to reflect work done below. Should 861 * be done before reference is created 862 * so reparation is possible if we crash. 863 */ 864 dp->i_nlink++; 865 dp->i_flag |= ICHG; 866 if (error = lfs_iupdat(dp, &time, &time, 1)) /* LFS */ 867 goto bad; 868 869 /* 870 * Initialize directory with "." 871 * and ".." from static template. 872 */ 873 dirtemplate = mastertemplate; 874 dirtemplate.dot_ino = ip->i_number; 875 dirtemplate.dotdot_ino = dp->i_number; 876 error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate, 877 sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, 878 IO_NODELOCKED|IO_SYNC, ndp->ni_cred, (int *)0, (struct proc *)0); 879 if (error) { 880 dp->i_nlink--; 881 dp->i_flag |= ICHG; 882 goto bad; 883 } 884 if (DIRBLKSIZ > dp->i_lfs->lfs_fsize) { 885 panic("mkdir: blksize"); /* XXX - should grow w/balloc() */ 886 } else { 887 ip->i_size = DIRBLKSIZ; 888 ip->i_flag |= ICHG; 889 } 890 /* 891 * Directory all set up, now 892 * install the entry for it in 893 * the parent directory. 894 */ 895 if (error = lfs_direnter(ip, ndp)) { /* LFS */ 896 dp->i_nlink--; 897 dp->i_flag |= ICHG; 898 } 899 bad: 900 /* 901 * No need to do an explicit lfs_itrunc here, 902 * vrele will do this for us because we set 903 * the link count to 0. 904 */ 905 if (error) { 906 ip->i_nlink = 0; 907 ip->i_flag |= ICHG; 908 iput(ip); 909 } else 910 ndp->ni_vp = ITOV(ip); 911 FREE(ndp->ni_pnbuf, M_NAMEI); 912 iput(dp); 913 return (error); 914 } 915 916 /* 917 * Rmdir system call. 918 */ 919 lfs_rmdir(ndp, p) 920 register struct nameidata *ndp; 921 struct proc *p; 922 { 923 register struct inode *ip, *dp; 924 int error = 0; 925 926 printf("lfs_rmdir\n"); 927 ip = VTOI(ndp->ni_vp); 928 dp = VTOI(ndp->ni_dvp); 929 /* 930 * No rmdir "." please. 931 */ 932 if (dp == ip) { 933 vrele(ITOV(dp)); 934 iput(ip); 935 return (EINVAL); 936 } 937 /* 938 * Verify the directory is empty (and valid). 939 * (Rmdir ".." won't be valid since 940 * ".." will contain a reference to 941 * the current directory and thus be 942 * non-empty.) 943 */ 944 if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number, ndp->ni_cred)) { 945 error = ENOTEMPTY; 946 goto out; 947 } 948 /* 949 * Delete reference to directory before purging 950 * inode. If we crash in between, the directory 951 * will be reattached to lost+found, 952 */ 953 if (error = lfs_dirremove(ndp)) /* LFS */ 954 goto out; 955 dp->i_nlink--; 956 dp->i_flag |= ICHG; 957 cache_purge(ITOV(dp)); 958 iput(dp); 959 ndp->ni_dvp = NULL; 960 /* 961 * Truncate inode. The only stuff left 962 * in the directory is "." and "..". The 963 * "." reference is inconsequential since 964 * we're quashing it. The ".." reference 965 * has already been adjusted above. We've 966 * removed the "." reference and the reference 967 * in the parent directory, but there may be 968 * other hard links so decrement by 2 and 969 * worry about them later. 970 */ 971 ip->i_nlink -= 2; 972 error = lfs_itrunc(ip, (u_long)0, IO_SYNC); /* LFS */ 973 cache_purge(ITOV(ip)); 974 out: 975 if (ndp->ni_dvp) 976 iput(dp); 977 iput(ip); 978 return (error); 979 } 980 981 /* 982 * symlink -- make a symbolic link 983 */ 984 lfs_symlink(ndp, vap, target, p) 985 struct nameidata *ndp; 986 struct vattr *vap; 987 char *target; 988 struct proc *p; 989 { 990 struct inode *ip; 991 int error; 992 993 printf("lfs_symlink\n"); 994 error = maknode(IFLNK | vap->va_mode, ndp, &ip); 995 if (error) 996 return (error); 997 error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0, 998 UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0, 999 (struct proc *)0); 1000 iput(ip); 1001 return (error); 1002 } 1003 1004 /* 1005 * Vnode op for read and write 1006 */ 1007 lfs_readdir(vp, uio, cred, eofflagp) 1008 struct vnode *vp; 1009 register struct uio *uio; 1010 struct ucred *cred; 1011 int *eofflagp; 1012 { 1013 int count, lost, error; 1014 1015 printf("lfs_readdir\n"); 1016 count = uio->uio_resid; 1017 count &= ~(DIRBLKSIZ - 1); 1018 lost = uio->uio_resid - count; 1019 if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1))) 1020 return (EINVAL); 1021 uio->uio_resid = count; 1022 uio->uio_iov->iov_len = count; 1023 error = lfs_read(vp, uio, 0, cred); /* LFS */ 1024 uio->uio_resid += lost; 1025 if ((VTOI(vp)->i_size - uio->uio_offset) <= 0) 1026 *eofflagp = 1; 1027 else 1028 *eofflagp = 0; 1029 return (error); 1030 } 1031 1032 /* 1033 * Return target name of a symbolic link 1034 */ 1035 lfs_readlink(vp, uiop, cred) 1036 struct vnode *vp; 1037 struct uio *uiop; 1038 struct ucred *cred; 1039 { 1040 1041 printf("lfs_readlink\n"); 1042 return (lfs_read(vp, uiop, 0, cred)); /* LFS */ 1043 } 1044 1045 /* 1046 * Get access to bmap 1047 */ 1048 lfs_vbmap(vp, bn, vpp, bnp) 1049 struct vnode *vp; 1050 daddr_t bn; 1051 struct vnode **vpp; 1052 daddr_t *bnp; 1053 { 1054 struct inode *ip = VTOI(vp); 1055 1056 printf("lfs_vbmap\n"); 1057 if (vpp != NULL) 1058 *vpp = ip->i_devvp; 1059 if (bnp == NULL) 1060 return (0); 1061 return (lfs_bmap(ip, bn, bnp)); /* LFS */ 1062 } 1063 1064 /* 1065 * Calculate the logical to physical mapping if not done already, 1066 * then call the device strategy routine. 1067 */ 1068 lfs_strategy(bp) 1069 register struct buf *bp; 1070 { 1071 register struct inode *ip = VTOI(bp->b_vp); 1072 struct vnode *vp; 1073 int error; 1074 1075 printf("lfs_strategy: type: %d lblk %d pblk %d\n", bp->b_vp->v_type, 1076 bp->b_lblkno, bp->b_blkno); 1077 if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR) 1078 panic("ufs_strategy: spec"); 1079 if (bp->b_blkno == bp->b_lblkno) { /* LFS */ 1080 if (error = lfs_bmap(ip, bp->b_lblkno, &bp->b_blkno)) 1081 return (error); 1082 if ((long)bp->b_blkno == -1) 1083 clrbuf(bp); 1084 } 1085 if ((long)bp->b_blkno == -1) { 1086 biodone(bp); 1087 return (0); 1088 } 1089 vp = ip->i_devvp; 1090 bp->b_dev = vp->v_rdev; 1091 (*(vp->v_op->vop_strategy))(bp); 1092 return (0); 1093 } 1094 1095 /* 1096 * Allocate a new inode. 1097 */ 1098 static int 1099 maknode(mode, ndp, ipp) 1100 int mode; 1101 register struct nameidata *ndp; 1102 struct inode **ipp; 1103 { 1104 register struct inode *ip; 1105 struct inode *tip; 1106 register struct inode *pdir = VTOI(ndp->ni_dvp); 1107 ino_t ipref; 1108 int error; 1109 1110 printf("maknode\n"); 1111 #ifdef DIANOSTIC 1112 if ((ndp->ni_nameiop & HASBUF) == 0) 1113 panic("maknode: no name"); 1114 #endif 1115 *ipp = 0; 1116 if ((mode & IFMT) == 0) 1117 mode |= IFREG; 1118 #ifdef NOTLFS /* LFS */ 1119 if ((mode & IFMT) == IFDIR) 1120 ipref = dirpref(pdir->i_fs); 1121 else 1122 ipref = pdir->i_number; 1123 if (error = ialloc(pdir, ipref, mode, ndp->ni_cred, &tip)) { 1124 #else 1125 if (error = lfs_ialloc(pdir->i_lfs, pdir, &tip, ndp->ni_cred)) { 1126 #endif 1127 free(ndp->ni_pnbuf, M_NAMEI); 1128 iput(pdir); 1129 return (error); 1130 } 1131 ip = tip; 1132 ip->i_uid = ndp->ni_cred->cr_uid; 1133 ip->i_gid = pdir->i_gid; 1134 #ifdef QUOTA 1135 if ((error = getinoquota(ip)) || 1136 (error = chkiq(ip, 1, ndp->ni_cred, 0))) { 1137 free(ndp->ni_pnbuf, M_NAMEI); 1138 #ifdef NOTLFS /* LFS */ 1139 ifree(ip, ip->i_number, mode); 1140 #else 1141 lfs_ifree(ip); 1142 #endif 1143 iput(ip); 1144 iput(pdir); 1145 return (error); 1146 } 1147 #endif 1148 ip->i_flag |= IACC|IUPD|ICHG; 1149 ip->i_mode = mode; 1150 ITOV(ip)->v_type = IFTOVT(mode); /* Rest init'd in iget() */ 1151 ip->i_nlink = 1; 1152 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, ndp->ni_cred) && 1153 suser(ndp->ni_cred, NULL)) 1154 ip->i_mode &= ~ISGID; 1155 1156 /* 1157 * Make sure inode goes to disk before directory entry. 1158 * 1159 * XXX Wrong... 1160 */ 1161 if (error = lfs_iupdat(ip, &time, &time, 1)) /* LFS */ 1162 goto bad; 1163 if (error = lfs_direnter(ip, ndp)) /* LFS */ 1164 goto bad; 1165 if ((ndp->ni_nameiop & SAVESTART) == 0) 1166 FREE(ndp->ni_pnbuf, M_NAMEI); 1167 iput(pdir); 1168 *ipp = ip; 1169 return (0); 1170 1171 bad: 1172 /* 1173 * Write error occurred trying to update the inode 1174 * or the directory so must deallocate the inode. 1175 */ 1176 free(ndp->ni_pnbuf, M_NAMEI); 1177 iput(pdir); 1178 ip->i_nlink = 0; 1179 ip->i_flag |= ICHG; 1180 iput(ip); 1181 return (error); 1182 } 1183 1184 /* 1185 * Global vfs data structures for lfs 1186 */ 1187 struct vnodeops lfs_vnodeops = { 1188 lfs_lookup, /* lookup */ 1189 lfs_create, /* create */ 1190 lfs_mknod, /* mknod */ 1191 ufs_open, /* open */ 1192 ufs_close, /* close */ 1193 ufs_access, /* access */ 1194 lfs_getattr, /* getattr */ 1195 lfs_setattr, /* setattr */ 1196 lfs_read, /* read */ 1197 lfs_write, /* write */ 1198 ufs_ioctl, /* ioctl */ 1199 ufs_select, /* select */ 1200 ufs_mmap, /* mmap */ 1201 lfs_fsync, /* fsync */ 1202 ufs_seek, /* seek */ 1203 lfs_remove, /* remove */ 1204 lfs_link, /* link */ 1205 lfs_rename, /* rename */ 1206 lfs_mkdir, /* mkdir */ 1207 lfs_rmdir, /* rmdir */ 1208 lfs_symlink, /* symlink */ 1209 lfs_readdir, /* readdir */ 1210 lfs_readlink, /* readlink */ 1211 ufs_abortop, /* abortop */ 1212 lfs_inactive, /* inactive */ 1213 ufs_reclaim, /* reclaim */ 1214 ufs_lock, /* lock */ 1215 ufs_unlock, /* unlock */ 1216 lfs_vbmap, /* bmap */ 1217 lfs_strategy, /* strategy */ 1218 ufs_print, /* print */ 1219 ufs_islocked, /* islocked */ 1220 ufs_advlock, /* advlock */ 1221 }; 1222