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