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