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