1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ufs_vnops.c 7.55 (Berkeley) 02/25/91 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "user.h" 13 #include "kernel.h" 14 #include "file.h" 15 #include "stat.h" 16 #include "buf.h" 17 #include "proc.h" 18 #include "socket.h" 19 #include "socketvar.h" 20 #include "conf.h" 21 #include "mount.h" 22 #include "vnode.h" 23 #include "specdev.h" 24 #include "fcntl.h" 25 #include "malloc.h" 26 #include "../ufs/lockf.h" 27 #include "../ufs/quota.h" 28 #include "../ufs/inode.h" 29 #include "../ufs/fs.h" 30 31 /* 32 * Global vfs data structures for ufs 33 */ 34 35 int ufs_lookup(), 36 ufs_create(), 37 ufs_mknod(), 38 ufs_open(), 39 ufs_close(), 40 ufs_access(), 41 ufs_getattr(), 42 ufs_setattr(), 43 ufs_read(), 44 ufs_write(), 45 ufs_ioctl(), 46 ufs_select(), 47 ufs_mmap(), 48 ufs_fsync(), 49 ufs_seek(), 50 ufs_remove(), 51 ufs_link(), 52 ufs_rename(), 53 ufs_mkdir(), 54 ufs_rmdir(), 55 ufs_symlink(), 56 ufs_readdir(), 57 ufs_readlink(), 58 ufs_abortop(), 59 ufs_inactive(), 60 ufs_reclaim(), 61 ufs_lock(), 62 ufs_unlock(), 63 ufs_bmap(), 64 ufs_strategy(), 65 ufs_print(), 66 ufs_islocked(), 67 ufs_advlock(); 68 69 struct vnodeops ufs_vnodeops = { 70 ufs_lookup, /* lookup */ 71 ufs_create, /* create */ 72 ufs_mknod, /* mknod */ 73 ufs_open, /* open */ 74 ufs_close, /* close */ 75 ufs_access, /* access */ 76 ufs_getattr, /* getattr */ 77 ufs_setattr, /* setattr */ 78 ufs_read, /* read */ 79 ufs_write, /* write */ 80 ufs_ioctl, /* ioctl */ 81 ufs_select, /* select */ 82 ufs_mmap, /* mmap */ 83 ufs_fsync, /* fsync */ 84 ufs_seek, /* seek */ 85 ufs_remove, /* remove */ 86 ufs_link, /* link */ 87 ufs_rename, /* rename */ 88 ufs_mkdir, /* mkdir */ 89 ufs_rmdir, /* rmdir */ 90 ufs_symlink, /* symlink */ 91 ufs_readdir, /* readdir */ 92 ufs_readlink, /* readlink */ 93 ufs_abortop, /* abortop */ 94 ufs_inactive, /* inactive */ 95 ufs_reclaim, /* reclaim */ 96 ufs_lock, /* lock */ 97 ufs_unlock, /* unlock */ 98 ufs_bmap, /* bmap */ 99 ufs_strategy, /* strategy */ 100 ufs_print, /* print */ 101 ufs_islocked, /* islocked */ 102 ufs_advlock, /* advlock */ 103 }; 104 105 int spec_lookup(), 106 spec_open(), 107 ufsspec_read(), 108 ufsspec_write(), 109 spec_strategy(), 110 spec_bmap(), 111 spec_ioctl(), 112 spec_select(), 113 ufsspec_close(), 114 spec_advlock(), 115 spec_badop(), 116 nullop(); 117 118 struct vnodeops spec_inodeops = { 119 spec_lookup, /* lookup */ 120 spec_badop, /* create */ 121 spec_badop, /* mknod */ 122 spec_open, /* open */ 123 ufsspec_close, /* close */ 124 ufs_access, /* access */ 125 ufs_getattr, /* getattr */ 126 ufs_setattr, /* setattr */ 127 ufsspec_read, /* read */ 128 ufsspec_write, /* write */ 129 spec_ioctl, /* ioctl */ 130 spec_select, /* select */ 131 spec_badop, /* mmap */ 132 nullop, /* fsync */ 133 spec_badop, /* seek */ 134 spec_badop, /* remove */ 135 spec_badop, /* link */ 136 spec_badop, /* rename */ 137 spec_badop, /* mkdir */ 138 spec_badop, /* rmdir */ 139 spec_badop, /* symlink */ 140 spec_badop, /* readdir */ 141 spec_badop, /* readlink */ 142 spec_badop, /* abortop */ 143 ufs_inactive, /* inactive */ 144 ufs_reclaim, /* reclaim */ 145 ufs_lock, /* lock */ 146 ufs_unlock, /* unlock */ 147 spec_bmap, /* bmap */ 148 spec_strategy, /* strategy */ 149 ufs_print, /* print */ 150 ufs_islocked, /* islocked */ 151 spec_advlock, /* advlock */ 152 }; 153 154 #ifdef FIFO 155 int fifo_lookup(), 156 fifo_open(), 157 ufsfifo_read(), 158 ufsfifo_write(), 159 fifo_bmap(), 160 fifo_ioctl(), 161 fifo_select(), 162 ufsfifo_close(), 163 fifo_print(), 164 fifo_advlock(), 165 fifo_badop(); 166 167 struct vnodeops fifo_inodeops = { 168 fifo_lookup, /* lookup */ 169 fifo_badop, /* create */ 170 fifo_badop, /* mknod */ 171 fifo_open, /* open */ 172 ufsfifo_close, /* close */ 173 ufs_access, /* access */ 174 ufs_getattr, /* getattr */ 175 ufs_setattr, /* setattr */ 176 ufsfifo_read, /* read */ 177 ufsfifo_write, /* write */ 178 fifo_ioctl, /* ioctl */ 179 fifo_select, /* select */ 180 fifo_badop, /* mmap */ 181 nullop, /* fsync */ 182 fifo_badop, /* seek */ 183 fifo_badop, /* remove */ 184 fifo_badop, /* link */ 185 fifo_badop, /* rename */ 186 fifo_badop, /* mkdir */ 187 fifo_badop, /* rmdir */ 188 fifo_badop, /* symlink */ 189 fifo_badop, /* readdir */ 190 fifo_badop, /* readlink */ 191 fifo_badop, /* abortop */ 192 ufs_inactive, /* inactive */ 193 ufs_reclaim, /* reclaim */ 194 ufs_lock, /* lock */ 195 ufs_unlock, /* unlock */ 196 fifo_bmap, /* bmap */ 197 fifo_badop, /* strategy */ 198 ufs_print, /* print */ 199 ufs_islocked, /* islocked */ 200 fifo_advlock, /* advlock */ 201 }; 202 #endif /* FIFO */ 203 204 enum vtype iftovt_tab[16] = { 205 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, 206 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, 207 }; 208 int vttoif_tab[9] = { 209 0, IFREG, IFDIR, IFBLK, IFCHR, IFLNK, IFSOCK, IFIFO, IFMT, 210 }; 211 212 /* 213 * Create a regular file 214 */ 215 ufs_create(ndp, vap) 216 struct nameidata *ndp; 217 struct vattr *vap; 218 { 219 struct inode *ip; 220 int error; 221 222 if (error = maknode(MAKEIMODE(vap->va_type, vap->va_mode), ndp, &ip)) 223 return (error); 224 ndp->ni_vp = ITOV(ip); 225 return (0); 226 } 227 228 /* 229 * Mknod vnode call 230 */ 231 /* ARGSUSED */ 232 ufs_mknod(ndp, vap, cred) 233 struct nameidata *ndp; 234 struct ucred *cred; 235 struct vattr *vap; 236 { 237 register struct vnode *vp; 238 struct inode *ip; 239 int error; 240 241 if (error = maknode(MAKEIMODE(vap->va_type, vap->va_mode), ndp, &ip)) 242 return (error); 243 ip->i_flag |= IACC|IUPD|ICHG; 244 if (vap->va_rdev != VNOVAL) { 245 /* 246 * Want to be able to use this to make badblock 247 * inodes, so don't truncate the dev number. 248 */ 249 ip->i_rdev = vap->va_rdev; 250 } 251 /* 252 * Remove inode so that it will be reloaded by iget and 253 * checked to see if it is an alias of an existing entry 254 * in the inode cache. 255 */ 256 vp = ITOV(ip); 257 vput(vp); 258 vp->v_type = VNON; 259 vgone(vp); 260 return (0); 261 } 262 263 /* 264 * Open called. 265 * 266 * Nothing to do. 267 */ 268 /* ARGSUSED */ 269 ufs_open(vp, mode, cred) 270 struct vnode *vp; 271 int mode; 272 struct ucred *cred; 273 { 274 275 return (0); 276 } 277 278 /* 279 * Close called 280 * 281 * Update the times on the inode. 282 */ 283 /* ARGSUSED */ 284 ufs_close(vp, fflag, cred) 285 struct vnode *vp; 286 int fflag; 287 struct ucred *cred; 288 { 289 register struct inode *ip = VTOI(vp); 290 291 if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED)) 292 ITIMES(ip, &time, &time); 293 return (0); 294 } 295 296 /* 297 * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 298 * The mode is shifted to select the owner/group/other fields. The 299 * super user is granted all permissions. 300 */ 301 ufs_access(vp, mode, cred) 302 struct vnode *vp; 303 register int mode; 304 struct ucred *cred; 305 { 306 register struct inode *ip = VTOI(vp); 307 register gid_t *gp; 308 int i, error; 309 310 #ifdef DIAGNOSTIC 311 if (!VOP_ISLOCKED(vp)) { 312 vprint("ufs_access: not locked", vp); 313 panic("ufs_access: not locked"); 314 } 315 #endif 316 #ifdef QUOTA 317 if (mode & VWRITE) { 318 switch (vp->v_type) { 319 case VREG: case VDIR: case VLNK: 320 if (error = getinoquota(ip)) 321 return (error); 322 } 323 } 324 #endif /* QUOTA */ 325 /* 326 * If you're the super-user, you always get access. 327 */ 328 if (cred->cr_uid == 0) 329 return (0); 330 /* 331 * Access check is based on only one of owner, group, public. 332 * If not owner, then check group. If not a member of the 333 * group, then check public access. 334 */ 335 if (cred->cr_uid != ip->i_uid) { 336 mode >>= 3; 337 gp = cred->cr_groups; 338 for (i = 0; i < cred->cr_ngroups; i++, gp++) 339 if (ip->i_gid == *gp) 340 goto found; 341 mode >>= 3; 342 found: 343 ; 344 } 345 if ((ip->i_mode & mode) != 0) 346 return (0); 347 return (EACCES); 348 } 349 350 /* ARGSUSED */ 351 ufs_getattr(vp, vap, cred) 352 struct vnode *vp; 353 register struct vattr *vap; 354 struct ucred *cred; 355 { 356 register struct inode *ip = VTOI(vp); 357 358 ITIMES(ip, &time, &time); 359 /* 360 * Copy from inode table 361 */ 362 vap->va_fsid = ip->i_dev; 363 vap->va_fileid = ip->i_number; 364 vap->va_mode = ip->i_mode & ~IFMT; 365 vap->va_nlink = ip->i_nlink; 366 vap->va_uid = ip->i_uid; 367 vap->va_gid = ip->i_gid; 368 vap->va_rdev = (dev_t)ip->i_rdev; 369 #ifdef tahoe 370 vap->va_size = ip->i_size; 371 vap->va_size_rsv = 0; 372 #else 373 vap->va_qsize = ip->i_din.di_qsize; 374 #endif 375 vap->va_atime.tv_sec = ip->i_atime; 376 vap->va_atime.tv_usec = 0; 377 vap->va_mtime.tv_sec = ip->i_mtime; 378 vap->va_mtime.tv_usec = 0; 379 vap->va_ctime.tv_sec = ip->i_ctime; 380 vap->va_ctime.tv_usec = 0; 381 vap->va_flags = ip->i_flags; 382 vap->va_gen = ip->i_gen; 383 /* this doesn't belong here */ 384 if (vp->v_type == VBLK) 385 vap->va_blocksize = BLKDEV_IOSIZE; 386 else if (vp->v_type == VCHR) 387 vap->va_blocksize = MAXBSIZE; 388 else 389 vap->va_blocksize = ip->i_fs->fs_bsize; 390 vap->va_bytes = dbtob(ip->i_blocks); 391 vap->va_bytes_rsv = 0; 392 vap->va_type = vp->v_type; 393 return (0); 394 } 395 396 /* 397 * Set attribute vnode op. called from several syscalls 398 */ 399 ufs_setattr(vp, vap, cred) 400 register struct vnode *vp; 401 register struct vattr *vap; 402 register struct ucred *cred; 403 { 404 register struct inode *ip = VTOI(vp); 405 int error = 0; 406 407 /* 408 * Check for unsetable attributes. 409 */ 410 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 411 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 412 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 413 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 414 return (EINVAL); 415 } 416 /* 417 * Go through the fields and update iff not VNOVAL. 418 */ 419 if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL) 420 if (error = chown1(vp, vap->va_uid, vap->va_gid, cred)) 421 return (error); 422 if (vap->va_size != VNOVAL) { 423 if (vp->v_type == VDIR) 424 return (EISDIR); 425 if (error = itrunc(ip, vap->va_size, 0)) /* XXX IO_SYNC? */ 426 return (error); 427 } 428 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 429 if (cred->cr_uid != ip->i_uid && 430 (error = suser(cred, &u.u_acflag))) 431 return (error); 432 if (vap->va_atime.tv_sec != VNOVAL) 433 ip->i_flag |= IACC; 434 if (vap->va_mtime.tv_sec != VNOVAL) 435 ip->i_flag |= IUPD; 436 ip->i_flag |= ICHG; 437 if (error = iupdat(ip, &vap->va_atime, &vap->va_mtime, 1)) 438 return (error); 439 } 440 if (vap->va_mode != (u_short)VNOVAL) 441 error = chmod1(vp, (int)vap->va_mode, cred); 442 if (vap->va_flags != VNOVAL) { 443 if (cred->cr_uid != ip->i_uid && 444 (error = suser(cred, &u.u_acflag))) 445 return (error); 446 if (cred->cr_uid == 0) { 447 ip->i_flags = vap->va_flags; 448 } else { 449 ip->i_flags &= 0xffff0000; 450 ip->i_flags |= (vap->va_flags & 0xffff); 451 } 452 ip->i_flag |= ICHG; 453 } 454 return (error); 455 } 456 457 /* 458 * Change the mode on a file. 459 * Inode must be locked before calling. 460 */ 461 chmod1(vp, mode, cred) 462 register struct vnode *vp; 463 register int mode; 464 struct ucred *cred; 465 { 466 register struct inode *ip = VTOI(vp); 467 int error; 468 469 if (cred->cr_uid != ip->i_uid && 470 (error = suser(cred, &u.u_acflag))) 471 return (error); 472 if (cred->cr_uid) { 473 if (vp->v_type != VDIR && (mode & ISVTX)) 474 return (EFTYPE); 475 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) 476 return (EPERM); 477 } 478 ip->i_mode &= ~07777; 479 ip->i_mode |= mode & 07777; 480 ip->i_flag |= ICHG; 481 if ((vp->v_flag & VTEXT) && (ip->i_mode & ISVTX) == 0) 482 (void) vnode_pager_uncache(vp); 483 return (0); 484 } 485 486 /* 487 * Perform chown operation on inode ip; 488 * inode must be locked prior to call. 489 */ 490 chown1(vp, uid, gid, cred) 491 register struct vnode *vp; 492 uid_t uid; 493 gid_t gid; 494 struct ucred *cred; 495 { 496 register struct inode *ip = VTOI(vp); 497 uid_t ouid; 498 gid_t ogid; 499 int error = 0; 500 #ifdef QUOTA 501 register int i; 502 long change; 503 #endif 504 505 if (uid == (u_short)VNOVAL) 506 uid = ip->i_uid; 507 if (gid == (u_short)VNOVAL) 508 gid = ip->i_gid; 509 /* 510 * If we don't own the file, are trying to change the owner 511 * of the file, or are not a member of the target group, 512 * the caller must be superuser or the call fails. 513 */ 514 if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid || 515 !groupmember((gid_t)gid, cred)) && 516 (error = suser(cred, &u.u_acflag))) 517 return (error); 518 ouid = ip->i_uid; 519 ogid = ip->i_gid; 520 #ifdef QUOTA 521 if (error = getinoquota(ip)) 522 return (error); 523 if (ouid == uid) { 524 dqrele(vp, ip->i_dquot[USRQUOTA]); 525 ip->i_dquot[USRQUOTA] = NODQUOT; 526 } 527 if (ogid == gid) { 528 dqrele(vp, ip->i_dquot[GRPQUOTA]); 529 ip->i_dquot[GRPQUOTA] = NODQUOT; 530 } 531 change = ip->i_blocks; 532 (void) chkdq(ip, -change, cred, CHOWN); 533 (void) chkiq(ip, -1, cred, CHOWN); 534 for (i = 0; i < MAXQUOTAS; i++) { 535 dqrele(vp, ip->i_dquot[i]); 536 ip->i_dquot[i] = NODQUOT; 537 } 538 #endif 539 ip->i_uid = uid; 540 ip->i_gid = gid; 541 #ifdef QUOTA 542 if ((error = getinoquota(ip)) == 0) { 543 if (ouid == uid) { 544 dqrele(vp, ip->i_dquot[USRQUOTA]); 545 ip->i_dquot[USRQUOTA] = NODQUOT; 546 } 547 if (ogid == gid) { 548 dqrele(vp, ip->i_dquot[GRPQUOTA]); 549 ip->i_dquot[GRPQUOTA] = NODQUOT; 550 } 551 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) { 552 if ((error = chkiq(ip, 1, cred, CHOWN)) == 0) 553 goto good; 554 else 555 (void) chkdq(ip, -change, cred, CHOWN|FORCE); 556 } 557 for (i = 0; i < MAXQUOTAS; i++) { 558 dqrele(vp, ip->i_dquot[i]); 559 ip->i_dquot[i] = NODQUOT; 560 } 561 } 562 ip->i_uid = ouid; 563 ip->i_gid = ogid; 564 if (getinoquota(ip) == 0) { 565 if (ouid == uid) { 566 dqrele(vp, ip->i_dquot[USRQUOTA]); 567 ip->i_dquot[USRQUOTA] = NODQUOT; 568 } 569 if (ogid == gid) { 570 dqrele(vp, ip->i_dquot[GRPQUOTA]); 571 ip->i_dquot[GRPQUOTA] = NODQUOT; 572 } 573 (void) chkdq(ip, change, cred, FORCE|CHOWN); 574 (void) chkiq(ip, 1, cred, FORCE|CHOWN); 575 (void) getinoquota(ip); 576 } 577 return (error); 578 good: 579 if (getinoquota(ip)) 580 panic("chown: lost quota"); 581 #endif /* QUOTA */ 582 if (ouid != uid || ogid != gid) 583 ip->i_flag |= ICHG; 584 if (ouid != uid && cred->cr_uid != 0) 585 ip->i_mode &= ~ISUID; 586 if (ogid != gid && cred->cr_uid != 0) 587 ip->i_mode &= ~ISGID; 588 return (0); 589 } 590 591 /* 592 * Vnode op for reading. 593 */ 594 /* ARGSUSED */ 595 ufs_read(vp, uio, ioflag, cred) 596 struct vnode *vp; 597 register struct uio *uio; 598 int ioflag; 599 struct ucred *cred; 600 { 601 register struct inode *ip = VTOI(vp); 602 register struct fs *fs; 603 struct buf *bp; 604 daddr_t lbn, bn, rablock; 605 int size, diff, error = 0; 606 long n, on, type; 607 608 if (uio->uio_rw != UIO_READ) 609 panic("ufs_read mode"); 610 type = ip->i_mode & IFMT; 611 if (type != IFDIR && type != IFREG && type != IFLNK) 612 panic("ufs_read type"); 613 if (uio->uio_resid == 0) 614 return (0); 615 if (uio->uio_offset < 0) 616 return (EINVAL); 617 ip->i_flag |= IACC; 618 fs = ip->i_fs; 619 do { 620 lbn = lblkno(fs, uio->uio_offset); 621 on = blkoff(fs, uio->uio_offset); 622 n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid); 623 diff = ip->i_size - uio->uio_offset; 624 if (diff <= 0) 625 return (0); 626 if (diff < n) 627 n = diff; 628 size = blksize(fs, ip, lbn); 629 rablock = lbn + 1; 630 if (vp->v_lastr + 1 == lbn && 631 lblktosize(fs, rablock) < ip->i_size) 632 error = breada(ITOV(ip), lbn, size, rablock, 633 blksize(fs, ip, rablock), NOCRED, &bp); 634 else 635 error = bread(ITOV(ip), lbn, size, NOCRED, &bp); 636 vp->v_lastr = lbn; 637 n = MIN(n, size - bp->b_resid); 638 if (error) { 639 brelse(bp); 640 return (error); 641 } 642 error = uiomove(bp->b_un.b_addr + on, (int)n, uio); 643 if (n + on == fs->fs_bsize || uio->uio_offset == ip->i_size) 644 bp->b_flags |= B_AGE; 645 brelse(bp); 646 } while (error == 0 && uio->uio_resid > 0 && n != 0); 647 return (error); 648 } 649 650 /* 651 * Vnode op for writing. 652 */ 653 ufs_write(vp, uio, ioflag, cred) 654 register struct vnode *vp; 655 struct uio *uio; 656 int ioflag; 657 struct ucred *cred; 658 { 659 register struct inode *ip = VTOI(vp); 660 register struct fs *fs; 661 struct buf *bp; 662 daddr_t lbn, bn; 663 u_long osize; 664 int n, on, flags; 665 int size, resid, error = 0; 666 667 if (uio->uio_rw != UIO_WRITE) 668 panic("ufs_write mode"); 669 switch (vp->v_type) { 670 case VREG: 671 if (ioflag & IO_APPEND) 672 uio->uio_offset = ip->i_size; 673 /* fall through */ 674 case VLNK: 675 break; 676 677 case VDIR: 678 if ((ioflag & IO_SYNC) == 0) 679 panic("ufs_write nonsync dir write"); 680 break; 681 682 default: 683 panic("ufs_write type"); 684 } 685 if (uio->uio_offset < 0) 686 return (EINVAL); 687 if (uio->uio_resid == 0) 688 return (0); 689 /* 690 * Maybe this should be above the vnode op call, but so long as 691 * file servers have no limits, i don't think it matters 692 */ 693 if (vp->v_type == VREG && 694 uio->uio_offset + uio->uio_resid > 695 u.u_rlimit[RLIMIT_FSIZE].rlim_cur) { 696 psignal(u.u_procp, SIGXFSZ); 697 return (EFBIG); 698 } 699 resid = uio->uio_resid; 700 osize = ip->i_size; 701 fs = ip->i_fs; 702 flags = 0; 703 if (ioflag & IO_SYNC) 704 flags = B_SYNC; 705 do { 706 lbn = lblkno(fs, uio->uio_offset); 707 on = blkoff(fs, uio->uio_offset); 708 n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid); 709 if (n < fs->fs_bsize) 710 flags |= B_CLRBUF; 711 else 712 flags &= ~B_CLRBUF; 713 if (error = balloc(ip, lbn, (int)(on + n), &bp, flags)) 714 break; 715 bn = bp->b_blkno; 716 if (uio->uio_offset + n > ip->i_size) { 717 ip->i_size = uio->uio_offset + n; 718 vnode_pager_setsize(vp, ip->i_size); 719 } 720 size = blksize(fs, ip, lbn); 721 (void) vnode_pager_uncache(vp); 722 n = MIN(n, size - bp->b_resid); 723 error = uiomove(bp->b_un.b_addr + on, n, uio); 724 if (ioflag & IO_SYNC) 725 (void) bwrite(bp); 726 else if (n + on == fs->fs_bsize) { 727 bp->b_flags |= B_AGE; 728 bawrite(bp); 729 } else 730 bdwrite(bp); 731 ip->i_flag |= IUPD|ICHG; 732 if (cred->cr_uid != 0) 733 ip->i_mode &= ~(ISUID|ISGID); 734 } while (error == 0 && uio->uio_resid > 0 && n != 0); 735 if (error && (ioflag & IO_UNIT)) { 736 (void) itrunc(ip, osize, ioflag & IO_SYNC); 737 uio->uio_offset -= resid - uio->uio_resid; 738 uio->uio_resid = resid; 739 } 740 if (!error && (ioflag & IO_SYNC)) 741 error = iupdat(ip, &time, &time, 1); 742 return (error); 743 } 744 745 /* ARGSUSED */ 746 ufs_ioctl(vp, com, data, fflag, cred) 747 struct vnode *vp; 748 int com; 749 caddr_t data; 750 int fflag; 751 struct ucred *cred; 752 { 753 754 return (ENOTTY); 755 } 756 757 /* ARGSUSED */ 758 ufs_select(vp, which, fflags, cred) 759 struct vnode *vp; 760 int which, fflags; 761 struct ucred *cred; 762 { 763 764 return (1); /* XXX */ 765 } 766 767 /* 768 * Mmap a file 769 * 770 * NB Currently unsupported. 771 */ 772 /* ARGSUSED */ 773 ufs_mmap(vp, fflags, cred) 774 struct vnode *vp; 775 int fflags; 776 struct ucred *cred; 777 { 778 779 return (EINVAL); 780 } 781 782 /* 783 * Synch an open file. 784 */ 785 /* ARGSUSED */ 786 ufs_fsync(vp, fflags, cred, waitfor) 787 struct vnode *vp; 788 int fflags; 789 struct ucred *cred; 790 int waitfor; 791 { 792 struct inode *ip = VTOI(vp); 793 794 if (fflags&FWRITE) 795 ip->i_flag |= ICHG; 796 vflushbuf(vp, waitfor == MNT_WAIT ? B_SYNC : 0); 797 return (iupdat(ip, &time, &time, waitfor == MNT_WAIT)); 798 } 799 800 /* 801 * Seek on a file 802 * 803 * Nothing to do, so just return. 804 */ 805 /* ARGSUSED */ 806 ufs_seek(vp, oldoff, newoff, cred) 807 struct vnode *vp; 808 off_t oldoff, newoff; 809 struct ucred *cred; 810 { 811 812 return (0); 813 } 814 815 /* 816 * ufs remove 817 * Hard to avoid races here, especially 818 * in unlinking directories. 819 */ 820 ufs_remove(ndp) 821 struct nameidata *ndp; 822 { 823 register struct inode *ip, *dp; 824 int error; 825 826 ip = VTOI(ndp->ni_vp); 827 dp = VTOI(ndp->ni_dvp); 828 error = dirremove(ndp); 829 if (!error) { 830 ip->i_nlink--; 831 ip->i_flag |= ICHG; 832 } 833 if (dp == ip) 834 vrele(ITOV(ip)); 835 else 836 iput(ip); 837 iput(dp); 838 return (error); 839 } 840 841 /* 842 * link vnode call 843 */ 844 ufs_link(vp, ndp) 845 register struct vnode *vp; 846 register struct nameidata *ndp; 847 { 848 register struct inode *ip = VTOI(vp); 849 int error; 850 851 if ((unsigned short)ip->i_nlink >= LINK_MAX) 852 return (EMLINK); 853 if (ndp->ni_dvp != vp) 854 ILOCK(ip); 855 ip->i_nlink++; 856 ip->i_flag |= ICHG; 857 error = iupdat(ip, &time, &time, 1); 858 if (!error) 859 error = direnter(ip, ndp); 860 if (ndp->ni_dvp != vp) 861 IUNLOCK(ip); 862 if (error) { 863 ip->i_nlink--; 864 ip->i_flag |= ICHG; 865 } 866 return (error); 867 } 868 869 /* 870 * Rename system call. 871 * rename("foo", "bar"); 872 * is essentially 873 * unlink("bar"); 874 * link("foo", "bar"); 875 * unlink("foo"); 876 * but ``atomically''. Can't do full commit without saving state in the 877 * inode on disk which isn't feasible at this time. Best we can do is 878 * always guarantee the target exists. 879 * 880 * Basic algorithm is: 881 * 882 * 1) Bump link count on source while we're linking it to the 883 * target. This also ensure the inode won't be deleted out 884 * from underneath us while we work (it may be truncated by 885 * a concurrent `trunc' or `open' for creation). 886 * 2) Link source to destination. If destination already exists, 887 * delete it first. 888 * 3) Unlink source reference to inode if still around. If a 889 * directory was moved and the parent of the destination 890 * is different from the source, patch the ".." entry in the 891 * directory. 892 */ 893 ufs_rename(fndp, tndp) 894 register struct nameidata *fndp, *tndp; 895 { 896 register struct inode *ip, *xp, *dp; 897 struct dirtemplate dirbuf; 898 int doingdirectory = 0, oldparent = 0, newparent = 0; 899 int error = 0; 900 901 dp = VTOI(fndp->ni_dvp); 902 ip = VTOI(fndp->ni_vp); 903 ILOCK(ip); 904 if ((ip->i_mode&IFMT) == IFDIR) { 905 register struct direct *d = &fndp->ni_dent; 906 907 /* 908 * Avoid ".", "..", and aliases of "." for obvious reasons. 909 */ 910 if ((d->d_namlen == 1 && d->d_name[0] == '.') || dp == ip || 911 fndp->ni_isdotdot || (ip->i_flag & IRENAME)) { 912 VOP_ABORTOP(tndp); 913 vput(tndp->ni_dvp); 914 if (tndp->ni_vp) 915 vput(tndp->ni_vp); 916 VOP_ABORTOP(fndp); 917 vrele(fndp->ni_dvp); 918 vput(fndp->ni_vp); 919 return (EINVAL); 920 } 921 ip->i_flag |= IRENAME; 922 oldparent = dp->i_number; 923 doingdirectory++; 924 } 925 vrele(fndp->ni_dvp); 926 927 /* 928 * 1) Bump link count while we're moving stuff 929 * around. If we crash somewhere before 930 * completing our work, the link count 931 * may be wrong, but correctable. 932 */ 933 ip->i_nlink++; 934 ip->i_flag |= ICHG; 935 error = iupdat(ip, &time, &time, 1); 936 IUNLOCK(ip); 937 938 /* 939 * When the target exists, both the directory 940 * and target vnodes are returned locked. 941 */ 942 dp = VTOI(tndp->ni_dvp); 943 xp = NULL; 944 if (tndp->ni_vp) 945 xp = VTOI(tndp->ni_vp); 946 /* 947 * If ".." must be changed (ie the directory gets a new 948 * parent) then the source directory must not be in the 949 * directory heirarchy above the target, as this would 950 * orphan everything below the source directory. Also 951 * the user must have write permission in the source so 952 * as to be able to change "..". We must repeat the call 953 * to namei, as the parent directory is unlocked by the 954 * call to checkpath(). 955 */ 956 if (oldparent != dp->i_number) 957 newparent = dp->i_number; 958 if (doingdirectory && newparent) { 959 VOP_LOCK(fndp->ni_vp); 960 error = ufs_access(fndp->ni_vp, VWRITE, tndp->ni_cred); 961 VOP_UNLOCK(fndp->ni_vp); 962 if (error) 963 goto bad; 964 tndp->ni_nameiop &= ~(MODMASK | OPMASK); 965 tndp->ni_nameiop |= RENAME | LOCKPARENT | LOCKLEAF | NOCACHE; 966 do { 967 dp = VTOI(tndp->ni_dvp); 968 if (xp != NULL) 969 iput(xp); 970 if (error = checkpath(ip, dp, tndp->ni_cred)) 971 goto out; 972 if (error = namei(tndp)) 973 goto out; 974 xp = NULL; 975 if (tndp->ni_vp) 976 xp = VTOI(tndp->ni_vp); 977 } while (dp != VTOI(tndp->ni_dvp)); 978 } 979 /* 980 * 2) If target doesn't exist, link the target 981 * to the source and unlink the source. 982 * Otherwise, rewrite the target directory 983 * entry to reference the source inode and 984 * expunge the original entry's existence. 985 */ 986 if (xp == NULL) { 987 if (dp->i_dev != ip->i_dev) 988 panic("rename: EXDEV"); 989 /* 990 * Account for ".." in new directory. 991 * When source and destination have the same 992 * parent we don't fool with the link count. 993 */ 994 if (doingdirectory && newparent) { 995 if ((unsigned short)dp->i_nlink >= LINK_MAX) { 996 error = EMLINK; 997 goto bad; 998 } 999 dp->i_nlink++; 1000 dp->i_flag |= ICHG; 1001 if (error = iupdat(dp, &time, &time, 1)) 1002 goto bad; 1003 } 1004 if (error = direnter(ip, tndp)) 1005 goto out; 1006 } else { 1007 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) 1008 panic("rename: EXDEV"); 1009 /* 1010 * Short circuit rename(foo, foo). 1011 */ 1012 if (xp->i_number == ip->i_number) 1013 panic("rename: same file"); 1014 /* 1015 * If the parent directory is "sticky", then the user must 1016 * own the parent directory, or the destination of the rename, 1017 * otherwise the destination may not be changed (except by 1018 * root). This implements append-only directories. 1019 */ 1020 if ((dp->i_mode & ISVTX) && tndp->ni_cred->cr_uid != 0 && 1021 tndp->ni_cred->cr_uid != dp->i_uid && 1022 xp->i_uid != tndp->ni_cred->cr_uid) { 1023 error = EPERM; 1024 goto bad; 1025 } 1026 /* 1027 * Target must be empty if a directory 1028 * and have no links to it. 1029 * Also, insure source and target are 1030 * compatible (both directories, or both 1031 * not directories). 1032 */ 1033 if ((xp->i_mode&IFMT) == IFDIR) { 1034 if (!dirempty(xp, dp->i_number, tndp->ni_cred) || 1035 xp->i_nlink > 2) { 1036 error = ENOTEMPTY; 1037 goto bad; 1038 } 1039 if (!doingdirectory) { 1040 error = ENOTDIR; 1041 goto bad; 1042 } 1043 cache_purge(ITOV(dp)); 1044 } else if (doingdirectory) { 1045 error = EISDIR; 1046 goto bad; 1047 } 1048 if (error = dirrewrite(dp, ip, tndp)) 1049 goto bad; 1050 /* 1051 * If the target directory is in the same 1052 * directory as the source directory, 1053 * decrement the link count on the parent 1054 * of the target directory. 1055 */ 1056 if (doingdirectory && !newparent) { 1057 dp->i_nlink--; 1058 dp->i_flag |= ICHG; 1059 } 1060 vput(ITOV(dp)); 1061 /* 1062 * Adjust the link count of the target to 1063 * reflect the dirrewrite above. If this is 1064 * a directory it is empty and there are 1065 * no links to it, so we can squash the inode and 1066 * any space associated with it. We disallowed 1067 * renaming over top of a directory with links to 1068 * it above, as the remaining link would point to 1069 * a directory without "." or ".." entries. 1070 */ 1071 xp->i_nlink--; 1072 if (doingdirectory) { 1073 if (--xp->i_nlink != 0) 1074 panic("rename: linked directory"); 1075 error = itrunc(xp, (u_long)0, IO_SYNC); 1076 } 1077 xp->i_flag |= ICHG; 1078 iput(xp); 1079 xp = NULL; 1080 } 1081 1082 /* 1083 * 3) Unlink the source. 1084 */ 1085 fndp->ni_nameiop &= ~(MODMASK | OPMASK); 1086 fndp->ni_nameiop |= DELETE | LOCKPARENT | LOCKLEAF; 1087 (void)namei(fndp); 1088 if (fndp->ni_vp != NULL) { 1089 xp = VTOI(fndp->ni_vp); 1090 dp = VTOI(fndp->ni_dvp); 1091 } else { 1092 /* 1093 * From name has disappeared. 1094 */ 1095 if (doingdirectory) 1096 panic("rename: lost dir entry"); 1097 vrele(ITOV(ip)); 1098 return (0); 1099 } 1100 /* 1101 * Ensure that the directory entry still exists and has not 1102 * changed while the new name has been entered. If the source is 1103 * a file then the entry may have been unlinked or renamed. In 1104 * either case there is no further work to be done. If the source 1105 * is a directory then it cannot have been rmdir'ed; its link 1106 * count of three would cause a rmdir to fail with ENOTEMPTY. 1107 * The IRENAME flag ensures that it cannot be moved by another 1108 * rename. 1109 */ 1110 if (xp != ip) { 1111 if (doingdirectory) 1112 panic("rename: lost dir entry"); 1113 } else { 1114 /* 1115 * If the source is a directory with a 1116 * new parent, the link count of the old 1117 * parent directory must be decremented 1118 * and ".." set to point to the new parent. 1119 */ 1120 if (doingdirectory && newparent) { 1121 dp->i_nlink--; 1122 dp->i_flag |= ICHG; 1123 error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf, 1124 sizeof (struct dirtemplate), (off_t)0, 1125 UIO_SYSSPACE, IO_NODELOCKED, 1126 tndp->ni_cred, (int *)0); 1127 if (error == 0) { 1128 if (dirbuf.dotdot_namlen != 2 || 1129 dirbuf.dotdot_name[0] != '.' || 1130 dirbuf.dotdot_name[1] != '.') { 1131 dirbad(xp, 12, "rename: mangled dir"); 1132 } else { 1133 dirbuf.dotdot_ino = newparent; 1134 (void) vn_rdwr(UIO_WRITE, ITOV(xp), 1135 (caddr_t)&dirbuf, 1136 sizeof (struct dirtemplate), 1137 (off_t)0, UIO_SYSSPACE, 1138 IO_NODELOCKED|IO_SYNC, 1139 tndp->ni_cred, (int *)0); 1140 cache_purge(ITOV(dp)); 1141 } 1142 } 1143 } 1144 error = dirremove(fndp); 1145 if (!error) { 1146 xp->i_nlink--; 1147 xp->i_flag |= ICHG; 1148 } 1149 xp->i_flag &= ~IRENAME; 1150 } 1151 if (dp) 1152 vput(ITOV(dp)); 1153 if (xp) 1154 vput(ITOV(xp)); 1155 vrele(ITOV(ip)); 1156 return (error); 1157 1158 bad: 1159 if (xp) 1160 vput(ITOV(xp)); 1161 vput(ITOV(dp)); 1162 out: 1163 ip->i_nlink--; 1164 ip->i_flag |= ICHG; 1165 vrele(ITOV(ip)); 1166 return (error); 1167 } 1168 1169 /* 1170 * A virgin directory (no blushing please). 1171 */ 1172 struct dirtemplate mastertemplate = { 1173 0, 12, 1, ".", 1174 0, DIRBLKSIZ - 12, 2, ".." 1175 }; 1176 1177 /* 1178 * Mkdir system call 1179 */ 1180 ufs_mkdir(ndp, vap) 1181 struct nameidata *ndp; 1182 struct vattr *vap; 1183 { 1184 register struct inode *ip, *dp; 1185 struct inode *tip; 1186 struct vnode *dvp; 1187 struct dirtemplate dirtemplate; 1188 int error; 1189 int dmode; 1190 1191 dvp = ndp->ni_dvp; 1192 dp = VTOI(dvp); 1193 if ((unsigned short)dp->i_nlink >= LINK_MAX) { 1194 iput(dp); 1195 return (EMLINK); 1196 } 1197 dmode = vap->va_mode&0777; 1198 dmode |= IFDIR; 1199 /* 1200 * Must simulate part of maknode here 1201 * in order to acquire the inode, but 1202 * not have it entered in the parent 1203 * directory. The entry is made later 1204 * after writing "." and ".." entries out. 1205 */ 1206 if (error = ialloc(dp, dirpref(dp->i_fs), dmode, ndp->ni_cred, &tip)) { 1207 iput(dp); 1208 return (error); 1209 } 1210 ip = tip; 1211 ip->i_uid = ndp->ni_cred->cr_uid; 1212 ip->i_gid = dp->i_gid; 1213 #ifdef QUOTA 1214 if ((error = getinoquota(ip)) || 1215 (error = chkiq(ip, 1, ndp->ni_cred, 0))) { 1216 ifree(ip, ip->i_number, dmode); 1217 iput(ip); 1218 iput(dp); 1219 return (error); 1220 } 1221 #endif 1222 ip->i_flag |= IACC|IUPD|ICHG; 1223 ip->i_mode = dmode; 1224 ITOV(ip)->v_type = VDIR; /* Rest init'd in iget() */ 1225 ip->i_nlink = 2; 1226 error = iupdat(ip, &time, &time, 1); 1227 1228 /* 1229 * Bump link count in parent directory 1230 * to reflect work done below. Should 1231 * be done before reference is created 1232 * so reparation is possible if we crash. 1233 */ 1234 dp->i_nlink++; 1235 dp->i_flag |= ICHG; 1236 error = iupdat(dp, &time, &time, 1); 1237 1238 /* 1239 * Initialize directory with "." 1240 * and ".." from static template. 1241 */ 1242 dirtemplate = mastertemplate; 1243 dirtemplate.dot_ino = ip->i_number; 1244 dirtemplate.dotdot_ino = dp->i_number; 1245 error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate, 1246 sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, 1247 IO_NODELOCKED|IO_SYNC, ndp->ni_cred, (int *)0); 1248 if (error) { 1249 dp->i_nlink--; 1250 dp->i_flag |= ICHG; 1251 goto bad; 1252 } 1253 if (DIRBLKSIZ > dp->i_fs->fs_fsize) { 1254 panic("mkdir: blksize"); /* XXX - should grow w/balloc() */ 1255 } else { 1256 ip->i_size = DIRBLKSIZ; 1257 ip->i_flag |= ICHG; 1258 } 1259 /* 1260 * Directory all set up, now 1261 * install the entry for it in 1262 * the parent directory. 1263 */ 1264 error = direnter(ip, ndp); 1265 dp = NULL; 1266 if (error) { 1267 ndp->ni_nameiop &= ~(MODMASK | OPMASK); 1268 ndp->ni_nameiop |= LOOKUP | NOCACHE; 1269 error = namei(ndp); 1270 if (!error) { 1271 dp = VTOI(ndp->ni_vp); 1272 dp->i_nlink--; 1273 dp->i_flag |= ICHG; 1274 } 1275 } 1276 bad: 1277 /* 1278 * No need to do an explicit itrunc here, 1279 * vrele will do this for us because we set 1280 * the link count to 0. 1281 */ 1282 if (error) { 1283 ip->i_nlink = 0; 1284 ip->i_flag |= ICHG; 1285 iput(ip); 1286 } else 1287 ndp->ni_vp = ITOV(ip); 1288 if (dp) 1289 iput(dp); 1290 return (error); 1291 } 1292 1293 /* 1294 * Rmdir system call. 1295 */ 1296 ufs_rmdir(ndp) 1297 register struct nameidata *ndp; 1298 { 1299 register struct inode *ip, *dp; 1300 int error = 0; 1301 1302 ip = VTOI(ndp->ni_vp); 1303 dp = VTOI(ndp->ni_dvp); 1304 /* 1305 * No rmdir "." please. 1306 */ 1307 if (dp == ip) { 1308 vrele(ITOV(dp)); 1309 iput(ip); 1310 return (EINVAL); 1311 } 1312 /* 1313 * Verify the directory is empty (and valid). 1314 * (Rmdir ".." won't be valid since 1315 * ".." will contain a reference to 1316 * the current directory and thus be 1317 * non-empty.) 1318 */ 1319 if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number, ndp->ni_cred)) { 1320 error = ENOTEMPTY; 1321 goto out; 1322 } 1323 /* 1324 * Delete reference to directory before purging 1325 * inode. If we crash in between, the directory 1326 * will be reattached to lost+found, 1327 */ 1328 if (error = dirremove(ndp)) 1329 goto out; 1330 dp->i_nlink--; 1331 dp->i_flag |= ICHG; 1332 cache_purge(ITOV(dp)); 1333 iput(dp); 1334 ndp->ni_dvp = NULL; 1335 /* 1336 * Truncate inode. The only stuff left 1337 * in the directory is "." and "..". The 1338 * "." reference is inconsequential since 1339 * we're quashing it. The ".." reference 1340 * has already been adjusted above. We've 1341 * removed the "." reference and the reference 1342 * in the parent directory, but there may be 1343 * other hard links so decrement by 2 and 1344 * worry about them later. 1345 */ 1346 ip->i_nlink -= 2; 1347 error = itrunc(ip, (u_long)0, IO_SYNC); 1348 cache_purge(ITOV(ip)); 1349 out: 1350 if (ndp->ni_dvp) 1351 iput(dp); 1352 iput(ip); 1353 return (error); 1354 } 1355 1356 /* 1357 * symlink -- make a symbolic link 1358 */ 1359 ufs_symlink(ndp, vap, target) 1360 struct nameidata *ndp; 1361 struct vattr *vap; 1362 char *target; 1363 { 1364 struct inode *ip; 1365 int error; 1366 1367 error = maknode(IFLNK | vap->va_mode, ndp, &ip); 1368 if (error) 1369 return (error); 1370 error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0, 1371 UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0); 1372 iput(ip); 1373 return (error); 1374 } 1375 1376 /* 1377 * Vnode op for read and write 1378 */ 1379 ufs_readdir(vp, uio, cred, eofflagp) 1380 struct vnode *vp; 1381 register struct uio *uio; 1382 struct ucred *cred; 1383 int *eofflagp; 1384 { 1385 int count, lost, error; 1386 1387 count = uio->uio_resid; 1388 count &= ~(DIRBLKSIZ - 1); 1389 lost = uio->uio_resid - count; 1390 if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1))) 1391 return (EINVAL); 1392 uio->uio_resid = count; 1393 uio->uio_iov->iov_len = count; 1394 error = ufs_read(vp, uio, 0, cred); 1395 uio->uio_resid += lost; 1396 if ((VTOI(vp)->i_size - uio->uio_offset) <= 0) 1397 *eofflagp = 1; 1398 else 1399 *eofflagp = 0; 1400 return (error); 1401 } 1402 1403 /* 1404 * Return target name of a symbolic link 1405 */ 1406 ufs_readlink(vp, uiop, cred) 1407 struct vnode *vp; 1408 struct uio *uiop; 1409 struct ucred *cred; 1410 { 1411 1412 return (ufs_read(vp, uiop, 0, cred)); 1413 } 1414 1415 /* 1416 * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 1417 * done. Nothing to do at the moment. 1418 */ 1419 /* ARGSUSED */ 1420 ufs_abortop(ndp) 1421 struct nameidata *ndp; 1422 { 1423 1424 return (0); 1425 } 1426 1427 /* 1428 * Lock an inode. 1429 */ 1430 ufs_lock(vp) 1431 struct vnode *vp; 1432 { 1433 register struct inode *ip = VTOI(vp); 1434 1435 ILOCK(ip); 1436 return (0); 1437 } 1438 1439 /* 1440 * Unlock an inode. 1441 */ 1442 ufs_unlock(vp) 1443 struct vnode *vp; 1444 { 1445 register struct inode *ip = VTOI(vp); 1446 1447 if (!(ip->i_flag & ILOCKED)) 1448 panic("ufs_unlock NOT LOCKED"); 1449 IUNLOCK(ip); 1450 return (0); 1451 } 1452 1453 /* 1454 * Check for a locked inode. 1455 */ 1456 ufs_islocked(vp) 1457 struct vnode *vp; 1458 { 1459 1460 if (VTOI(vp)->i_flag & ILOCKED) 1461 return (1); 1462 return (0); 1463 } 1464 1465 /* 1466 * Get access to bmap 1467 */ 1468 ufs_bmap(vp, bn, vpp, bnp) 1469 struct vnode *vp; 1470 daddr_t bn; 1471 struct vnode **vpp; 1472 daddr_t *bnp; 1473 { 1474 struct inode *ip = VTOI(vp); 1475 1476 if (vpp != NULL) 1477 *vpp = ip->i_devvp; 1478 if (bnp == NULL) 1479 return (0); 1480 return (bmap(ip, bn, bnp)); 1481 } 1482 1483 /* 1484 * Calculate the logical to physical mapping if not done already, 1485 * then call the device strategy routine. 1486 */ 1487 int checkoverlap = 0; 1488 1489 ufs_strategy(bp) 1490 register struct buf *bp; 1491 { 1492 register struct inode *ip = VTOI(bp->b_vp); 1493 struct vnode *vp; 1494 int error; 1495 1496 if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR) 1497 panic("ufs_strategy: spec"); 1498 if (bp->b_blkno == bp->b_lblkno) { 1499 if (error = bmap(ip, bp->b_lblkno, &bp->b_blkno)) 1500 return (error); 1501 if ((long)bp->b_blkno == -1) 1502 clrbuf(bp); 1503 } 1504 if ((long)bp->b_blkno == -1) { 1505 biodone(bp); 1506 return (0); 1507 } 1508 #ifdef DIAGNOSTIC 1509 if (checkoverlap) { 1510 register struct buf *ep; 1511 struct buf *ebp; 1512 daddr_t start, last; 1513 1514 ebp = &buf[nbuf]; 1515 start = bp->b_blkno; 1516 last = start + btodb(bp->b_bcount) - 1; 1517 for (ep = buf; ep < ebp; ep++) { 1518 if (ep == bp || (ep->b_flags & B_INVAL) || 1519 ep->b_vp == NULLVP) 1520 continue; 1521 if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0)) 1522 continue; 1523 if (vp != ip->i_devvp) 1524 continue; 1525 /* look for overlap */ 1526 if (ep->b_bcount == 0 || ep->b_blkno > last || 1527 ep->b_blkno + btodb(ep->b_bcount) <= start) 1528 continue; 1529 vprint("Disk overlap", vp); 1530 printf("\tstart %d, end %d overlap start %d, end %d\n", 1531 start, last, ep->b_blkno, 1532 ep->b_blkno + btodb(ep->b_bcount) - 1); 1533 panic("Disk buffer overlap"); 1534 } 1535 } 1536 #endif /* DIAGNOSTIC */ 1537 vp = ip->i_devvp; 1538 bp->b_dev = vp->v_rdev; 1539 (*(vp->v_op->vn_strategy))(bp); 1540 return (0); 1541 } 1542 1543 /* 1544 * Print out the contents of an inode. 1545 */ 1546 ufs_print(vp) 1547 struct vnode *vp; 1548 { 1549 register struct inode *ip = VTOI(vp); 1550 1551 printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number, 1552 major(ip->i_dev), minor(ip->i_dev)); 1553 #ifdef FIFO 1554 if (vp->v_type == VFIFO) 1555 fifo_printinfo(vp); 1556 #endif /* FIFO */ 1557 printf("%s\n", (ip->i_flag & ILOCKED) ? " (LOCKED)" : ""); 1558 if (ip->i_spare0 == 0) 1559 return; 1560 printf("\towner pid %d", ip->i_spare0); 1561 if (ip->i_spare1) 1562 printf(" waiting pid %d", ip->i_spare1); 1563 printf("\n"); 1564 } 1565 1566 /* 1567 * Read wrapper for special devices. 1568 */ 1569 ufsspec_read(vp, uio, ioflag, cred) 1570 struct vnode *vp; 1571 struct uio *uio; 1572 int ioflag; 1573 struct ucred *cred; 1574 { 1575 1576 /* 1577 * Set access flag. 1578 */ 1579 VTOI(vp)->i_flag |= IACC; 1580 return (spec_read(vp, uio, ioflag, cred)); 1581 } 1582 1583 /* 1584 * Write wrapper for special devices. 1585 */ 1586 ufsspec_write(vp, uio, ioflag, cred) 1587 struct vnode *vp; 1588 struct uio *uio; 1589 int ioflag; 1590 struct ucred *cred; 1591 { 1592 1593 /* 1594 * Set update and change flags. 1595 */ 1596 VTOI(vp)->i_flag |= IUPD|ICHG; 1597 return (spec_write(vp, uio, ioflag, cred)); 1598 } 1599 1600 /* 1601 * Close wrapper for special devices. 1602 * 1603 * Update the times on the inode then do device close. 1604 */ 1605 ufsspec_close(vp, fflag, cred) 1606 struct vnode *vp; 1607 int fflag; 1608 struct ucred *cred; 1609 { 1610 register struct inode *ip = VTOI(vp); 1611 1612 if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED)) 1613 ITIMES(ip, &time, &time); 1614 return (spec_close(vp, fflag, cred)); 1615 } 1616 1617 #ifdef FIFO 1618 /* 1619 * Read wrapper for fifo's 1620 */ 1621 ufsfifo_read(vp, uio, ioflag, cred) 1622 struct vnode *vp; 1623 struct uio *uio; 1624 int ioflag; 1625 struct ucred *cred; 1626 { 1627 1628 /* 1629 * Set access flag. 1630 */ 1631 VTOI(vp)->i_flag |= IACC; 1632 return (fifo_read(vp, uio, ioflag, cred)); 1633 } 1634 1635 /* 1636 * Write wrapper for fifo's. 1637 */ 1638 ufsfifo_write(vp, uio, ioflag, cred) 1639 struct vnode *vp; 1640 struct uio *uio; 1641 int ioflag; 1642 struct ucred *cred; 1643 { 1644 1645 /* 1646 * Set update and change flags. 1647 */ 1648 VTOI(vp)->i_flag |= IUPD|ICHG; 1649 return (fifo_write(vp, uio, ioflag, cred)); 1650 } 1651 1652 /* 1653 * Close wrapper for fifo's. 1654 * 1655 * Update the times on the inode then do device close. 1656 */ 1657 ufsfifo_close(vp, fflag, cred) 1658 struct vnode *vp; 1659 int fflag; 1660 struct ucred *cred; 1661 { 1662 register struct inode *ip = VTOI(vp); 1663 1664 if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED)) 1665 ITIMES(ip, &time, &time); 1666 return (fifo_close(vp, fflag, cred)); 1667 } 1668 #endif /* FIFO */ 1669 1670 /* 1671 * Make a new file. 1672 */ 1673 maknode(mode, ndp, ipp) 1674 int mode; 1675 register struct nameidata *ndp; 1676 struct inode **ipp; 1677 { 1678 register struct inode *ip; 1679 struct inode *tip; 1680 register struct inode *pdir = VTOI(ndp->ni_dvp); 1681 ino_t ipref; 1682 int error; 1683 1684 *ipp = 0; 1685 if ((mode & IFMT) == 0) 1686 mode |= IFREG; 1687 if ((mode & IFMT) == IFDIR) 1688 ipref = dirpref(pdir->i_fs); 1689 else 1690 ipref = pdir->i_number; 1691 if (error = ialloc(pdir, ipref, mode, ndp->ni_cred, &tip)) { 1692 iput(pdir); 1693 return (error); 1694 } 1695 ip = tip; 1696 ip->i_uid = ndp->ni_cred->cr_uid; 1697 ip->i_gid = pdir->i_gid; 1698 #ifdef QUOTA 1699 if ((error = getinoquota(ip)) || 1700 (error = chkiq(ip, 1, ndp->ni_cred, 0))) { 1701 ifree(ip, ip->i_number, mode); 1702 iput(ip); 1703 iput(pdir); 1704 return (error); 1705 } 1706 #endif 1707 ip->i_flag |= IACC|IUPD|ICHG; 1708 ip->i_mode = mode; 1709 ITOV(ip)->v_type = IFTOVT(mode); /* Rest init'd in iget() */ 1710 ip->i_nlink = 1; 1711 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, ndp->ni_cred) && 1712 suser(ndp->ni_cred, NULL)) 1713 ip->i_mode &= ~ISGID; 1714 1715 /* 1716 * Make sure inode goes to disk before directory entry. 1717 */ 1718 if (error = iupdat(ip, &time, &time, 1)) 1719 goto bad; 1720 if (error = direnter(ip, ndp)) { 1721 pdir = NULL; 1722 goto bad; 1723 } 1724 *ipp = ip; 1725 return (0); 1726 1727 bad: 1728 /* 1729 * Write error occurred trying to update the inode 1730 * or the directory so must deallocate the inode. 1731 */ 1732 if (pdir) 1733 iput(pdir); 1734 ip->i_nlink = 0; 1735 ip->i_flag |= ICHG; 1736 iput(ip); 1737 return (error); 1738 } 1739 1740 /* 1741 * Advisory record locking support 1742 */ 1743 ufs_advlock(vp, id, op, fl, flags) 1744 struct vnode *vp; 1745 caddr_t id; 1746 int op; 1747 register struct flock *fl; 1748 int flags; 1749 { 1750 register struct inode *ip = VTOI(vp); 1751 register struct lockf *lock; 1752 off_t start, end; 1753 int error; 1754 1755 /* 1756 * Avoid the common case of unlocking when inode has no locks. 1757 */ 1758 if (ip->i_lockf == (struct lockf *)0) { 1759 if (op != F_SETLK) { 1760 fl->l_type = F_UNLCK; 1761 return (0); 1762 } 1763 } 1764 /* 1765 * Convert the flock structure into a start and end. 1766 */ 1767 switch (fl->l_whence) { 1768 1769 case SEEK_SET: 1770 case SEEK_CUR: 1771 /* 1772 * Caller is responsible for adding any necessary offset 1773 * when SEEK_CUR is used. 1774 */ 1775 start = fl->l_start; 1776 break; 1777 1778 case SEEK_END: 1779 start = ip->i_size + fl->l_start; 1780 break; 1781 1782 default: 1783 return (EINVAL); 1784 } 1785 if (start < 0) 1786 return (EINVAL); 1787 if (fl->l_len == 0) 1788 end = -1; 1789 else 1790 end = start + fl->l_len - 1; 1791 /* 1792 * Create the lockf structure 1793 */ 1794 MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK); 1795 lock->lf_start = start; 1796 lock->lf_end = end; 1797 lock->lf_id = id; 1798 lock->lf_inode = ip; 1799 lock->lf_type = fl->l_type; 1800 lock->lf_next = (struct lockf *)0; 1801 lock->lf_block = (struct lockf *)0; 1802 lock->lf_flags = flags; 1803 /* 1804 * Do the requested operation. 1805 */ 1806 switch(op) { 1807 case F_SETLK: 1808 return (lf_setlock(lock)); 1809 1810 case F_UNLCK: 1811 error = lf_clearlock(lock); 1812 FREE(lock, M_LOCKF); 1813 return (error); 1814 1815 case F_GETLK: 1816 error = lf_getlock(lock, fl); 1817 FREE(lock, M_LOCKF); 1818 return (error); 1819 1820 default: 1821 free(lock, M_LOCKF); 1822 return (EINVAL); 1823 } 1824 /* NOTREACHED */ 1825 } 1826