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