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