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