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