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