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