1 /* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)ufs_vnops.c 8.24 (Berkeley) 04/28/95 13 */ 14 15 #include <sys/param.h> 16 #include <sys/systm.h> 17 #include <sys/namei.h> 18 #include <sys/resourcevar.h> 19 #include <sys/kernel.h> 20 #include <sys/file.h> 21 #include <sys/stat.h> 22 #include <sys/buf.h> 23 #include <sys/proc.h> 24 #include <sys/conf.h> 25 #include <sys/mount.h> 26 #include <sys/vnode.h> 27 #include <sys/malloc.h> 28 #include <sys/dirent.h> 29 30 #include <vm/vm.h> 31 32 #include <miscfs/specfs/specdev.h> 33 34 #include <ufs/ufs/lockf.h> 35 #include <ufs/ufs/quota.h> 36 #include <ufs/ufs/inode.h> 37 #include <ufs/ufs/dir.h> 38 #include <ufs/ufs/ufsmount.h> 39 #include <ufs/ufs/ufs_extern.h> 40 41 static int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *)); 42 static int ufs_chown 43 __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *)); 44 45 union _qcvt { 46 int64_t qcvt; 47 int32_t val[2]; 48 }; 49 #define SETHIGH(q, h) { \ 50 union _qcvt tmp; \ 51 tmp.qcvt = (q); \ 52 tmp.val[_QUAD_HIGHWORD] = (h); \ 53 (q) = tmp.qcvt; \ 54 } 55 #define SETLOW(q, l) { \ 56 union _qcvt tmp; \ 57 tmp.qcvt = (q); \ 58 tmp.val[_QUAD_LOWWORD] = (l); \ 59 (q) = tmp.qcvt; \ 60 } 61 62 /* 63 * Create a regular file 64 */ 65 int 66 ufs_create(ap) 67 struct vop_create_args /* { 68 struct vnode *a_dvp; 69 struct vnode **a_vpp; 70 struct componentname *a_cnp; 71 struct vattr *a_vap; 72 } */ *ap; 73 { 74 int error; 75 76 if (error = 77 ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), 78 ap->a_dvp, ap->a_vpp, ap->a_cnp)) 79 return (error); 80 return (0); 81 } 82 83 /* 84 * Mknod vnode call 85 */ 86 /* ARGSUSED */ 87 int 88 ufs_mknod(ap) 89 struct vop_mknod_args /* { 90 struct vnode *a_dvp; 91 struct vnode **a_vpp; 92 struct componentname *a_cnp; 93 struct vattr *a_vap; 94 } */ *ap; 95 { 96 register struct vattr *vap = ap->a_vap; 97 register struct vnode **vpp = ap->a_vpp; 98 register struct inode *ip; 99 int error; 100 101 if (error = 102 ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), 103 ap->a_dvp, vpp, ap->a_cnp)) 104 return (error); 105 ip = VTOI(*vpp); 106 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 107 if (vap->va_rdev != VNOVAL) { 108 /* 109 * Want to be able to use this to make badblock 110 * inodes, so don't truncate the dev number. 111 */ 112 ip->i_rdev = vap->va_rdev; 113 } 114 /* 115 * Remove inode so that it will be reloaded by VFS_VGET and 116 * checked to see if it is an alias of an existing entry in 117 * the inode cache. 118 */ 119 vput(*vpp); 120 (*vpp)->v_type = VNON; 121 vgone(*vpp); 122 *vpp = 0; 123 return (0); 124 } 125 126 /* 127 * Open called. 128 * 129 * Nothing to do. 130 */ 131 /* ARGSUSED */ 132 int 133 ufs_open(ap) 134 struct vop_open_args /* { 135 struct vnode *a_vp; 136 int a_mode; 137 struct ucred *a_cred; 138 struct proc *a_p; 139 } */ *ap; 140 { 141 142 /* 143 * Files marked append-only must be opened for appending. 144 */ 145 if ((VTOI(ap->a_vp)->i_flags & APPEND) && 146 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) 147 return (EPERM); 148 return (0); 149 } 150 151 /* 152 * Close called. 153 * 154 * Update the times on the inode. 155 */ 156 /* ARGSUSED */ 157 int 158 ufs_close(ap) 159 struct vop_close_args /* { 160 struct vnode *a_vp; 161 int a_fflag; 162 struct ucred *a_cred; 163 struct proc *a_p; 164 } */ *ap; 165 { 166 register struct vnode *vp = ap->a_vp; 167 register struct inode *ip = VTOI(vp); 168 169 if (vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED)) 170 ITIMES(ip, &time, &time); 171 return (0); 172 } 173 174 int 175 ufs_access(ap) 176 struct vop_access_args /* { 177 struct vnode *a_vp; 178 int a_mode; 179 struct ucred *a_cred; 180 struct proc *a_p; 181 } */ *ap; 182 { 183 register struct vnode *vp = ap->a_vp; 184 register struct inode *ip = VTOI(vp); 185 register struct ucred *cred = ap->a_cred; 186 mode_t mask, mode = ap->a_mode; 187 register gid_t *gp; 188 int i, error; 189 190 #ifdef DIAGNOSTIC 191 if (!VOP_ISLOCKED(vp)) { 192 vprint("ufs_access: not locked", vp); 193 panic("ufs_access: not locked"); 194 } 195 #endif 196 #ifdef QUOTA 197 if (mode & VWRITE) 198 switch (vp->v_type) { 199 case VDIR: 200 case VLNK: 201 case VREG: 202 if (error = getinoquota(ip)) 203 return (error); 204 break; 205 } 206 #endif 207 208 /* If immutable bit set, nobody gets to write it. */ 209 if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE)) 210 return (EPERM); 211 212 /* Otherwise, user id 0 always gets access. */ 213 if (cred->cr_uid == 0) 214 return (0); 215 216 mask = 0; 217 218 /* Otherwise, check the owner. */ 219 if (cred->cr_uid == ip->i_uid) { 220 if (mode & VEXEC) 221 mask |= S_IXUSR; 222 if (mode & VREAD) 223 mask |= S_IRUSR; 224 if (mode & VWRITE) 225 mask |= S_IWUSR; 226 return ((ip->i_mode & mask) == mask ? 0 : EACCES); 227 } 228 229 /* Otherwise, check the groups. */ 230 for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) 231 if (ip->i_gid == *gp) { 232 if (mode & VEXEC) 233 mask |= S_IXGRP; 234 if (mode & VREAD) 235 mask |= S_IRGRP; 236 if (mode & VWRITE) 237 mask |= S_IWGRP; 238 return ((ip->i_mode & mask) == mask ? 0 : EACCES); 239 } 240 241 /* Otherwise, check everyone else. */ 242 if (mode & VEXEC) 243 mask |= S_IXOTH; 244 if (mode & VREAD) 245 mask |= S_IROTH; 246 if (mode & VWRITE) 247 mask |= S_IWOTH; 248 return ((ip->i_mode & mask) == mask ? 0 : EACCES); 249 } 250 251 /* ARGSUSED */ 252 int 253 ufs_getattr(ap) 254 struct vop_getattr_args /* { 255 struct vnode *a_vp; 256 struct vattr *a_vap; 257 struct ucred *a_cred; 258 struct proc *a_p; 259 } */ *ap; 260 { 261 register struct vnode *vp = ap->a_vp; 262 register struct inode *ip = VTOI(vp); 263 register struct vattr *vap = ap->a_vap; 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_size; 277 vap->va_atime.ts_sec = ip->i_atime; 278 vap->va_atime.ts_nsec = ip->i_atimensec; 279 vap->va_mtime.ts_sec = ip->i_mtime; 280 vap->va_mtime.ts_nsec = ip->i_mtimensec; 281 vap->va_ctime.ts_sec = ip->i_ctime; 282 vap->va_ctime.ts_nsec = ip->i_ctimensec; 283 vap->va_flags = ip->i_flags; 284 vap->va_gen = ip->i_gen; 285 /* this doesn't belong here */ 286 if (vp->v_type == VBLK) 287 vap->va_blocksize = BLKDEV_IOSIZE; 288 else if (vp->v_type == VCHR) 289 vap->va_blocksize = MAXBSIZE; 290 else 291 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; 292 vap->va_bytes = dbtob((u_quad_t)ip->i_blocks); 293 vap->va_type = vp->v_type; 294 vap->va_filerev = ip->i_modrev; 295 return (0); 296 } 297 298 /* 299 * Set attribute vnode op. called from several syscalls 300 */ 301 int 302 ufs_setattr(ap) 303 struct vop_setattr_args /* { 304 struct vnode *a_vp; 305 struct vattr *a_vap; 306 struct ucred *a_cred; 307 struct proc *a_p; 308 } */ *ap; 309 { 310 register struct vattr *vap = ap->a_vap; 311 register struct vnode *vp = ap->a_vp; 312 register struct inode *ip = VTOI(vp); 313 register struct ucred *cred = ap->a_cred; 314 register struct proc *p = ap->a_p; 315 struct timeval atimeval, mtimeval; 316 int error; 317 318 /* 319 * Check for unsettable attributes. 320 */ 321 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 322 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 323 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 324 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 325 return (EINVAL); 326 } 327 if (vap->va_flags != VNOVAL) { 328 if (cred->cr_uid != ip->i_uid && 329 (error = suser(cred, &p->p_acflag))) 330 return (error); 331 if (cred->cr_uid == 0) { 332 if ((ip->i_flags & (SF_IMMUTABLE | SF_APPEND)) && 333 securelevel > 0) 334 return (EPERM); 335 ip->i_flags = vap->va_flags; 336 } else { 337 if (ip->i_flags & (SF_IMMUTABLE | SF_APPEND) || 338 (vap->va_flags & UF_SETTABLE) != vap->va_flags) 339 return (EPERM); 340 ip->i_flags &= SF_SETTABLE; 341 ip->i_flags |= (vap->va_flags & UF_SETTABLE); 342 } 343 ip->i_flag |= IN_CHANGE; 344 if (vap->va_flags & (IMMUTABLE | APPEND)) 345 return (0); 346 } 347 if (ip->i_flags & (IMMUTABLE | APPEND)) 348 return (EPERM); 349 /* 350 * Go through the fields and update iff not VNOVAL. 351 */ 352 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) 353 if (error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p)) 354 return (error); 355 if (vap->va_size != VNOVAL) { 356 if (vp->v_type == VDIR) 357 return (EISDIR); 358 if (error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p)) 359 return (error); 360 } 361 ip = VTOI(vp); 362 if (vap->va_atime.ts_sec != VNOVAL || vap->va_mtime.ts_sec != VNOVAL) { 363 if (cred->cr_uid != ip->i_uid && 364 (error = suser(cred, &p->p_acflag)) && 365 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || 366 (error = VOP_ACCESS(vp, VWRITE, cred, p)))) 367 return (error); 368 if (vap->va_atime.ts_sec != VNOVAL) 369 ip->i_flag |= IN_ACCESS; 370 if (vap->va_mtime.ts_sec != VNOVAL) 371 ip->i_flag |= IN_CHANGE | IN_UPDATE; 372 atimeval.tv_sec = vap->va_atime.ts_sec; 373 atimeval.tv_usec = vap->va_atime.ts_nsec / 1000; 374 mtimeval.tv_sec = vap->va_mtime.ts_sec; 375 mtimeval.tv_usec = vap->va_mtime.ts_nsec / 1000; 376 if (error = VOP_UPDATE(vp, &atimeval, &mtimeval, 1)) 377 return (error); 378 } 379 error = 0; 380 if (vap->va_mode != (mode_t)VNOVAL) 381 error = ufs_chmod(vp, (int)vap->va_mode, cred, p); 382 return (error); 383 } 384 385 /* 386 * Change the mode on a file. 387 * Inode must be locked before calling. 388 */ 389 static int 390 ufs_chmod(vp, mode, cred, p) 391 register struct vnode *vp; 392 register int mode; 393 register struct ucred *cred; 394 struct proc *p; 395 { 396 register struct inode *ip = VTOI(vp); 397 int error; 398 399 if (cred->cr_uid != ip->i_uid && 400 (error = suser(cred, &p->p_acflag))) 401 return (error); 402 if (cred->cr_uid) { 403 if (vp->v_type != VDIR && (mode & S_ISTXT)) 404 return (EFTYPE); 405 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) 406 return (EPERM); 407 } 408 ip->i_mode &= ~ALLPERMS; 409 ip->i_mode |= (mode & ALLPERMS); 410 ip->i_flag |= IN_CHANGE; 411 if ((vp->v_flag & VTEXT) && (ip->i_mode & S_ISTXT) == 0) 412 (void) vnode_pager_uncache(vp); 413 return (0); 414 } 415 416 /* 417 * Perform chown operation on inode ip; 418 * inode must be locked prior to call. 419 */ 420 static int 421 ufs_chown(vp, uid, gid, cred, p) 422 register struct vnode *vp; 423 uid_t uid; 424 gid_t gid; 425 struct ucred *cred; 426 struct proc *p; 427 { 428 register struct inode *ip = VTOI(vp); 429 uid_t ouid; 430 gid_t ogid; 431 int error = 0; 432 #ifdef QUOTA 433 register int i; 434 long change; 435 #endif 436 437 if (uid == (uid_t)VNOVAL) 438 uid = ip->i_uid; 439 if (gid == (gid_t)VNOVAL) 440 gid = ip->i_gid; 441 /* 442 * If we don't own the file, are trying to change the owner 443 * of the file, or are not a member of the target group, 444 * the caller must be superuser or the call fails. 445 */ 446 if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid || 447 (gid != ip->i_gid && !groupmember((gid_t)gid, cred))) && 448 (error = suser(cred, &p->p_acflag))) 449 return (error); 450 ogid = ip->i_gid; 451 ouid = ip->i_uid; 452 #ifdef QUOTA 453 if (error = getinoquota(ip)) 454 return (error); 455 if (ouid == uid) { 456 dqrele(vp, ip->i_dquot[USRQUOTA]); 457 ip->i_dquot[USRQUOTA] = NODQUOT; 458 } 459 if (ogid == gid) { 460 dqrele(vp, ip->i_dquot[GRPQUOTA]); 461 ip->i_dquot[GRPQUOTA] = NODQUOT; 462 } 463 change = ip->i_blocks; 464 (void) chkdq(ip, -change, cred, CHOWN); 465 (void) chkiq(ip, -1, cred, CHOWN); 466 for (i = 0; i < MAXQUOTAS; i++) { 467 dqrele(vp, ip->i_dquot[i]); 468 ip->i_dquot[i] = NODQUOT; 469 } 470 #endif 471 ip->i_gid = gid; 472 ip->i_uid = uid; 473 #ifdef QUOTA 474 if ((error = getinoquota(ip)) == 0) { 475 if (ouid == uid) { 476 dqrele(vp, ip->i_dquot[USRQUOTA]); 477 ip->i_dquot[USRQUOTA] = NODQUOT; 478 } 479 if (ogid == gid) { 480 dqrele(vp, ip->i_dquot[GRPQUOTA]); 481 ip->i_dquot[GRPQUOTA] = NODQUOT; 482 } 483 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) { 484 if ((error = chkiq(ip, 1, cred, CHOWN)) == 0) 485 goto good; 486 else 487 (void) chkdq(ip, -change, cred, CHOWN|FORCE); 488 } 489 for (i = 0; i < MAXQUOTAS; i++) { 490 dqrele(vp, ip->i_dquot[i]); 491 ip->i_dquot[i] = NODQUOT; 492 } 493 } 494 ip->i_gid = ogid; 495 ip->i_uid = ouid; 496 if (getinoquota(ip) == 0) { 497 if (ouid == uid) { 498 dqrele(vp, ip->i_dquot[USRQUOTA]); 499 ip->i_dquot[USRQUOTA] = NODQUOT; 500 } 501 if (ogid == gid) { 502 dqrele(vp, ip->i_dquot[GRPQUOTA]); 503 ip->i_dquot[GRPQUOTA] = NODQUOT; 504 } 505 (void) chkdq(ip, change, cred, FORCE|CHOWN); 506 (void) chkiq(ip, 1, cred, FORCE|CHOWN); 507 (void) getinoquota(ip); 508 } 509 return (error); 510 good: 511 if (getinoquota(ip)) 512 panic("chown: lost quota"); 513 #endif /* QUOTA */ 514 if (ouid != uid || ogid != gid) 515 ip->i_flag |= IN_CHANGE; 516 if (ouid != uid && cred->cr_uid != 0) 517 ip->i_mode &= ~ISUID; 518 if (ogid != gid && cred->cr_uid != 0) 519 ip->i_mode &= ~ISGID; 520 return (0); 521 } 522 523 /* ARGSUSED */ 524 int 525 ufs_ioctl(ap) 526 struct vop_ioctl_args /* { 527 struct vnode *a_vp; 528 int a_command; 529 caddr_t a_data; 530 int a_fflag; 531 struct ucred *a_cred; 532 struct proc *a_p; 533 } */ *ap; 534 { 535 536 return (ENOTTY); 537 } 538 539 /* ARGSUSED */ 540 int 541 ufs_select(ap) 542 struct vop_select_args /* { 543 struct vnode *a_vp; 544 int a_which; 545 int a_fflags; 546 struct ucred *a_cred; 547 struct proc *a_p; 548 } */ *ap; 549 { 550 551 /* 552 * We should really check to see if I/O is possible. 553 */ 554 return (1); 555 } 556 557 /* 558 * Mmap a file 559 * 560 * NB Currently unsupported. 561 */ 562 /* ARGSUSED */ 563 int 564 ufs_mmap(ap) 565 struct vop_mmap_args /* { 566 struct vnode *a_vp; 567 int a_fflags; 568 struct ucred *a_cred; 569 struct proc *a_p; 570 } */ *ap; 571 { 572 573 return (EINVAL); 574 } 575 576 /* 577 * Seek on a file 578 * 579 * Nothing to do, so just return. 580 */ 581 /* ARGSUSED */ 582 int 583 ufs_seek(ap) 584 struct vop_seek_args /* { 585 struct vnode *a_vp; 586 off_t a_oldoff; 587 off_t a_newoff; 588 struct ucred *a_cred; 589 } */ *ap; 590 { 591 592 return (0); 593 } 594 595 int 596 ufs_remove(ap) 597 struct vop_remove_args /* { 598 struct vnode *a_dvp; 599 struct vnode *a_vp; 600 struct componentname *a_cnp; 601 } */ *ap; 602 { 603 register struct inode *ip; 604 register struct vnode *vp = ap->a_vp; 605 register struct vnode *dvp = ap->a_dvp; 606 int error; 607 608 ip = VTOI(vp); 609 if ((ip->i_flags & (IMMUTABLE | APPEND)) || 610 (VTOI(dvp)->i_flags & APPEND)) { 611 error = EPERM; 612 goto out; 613 } 614 if ((error = ufs_dirremove(dvp, ap->a_cnp)) == 0) { 615 ip->i_nlink--; 616 ip->i_flag |= IN_CHANGE; 617 } 618 out: 619 if (dvp == vp) 620 vrele(vp); 621 else 622 vput(vp); 623 vput(dvp); 624 return (error); 625 } 626 627 /* 628 * link vnode call 629 */ 630 int 631 ufs_link(ap) 632 struct vop_link_args /* { 633 struct vnode *a_vp; 634 struct vnode *a_tdvp; 635 struct componentname *a_cnp; 636 } */ *ap; 637 { 638 register struct vnode *vp = ap->a_vp; 639 register struct vnode *tdvp = ap->a_tdvp; 640 register struct componentname *cnp = ap->a_cnp; 641 register struct inode *ip; 642 struct timeval tv; 643 int error; 644 645 #ifdef DIAGNOSTIC 646 if ((cnp->cn_flags & HASBUF) == 0) 647 panic("ufs_link: no name"); 648 #endif 649 if (tdvp->v_mount != vp->v_mount) { 650 VOP_ABORTOP(tdvp, cnp); 651 error = EXDEV; 652 goto out2; 653 } 654 if (tdvp != vp && (error = VOP_LOCK(vp))) { 655 VOP_ABORTOP(tdvp, cnp); 656 goto out2; 657 } 658 ip = VTOI(vp); 659 if ((nlink_t)ip->i_nlink >= LINK_MAX) { 660 VOP_ABORTOP(tdvp, cnp); 661 error = EMLINK; 662 goto out1; 663 } 664 if (ip->i_flags & (IMMUTABLE | APPEND)) { 665 VOP_ABORTOP(tdvp, cnp); 666 error = EPERM; 667 goto out1; 668 } 669 ip->i_nlink++; 670 ip->i_flag |= IN_CHANGE; 671 tv = time; 672 error = VOP_UPDATE(vp, &tv, &tv, 1); 673 if (!error) 674 error = ufs_direnter(ip, tdvp, cnp); 675 if (error) { 676 ip->i_nlink--; 677 ip->i_flag |= IN_CHANGE; 678 } 679 FREE(cnp->cn_pnbuf, M_NAMEI); 680 out1: 681 if (tdvp != vp) 682 VOP_UNLOCK(vp); 683 out2: 684 vput(tdvp); 685 return (error); 686 } 687 688 /* 689 * whiteout vnode call 690 */ 691 int 692 ufs_whiteout(ap) 693 struct vop_whiteout_args /* { 694 struct vnode *a_dvp; 695 struct componentname *a_cnp; 696 int a_flags; 697 } */ *ap; 698 { 699 struct vnode *dvp = ap->a_dvp; 700 struct componentname *cnp = ap->a_cnp; 701 struct direct newdir; 702 int error; 703 704 switch (ap->a_flags) { 705 case LOOKUP: 706 /* 4.4 format directories support whiteout operations */ 707 if (dvp->v_mount->mnt_maxsymlinklen > 0) 708 return (0); 709 return (EOPNOTSUPP); 710 711 case CREATE: 712 /* create a new directory whiteout */ 713 #ifdef DIAGNOSTIC 714 if ((cnp->cn_flags & SAVENAME) == 0) 715 panic("ufs_whiteout: missing name"); 716 if (dvp->v_mount->mnt_maxsymlinklen <= 0) 717 panic("ufs_whiteout: old format filesystem"); 718 #endif 719 720 newdir.d_ino = WINO; 721 newdir.d_namlen = cnp->cn_namelen; 722 bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1); 723 newdir.d_type = DT_WHT; 724 error = ufs_direnter2(dvp, &newdir, cnp->cn_cred, cnp->cn_proc); 725 break; 726 727 case DELETE: 728 /* remove an existing directory whiteout */ 729 #ifdef DIAGNOSTIC 730 if (dvp->v_mount->mnt_maxsymlinklen <= 0) 731 panic("ufs_whiteout: old format filesystem"); 732 #endif 733 734 cnp->cn_flags &= ~DOWHITEOUT; 735 error = ufs_dirremove(dvp, cnp); 736 break; 737 } 738 if (cnp->cn_flags & HASBUF) { 739 FREE(cnp->cn_pnbuf, M_NAMEI); 740 cnp->cn_flags &= ~HASBUF; 741 } 742 return (error); 743 } 744 745 746 /* 747 * Rename system call. 748 * rename("foo", "bar"); 749 * is essentially 750 * unlink("bar"); 751 * link("foo", "bar"); 752 * unlink("foo"); 753 * but ``atomically''. Can't do full commit without saving state in the 754 * inode on disk which isn't feasible at this time. Best we can do is 755 * always guarantee the target exists. 756 * 757 * Basic algorithm is: 758 * 759 * 1) Bump link count on source while we're linking it to the 760 * target. This also ensure the inode won't be deleted out 761 * from underneath us while we work (it may be truncated by 762 * a concurrent `trunc' or `open' for creation). 763 * 2) Link source to destination. If destination already exists, 764 * delete it first. 765 * 3) Unlink source reference to inode if still around. If a 766 * directory was moved and the parent of the destination 767 * is different from the source, patch the ".." entry in the 768 * directory. 769 */ 770 int 771 ufs_rename(ap) 772 struct vop_rename_args /* { 773 struct vnode *a_fdvp; 774 struct vnode *a_fvp; 775 struct componentname *a_fcnp; 776 struct vnode *a_tdvp; 777 struct vnode *a_tvp; 778 struct componentname *a_tcnp; 779 } */ *ap; 780 { 781 struct vnode *tvp = ap->a_tvp; 782 register struct vnode *tdvp = ap->a_tdvp; 783 struct vnode *fvp = ap->a_fvp; 784 register struct vnode *fdvp = ap->a_fdvp; 785 register struct componentname *tcnp = ap->a_tcnp; 786 register struct componentname *fcnp = ap->a_fcnp; 787 register struct inode *ip, *xp, *dp; 788 struct dirtemplate dirbuf; 789 struct timeval tv; 790 int doingdirectory = 0, oldparent = 0, newparent = 0; 791 int error = 0; 792 u_char namlen; 793 794 #ifdef DIAGNOSTIC 795 if ((tcnp->cn_flags & HASBUF) == 0 || 796 (fcnp->cn_flags & HASBUF) == 0) 797 panic("ufs_rename: no name"); 798 #endif 799 /* 800 * Check for cross-device rename. 801 */ 802 if ((fvp->v_mount != tdvp->v_mount) || 803 (tvp && (fvp->v_mount != tvp->v_mount))) { 804 error = EXDEV; 805 abortit: 806 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */ 807 if (tdvp == tvp) 808 vrele(tdvp); 809 else 810 vput(tdvp); 811 if (tvp) 812 vput(tvp); 813 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */ 814 vrele(fdvp); 815 vrele(fvp); 816 return (error); 817 } 818 819 /* 820 * Check if just deleting a link name. 821 */ 822 if (tvp && ((VTOI(tvp)->i_flags & (IMMUTABLE | APPEND)) || 823 (VTOI(tdvp)->i_flags & APPEND))) { 824 error = EPERM; 825 goto abortit; 826 } 827 if (fvp == tvp) { 828 if (fvp->v_type == VDIR) { 829 error = EINVAL; 830 goto abortit; 831 } 832 833 /* Release destination completely. */ 834 VOP_ABORTOP(tdvp, tcnp); 835 vput(tdvp); 836 vput(tvp); 837 838 /* Delete source. */ 839 vrele(fdvp); 840 vrele(fvp); 841 fcnp->cn_flags &= ~MODMASK; 842 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; 843 if ((fcnp->cn_flags & SAVESTART) == 0) 844 panic("ufs_rename: lost from startdir"); 845 fcnp->cn_nameiop = DELETE; 846 (void) relookup(fdvp, &fvp, fcnp); 847 return (VOP_REMOVE(fdvp, fvp, fcnp)); 848 } 849 if (error = VOP_LOCK(fvp)) 850 goto abortit; 851 dp = VTOI(fdvp); 852 ip = VTOI(fvp); 853 if ((ip->i_flags & (IMMUTABLE | APPEND)) || (dp->i_flags & APPEND)) { 854 VOP_UNLOCK(fvp); 855 error = EPERM; 856 goto abortit; 857 } 858 if ((ip->i_mode & IFMT) == IFDIR) { 859 /* 860 * Avoid ".", "..", and aliases of "." for obvious reasons. 861 */ 862 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') || 863 dp == ip || (fcnp->cn_flags&ISDOTDOT) || 864 (ip->i_flag & IN_RENAME)) { 865 VOP_UNLOCK(fvp); 866 error = EINVAL; 867 goto abortit; 868 } 869 ip->i_flag |= IN_RENAME; 870 oldparent = dp->i_number; 871 doingdirectory++; 872 } 873 vrele(fdvp); 874 875 /* 876 * When the target exists, both the directory 877 * and target vnodes are returned locked. 878 */ 879 dp = VTOI(tdvp); 880 xp = NULL; 881 if (tvp) 882 xp = VTOI(tvp); 883 884 /* 885 * 1) Bump link count while we're moving stuff 886 * around. If we crash somewhere before 887 * completing our work, the link count 888 * may be wrong, but correctable. 889 */ 890 ip->i_nlink++; 891 ip->i_flag |= IN_CHANGE; 892 tv = time; 893 if (error = VOP_UPDATE(fvp, &tv, &tv, 1)) { 894 VOP_UNLOCK(fvp); 895 goto bad; 896 } 897 898 /* 899 * If ".." must be changed (ie the directory gets a new 900 * parent) then the source directory must not be in the 901 * directory heirarchy above the target, as this would 902 * orphan everything below the source directory. Also 903 * the user must have write permission in the source so 904 * as to be able to change "..". We must repeat the call 905 * to namei, as the parent directory is unlocked by the 906 * call to checkpath(). 907 */ 908 error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc); 909 VOP_UNLOCK(fvp); 910 if (oldparent != dp->i_number) 911 newparent = dp->i_number; 912 if (doingdirectory && newparent) { 913 if (error) /* write access check above */ 914 goto bad; 915 if (xp != NULL) 916 vput(tvp); 917 if (error = ufs_checkpath(ip, dp, tcnp->cn_cred)) 918 goto out; 919 if ((tcnp->cn_flags & SAVESTART) == 0) 920 panic("ufs_rename: lost to startdir"); 921 if (error = relookup(tdvp, &tvp, tcnp)) 922 goto out; 923 dp = VTOI(tdvp); 924 xp = NULL; 925 if (tvp) 926 xp = VTOI(tvp); 927 } 928 /* 929 * 2) If target doesn't exist, link the target 930 * to the source and unlink the source. 931 * Otherwise, rewrite the target directory 932 * entry to reference the source inode and 933 * expunge the original entry's existence. 934 */ 935 if (xp == NULL) { 936 if (dp->i_dev != ip->i_dev) 937 panic("rename: EXDEV"); 938 /* 939 * Account for ".." in new directory. 940 * When source and destination have the same 941 * parent we don't fool with the link count. 942 */ 943 if (doingdirectory && newparent) { 944 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 945 error = EMLINK; 946 goto bad; 947 } 948 dp->i_nlink++; 949 dp->i_flag |= IN_CHANGE; 950 if (error = VOP_UPDATE(tdvp, &tv, &tv, 1)) 951 goto bad; 952 } 953 if (error = ufs_direnter(ip, tdvp, tcnp)) { 954 if (doingdirectory && newparent) { 955 dp->i_nlink--; 956 dp->i_flag |= IN_CHANGE; 957 (void)VOP_UPDATE(tdvp, &tv, &tv, 1); 958 } 959 goto bad; 960 } 961 vput(tdvp); 962 } else { 963 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) 964 panic("rename: EXDEV"); 965 /* 966 * Short circuit rename(foo, foo). 967 */ 968 if (xp->i_number == ip->i_number) 969 panic("rename: same file"); 970 /* 971 * If the parent directory is "sticky", then the user must 972 * own the parent directory, or the destination of the rename, 973 * otherwise the destination may not be changed (except by 974 * root). This implements append-only directories. 975 */ 976 if ((dp->i_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 && 977 tcnp->cn_cred->cr_uid != dp->i_uid && 978 xp->i_uid != tcnp->cn_cred->cr_uid) { 979 error = EPERM; 980 goto bad; 981 } 982 /* 983 * Target must be empty if a directory and have no links 984 * to it. Also, ensure source and target are compatible 985 * (both directories, or both not directories). 986 */ 987 if ((xp->i_mode&IFMT) == IFDIR) { 988 if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) || 989 xp->i_nlink > 2) { 990 error = ENOTEMPTY; 991 goto bad; 992 } 993 if (!doingdirectory) { 994 error = ENOTDIR; 995 goto bad; 996 } 997 cache_purge(tdvp); 998 } else if (doingdirectory) { 999 error = EISDIR; 1000 goto bad; 1001 } 1002 if (error = ufs_dirrewrite(dp, ip, tcnp)) 1003 goto bad; 1004 /* 1005 * If the target directory is in the same 1006 * directory as the source directory, 1007 * decrement the link count on the parent 1008 * of the target directory. 1009 */ 1010 if (doingdirectory && !newparent) { 1011 dp->i_nlink--; 1012 dp->i_flag |= IN_CHANGE; 1013 } 1014 vput(tdvp); 1015 /* 1016 * Adjust the link count of the target to 1017 * reflect the dirrewrite above. If this is 1018 * a directory it is empty and there are 1019 * no links to it, so we can squash the inode and 1020 * any space associated with it. We disallowed 1021 * renaming over top of a directory with links to 1022 * it above, as the remaining link would point to 1023 * a directory without "." or ".." entries. 1024 */ 1025 xp->i_nlink--; 1026 if (doingdirectory) { 1027 if (--xp->i_nlink != 0) 1028 panic("rename: linked directory"); 1029 error = VOP_TRUNCATE(tvp, (off_t)0, IO_SYNC, 1030 tcnp->cn_cred, tcnp->cn_proc); 1031 } 1032 xp->i_flag |= IN_CHANGE; 1033 vput(tvp); 1034 xp = NULL; 1035 } 1036 1037 /* 1038 * 3) Unlink the source. 1039 */ 1040 fcnp->cn_flags &= ~MODMASK; 1041 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; 1042 if ((fcnp->cn_flags & SAVESTART) == 0) 1043 panic("ufs_rename: lost from startdir"); 1044 (void) relookup(fdvp, &fvp, fcnp); 1045 if (fvp != NULL) { 1046 xp = VTOI(fvp); 1047 dp = VTOI(fdvp); 1048 } else { 1049 /* 1050 * From name has disappeared. 1051 */ 1052 if (doingdirectory) 1053 panic("rename: lost dir entry"); 1054 vrele(ap->a_fvp); 1055 return (0); 1056 } 1057 /* 1058 * Ensure that the directory entry still exists and has not 1059 * changed while the new name has been entered. If the source is 1060 * a file then the entry may have been unlinked or renamed. In 1061 * either case there is no further work to be done. If the source 1062 * is a directory then it cannot have been rmdir'ed; its link 1063 * count of three would cause a rmdir to fail with ENOTEMPTY. 1064 * The IRENAME flag ensures that it cannot be moved by another 1065 * rename. 1066 */ 1067 if (xp != ip) { 1068 if (doingdirectory) 1069 panic("rename: lost dir entry"); 1070 } else { 1071 /* 1072 * If the source is a directory with a 1073 * new parent, the link count of the old 1074 * parent directory must be decremented 1075 * and ".." set to point to the new parent. 1076 */ 1077 if (doingdirectory && newparent) { 1078 dp->i_nlink--; 1079 dp->i_flag |= IN_CHANGE; 1080 error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf, 1081 sizeof (struct dirtemplate), (off_t)0, 1082 UIO_SYSSPACE, IO_NODELOCKED, 1083 tcnp->cn_cred, (int *)0, (struct proc *)0); 1084 if (error == 0) { 1085 # if (BYTE_ORDER == LITTLE_ENDIAN) 1086 if (fvp->v_mount->mnt_maxsymlinklen <= 0) 1087 namlen = dirbuf.dotdot_type; 1088 else 1089 namlen = dirbuf.dotdot_namlen; 1090 # else 1091 namlen = dirbuf.dotdot_namlen; 1092 # endif 1093 if (namlen != 2 || 1094 dirbuf.dotdot_name[0] != '.' || 1095 dirbuf.dotdot_name[1] != '.') { 1096 ufs_dirbad(xp, (doff_t)12, 1097 "rename: mangled dir"); 1098 } else { 1099 dirbuf.dotdot_ino = newparent; 1100 (void) vn_rdwr(UIO_WRITE, fvp, 1101 (caddr_t)&dirbuf, 1102 sizeof (struct dirtemplate), 1103 (off_t)0, UIO_SYSSPACE, 1104 IO_NODELOCKED|IO_SYNC, 1105 tcnp->cn_cred, (int *)0, 1106 (struct proc *)0); 1107 cache_purge(fdvp); 1108 } 1109 } 1110 } 1111 error = ufs_dirremove(fdvp, fcnp); 1112 if (!error) { 1113 xp->i_nlink--; 1114 xp->i_flag |= IN_CHANGE; 1115 } 1116 xp->i_flag &= ~IN_RENAME; 1117 } 1118 if (dp) 1119 vput(fdvp); 1120 if (xp) 1121 vput(fvp); 1122 vrele(ap->a_fvp); 1123 return (error); 1124 1125 bad: 1126 if (xp) 1127 vput(ITOV(xp)); 1128 vput(ITOV(dp)); 1129 out: 1130 if (doingdirectory) 1131 ip->i_flag &= ~IN_RENAME; 1132 if (VOP_LOCK(fvp) == 0) { 1133 ip->i_nlink--; 1134 ip->i_flag |= IN_CHANGE; 1135 vput(fvp); 1136 } else 1137 vrele(fvp); 1138 return (error); 1139 } 1140 1141 /* 1142 * A virgin directory (no blushing please). 1143 */ 1144 static struct dirtemplate mastertemplate = { 1145 0, 12, DT_DIR, 1, ".", 1146 0, DIRBLKSIZ - 12, DT_DIR, 2, ".." 1147 }; 1148 static struct odirtemplate omastertemplate = { 1149 0, 12, 1, ".", 1150 0, DIRBLKSIZ - 12, 2, ".." 1151 }; 1152 1153 /* 1154 * Mkdir system call 1155 */ 1156 int 1157 ufs_mkdir(ap) 1158 struct vop_mkdir_args /* { 1159 struct vnode *a_dvp; 1160 struct vnode **a_vpp; 1161 struct componentname *a_cnp; 1162 struct vattr *a_vap; 1163 } */ *ap; 1164 { 1165 register struct vnode *dvp = ap->a_dvp; 1166 register struct vattr *vap = ap->a_vap; 1167 register struct componentname *cnp = ap->a_cnp; 1168 register struct inode *ip, *dp; 1169 struct vnode *tvp; 1170 struct dirtemplate dirtemplate, *dtp; 1171 struct timeval tv; 1172 int error, dmode; 1173 1174 #ifdef DIAGNOSTIC 1175 if ((cnp->cn_flags & HASBUF) == 0) 1176 panic("ufs_mkdir: no name"); 1177 #endif 1178 dp = VTOI(dvp); 1179 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 1180 error = EMLINK; 1181 goto out; 1182 } 1183 dmode = vap->va_mode & 0777; 1184 dmode |= IFDIR; 1185 /* 1186 * Must simulate part of ufs_makeinode here to acquire the inode, 1187 * but not have it entered in the parent directory. The entry is 1188 * made later after writing "." and ".." entries. 1189 */ 1190 if (error = VOP_VALLOC(dvp, dmode, cnp->cn_cred, &tvp)) 1191 goto out; 1192 ip = VTOI(tvp); 1193 ip->i_uid = cnp->cn_cred->cr_uid; 1194 ip->i_gid = dp->i_gid; 1195 #ifdef QUOTA 1196 if ((error = getinoquota(ip)) || 1197 (error = chkiq(ip, 1, cnp->cn_cred, 0))) { 1198 free(cnp->cn_pnbuf, M_NAMEI); 1199 VOP_VFREE(tvp, ip->i_number, dmode); 1200 vput(tvp); 1201 vput(dvp); 1202 return (error); 1203 } 1204 #endif 1205 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 1206 ip->i_mode = dmode; 1207 tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ 1208 ip->i_nlink = 2; 1209 if (cnp->cn_flags & ISWHITEOUT) 1210 ip->i_flags |= UF_OPAQUE; 1211 tv = time; 1212 error = VOP_UPDATE(tvp, &tv, &tv, 1); 1213 1214 /* 1215 * Bump link count in parent directory 1216 * to reflect work done below. Should 1217 * be done before reference is created 1218 * so reparation is possible if we crash. 1219 */ 1220 dp->i_nlink++; 1221 dp->i_flag |= IN_CHANGE; 1222 if (error = VOP_UPDATE(dvp, &tv, &tv, 1)) 1223 goto bad; 1224 1225 /* Initialize directory with "." and ".." from static template. */ 1226 if (dvp->v_mount->mnt_maxsymlinklen > 0) 1227 dtp = &mastertemplate; 1228 else 1229 dtp = (struct dirtemplate *)&omastertemplate; 1230 dirtemplate = *dtp; 1231 dirtemplate.dot_ino = ip->i_number; 1232 dirtemplate.dotdot_ino = dp->i_number; 1233 error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate, 1234 sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, 1235 IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0); 1236 if (error) { 1237 dp->i_nlink--; 1238 dp->i_flag |= IN_CHANGE; 1239 goto bad; 1240 } 1241 if (DIRBLKSIZ > VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize) 1242 panic("ufs_mkdir: blksize"); /* XXX should grow with balloc() */ 1243 else { 1244 ip->i_size = DIRBLKSIZ; 1245 ip->i_flag |= IN_CHANGE; 1246 } 1247 1248 /* Directory set up, now install it's entry in the parent directory. */ 1249 if (error = ufs_direnter(ip, dvp, cnp)) { 1250 dp->i_nlink--; 1251 dp->i_flag |= IN_CHANGE; 1252 } 1253 bad: 1254 /* 1255 * No need to do an explicit VOP_TRUNCATE here, vrele will do this 1256 * for us because we set the link count to 0. 1257 */ 1258 if (error) { 1259 ip->i_nlink = 0; 1260 ip->i_flag |= IN_CHANGE; 1261 vput(tvp); 1262 } else 1263 *ap->a_vpp = tvp; 1264 out: 1265 FREE(cnp->cn_pnbuf, M_NAMEI); 1266 vput(dvp); 1267 return (error); 1268 } 1269 1270 /* 1271 * Rmdir system call. 1272 */ 1273 int 1274 ufs_rmdir(ap) 1275 struct vop_rmdir_args /* { 1276 struct vnode *a_dvp; 1277 struct vnode *a_vp; 1278 struct componentname *a_cnp; 1279 } */ *ap; 1280 { 1281 register struct vnode *vp = ap->a_vp; 1282 register struct vnode *dvp = ap->a_dvp; 1283 register struct componentname *cnp = ap->a_cnp; 1284 register struct inode *ip, *dp; 1285 int error; 1286 1287 ip = VTOI(vp); 1288 dp = VTOI(dvp); 1289 /* 1290 * No rmdir "." please. 1291 */ 1292 if (dp == ip) { 1293 vrele(dvp); 1294 vput(vp); 1295 return (EINVAL); 1296 } 1297 /* 1298 * Verify the directory is empty (and valid). 1299 * (Rmdir ".." won't be valid since 1300 * ".." will contain a reference to 1301 * the current directory and thus be 1302 * non-empty.) 1303 */ 1304 error = 0; 1305 if (ip->i_nlink != 2 || 1306 !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) { 1307 error = ENOTEMPTY; 1308 goto out; 1309 } 1310 if ((dp->i_flags & APPEND) || (ip->i_flags & (IMMUTABLE | APPEND))) { 1311 error = EPERM; 1312 goto out; 1313 } 1314 /* 1315 * Delete reference to directory before purging 1316 * inode. If we crash in between, the directory 1317 * will be reattached to lost+found, 1318 */ 1319 if (error = ufs_dirremove(dvp, cnp)) 1320 goto out; 1321 dp->i_nlink--; 1322 dp->i_flag |= IN_CHANGE; 1323 cache_purge(dvp); 1324 vput(dvp); 1325 dvp = NULL; 1326 /* 1327 * Truncate inode. The only stuff left 1328 * in the directory is "." and "..". The 1329 * "." reference is inconsequential since 1330 * we're quashing it. The ".." reference 1331 * has already been adjusted above. We've 1332 * removed the "." reference and the reference 1333 * in the parent directory, but there may be 1334 * other hard links so decrement by 2 and 1335 * worry about them later. 1336 */ 1337 ip->i_nlink -= 2; 1338 error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred, 1339 cnp->cn_proc); 1340 cache_purge(ITOV(ip)); 1341 out: 1342 if (dvp) 1343 vput(dvp); 1344 vput(vp); 1345 return (error); 1346 } 1347 1348 /* 1349 * symlink -- make a symbolic link 1350 */ 1351 int 1352 ufs_symlink(ap) 1353 struct vop_symlink_args /* { 1354 struct vnode *a_dvp; 1355 struct vnode **a_vpp; 1356 struct componentname *a_cnp; 1357 struct vattr *a_vap; 1358 char *a_target; 1359 } */ *ap; 1360 { 1361 register struct vnode *vp, **vpp = ap->a_vpp; 1362 register struct inode *ip; 1363 int len, error; 1364 1365 if (error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, 1366 vpp, ap->a_cnp)) 1367 return (error); 1368 vp = *vpp; 1369 len = strlen(ap->a_target); 1370 if (len < vp->v_mount->mnt_maxsymlinklen) { 1371 ip = VTOI(vp); 1372 bcopy(ap->a_target, (char *)ip->i_shortlink, len); 1373 ip->i_size = len; 1374 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1375 } else 1376 error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, 1377 UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0, 1378 (struct proc *)0); 1379 vput(vp); 1380 return (error); 1381 } 1382 1383 /* 1384 * Vnode op for reading directories. 1385 * 1386 * The routine below assumes that the on-disk format of a directory 1387 * is the same as that defined by <sys/dirent.h>. If the on-disk 1388 * format changes, then it will be necessary to do a conversion 1389 * from the on-disk format that read returns to the format defined 1390 * by <sys/dirent.h>. 1391 */ 1392 int 1393 ufs_readdir(ap) 1394 struct vop_readdir_args /* { 1395 struct vnode *a_vp; 1396 struct uio *a_uio; 1397 struct ucred *a_cred; 1398 int *a_eofflag; 1399 int *ncookies; 1400 u_long **a_cookies; 1401 } */ *ap; 1402 { 1403 register struct uio *uio = ap->a_uio; 1404 int error; 1405 size_t count, lost; 1406 off_t off = uio->uio_offset; 1407 1408 count = uio->uio_resid; 1409 /* Make sure we don't return partial entries. */ 1410 count -= (uio->uio_offset + count) & (DIRBLKSIZ -1); 1411 if (count <= 0) 1412 return (EINVAL); 1413 lost = uio->uio_resid - count; 1414 uio->uio_resid = count; 1415 uio->uio_iov->iov_len = count; 1416 # if (BYTE_ORDER == LITTLE_ENDIAN) 1417 if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) { 1418 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred); 1419 } else { 1420 struct dirent *dp, *edp; 1421 struct uio auio; 1422 struct iovec aiov; 1423 caddr_t dirbuf; 1424 int readcnt; 1425 u_char tmp; 1426 1427 auio = *uio; 1428 auio.uio_iov = &aiov; 1429 auio.uio_iovcnt = 1; 1430 auio.uio_segflg = UIO_SYSSPACE; 1431 aiov.iov_len = count; 1432 MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK); 1433 aiov.iov_base = dirbuf; 1434 error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred); 1435 if (error == 0) { 1436 readcnt = count - auio.uio_resid; 1437 edp = (struct dirent *)&dirbuf[readcnt]; 1438 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 1439 tmp = dp->d_namlen; 1440 dp->d_namlen = dp->d_type; 1441 dp->d_type = tmp; 1442 if (dp->d_reclen > 0) { 1443 dp = (struct dirent *) 1444 ((char *)dp + dp->d_reclen); 1445 } else { 1446 error = EIO; 1447 break; 1448 } 1449 } 1450 if (dp >= edp) 1451 error = uiomove(dirbuf, readcnt, uio); 1452 } 1453 FREE(dirbuf, M_TEMP); 1454 } 1455 # else 1456 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred); 1457 # endif 1458 if (!error && ap->a_ncookies) { 1459 struct dirent *dp, *dpstart; 1460 off_t offstart; 1461 u_long *cookies; 1462 int ncookies; 1463 1464 /* 1465 * Only the NFS server uses cookies, and it loads the 1466 * directory block into system space, so we can just look at 1467 * it directly. 1468 */ 1469 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) 1470 panic("ufs_readdir: lost in space"); 1471 dpstart = (struct dirent *) 1472 (uio->uio_iov->iov_base - (uio->uio_offset - off)); 1473 offstart = off; 1474 for (dp = dpstart, ncookies = 0; off < uio->uio_offset; ) { 1475 if (dp->d_reclen == 0) 1476 break; 1477 off += dp->d_reclen; 1478 ncookies++; 1479 dp = (struct dirent *)((caddr_t)dp + dp->d_reclen); 1480 } 1481 lost += uio->uio_offset - off; 1482 uio->uio_offset = off; 1483 MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP, 1484 M_WAITOK); 1485 *ap->a_ncookies = ncookies; 1486 *ap->a_cookies = cookies; 1487 for (off = offstart, dp = dpstart; off < uio->uio_offset; ) { 1488 *(cookies++) = off; 1489 off += dp->d_reclen; 1490 dp = (struct dirent *)((caddr_t)dp + dp->d_reclen); 1491 } 1492 } 1493 uio->uio_resid += lost; 1494 *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset; 1495 return (error); 1496 } 1497 1498 /* 1499 * Return target name of a symbolic link 1500 */ 1501 int 1502 ufs_readlink(ap) 1503 struct vop_readlink_args /* { 1504 struct vnode *a_vp; 1505 struct uio *a_uio; 1506 struct ucred *a_cred; 1507 } */ *ap; 1508 { 1509 register struct vnode *vp = ap->a_vp; 1510 register struct inode *ip = VTOI(vp); 1511 int isize; 1512 1513 isize = ip->i_size; 1514 if (isize < vp->v_mount->mnt_maxsymlinklen) { 1515 uiomove((char *)ip->i_shortlink, isize, ap->a_uio); 1516 return (0); 1517 } 1518 return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); 1519 } 1520 1521 /* 1522 * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 1523 * done. If a buffer has been saved in anticipation of a CREATE, delete it. 1524 */ 1525 /* ARGSUSED */ 1526 int 1527 ufs_abortop(ap) 1528 struct vop_abortop_args /* { 1529 struct vnode *a_dvp; 1530 struct componentname *a_cnp; 1531 } */ *ap; 1532 { 1533 if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 1534 FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 1535 return (0); 1536 } 1537 1538 /* 1539 * Lock an inode. If its already locked, set the WANT bit and sleep. 1540 */ 1541 int 1542 ufs_lock(ap) 1543 struct vop_lock_args /* { 1544 struct vnode *a_vp; 1545 } */ *ap; 1546 { 1547 register struct vnode *vp = ap->a_vp; 1548 register struct inode *ip; 1549 struct proc *p = curproc; /* XXX */ 1550 1551 start: 1552 while (vp->v_flag & VXLOCK) { 1553 vp->v_flag |= VXWANT; 1554 sleep((caddr_t)vp, PINOD); 1555 } 1556 if (vp->v_tag == VT_NON) 1557 return (ENOENT); 1558 ip = VTOI(vp); 1559 if (ip->i_flag & IN_LOCKED) { 1560 ip->i_flag |= IN_WANTED; 1561 #ifdef DIAGNOSTIC 1562 if (p) { 1563 if (p->p_pid == ip->i_lockholder) 1564 panic("locking against myself"); 1565 ip->i_lockwaiter = p->p_pid; 1566 } else 1567 ip->i_lockwaiter = -1; 1568 #endif 1569 (void) sleep((caddr_t)ip, PINOD); 1570 goto start; 1571 } 1572 #ifdef DIAGNOSTIC 1573 ip->i_lockwaiter = 0; 1574 if (ip->i_lockholder != 0) 1575 panic("lockholder (%d) != 0", ip->i_lockholder); 1576 if (p && p->p_pid == 0) 1577 printf("locking by process 0\n"); 1578 if (p) 1579 ip->i_lockholder = p->p_pid; 1580 else 1581 ip->i_lockholder = -1; 1582 #endif 1583 ip->i_flag |= IN_LOCKED; 1584 return (0); 1585 } 1586 1587 /* 1588 * Unlock an inode. If WANT bit is on, wakeup. 1589 */ 1590 int lockcount = 90; 1591 int 1592 ufs_unlock(ap) 1593 struct vop_unlock_args /* { 1594 struct vnode *a_vp; 1595 } */ *ap; 1596 { 1597 register struct inode *ip = VTOI(ap->a_vp); 1598 struct proc *p = curproc; /* XXX */ 1599 1600 #ifdef DIAGNOSTIC 1601 if ((ip->i_flag & IN_LOCKED) == 0) { 1602 vprint("ufs_unlock: unlocked inode", ap->a_vp); 1603 panic("ufs_unlock NOT LOCKED"); 1604 } 1605 if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 && 1606 ip->i_lockholder > -1 && lockcount++ < 100) 1607 panic("unlocker (%d) != lock holder (%d)", 1608 p->p_pid, ip->i_lockholder); 1609 ip->i_lockholder = 0; 1610 #endif 1611 ip->i_flag &= ~IN_LOCKED; 1612 if (ip->i_flag & IN_WANTED) { 1613 ip->i_flag &= ~IN_WANTED; 1614 wakeup((caddr_t)ip); 1615 } 1616 return (0); 1617 } 1618 1619 /* 1620 * Check for a locked inode. 1621 */ 1622 int 1623 ufs_islocked(ap) 1624 struct vop_islocked_args /* { 1625 struct vnode *a_vp; 1626 } */ *ap; 1627 { 1628 1629 if (VTOI(ap->a_vp)->i_flag & IN_LOCKED) 1630 return (1); 1631 return (0); 1632 } 1633 1634 /* 1635 * Calculate the logical to physical mapping if not done already, 1636 * then call the device strategy routine. 1637 */ 1638 int 1639 ufs_strategy(ap) 1640 struct vop_strategy_args /* { 1641 struct buf *a_bp; 1642 } */ *ap; 1643 { 1644 register struct buf *bp = ap->a_bp; 1645 register struct vnode *vp = bp->b_vp; 1646 register struct inode *ip; 1647 int error; 1648 1649 ip = VTOI(vp); 1650 if (vp->v_type == VBLK || vp->v_type == VCHR) 1651 panic("ufs_strategy: spec"); 1652 if (bp->b_blkno == bp->b_lblkno) { 1653 if (error = 1654 VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) { 1655 bp->b_error = error; 1656 bp->b_flags |= B_ERROR; 1657 biodone(bp); 1658 return (error); 1659 } 1660 if ((long)bp->b_blkno == -1) 1661 clrbuf(bp); 1662 } 1663 if ((long)bp->b_blkno == -1) { 1664 biodone(bp); 1665 return (0); 1666 } 1667 vp = ip->i_devvp; 1668 bp->b_dev = vp->v_rdev; 1669 VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 1670 return (0); 1671 } 1672 1673 /* 1674 * Print out the contents of an inode. 1675 */ 1676 int 1677 ufs_print(ap) 1678 struct vop_print_args /* { 1679 struct vnode *a_vp; 1680 } */ *ap; 1681 { 1682 register struct vnode *vp = ap->a_vp; 1683 register struct inode *ip = VTOI(vp); 1684 1685 printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number, 1686 major(ip->i_dev), minor(ip->i_dev)); 1687 #ifdef FIFO 1688 if (vp->v_type == VFIFO) 1689 fifo_printinfo(vp); 1690 #endif /* FIFO */ 1691 printf("%s\n", (ip->i_flag & IN_LOCKED) ? " (LOCKED)" : ""); 1692 if (ip->i_lockholder == 0) 1693 return (0); 1694 printf("\towner pid %d", ip->i_lockholder); 1695 if (ip->i_lockwaiter) 1696 printf(" waiting pid %d", ip->i_lockwaiter); 1697 printf("\n"); 1698 return (0); 1699 } 1700 1701 /* 1702 * Read wrapper for special devices. 1703 */ 1704 int 1705 ufsspec_read(ap) 1706 struct vop_read_args /* { 1707 struct vnode *a_vp; 1708 struct uio *a_uio; 1709 int a_ioflag; 1710 struct ucred *a_cred; 1711 } */ *ap; 1712 { 1713 1714 /* 1715 * Set access flag. 1716 */ 1717 VTOI(ap->a_vp)->i_flag |= IN_ACCESS; 1718 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_read), ap)); 1719 } 1720 1721 /* 1722 * Write wrapper for special devices. 1723 */ 1724 int 1725 ufsspec_write(ap) 1726 struct vop_write_args /* { 1727 struct vnode *a_vp; 1728 struct uio *a_uio; 1729 int a_ioflag; 1730 struct ucred *a_cred; 1731 } */ *ap; 1732 { 1733 1734 /* 1735 * Set update and change flags. 1736 */ 1737 VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE; 1738 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_write), ap)); 1739 } 1740 1741 /* 1742 * Close wrapper for special devices. 1743 * 1744 * Update the times on the inode then do device close. 1745 */ 1746 int 1747 ufsspec_close(ap) 1748 struct vop_close_args /* { 1749 struct vnode *a_vp; 1750 int a_fflag; 1751 struct ucred *a_cred; 1752 struct proc *a_p; 1753 } */ *ap; 1754 { 1755 register struct inode *ip = VTOI(ap->a_vp); 1756 1757 if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED)) 1758 ITIMES(ip, &time, &time); 1759 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap)); 1760 } 1761 1762 #ifdef FIFO 1763 /* 1764 * Read wrapper for fifo's 1765 */ 1766 int 1767 ufsfifo_read(ap) 1768 struct vop_read_args /* { 1769 struct vnode *a_vp; 1770 struct uio *a_uio; 1771 int a_ioflag; 1772 struct ucred *a_cred; 1773 } */ *ap; 1774 { 1775 extern int (**fifo_vnodeop_p)(); 1776 1777 /* 1778 * Set access flag. 1779 */ 1780 VTOI(ap->a_vp)->i_flag |= IN_ACCESS; 1781 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_read), ap)); 1782 } 1783 1784 /* 1785 * Write wrapper for fifo's. 1786 */ 1787 int 1788 ufsfifo_write(ap) 1789 struct vop_write_args /* { 1790 struct vnode *a_vp; 1791 struct uio *a_uio; 1792 int a_ioflag; 1793 struct ucred *a_cred; 1794 } */ *ap; 1795 { 1796 extern int (**fifo_vnodeop_p)(); 1797 1798 /* 1799 * Set update and change flags. 1800 */ 1801 VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE; 1802 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_write), ap)); 1803 } 1804 1805 /* 1806 * Close wrapper for fifo's. 1807 * 1808 * Update the times on the inode then do device close. 1809 */ 1810 ufsfifo_close(ap) 1811 struct vop_close_args /* { 1812 struct vnode *a_vp; 1813 int a_fflag; 1814 struct ucred *a_cred; 1815 struct proc *a_p; 1816 } */ *ap; 1817 { 1818 extern int (**fifo_vnodeop_p)(); 1819 register struct inode *ip = VTOI(ap->a_vp); 1820 1821 if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED)) 1822 ITIMES(ip, &time, &time); 1823 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap)); 1824 } 1825 #endif /* FIFO */ 1826 1827 /* 1828 * Return POSIX pathconf information applicable to ufs filesystems. 1829 */ 1830 ufs_pathconf(ap) 1831 struct vop_pathconf_args /* { 1832 struct vnode *a_vp; 1833 int a_name; 1834 int *a_retval; 1835 } */ *ap; 1836 { 1837 1838 switch (ap->a_name) { 1839 case _PC_LINK_MAX: 1840 *ap->a_retval = LINK_MAX; 1841 return (0); 1842 case _PC_NAME_MAX: 1843 *ap->a_retval = NAME_MAX; 1844 return (0); 1845 case _PC_PATH_MAX: 1846 *ap->a_retval = PATH_MAX; 1847 return (0); 1848 case _PC_PIPE_BUF: 1849 *ap->a_retval = PIPE_BUF; 1850 return (0); 1851 case _PC_CHOWN_RESTRICTED: 1852 *ap->a_retval = 1; 1853 return (0); 1854 case _PC_NO_TRUNC: 1855 *ap->a_retval = 1; 1856 return (0); 1857 default: 1858 return (EINVAL); 1859 } 1860 /* NOTREACHED */ 1861 } 1862 1863 /* 1864 * Advisory record locking support 1865 */ 1866 int 1867 ufs_advlock(ap) 1868 struct vop_advlock_args /* { 1869 struct vnode *a_vp; 1870 caddr_t a_id; 1871 int a_op; 1872 struct flock *a_fl; 1873 int a_flags; 1874 } */ *ap; 1875 { 1876 register struct inode *ip = VTOI(ap->a_vp); 1877 register struct flock *fl = ap->a_fl; 1878 register struct lockf *lock; 1879 off_t start, end; 1880 int error; 1881 1882 /* 1883 * Avoid the common case of unlocking when inode has no locks. 1884 */ 1885 if (ip->i_lockf == (struct lockf *)0) { 1886 if (ap->a_op != F_SETLK) { 1887 fl->l_type = F_UNLCK; 1888 return (0); 1889 } 1890 } 1891 /* 1892 * Convert the flock structure into a start and end. 1893 */ 1894 switch (fl->l_whence) { 1895 1896 case SEEK_SET: 1897 case SEEK_CUR: 1898 /* 1899 * Caller is responsible for adding any necessary offset 1900 * when SEEK_CUR is used. 1901 */ 1902 start = fl->l_start; 1903 break; 1904 1905 case SEEK_END: 1906 start = ip->i_size + fl->l_start; 1907 break; 1908 1909 default: 1910 return (EINVAL); 1911 } 1912 if (start < 0) 1913 return (EINVAL); 1914 if (fl->l_len == 0) 1915 end = -1; 1916 else 1917 end = start + fl->l_len - 1; 1918 /* 1919 * Create the lockf structure 1920 */ 1921 MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK); 1922 lock->lf_start = start; 1923 lock->lf_end = end; 1924 lock->lf_id = ap->a_id; 1925 lock->lf_inode = ip; 1926 lock->lf_type = fl->l_type; 1927 lock->lf_next = (struct lockf *)0; 1928 TAILQ_INIT(&lock->lf_blkhd); 1929 lock->lf_flags = ap->a_flags; 1930 /* 1931 * Do the requested operation. 1932 */ 1933 switch(ap->a_op) { 1934 case F_SETLK: 1935 return (lf_setlock(lock)); 1936 1937 case F_UNLCK: 1938 error = lf_clearlock(lock); 1939 FREE(lock, M_LOCKF); 1940 return (error); 1941 1942 case F_GETLK: 1943 error = lf_getlock(lock, fl); 1944 FREE(lock, M_LOCKF); 1945 return (error); 1946 1947 default: 1948 free(lock, M_LOCKF); 1949 return (EINVAL); 1950 } 1951 /* NOTREACHED */ 1952 } 1953 1954 /* 1955 * Initialize the vnode associated with a new inode, handle aliased 1956 * vnodes. 1957 */ 1958 int 1959 ufs_vinit(mntp, specops, fifoops, vpp) 1960 struct mount *mntp; 1961 int (**specops)(); 1962 int (**fifoops)(); 1963 struct vnode **vpp; 1964 { 1965 struct inode *ip; 1966 struct vnode *vp, *nvp; 1967 1968 vp = *vpp; 1969 ip = VTOI(vp); 1970 switch(vp->v_type = IFTOVT(ip->i_mode)) { 1971 case VCHR: 1972 case VBLK: 1973 vp->v_op = specops; 1974 if (nvp = checkalias(vp, ip->i_rdev, mntp)) { 1975 /* 1976 * Discard unneeded vnode, but save its inode. 1977 */ 1978 ufs_ihashrem(ip); 1979 VOP_UNLOCK(vp); 1980 nvp->v_data = vp->v_data; 1981 vp->v_data = NULL; 1982 vp->v_op = spec_vnodeop_p; 1983 vrele(vp); 1984 vgone(vp); 1985 /* 1986 * Reinitialize aliased inode. 1987 */ 1988 vp = nvp; 1989 ip->i_vnode = vp; 1990 ufs_ihashins(ip); 1991 } 1992 break; 1993 case VFIFO: 1994 #ifdef FIFO 1995 vp->v_op = fifoops; 1996 break; 1997 #else 1998 return (EOPNOTSUPP); 1999 #endif 2000 } 2001 if (ip->i_number == ROOTINO) 2002 vp->v_flag |= VROOT; 2003 /* 2004 * Initialize modrev times 2005 */ 2006 SETHIGH(ip->i_modrev, mono_time.tv_sec); 2007 SETLOW(ip->i_modrev, mono_time.tv_usec * 4294); 2008 *vpp = vp; 2009 return (0); 2010 } 2011 2012 /* 2013 * Allocate a new inode. 2014 */ 2015 int 2016 ufs_makeinode(mode, dvp, vpp, cnp) 2017 int mode; 2018 struct vnode *dvp; 2019 struct vnode **vpp; 2020 struct componentname *cnp; 2021 { 2022 register struct inode *ip, *pdir; 2023 struct timeval tv; 2024 struct vnode *tvp; 2025 int error; 2026 2027 pdir = VTOI(dvp); 2028 #ifdef DIAGNOSTIC 2029 if ((cnp->cn_flags & HASBUF) == 0) 2030 panic("ufs_makeinode: no name"); 2031 #endif 2032 *vpp = NULL; 2033 if ((mode & IFMT) == 0) 2034 mode |= IFREG; 2035 2036 if (error = VOP_VALLOC(dvp, mode, cnp->cn_cred, &tvp)) { 2037 free(cnp->cn_pnbuf, M_NAMEI); 2038 vput(dvp); 2039 return (error); 2040 } 2041 ip = VTOI(tvp); 2042 ip->i_gid = pdir->i_gid; 2043 if ((mode & IFMT) == IFLNK) 2044 ip->i_uid = pdir->i_uid; 2045 else 2046 ip->i_uid = cnp->cn_cred->cr_uid; 2047 #ifdef QUOTA 2048 if ((error = getinoquota(ip)) || 2049 (error = chkiq(ip, 1, cnp->cn_cred, 0))) { 2050 free(cnp->cn_pnbuf, M_NAMEI); 2051 VOP_VFREE(tvp, ip->i_number, mode); 2052 vput(tvp); 2053 vput(dvp); 2054 return (error); 2055 } 2056 #endif 2057 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 2058 ip->i_mode = mode; 2059 tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ 2060 ip->i_nlink = 1; 2061 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && 2062 suser(cnp->cn_cred, NULL)) 2063 ip->i_mode &= ~ISGID; 2064 2065 if (cnp->cn_flags & ISWHITEOUT) 2066 ip->i_flags |= UF_OPAQUE; 2067 2068 /* 2069 * Make sure inode goes to disk before directory entry. 2070 */ 2071 tv = time; 2072 if (error = VOP_UPDATE(tvp, &tv, &tv, 1)) 2073 goto bad; 2074 if (error = ufs_direnter(ip, dvp, cnp)) 2075 goto bad; 2076 if ((cnp->cn_flags & SAVESTART) == 0) 2077 FREE(cnp->cn_pnbuf, M_NAMEI); 2078 vput(dvp); 2079 *vpp = tvp; 2080 return (0); 2081 2082 bad: 2083 /* 2084 * Write error occurred trying to update the inode 2085 * or the directory so must deallocate the inode. 2086 */ 2087 free(cnp->cn_pnbuf, M_NAMEI); 2088 vput(dvp); 2089 ip->i_nlink = 0; 2090 ip->i_flag |= IN_CHANGE; 2091 vput(tvp); 2092 return (error); 2093 } 2094