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