1 /* $NetBSD: ufs_vnops.c,v 1.262 2022/03/27 16:24:59 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1982, 1986, 1989, 1993, 1995 34 * The Regents of the University of California. All rights reserved. 35 * (c) UNIX System Laboratories, Inc. 36 * All or some portions of this file are derived from material licensed 37 * to the University of California by American Telephone and Telegraph 38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 39 * the permission of UNIX System Laboratories, Inc. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)ufs_vnops.c 8.28 (Berkeley) 7/31/95 66 */ 67 68 #include <sys/cdefs.h> 69 __KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.262 2022/03/27 16:24:59 christos Exp $"); 70 71 #if defined(_KERNEL_OPT) 72 #include "opt_ffs.h" 73 #include "opt_quota.h" 74 #include "opt_uvmhist.h" 75 #endif 76 77 #include <sys/param.h> 78 #include <sys/systm.h> 79 #include <sys/namei.h> 80 #include <sys/resourcevar.h> 81 #include <sys/kernel.h> 82 #include <sys/file.h> 83 #include <sys/stat.h> 84 #include <sys/buf.h> 85 #include <sys/proc.h> 86 #include <sys/mount.h> 87 #include <sys/vnode.h> 88 #include <sys/fstrans.h> 89 #include <sys/kmem.h> 90 #include <sys/malloc.h> 91 #include <sys/dirent.h> 92 #include <sys/lockf.h> 93 #include <sys/kauth.h> 94 #include <sys/wapbl.h> 95 96 #include <miscfs/specfs/specdev.h> 97 #include <miscfs/fifofs/fifo.h> 98 #include <miscfs/genfs/genfs.h> 99 100 #include <ufs/ufs/acl.h> 101 #include <ufs/ufs/inode.h> 102 #include <ufs/ufs/dir.h> 103 #include <ufs/ufs/ufsmount.h> 104 #include <ufs/ufs/ufs_bswap.h> 105 #include <ufs/ufs/ufs_extern.h> 106 #include <ufs/ufs/ufs_wapbl.h> 107 #ifdef UFS_DIRHASH 108 #include <ufs/ufs/dirhash.h> 109 #endif 110 #include <ufs/ext2fs/ext2fs_extern.h> 111 #include <ufs/ext2fs/ext2fs_dir.h> 112 #include <ufs/ffs/ffs_extern.h> 113 #include <ufs/lfs/lfs_extern.h> 114 #include <ufs/lfs/lfs.h> 115 116 #ifdef UVMHIST 117 #include <uvm/uvm.h> 118 #endif 119 #include <uvm/uvm_extern.h> 120 #include <uvm/uvm_stat.h> 121 122 __CTASSERT(EXT2FS_MAXNAMLEN == FFS_MAXNAMLEN); 123 __CTASSERT(LFS_MAXNAMLEN == FFS_MAXNAMLEN); 124 125 static int ufs_chmod(struct vnode *, int, kauth_cred_t, struct lwp *); 126 static int ufs_chown(struct vnode *, uid_t, gid_t, kauth_cred_t, 127 struct lwp *); 128 static int ufs_makeinode(struct vattr *, struct vnode *, 129 const struct ufs_lookup_results *, struct vnode **, struct componentname *); 130 131 /* 132 * A virgin directory (no blushing please). 133 */ 134 static const struct dirtemplate mastertemplate = { 135 0, 12, DT_DIR, 1, ".", 136 0, UFS_DIRBLKSIZ - 12, DT_DIR, 2, ".." 137 }; 138 139 /* 140 * Create a regular file 141 */ 142 int 143 ufs_create(void *v) 144 { 145 struct vop_create_v3_args /* { 146 struct vnode *a_dvp; 147 struct vnode **a_vpp; 148 struct componentname *a_cnp; 149 struct vattr *a_vap; 150 } */ *ap = v; 151 int error; 152 struct vnode *dvp = ap->a_dvp; 153 struct ufs_lookup_results *ulr; 154 155 /* XXX should handle this material another way */ 156 ulr = &VTOI(dvp)->i_crap; 157 UFS_CHECK_CRAPCOUNTER(VTOI(dvp)); 158 159 /* 160 * UFS_WAPBL_BEGIN(dvp->v_mount) performed by successful 161 * ufs_makeinode 162 */ 163 error = ufs_makeinode(ap->a_vap, dvp, ulr, ap->a_vpp, ap->a_cnp); 164 if (error) { 165 return (error); 166 } 167 UFS_WAPBL_END(dvp->v_mount); 168 VOP_UNLOCK(*ap->a_vpp); 169 return (0); 170 } 171 172 /* 173 * Mknod vnode call 174 */ 175 /* ARGSUSED */ 176 int 177 ufs_mknod(void *v) 178 { 179 struct vop_mknod_v3_args /* { 180 struct vnode *a_dvp; 181 struct vnode **a_vpp; 182 struct componentname *a_cnp; 183 struct vattr *a_vap; 184 } */ *ap = v; 185 struct vattr *vap; 186 struct vnode **vpp; 187 struct inode *ip; 188 int error; 189 struct ufs_lookup_results *ulr; 190 191 vap = ap->a_vap; 192 vpp = ap->a_vpp; 193 194 /* XXX should handle this material another way */ 195 ulr = &VTOI(ap->a_dvp)->i_crap; 196 UFS_CHECK_CRAPCOUNTER(VTOI(ap->a_dvp)); 197 198 /* 199 * UFS_WAPBL_BEGIN(dvp->v_mount) performed by successful 200 * ufs_makeinode 201 */ 202 if ((error = ufs_makeinode(vap, ap->a_dvp, ulr, vpp, ap->a_cnp)) != 0) 203 goto out; 204 ip = VTOI(*vpp); 205 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 206 UFS_WAPBL_UPDATE(*vpp, NULL, NULL, 0); 207 UFS_WAPBL_END(ap->a_dvp->v_mount); 208 VOP_UNLOCK(*vpp); 209 out: 210 if (error != 0) { 211 *vpp = NULL; 212 return (error); 213 } 214 return (0); 215 } 216 217 /* 218 * Open called. 219 * 220 * Nothing to do. 221 */ 222 /* ARGSUSED */ 223 int 224 ufs_open(void *v) 225 { 226 struct vop_open_args /* { 227 struct vnode *a_vp; 228 int a_mode; 229 kauth_cred_t a_cred; 230 } */ *ap = v; 231 232 /* 233 * Files marked append-only must be opened for appending. 234 */ 235 if ((VTOI(ap->a_vp)->i_flags & APPEND) && 236 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) 237 return (EPERM); 238 return (0); 239 } 240 241 /* 242 * Close called. 243 * 244 * Update the times on the inode. 245 */ 246 /* ARGSUSED */ 247 int 248 ufs_close(void *v) 249 { 250 struct vop_close_args /* { 251 struct vnode *a_vp; 252 int a_fflag; 253 kauth_cred_t a_cred; 254 } */ *ap = v; 255 struct vnode *vp; 256 257 vp = ap->a_vp; 258 if (vrefcnt(vp) > 1) 259 UFS_ITIMES(vp, NULL, NULL, NULL); 260 return (0); 261 } 262 263 static int 264 ufs_check_possible(struct vnode *vp, struct inode *ip, accmode_t accmode, 265 kauth_cred_t cred) 266 { 267 #if defined(QUOTA) || defined(QUOTA2) 268 int error; 269 #endif 270 271 /* 272 * Disallow write attempts on read-only file systems; 273 * unless the file is a socket, fifo, or a block or 274 * character device resident on the file system. 275 */ 276 if (accmode & VMODIFY_PERMS) { 277 switch (vp->v_type) { 278 case VDIR: 279 case VLNK: 280 case VREG: 281 if (vp->v_mount->mnt_flag & MNT_RDONLY) 282 return EROFS; 283 #if defined(QUOTA) || defined(QUOTA2) 284 error = chkdq(ip, 0, cred, 0); 285 if (error != 0) 286 return error; 287 #endif 288 break; 289 case VBAD: 290 case VBLK: 291 case VCHR: 292 case VSOCK: 293 case VFIFO: 294 case VNON: 295 default: 296 break; 297 } 298 } 299 300 /* If it is a snapshot, nobody gets access to it. */ 301 if ((ip->i_flags & SF_SNAPSHOT)) 302 return EPERM; 303 /* 304 * If immutable bit set, nobody gets to write it. "& ~VADMIN_PERMS" 305 * permits the owner of the file to remove the IMMUTABLE flag. 306 */ 307 if ((accmode & (VMODIFY_PERMS & ~VADMIN_PERMS)) && 308 (ip->i_flags & IMMUTABLE)) 309 return EPERM; 310 311 return 0; 312 } 313 314 static int 315 ufs_check_permitted(struct vnode *vp, struct inode *ip, 316 struct acl *acl, accmode_t accmode, kauth_cred_t cred, 317 int (*func)(struct vnode *, kauth_cred_t, uid_t, gid_t, mode_t, 318 struct acl *, accmode_t)) 319 { 320 321 return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(accmode, 322 vp->v_type, ip->i_mode & ALLPERMS), vp, NULL, (*func)(vp, cred, 323 ip->i_uid, ip->i_gid, ip->i_mode & ALLPERMS, acl, accmode)); 324 } 325 326 int 327 ufs_accessx(void *v) 328 { 329 struct vop_accessx_args /* { 330 struct vnode *a_vp; 331 accmode_t a_accmode; 332 kauth_cred_t a_cred; 333 } */ *ap = v; 334 struct vnode *vp = ap->a_vp; 335 struct inode *ip = VTOI(vp); 336 accmode_t accmode = ap->a_accmode; 337 int error; 338 #ifdef UFS_ACL 339 struct acl *acl; 340 acl_type_t type; 341 #endif 342 343 error = ufs_check_possible(vp, ip, accmode, ap->a_cred); 344 if (error) 345 return error; 346 347 #ifdef UFS_ACL 348 if ((vp->v_mount->mnt_flag & (MNT_POSIX1EACLS | MNT_NFS4ACLS)) != 0) { 349 if (vp->v_mount->mnt_flag & MNT_NFS4ACLS) 350 type = ACL_TYPE_NFS4; 351 else 352 type = ACL_TYPE_ACCESS; 353 354 acl = acl_alloc(KM_SLEEP); 355 if (type == ACL_TYPE_NFS4) 356 error = ufs_getacl_nfs4_internal(vp, acl, curlwp); 357 else 358 error = VOP_GETACL(vp, type, acl, ap->a_cred); 359 if (!error) { 360 if (type == ACL_TYPE_NFS4) { 361 error = ufs_check_permitted(vp, 362 ip, acl, accmode, ap->a_cred, 363 genfs_can_access_acl_nfs4); 364 } else { 365 error = vfs_unixify_accmode(&accmode); 366 if (error == 0) 367 error = ufs_check_permitted(vp, 368 ip, acl, accmode, ap->a_cred, 369 genfs_can_access_acl_posix1e); 370 } 371 acl_free(acl); 372 return error; 373 } 374 if (error != EOPNOTSUPP) 375 printf("%s: Error retrieving ACL: %d\n", 376 __func__, error); 377 /* 378 * XXX: Fall back until debugged. Should 379 * eventually possibly log an error, and return 380 * EPERM for safety. 381 */ 382 acl_free(acl); 383 } 384 #endif /* !UFS_ACL */ 385 error = vfs_unixify_accmode(&accmode); 386 if (error) 387 return error; 388 return ufs_check_permitted(vp, ip, 389 NULL, accmode, ap->a_cred, genfs_can_access); 390 } 391 392 /* ARGSUSED */ 393 int 394 ufs_getattr(void *v) 395 { 396 struct vop_getattr_args /* { 397 struct vnode *a_vp; 398 struct vattr *a_vap; 399 kauth_cred_t a_cred; 400 } */ *ap = v; 401 struct vnode *vp; 402 struct inode *ip; 403 struct vattr *vap; 404 405 vp = ap->a_vp; 406 ip = VTOI(vp); 407 vap = ap->a_vap; 408 UFS_ITIMES(vp, NULL, NULL, NULL); 409 410 /* 411 * Copy from inode table 412 */ 413 vap->va_fsid = ip->i_dev; 414 vap->va_fileid = ip->i_number; 415 vap->va_mode = ip->i_mode & ALLPERMS; 416 vap->va_nlink = ip->i_nlink; 417 vap->va_uid = ip->i_uid; 418 vap->va_gid = ip->i_gid; 419 vap->va_size = vp->v_size; 420 if (ip->i_ump->um_fstype == UFS1) { 421 switch (vp->v_type) { 422 case VBLK: 423 case VCHR: 424 vap->va_rdev = (dev_t)ufs_rw32(ip->i_ffs1_rdev, 425 UFS_MPNEEDSWAP(ip->i_ump)); 426 break; 427 default: 428 vap->va_rdev = NODEV; 429 break; 430 } 431 vap->va_atime.tv_sec = ip->i_ffs1_atime; 432 vap->va_atime.tv_nsec = ip->i_ffs1_atimensec; 433 vap->va_mtime.tv_sec = ip->i_ffs1_mtime; 434 vap->va_mtime.tv_nsec = ip->i_ffs1_mtimensec; 435 vap->va_ctime.tv_sec = ip->i_ffs1_ctime; 436 vap->va_ctime.tv_nsec = ip->i_ffs1_ctimensec; 437 vap->va_birthtime.tv_sec = 0; 438 vap->va_birthtime.tv_nsec = 0; 439 vap->va_bytes = dbtob((u_quad_t)ip->i_ffs1_blocks); 440 } else { 441 switch (vp->v_type) { 442 case VBLK: 443 case VCHR: 444 vap->va_rdev = (dev_t)ufs_rw64(ip->i_ffs2_rdev, 445 UFS_MPNEEDSWAP(ip->i_ump)); 446 break; 447 default: 448 vap->va_rdev = NODEV; 449 break; 450 } 451 vap->va_atime.tv_sec = ip->i_ffs2_atime; 452 vap->va_atime.tv_nsec = ip->i_ffs2_atimensec; 453 vap->va_mtime.tv_sec = ip->i_ffs2_mtime; 454 vap->va_mtime.tv_nsec = ip->i_ffs2_mtimensec; 455 vap->va_ctime.tv_sec = ip->i_ffs2_ctime; 456 vap->va_ctime.tv_nsec = ip->i_ffs2_ctimensec; 457 vap->va_birthtime.tv_sec = ip->i_ffs2_birthtime; 458 vap->va_birthtime.tv_nsec = ip->i_ffs2_birthnsec; 459 vap->va_bytes = dbtob(ip->i_ffs2_blocks); 460 } 461 vap->va_gen = ip->i_gen; 462 vap->va_flags = ip->i_flags; 463 464 /* this doesn't belong here */ 465 if (vp->v_type == VBLK) 466 vap->va_blocksize = BLKDEV_IOSIZE; 467 else if (vp->v_type == VCHR) 468 vap->va_blocksize = MAXBSIZE; 469 else 470 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; 471 vap->va_type = vp->v_type; 472 vap->va_filerev = ip->i_modrev; 473 return (0); 474 } 475 476 /* 477 * Set attribute vnode op. called from several syscalls 478 */ 479 int 480 ufs_setattr(void *v) 481 { 482 struct vop_setattr_args /* { 483 struct vnode *a_vp; 484 struct vattr *a_vap; 485 kauth_cred_t a_cred; 486 } */ *ap = v; 487 struct vattr *vap; 488 struct vnode *vp; 489 struct inode *ip; 490 kauth_cred_t cred; 491 struct lwp *l; 492 int error; 493 kauth_action_t action; 494 bool changing_sysflags; 495 496 vap = ap->a_vap; 497 vp = ap->a_vp; 498 ip = VTOI(vp); 499 cred = ap->a_cred; 500 l = curlwp; 501 action = KAUTH_VNODE_WRITE_FLAGS; 502 changing_sysflags = false; 503 504 /* 505 * Check for unsettable attributes. 506 */ 507 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 508 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 509 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 510 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 511 return (EINVAL); 512 } 513 514 UFS_WAPBL_JUNLOCK_ASSERT(vp->v_mount); 515 516 if (vap->va_flags != VNOVAL) { 517 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 518 error = EROFS; 519 goto out; 520 } 521 522 /* Snapshot flag cannot be set or cleared */ 523 if ((vap->va_flags & (SF_SNAPSHOT | SF_SNAPINVAL)) != 524 (ip->i_flags & (SF_SNAPSHOT | SF_SNAPINVAL))) { 525 error = EPERM; 526 goto out; 527 } 528 529 if (ip->i_flags & (SF_IMMUTABLE | SF_APPEND)) { 530 action |= KAUTH_VNODE_HAS_SYSFLAGS; 531 } 532 533 if ((vap->va_flags & SF_SETTABLE) != 534 (ip->i_flags & SF_SETTABLE)) { 535 action |= KAUTH_VNODE_WRITE_SYSFLAGS; 536 changing_sysflags = true; 537 } 538 539 error = kauth_authorize_vnode(cred, action, vp, NULL, 540 genfs_can_chflags(vp, cred, ip->i_uid, changing_sysflags)); 541 if (error) 542 goto out; 543 544 if (changing_sysflags) { 545 error = UFS_WAPBL_BEGIN(vp->v_mount); 546 if (error) 547 goto out; 548 ip->i_flags = vap->va_flags; 549 DIP_ASSIGN(ip, flags, ip->i_flags); 550 } else { 551 error = UFS_WAPBL_BEGIN(vp->v_mount); 552 if (error) 553 goto out; 554 ip->i_flags &= SF_SETTABLE; 555 ip->i_flags |= (vap->va_flags & UF_SETTABLE); 556 DIP_ASSIGN(ip, flags, ip->i_flags); 557 } 558 ip->i_flag |= IN_CHANGE; 559 UFS_WAPBL_UPDATE(vp, NULL, NULL, 0); 560 UFS_WAPBL_END(vp->v_mount); 561 if (vap->va_flags & (IMMUTABLE | APPEND)) { 562 error = 0; 563 goto out; 564 } 565 } 566 if (ip->i_flags & (IMMUTABLE | APPEND)) { 567 error = EPERM; 568 goto out; 569 } 570 /* 571 * Go through the fields and update iff not VNOVAL. 572 */ 573 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { 574 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 575 error = EROFS; 576 goto out; 577 } 578 error = UFS_WAPBL_BEGIN(vp->v_mount); 579 if (error) 580 goto out; 581 error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, l); 582 UFS_WAPBL_END(vp->v_mount); 583 if (error) 584 goto out; 585 } 586 if (vap->va_size != VNOVAL) { 587 /* 588 * Disallow write attempts on read-only file systems; 589 * unless the file is a socket, fifo, or a block or 590 * character device resident on the file system. 591 */ 592 switch (vp->v_type) { 593 case VDIR: 594 error = EISDIR; 595 goto out; 596 case VCHR: 597 case VBLK: 598 case VFIFO: 599 break; 600 case VREG: 601 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 602 error = EROFS; 603 goto out; 604 } 605 if ((ip->i_flags & SF_SNAPSHOT) != 0) { 606 error = EPERM; 607 goto out; 608 } 609 error = ufs_truncate_retry(vp, 0, vap->va_size, cred); 610 if (error) 611 goto out; 612 break; 613 default: 614 error = EOPNOTSUPP; 615 goto out; 616 } 617 } 618 ip = VTOI(vp); 619 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || 620 vap->va_birthtime.tv_sec != VNOVAL) { 621 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 622 error = EROFS; 623 goto out; 624 } 625 if ((ip->i_flags & SF_SNAPSHOT) != 0) { 626 error = EPERM; 627 goto out; 628 } 629 error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES, vp, 630 NULL, genfs_can_chtimes(vp, cred, ip->i_uid, 631 vap->va_vaflags)); 632 if (error) 633 goto out; 634 error = UFS_WAPBL_BEGIN(vp->v_mount); 635 if (error) 636 goto out; 637 if (vap->va_atime.tv_sec != VNOVAL) 638 if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) 639 ip->i_flag |= IN_ACCESS; 640 if (vap->va_mtime.tv_sec != VNOVAL) { 641 ip->i_flag |= IN_CHANGE | IN_UPDATE; 642 if (vp->v_mount->mnt_flag & MNT_RELATIME) 643 ip->i_flag |= IN_ACCESS; 644 } 645 if (vap->va_birthtime.tv_sec != VNOVAL && 646 ip->i_ump->um_fstype == UFS2) { 647 ip->i_ffs2_birthtime = vap->va_birthtime.tv_sec; 648 ip->i_ffs2_birthnsec = vap->va_birthtime.tv_nsec; 649 } 650 error = UFS_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 0); 651 UFS_WAPBL_END(vp->v_mount); 652 if (error) 653 goto out; 654 } 655 error = 0; 656 if (vap->va_mode != (mode_t)VNOVAL) { 657 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 658 error = EROFS; 659 goto out; 660 } 661 if ((ip->i_flags & SF_SNAPSHOT) != 0 && 662 (vap->va_mode & (S_IXUSR | S_IWUSR | S_IXGRP | S_IWGRP | 663 S_IXOTH | S_IWOTH))) { 664 error = EPERM; 665 goto out; 666 } 667 error = UFS_WAPBL_BEGIN(vp->v_mount); 668 if (error) 669 goto out; 670 error = ufs_chmod(vp, (int)vap->va_mode, cred, l); 671 UFS_WAPBL_END(vp->v_mount); 672 } 673 out: 674 cache_enter_id(vp, ip->i_mode, ip->i_uid, ip->i_gid, !HAS_ACLS(ip)); 675 return (error); 676 } 677 678 #ifdef UFS_ACL 679 static int 680 ufs_update_nfs4_acl_after_mode_change(struct vnode *vp, int mode, 681 int file_owner_id, kauth_cred_t cred, struct lwp *l) 682 { 683 int error; 684 struct acl *aclp; 685 686 aclp = acl_alloc(KM_SLEEP); 687 error = ufs_getacl_nfs4_internal(vp, aclp, l); 688 /* 689 * We don't have to handle EOPNOTSUPP here, as the filesystem claims 690 * it supports ACLs. 691 */ 692 if (error) 693 goto out; 694 695 acl_nfs4_sync_acl_from_mode(aclp, mode, file_owner_id); 696 error = ufs_setacl_nfs4_internal(vp, aclp, l, false); 697 698 out: 699 acl_free(aclp); 700 return (error); 701 } 702 #endif /* UFS_ACL */ 703 704 /* 705 * Change the mode on a file. 706 * Inode must be locked before calling. 707 */ 708 static int 709 ufs_chmod(struct vnode *vp, int mode, kauth_cred_t cred, struct lwp *l) 710 { 711 struct inode *ip; 712 int error; 713 714 UFS_WAPBL_JLOCK_ASSERT(vp->v_mount); 715 716 ip = VTOI(vp); 717 718 #ifdef UFS_ACL 719 /* 720 * To modify the permissions on a file, must possess VADMIN 721 * for that file. 722 */ 723 if ((error = VOP_ACCESSX(vp, VWRITE_ACL, cred)) != 0) 724 return error; 725 #endif 726 727 error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_SECURITY, vp, 728 NULL, genfs_can_chmod(vp, cred, ip->i_uid, ip->i_gid, mode)); 729 if (error) 730 return (error); 731 732 #ifdef UFS_ACL 733 if ((vp->v_mount->mnt_flag & MNT_NFS4ACLS) != 0) { 734 error = ufs_update_nfs4_acl_after_mode_change(vp, mode, 735 ip->i_uid, cred, l); 736 if (error) 737 return error; 738 } 739 #endif 740 ip->i_mode &= ~ALLPERMS; 741 ip->i_mode |= (mode & ALLPERMS); 742 ip->i_flag |= IN_CHANGE; 743 DIP_ASSIGN(ip, mode, ip->i_mode); 744 UFS_WAPBL_UPDATE(vp, NULL, NULL, 0); 745 cache_enter_id(vp, ip->i_mode, ip->i_uid, ip->i_gid, !HAS_ACLS(ip)); 746 return (0); 747 } 748 749 /* 750 * Perform chown operation on inode ip; 751 * inode must be locked prior to call. 752 */ 753 static int 754 ufs_chown(struct vnode *vp, uid_t uid, gid_t gid, kauth_cred_t cred, 755 struct lwp *l) 756 { 757 struct inode *ip; 758 int error = 0; 759 #if defined(QUOTA) || defined(QUOTA2) 760 uid_t ouid; 761 gid_t ogid; 762 int64_t change; 763 #endif 764 ip = VTOI(vp); 765 error = 0; 766 767 if (uid == (uid_t)VNOVAL) 768 uid = ip->i_uid; 769 if (gid == (gid_t)VNOVAL) 770 gid = ip->i_gid; 771 772 #ifdef UFS_ACL 773 /* 774 * To modify the ownership of a file, must possess VADMIN for that 775 * file. 776 */ 777 if ((error = VOP_ACCESSX(vp, VWRITE_OWNER, cred)) != 0) 778 return error; 779 #endif 780 781 error = kauth_authorize_vnode(cred, KAUTH_VNODE_CHANGE_OWNERSHIP, vp, 782 NULL, genfs_can_chown(vp, cred, ip->i_uid, ip->i_gid, uid, gid)); 783 if (error) 784 return (error); 785 786 #if defined(QUOTA) || defined(QUOTA2) 787 ogid = ip->i_gid; 788 ouid = ip->i_uid; 789 change = DIP(ip, blocks); 790 (void) chkdq(ip, -change, cred, 0); 791 (void) chkiq(ip, -1, cred, 0); 792 #endif 793 ip->i_gid = gid; 794 DIP_ASSIGN(ip, gid, gid); 795 ip->i_uid = uid; 796 DIP_ASSIGN(ip, uid, uid); 797 #if defined(QUOTA) || defined(QUOTA2) 798 if ((error = chkdq(ip, change, cred, 0)) == 0) { 799 if ((error = chkiq(ip, 1, cred, 0)) == 0) 800 goto good; 801 else 802 (void) chkdq(ip, -change, cred, FORCE); 803 } 804 ip->i_gid = ogid; 805 DIP_ASSIGN(ip, gid, ogid); 806 ip->i_uid = ouid; 807 DIP_ASSIGN(ip, uid, ouid); 808 (void) chkdq(ip, change, cred, FORCE); 809 (void) chkiq(ip, 1, cred, FORCE); 810 return (error); 811 good: 812 #endif /* QUOTA || QUOTA2 */ 813 ip->i_flag |= IN_CHANGE; 814 UFS_WAPBL_UPDATE(vp, NULL, NULL, 0); 815 cache_enter_id(vp, ip->i_mode, ip->i_uid, ip->i_gid, !HAS_ACLS(ip)); 816 return (0); 817 } 818 819 int 820 ufs_remove(void *v) 821 { 822 struct vop_remove_v3_args /* { 823 struct vnode *a_dvp; 824 struct vnode *a_vp; 825 struct componentname *a_cnp; 826 nlink_t ctx_vp_new_nlink; 827 } */ *ap = v; 828 struct vnode *vp, *dvp; 829 struct inode *ip; 830 struct mount *mp; 831 int error; 832 struct ufs_lookup_results *ulr; 833 834 vp = ap->a_vp; 835 dvp = ap->a_dvp; 836 ip = VTOI(vp); 837 mp = dvp->v_mount; 838 KASSERT(mp == vp->v_mount); /* XXX Not stable without lock. */ 839 840 #ifdef UFS_ACL 841 #ifdef notyet 842 /* We don't do this because if the filesystem is mounted without ACLs 843 * this goes through vfs_unixify_accmode() and we get EPERM. 844 */ 845 error = VOP_ACCESSX(vp, VDELETE, ap->a_cnp->cn_cred); 846 if (error) 847 goto err; 848 #endif 849 #endif 850 851 /* XXX should handle this material another way */ 852 ulr = &VTOI(dvp)->i_crap; 853 UFS_CHECK_CRAPCOUNTER(VTOI(dvp)); 854 855 if (vp->v_type == VDIR || (ip->i_flags & (IMMUTABLE | APPEND)) || 856 (VTOI(dvp)->i_flags & APPEND)) 857 error = EPERM; 858 else { 859 error = UFS_WAPBL_BEGIN(mp); 860 if (error == 0) { 861 error = ufs_dirremove(dvp, ulr, 862 ip, ap->a_cnp->cn_flags, 0); 863 UFS_WAPBL_END(mp); 864 if (error == 0) { 865 ap->ctx_vp_new_nlink = ip->i_nlink; 866 } 867 } 868 } 869 #ifdef notyet 870 err: 871 #endif 872 if (dvp == vp) 873 vrele(vp); 874 else 875 vput(vp); 876 return (error); 877 } 878 879 /* 880 * ufs_link: create hard link. 881 */ 882 int 883 ufs_link(void *v) 884 { 885 struct vop_link_v2_args /* { 886 struct vnode *a_dvp; 887 struct vnode *a_vp; 888 struct componentname *a_cnp; 889 } */ *ap = v; 890 struct vnode *dvp = ap->a_dvp; 891 struct vnode *vp = ap->a_vp; 892 struct componentname *cnp = ap->a_cnp; 893 struct mount *mp = dvp->v_mount; 894 struct inode *ip; 895 struct direct *newdir; 896 int error, abrt = 1; 897 struct ufs_lookup_results *ulr; 898 899 KASSERT(dvp != vp); 900 KASSERT(vp->v_type != VDIR); 901 KASSERT(mp == vp->v_mount); /* XXX Not stable without lock. */ 902 903 /* XXX should handle this material another way */ 904 ulr = &VTOI(dvp)->i_crap; 905 UFS_CHECK_CRAPCOUNTER(VTOI(dvp)); 906 907 error = vn_lock(vp, LK_EXCLUSIVE); 908 if (error) 909 goto out2; 910 911 ip = VTOI(vp); 912 if ((nlink_t)ip->i_nlink >= LINK_MAX) { 913 error = EMLINK; 914 goto out1; 915 } 916 if (ip->i_flags & (IMMUTABLE | APPEND)) { 917 error = EPERM; 918 goto out1; 919 } 920 921 error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, 922 dvp, 0); 923 if (error) 924 goto out1; 925 926 error = UFS_WAPBL_BEGIN(mp); 927 if (error) 928 goto out1; 929 930 ip->i_nlink++; 931 DIP_ASSIGN(ip, nlink, ip->i_nlink); 932 ip->i_flag |= IN_CHANGE; 933 abrt = 0; 934 error = UFS_UPDATE(vp, NULL, NULL, UPDATE_DIROP); 935 if (!error) { 936 newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK); 937 ufs_makedirentry(ip, cnp, newdir); 938 error = ufs_direnter(dvp, ulr, vp, newdir, cnp, NULL); 939 pool_cache_put(ufs_direct_cache, newdir); 940 } 941 if (error) { 942 ip->i_nlink--; 943 DIP_ASSIGN(ip, nlink, ip->i_nlink); 944 ip->i_flag |= IN_CHANGE; 945 UFS_WAPBL_UPDATE(vp, NULL, NULL, UPDATE_DIROP); 946 } 947 UFS_WAPBL_END(mp); 948 out1: 949 VOP_UNLOCK(vp); 950 out2: 951 if (abrt) 952 VOP_ABORTOP(dvp, cnp); 953 return (error); 954 } 955 956 /* 957 * whiteout vnode call 958 */ 959 int 960 ufs_whiteout(void *v) 961 { 962 struct vop_whiteout_args /* { 963 struct vnode *a_dvp; 964 struct componentname *a_cnp; 965 int a_flags; 966 } */ *ap = v; 967 struct vnode *dvp = ap->a_dvp; 968 struct componentname *cnp = ap->a_cnp; 969 struct direct *newdir; 970 int error; 971 struct ufsmount *ump = VFSTOUFS(dvp->v_mount); 972 struct ufs_lookup_results *ulr; 973 974 /* XXX should handle this material another way */ 975 ulr = &VTOI(dvp)->i_crap; 976 UFS_CHECK_CRAPCOUNTER(VTOI(dvp)); 977 978 error = 0; 979 switch (ap->a_flags) { 980 case LOOKUP: 981 /* 4.4 format directories support whiteout operations */ 982 if (ump->um_maxsymlinklen > 0) 983 return (0); 984 return (EOPNOTSUPP); 985 986 case CREATE: 987 /* create a new directory whiteout */ 988 error = UFS_WAPBL_BEGIN(dvp->v_mount); 989 if (error) 990 break; 991 992 KASSERTMSG((ump->um_maxsymlinklen > 0), 993 "ufs_whiteout: old format filesystem"); 994 995 newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK); 996 newdir->d_ino = UFS_WINO; 997 newdir->d_namlen = cnp->cn_namelen; 998 memcpy(newdir->d_name, cnp->cn_nameptr, 999 (size_t)cnp->cn_namelen); 1000 1001 /* NUL terminate and zero out padding */ 1002 memset(&newdir->d_name[cnp->cn_namelen], 0, 1003 UFS_NAMEPAD(cnp->cn_namelen)); 1004 1005 newdir->d_type = DT_WHT; 1006 error = ufs_direnter(dvp, ulr, NULL, newdir, cnp, NULL); 1007 pool_cache_put(ufs_direct_cache, newdir); 1008 break; 1009 1010 case DELETE: 1011 /* remove an existing directory whiteout */ 1012 error = UFS_WAPBL_BEGIN(dvp->v_mount); 1013 if (error) 1014 break; 1015 1016 KASSERTMSG((ump->um_maxsymlinklen > 0), 1017 "ufs_whiteout: old format filesystem"); 1018 1019 cnp->cn_flags &= ~DOWHITEOUT; 1020 error = ufs_dirremove(dvp, ulr, NULL, cnp->cn_flags, 0); 1021 break; 1022 default: 1023 panic("ufs_whiteout: unknown op"); 1024 /* NOTREACHED */ 1025 } 1026 UFS_WAPBL_END(dvp->v_mount); 1027 return (error); 1028 } 1029 1030 #ifdef UFS_ACL 1031 static int 1032 ufs_do_posix1e_acl_inheritance_dir(struct vnode *dvp, struct vnode *tvp, 1033 mode_t dmode, kauth_cred_t cred, struct lwp *l) 1034 { 1035 int error; 1036 struct inode *ip = VTOI(tvp); 1037 struct acl *dacl, *acl; 1038 1039 acl = acl_alloc(KM_SLEEP); 1040 dacl = acl_alloc(KM_SLEEP); 1041 1042 /* 1043 * Retrieve default ACL from parent, if any. 1044 */ 1045 error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred); 1046 switch (error) { 1047 case 0: 1048 /* 1049 * Retrieved a default ACL, so merge mode and ACL if 1050 * necessary. If the ACL is empty, fall through to 1051 * the "not defined or available" case. 1052 */ 1053 if (acl->acl_cnt != 0) { 1054 dmode = acl_posix1e_newfilemode(dmode, acl); 1055 ip->i_mode = dmode; 1056 DIP_ASSIGN(ip, mode, dmode); 1057 *dacl = *acl; 1058 ufs_sync_acl_from_inode(ip, acl); 1059 break; 1060 } 1061 /* FALLTHROUGH */ 1062 1063 case EOPNOTSUPP: 1064 /* 1065 * Just use the mode as-is. 1066 */ 1067 ip->i_mode = dmode; 1068 DIP_ASSIGN(ip, mode, dmode); 1069 error = 0; 1070 goto out; 1071 1072 default: 1073 goto out; 1074 } 1075 1076 /* 1077 * XXX: If we abort now, will Soft Updates notify the extattr 1078 * code that the EAs for the file need to be released? 1079 */ 1080 UFS_WAPBL_END(tvp->v_mount); 1081 error = ufs_setacl_posix1e(tvp, ACL_TYPE_ACCESS, acl, cred, l); 1082 if (error == 0) 1083 error = ufs_setacl_posix1e(tvp, ACL_TYPE_DEFAULT, dacl, cred, 1084 l); 1085 UFS_WAPBL_BEGIN(tvp->v_mount); 1086 switch (error) { 1087 case 0: 1088 break; 1089 1090 case EOPNOTSUPP: 1091 /* 1092 * XXX: This should not happen, as EOPNOTSUPP above 1093 * was supposed to free acl. 1094 */ 1095 printf("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()\n"); 1096 /* 1097 panic("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()"); 1098 */ 1099 break; 1100 1101 default: 1102 goto out; 1103 } 1104 1105 out: 1106 acl_free(acl); 1107 acl_free(dacl); 1108 1109 return (error); 1110 } 1111 1112 static int 1113 ufs_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp, 1114 mode_t mode, kauth_cred_t cred, struct lwp *l) 1115 { 1116 int error; 1117 struct inode *ip = VTOI(tvp); 1118 struct acl *acl; 1119 1120 acl = acl_alloc(KM_SLEEP); 1121 1122 /* 1123 * Retrieve default ACL for parent, if any. 1124 */ 1125 error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred); 1126 switch (error) { 1127 case 0: 1128 /* 1129 * Retrieved a default ACL, so merge mode and ACL if 1130 * necessary. 1131 */ 1132 if (acl->acl_cnt != 0) { 1133 /* 1134 * Two possible ways for default ACL to not 1135 * be present. First, the EA can be 1136 * undefined, or second, the default ACL can 1137 * be blank. If it's blank, fall through to 1138 * the it's not defined case. 1139 */ 1140 mode = acl_posix1e_newfilemode(mode, acl); 1141 ip->i_mode = mode; 1142 DIP_ASSIGN(ip, mode, mode); 1143 ufs_sync_acl_from_inode(ip, acl); 1144 break; 1145 } 1146 /* FALLTHROUGH */ 1147 1148 case EOPNOTSUPP: 1149 /* 1150 * Just use the mode as-is. 1151 */ 1152 ip->i_mode = mode; 1153 DIP_ASSIGN(ip, mode, mode); 1154 error = 0; 1155 goto out; 1156 1157 default: 1158 goto out; 1159 } 1160 1161 UFS_WAPBL_END(tvp->v_mount); 1162 /* 1163 * XXX: If we abort now, will Soft Updates notify the extattr 1164 * code that the EAs for the file need to be released? 1165 */ 1166 error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred); 1167 UFS_WAPBL_BEGIN(tvp->v_mount); 1168 switch (error) { 1169 case 0: 1170 break; 1171 1172 case EOPNOTSUPP: 1173 /* 1174 * XXX: This should not happen, as EOPNOTSUPP above was 1175 * supposed to free acl. 1176 */ 1177 printf("%s: VOP_GETACL() but no VOP_SETACL()\n", __func__); 1178 /* panic("%s: VOP_GETACL() but no VOP_SETACL()", __func__); */ 1179 break; 1180 1181 default: 1182 goto out; 1183 } 1184 1185 out: 1186 acl_free(acl); 1187 1188 return (error); 1189 } 1190 1191 static int 1192 ufs_do_nfs4_acl_inheritance(struct vnode *dvp, struct vnode *tvp, 1193 mode_t child_mode, kauth_cred_t cred, struct lwp *l) 1194 { 1195 int error; 1196 struct acl *parent_aclp, *child_aclp; 1197 1198 parent_aclp = acl_alloc(KM_SLEEP); 1199 child_aclp = acl_alloc(KM_SLEEP); 1200 1201 error = ufs_getacl_nfs4_internal(dvp, parent_aclp, l); 1202 if (error) 1203 goto out; 1204 acl_nfs4_compute_inherited_acl(parent_aclp, child_aclp, 1205 child_mode, VTOI(tvp)->i_uid, tvp->v_type == VDIR); 1206 error = ufs_setacl_nfs4_internal(tvp, child_aclp, l, false); 1207 if (error) 1208 goto out; 1209 out: 1210 acl_free(parent_aclp); 1211 acl_free(child_aclp); 1212 1213 return (error); 1214 } 1215 #endif 1216 1217 int 1218 ufs_mkdir(void *v) 1219 { 1220 struct vop_mkdir_v3_args /* { 1221 struct vnode *a_dvp; 1222 struct vnode **a_vpp; 1223 struct componentname *a_cnp; 1224 struct vattr *a_vap; 1225 } */ *ap = v; 1226 struct vnode *dvp = ap->a_dvp, *tvp; 1227 struct vattr *vap = ap->a_vap; 1228 struct componentname *cnp = ap->a_cnp; 1229 struct inode *ip, *dp = VTOI(dvp); 1230 struct buf *bp; 1231 struct dirtemplate dirtemplate; 1232 struct direct *newdir; 1233 int error; 1234 struct ufsmount *ump = dp->i_ump; 1235 int dirblksiz = ump->um_dirblksiz; 1236 struct ufs_lookup_results *ulr; 1237 1238 /* XXX should handle this material another way */ 1239 ulr = &dp->i_crap; 1240 UFS_CHECK_CRAPCOUNTER(dp); 1241 1242 KASSERT(vap->va_type == VDIR); 1243 1244 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 1245 error = EMLINK; 1246 goto out; 1247 } 1248 /* 1249 * Must simulate part of ufs_makeinode here to acquire the inode, 1250 * but not have it entered in the parent directory. The entry is 1251 * made later after writing "." and ".." entries. 1252 */ 1253 error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, NULL, 1254 ap->a_vpp); 1255 if (error) 1256 goto out; 1257 error = vn_lock(*ap->a_vpp, LK_EXCLUSIVE); 1258 if (error) { 1259 vrele(*ap->a_vpp); 1260 *ap->a_vpp = NULL; 1261 goto out; 1262 } 1263 error = UFS_WAPBL_BEGIN(ap->a_dvp->v_mount); 1264 if (error) { 1265 vput(*ap->a_vpp); 1266 goto out; 1267 } 1268 1269 tvp = *ap->a_vpp; 1270 ip = VTOI(tvp); 1271 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 1272 ip->i_nlink = 2; 1273 DIP_ASSIGN(ip, nlink, 2); 1274 if (cnp->cn_flags & ISWHITEOUT) { 1275 ip->i_flags |= UF_OPAQUE; 1276 DIP_ASSIGN(ip, flags, ip->i_flags); 1277 } 1278 1279 /* 1280 * Bump link count in parent directory to reflect work done below. 1281 * Should be done before reference is created so cleanup is 1282 * possible if we crash. 1283 */ 1284 dp->i_nlink++; 1285 DIP_ASSIGN(dp, nlink, dp->i_nlink); 1286 dp->i_flag |= IN_CHANGE; 1287 if ((error = UFS_UPDATE(dvp, NULL, NULL, UPDATE_DIROP)) != 0) 1288 goto bad; 1289 1290 #ifdef UFS_ACL 1291 mode_t dmode = (vap->va_mode & 0777) | IFDIR; 1292 struct lwp *l = curlwp; 1293 if (dvp->v_mount->mnt_flag & MNT_POSIX1EACLS) { 1294 1295 error = ufs_do_posix1e_acl_inheritance_dir(dvp, tvp, dmode, 1296 cnp->cn_cred, l); 1297 if (error) 1298 goto bad; 1299 } else if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { 1300 error = ufs_do_nfs4_acl_inheritance(dvp, tvp, dmode, 1301 cnp->cn_cred, l); 1302 if (error) 1303 goto bad; 1304 } 1305 #endif /* !UFS_ACL */ 1306 1307 /* 1308 * Initialize directory with "." and ".." from static template. 1309 */ 1310 dirtemplate = mastertemplate; 1311 dirtemplate.dotdot_reclen = dirblksiz - dirtemplate.dot_reclen; 1312 dirtemplate.dot_ino = ufs_rw32(ip->i_number, UFS_MPNEEDSWAP(ump)); 1313 dirtemplate.dotdot_ino = ufs_rw32(dp->i_number, UFS_MPNEEDSWAP(ump)); 1314 dirtemplate.dot_reclen = ufs_rw16(dirtemplate.dot_reclen, 1315 UFS_MPNEEDSWAP(ump)); 1316 dirtemplate.dotdot_reclen = ufs_rw16(dirtemplate.dotdot_reclen, 1317 UFS_MPNEEDSWAP(ump)); 1318 if (ump->um_maxsymlinklen <= 0) { 1319 #if BYTE_ORDER == LITTLE_ENDIAN 1320 if (UFS_MPNEEDSWAP(ump) == 0) 1321 #else 1322 if (UFS_MPNEEDSWAP(ump) != 0) 1323 #endif 1324 { 1325 dirtemplate.dot_type = dirtemplate.dot_namlen; 1326 dirtemplate.dotdot_type = dirtemplate.dotdot_namlen; 1327 dirtemplate.dot_namlen = dirtemplate.dotdot_namlen = 0; 1328 } else 1329 dirtemplate.dot_type = dirtemplate.dotdot_type = 0; 1330 } 1331 if ((error = UFS_BALLOC(tvp, (off_t)0, dirblksiz, cnp->cn_cred, 1332 B_CLRBUF, &bp)) != 0) 1333 goto bad; 1334 ip->i_size = dirblksiz; 1335 DIP_ASSIGN(ip, size, dirblksiz); 1336 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 1337 uvm_vnp_setsize(tvp, ip->i_size); 1338 memcpy((void *)bp->b_data, (void *)&dirtemplate, sizeof dirtemplate); 1339 1340 /* 1341 * Directory set up, now install its entry in the parent directory. 1342 * We must write out the buffer containing the new directory body 1343 * before entering the new name in the parent. 1344 */ 1345 if ((error = VOP_BWRITE(bp->b_vp, bp)) != 0) 1346 goto bad; 1347 if ((error = UFS_UPDATE(tvp, NULL, NULL, UPDATE_DIROP)) != 0) { 1348 goto bad; 1349 } 1350 newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK); 1351 ufs_makedirentry(ip, cnp, newdir); 1352 error = ufs_direnter(dvp, ulr, tvp, newdir, cnp, bp); 1353 pool_cache_put(ufs_direct_cache, newdir); 1354 bad: 1355 if (error == 0) { 1356 VOP_UNLOCK(tvp); 1357 UFS_WAPBL_END(dvp->v_mount); 1358 } else { 1359 dp->i_nlink--; 1360 DIP_ASSIGN(dp, nlink, dp->i_nlink); 1361 dp->i_flag |= IN_CHANGE; 1362 UFS_WAPBL_UPDATE(dvp, NULL, NULL, UPDATE_DIROP); 1363 /* 1364 * No need to do an explicit UFS_TRUNCATE here, vrele will 1365 * do this for us because we set the link count to 0. 1366 */ 1367 ip->i_nlink = 0; 1368 DIP_ASSIGN(ip, nlink, 0); 1369 ip->i_flag |= IN_CHANGE; 1370 UFS_WAPBL_UPDATE(tvp, NULL, NULL, UPDATE_DIROP); 1371 UFS_WAPBL_END(dvp->v_mount); 1372 vput(tvp); 1373 } 1374 out: 1375 return (error); 1376 } 1377 1378 int 1379 ufs_rmdir(void *v) 1380 { 1381 struct vop_rmdir_v2_args /* { 1382 struct vnode *a_dvp; 1383 struct vnode *a_vp; 1384 struct componentname *a_cnp; 1385 } */ *ap = v; 1386 struct vnode *vp, *dvp; 1387 struct componentname *cnp; 1388 struct inode *ip, *dp; 1389 int error; 1390 struct ufs_lookup_results *ulr; 1391 1392 vp = ap->a_vp; 1393 dvp = ap->a_dvp; 1394 cnp = ap->a_cnp; 1395 ip = VTOI(vp); 1396 dp = VTOI(dvp); 1397 1398 #ifdef UFS_ACL 1399 #ifdef notyet 1400 /* We don't do this because if the filesystem is mounted without ACLs 1401 * this goes through vfs_unixify_accmode() and we get EPERM. 1402 */ 1403 error = VOP_ACCESSX(vp, VDELETE, cnp->cn_cred); 1404 if (error) 1405 goto err; 1406 #endif 1407 #endif 1408 1409 /* XXX should handle this material another way */ 1410 ulr = &dp->i_crap; 1411 UFS_CHECK_CRAPCOUNTER(dp); 1412 1413 /* 1414 * No rmdir "." or of mounted directories please. 1415 */ 1416 if (dp == ip || vp->v_mountedhere != NULL) { 1417 error = EINVAL; 1418 goto err; 1419 } 1420 1421 /* 1422 * Do not remove a directory that is in the process of being renamed. 1423 * Verify that the directory is empty (and valid). (Rmdir ".." won't 1424 * be valid since ".." will contain a reference to the current 1425 * directory and thus be non-empty.) 1426 */ 1427 error = 0; 1428 if (ip->i_nlink != 2 || 1429 !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) { 1430 error = ENOTEMPTY; 1431 goto out; 1432 } 1433 if ((dp->i_flags & APPEND) || 1434 (ip->i_flags & (IMMUTABLE | APPEND))) { 1435 error = EPERM; 1436 goto out; 1437 } 1438 error = UFS_WAPBL_BEGIN(dvp->v_mount); 1439 if (error) 1440 goto out; 1441 /* 1442 * Delete reference to directory before purging 1443 * inode. If we crash in between, the directory 1444 * will be reattached to lost+found, 1445 */ 1446 error = ufs_dirremove(dvp, ulr, ip, cnp->cn_flags, 1); 1447 if (error) { 1448 UFS_WAPBL_END(dvp->v_mount); 1449 goto out; 1450 } 1451 cache_purge(dvp); 1452 /* 1453 * Truncate inode. The only stuff left in the directory is "." and 1454 * "..". The "." reference is inconsequential since we're quashing 1455 * it. 1456 */ 1457 dp->i_nlink--; 1458 DIP_ASSIGN(dp, nlink, dp->i_nlink); 1459 dp->i_flag |= IN_CHANGE; 1460 UFS_WAPBL_UPDATE(dvp, NULL, NULL, UPDATE_DIROP); 1461 ip->i_nlink--; 1462 DIP_ASSIGN(ip, nlink, ip->i_nlink); 1463 ip->i_flag |= IN_CHANGE; 1464 (void) UFS_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred); 1465 cache_purge(vp); 1466 /* 1467 * Unlock the log while we still have reference to unlinked 1468 * directory vp so that it will not get locked for recycling 1469 */ 1470 UFS_WAPBL_END(dvp->v_mount); 1471 #ifdef UFS_DIRHASH 1472 if (ip->i_dirhash != NULL) 1473 ufsdirhash_free(ip); 1474 #endif 1475 out: 1476 vput(vp); 1477 return error; 1478 err: 1479 if (dp == ip) 1480 vrele(vp); 1481 else 1482 vput(vp); 1483 return error; 1484 } 1485 1486 /* 1487 * symlink -- make a symbolic link 1488 */ 1489 int 1490 ufs_symlink(void *v) 1491 { 1492 struct vop_symlink_v3_args /* { 1493 struct vnode *a_dvp; 1494 struct vnode **a_vpp; 1495 struct componentname *a_cnp; 1496 struct vattr *a_vap; 1497 char *a_target; 1498 } */ *ap = v; 1499 struct vnode *vp, **vpp; 1500 struct inode *ip; 1501 int len, error; 1502 struct ufs_lookup_results *ulr; 1503 1504 vpp = ap->a_vpp; 1505 1506 /* XXX should handle this material another way */ 1507 ulr = &VTOI(ap->a_dvp)->i_crap; 1508 UFS_CHECK_CRAPCOUNTER(VTOI(ap->a_dvp)); 1509 1510 /* 1511 * UFS_WAPBL_BEGIN(dvp->v_mount) performed by successful 1512 * ufs_makeinode 1513 */ 1514 KASSERT(ap->a_vap->va_type == VLNK); 1515 error = ufs_makeinode(ap->a_vap, ap->a_dvp, ulr, vpp, ap->a_cnp); 1516 if (error) 1517 goto out; 1518 vp = *vpp; 1519 len = strlen(ap->a_target); 1520 ip = VTOI(vp); 1521 /* 1522 * This test is off by one. um_maxsymlinklen contains the 1523 * number of bytes available, and we aren't storing a \0, so 1524 * the test should properly be <=. However, it cannot be 1525 * changed as this would break compatibility with existing fs 1526 * images -- see the way ufs_readlink() works. 1527 */ 1528 if (len < ip->i_ump->um_maxsymlinklen) { 1529 memcpy((char *)SHORTLINK(ip), ap->a_target, len); 1530 ip->i_size = len; 1531 DIP_ASSIGN(ip, size, len); 1532 uvm_vnp_setsize(vp, ip->i_size); 1533 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1534 if (vp->v_mount->mnt_flag & MNT_RELATIME) 1535 ip->i_flag |= IN_ACCESS; 1536 UFS_WAPBL_UPDATE(vp, NULL, NULL, 0); 1537 } else 1538 error = ufs_bufio(UIO_WRITE, vp, ap->a_target, len, (off_t)0, 1539 IO_NODELOCKED | IO_JOURNALLOCKED, ap->a_cnp->cn_cred, NULL, 1540 NULL); 1541 UFS_WAPBL_END(ap->a_dvp->v_mount); 1542 VOP_UNLOCK(vp); 1543 if (error) 1544 vrele(vp); 1545 out: 1546 return (error); 1547 } 1548 1549 /* 1550 * Vnode op for reading directories. 1551 * 1552 * This routine handles converting from the on-disk directory format 1553 * "struct direct" to the in-memory format "struct dirent" as well as 1554 * byte swapping the entries if necessary. 1555 */ 1556 int 1557 ufs_readdir(void *v) 1558 { 1559 struct vop_readdir_args /* { 1560 struct vnode *a_vp; 1561 struct uio *a_uio; 1562 kauth_cred_t a_cred; 1563 int *a_eofflag; 1564 off_t **a_cookies; 1565 int *a_ncookies; 1566 } */ *ap = v; 1567 1568 /* vnode and fs */ 1569 struct vnode *vp = ap->a_vp; 1570 struct ufsmount *ump = VFSTOUFS(vp->v_mount); 1571 int nswap = UFS_MPNEEDSWAP(ump); 1572 #if BYTE_ORDER == LITTLE_ENDIAN 1573 int needswap = ump->um_maxsymlinklen <= 0 && nswap == 0; 1574 #else 1575 int needswap = ump->um_maxsymlinklen <= 0 && nswap != 0; 1576 #endif 1577 /* caller's buffer */ 1578 struct uio *calleruio = ap->a_uio; 1579 off_t startoffset, endoffset; 1580 size_t callerbytes; 1581 off_t curoffset; 1582 /* dirent production buffer */ 1583 char *direntbuf; 1584 size_t direntbufmax; 1585 struct dirent *dirent, *stopdirent; 1586 /* output cookies array */ 1587 off_t *cookies; 1588 size_t numcookies, maxcookies; 1589 /* disk buffer */ 1590 off_t physstart, physend; 1591 size_t skipstart, dropend; 1592 char *rawbuf; 1593 size_t rawbufmax, rawbytes; 1594 struct uio rawuio; 1595 struct iovec rawiov; 1596 struct direct *rawdp, *stoprawdp; 1597 /* general */ 1598 int error; 1599 1600 KASSERT(VOP_ISLOCKED(vp)); 1601 1602 /* 1603 * Figure out where the user wants us to read and how much. 1604 * 1605 * XXX: there should probably be an upper bound on callerbytes 1606 * to avoid silliness trying to do large kernel allocations. 1607 */ 1608 callerbytes = calleruio->uio_resid; 1609 startoffset = calleruio->uio_offset; 1610 endoffset = startoffset + callerbytes; 1611 1612 if (callerbytes < _DIRENT_MINSIZE(dirent)) { 1613 /* no room for even one struct dirent */ 1614 return EINVAL; 1615 } 1616 1617 /* 1618 * Now figure out where to actually start reading. Round the 1619 * start down to a block boundary: we need to start at the 1620 * beginning of a block in order to read the directory 1621 * correctly. 1622 * 1623 * We also want to always read a whole number of blocks so 1624 * that the copying code below doesn't have to worry about 1625 * partial entries. (It used to try at one point, and was a 1626 * horrible mess.) 1627 * 1628 * Furthermore, since blocks have to be scanned from the 1629 * beginning, if we go partially into another block now we'll 1630 * just have to rescan it on the next readdir call, which 1631 * doesn't really serve any useful purpose. 1632 * 1633 * So, round down the end as well. It's ok to underpopulate 1634 * the transfer buffer, as long as we send back at least one 1635 * dirent so as to avoid giving a bogus EOF indication. 1636 * 1637 * Note that because dirents are larger than ffs struct 1638 * directs, despite the rounding down we may not be able to 1639 * send all the entries in the blocks we read and may have to 1640 * rescan some of them on the next call anyway. Alternatively 1641 * if there's empty space on disk we might have actually been 1642 * able to fit the next block in, and so forth. None of this 1643 * actually matters that much in practice. 1644 * 1645 * XXX: what does ffs do if a directory block becomes 1646 * completely empty, and what happens if all the blocks we 1647 * read are completely empty even though we aren't at EOF? As 1648 * of this writing I (dholland) can't remember the details. 1649 */ 1650 physstart = rounddown2(startoffset, ump->um_dirblksiz); 1651 physend = rounddown2(endoffset, ump->um_dirblksiz); 1652 1653 if (physstart >= physend) { 1654 /* Need at least one block */ 1655 return EINVAL; 1656 } 1657 1658 /* 1659 * skipstart is the number of bytes we need to read in 1660 * (because we need to start at the beginning of a block) but 1661 * not transfer to the user. 1662 * 1663 * dropend is the number of bytes to ignore at the end of the 1664 * user's buffer. 1665 */ 1666 skipstart = startoffset - physstart; 1667 dropend = endoffset - physend; 1668 1669 /* 1670 * Make a transfer buffer. 1671 * 1672 * Note: rawbufmax = physend - physstart. Proof: 1673 * 1674 * physend - physstart = physend - physstart 1675 * = physend - physstart + startoffset - startoffset 1676 * = physend + (startoffset - physstart) - startoffset 1677 * = physend + skipstart - startoffset 1678 * = physend + skipstart - startoffset + endoffset - endoffset 1679 * = skipstart - startoffset + endoffset - (endoffset - physend) 1680 * = skipstart - startoffset + endoffset - dropend 1681 * = skipstart - startoffset + (startoffset + callerbytes) - dropend 1682 * = skipstart + callerbytes - dropend 1683 * = rawbufmax 1684 * Qed. 1685 * 1686 * XXX: this should just use physend - physstart. 1687 * 1688 * XXX: this should be rewritten to read the directs straight 1689 * out of bufferio buffers instead of copying twice. This would 1690 * also let us adapt better to the user's buffer size. 1691 */ 1692 1693 /* Base buffer space for CALLERBYTES of new data */ 1694 rawbufmax = callerbytes + skipstart; 1695 if (rawbufmax < callerbytes) 1696 return EINVAL; 1697 rawbufmax -= dropend; 1698 1699 if (rawbufmax < _DIRENT_MINSIZE(rawdp)) { 1700 /* no room for even one struct direct */ 1701 return EINVAL; 1702 } 1703 1704 /* read it */ 1705 rawbuf = kmem_alloc(rawbufmax, KM_SLEEP); 1706 rawiov.iov_base = rawbuf; 1707 rawiov.iov_len = rawbufmax; 1708 rawuio.uio_iov = &rawiov; 1709 rawuio.uio_iovcnt = 1; 1710 rawuio.uio_offset = physstart; 1711 rawuio.uio_resid = rawbufmax; 1712 UIO_SETUP_SYSSPACE(&rawuio); 1713 rawuio.uio_rw = UIO_READ; 1714 error = UFS_BUFRD(vp, &rawuio, 0, ap->a_cred); 1715 if (error != 0) { 1716 kmem_free(rawbuf, rawbufmax); 1717 return error; 1718 } 1719 rawbytes = rawbufmax - rawuio.uio_resid; 1720 1721 /* the raw entries to iterate over */ 1722 rawdp = (struct direct *)(void *)rawbuf; 1723 stoprawdp = (struct direct *)(void *)&rawbuf[rawbytes]; 1724 1725 /* allocate space to produce dirents into */ 1726 direntbufmax = callerbytes; 1727 direntbuf = kmem_alloc(direntbufmax, KM_SLEEP); 1728 1729 /* the dirents to iterate over */ 1730 dirent = (struct dirent *)(void *)direntbuf; 1731 stopdirent = (struct dirent *)(void *)&direntbuf[direntbufmax]; 1732 1733 /* the output "cookies" (seek positions of directory entries) */ 1734 if (ap->a_cookies) { 1735 numcookies = 0; 1736 maxcookies = rawbytes / _DIRENT_RECLEN(rawdp, 1); 1737 cookies = malloc(maxcookies * sizeof(*cookies), 1738 M_TEMP, M_WAITOK); 1739 } else { 1740 /* XXX: GCC */ 1741 maxcookies = 0; 1742 cookies = NULL; 1743 } 1744 1745 /* now produce the dirents */ 1746 curoffset = calleruio->uio_offset; 1747 while (rawdp < stoprawdp) { 1748 rawdp->d_reclen = ufs_rw16(rawdp->d_reclen, nswap); 1749 if (skipstart > 0) { 1750 /* drain skipstart */ 1751 if (rawdp->d_reclen <= skipstart) { 1752 skipstart -= rawdp->d_reclen; 1753 rawdp = _DIRENT_NEXT(rawdp); 1754 continue; 1755 } 1756 /* caller's start position wasn't on an entry */ 1757 error = EINVAL; 1758 goto out; 1759 } 1760 if (rawdp->d_reclen == 0) { 1761 struct dirent *save = dirent; 1762 dirent->d_reclen = _DIRENT_MINSIZE(dirent); 1763 dirent = _DIRENT_NEXT(dirent); 1764 save->d_reclen = 0; 1765 rawdp = stoprawdp; 1766 break; 1767 } 1768 1769 /* copy the header */ 1770 if (needswap) { 1771 dirent->d_type = rawdp->d_namlen; 1772 dirent->d_namlen = rawdp->d_type; 1773 } else { 1774 dirent->d_type = rawdp->d_type; 1775 dirent->d_namlen = rawdp->d_namlen; 1776 } 1777 dirent->d_reclen = _DIRENT_RECLEN(dirent, dirent->d_namlen); 1778 1779 /* stop if there isn't room for the name AND another header */ 1780 if ((char *)(void *)dirent + dirent->d_reclen + 1781 _DIRENT_MINSIZE(dirent) > (char *)(void *)stopdirent) 1782 break; 1783 1784 /* copy the name (and inode (XXX: why after the test?)) */ 1785 dirent->d_fileno = ufs_rw32(rawdp->d_ino, nswap); 1786 (void)memcpy(dirent->d_name, rawdp->d_name, dirent->d_namlen); 1787 memset(&dirent->d_name[dirent->d_namlen], 0, 1788 dirent->d_reclen - _DIRENT_NAMEOFF(dirent) 1789 - dirent->d_namlen); 1790 1791 /* onward */ 1792 curoffset += rawdp->d_reclen; 1793 if (ap->a_cookies) { 1794 KASSERT(numcookies < maxcookies); 1795 cookies[numcookies++] = curoffset; 1796 } 1797 dirent = _DIRENT_NEXT(dirent); 1798 rawdp = _DIRENT_NEXT(rawdp); 1799 } 1800 1801 /* transfer the dirents to the caller's buffer */ 1802 callerbytes = ((char *)(void *)dirent - direntbuf); 1803 error = uiomove(direntbuf, callerbytes, calleruio); 1804 1805 out: 1806 calleruio->uio_offset = curoffset; 1807 if (ap->a_cookies) { 1808 if (error) { 1809 free(cookies, M_TEMP); 1810 *ap->a_cookies = NULL; 1811 *ap->a_ncookies = 0; 1812 } else { 1813 *ap->a_cookies = cookies; 1814 *ap->a_ncookies = numcookies; 1815 } 1816 } 1817 kmem_free(direntbuf, direntbufmax); 1818 kmem_free(rawbuf, rawbufmax); 1819 *ap->a_eofflag = VTOI(vp)->i_size <= calleruio->uio_offset; 1820 return error; 1821 } 1822 1823 /* 1824 * Return target name of a symbolic link 1825 */ 1826 int 1827 ufs_readlink(void *v) 1828 { 1829 struct vop_readlink_args /* { 1830 struct vnode *a_vp; 1831 struct uio *a_uio; 1832 kauth_cred_t a_cred; 1833 } */ *ap = v; 1834 struct vnode *vp = ap->a_vp; 1835 struct inode *ip = VTOI(vp); 1836 struct ufsmount *ump = VFSTOUFS(vp->v_mount); 1837 int isize; 1838 1839 /* 1840 * The test against um_maxsymlinklen is off by one; it should 1841 * theoretically be <=, not <. However, it cannot be changed 1842 * as that would break compatibility with existing fs images. 1843 */ 1844 1845 isize = ip->i_size; 1846 if (isize < ump->um_maxsymlinklen || 1847 (ump->um_maxsymlinklen == 0 && DIP(ip, blocks) == 0)) { 1848 uiomove((char *)SHORTLINK(ip), isize, ap->a_uio); 1849 return (0); 1850 } 1851 return (UFS_BUFRD(vp, ap->a_uio, 0, ap->a_cred)); 1852 } 1853 1854 /* 1855 * Calculate the logical to physical mapping if not done already, 1856 * then call the device strategy routine. 1857 */ 1858 int 1859 ufs_strategy(void *v) 1860 { 1861 struct vop_strategy_args /* { 1862 struct vnode *a_vp; 1863 struct buf *a_bp; 1864 } */ *ap = v; 1865 struct buf *bp; 1866 struct vnode *vp; 1867 struct inode *ip; 1868 struct mount *mp; 1869 int error; 1870 1871 bp = ap->a_bp; 1872 vp = ap->a_vp; 1873 ip = VTOI(vp); 1874 if (vp->v_type == VBLK || vp->v_type == VCHR) 1875 panic("ufs_strategy: spec"); 1876 KASSERT(fstrans_held(vp->v_mount)); 1877 KASSERT(bp->b_bcount != 0); 1878 if (bp->b_blkno == bp->b_lblkno) { 1879 error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, 1880 NULL); 1881 if (error) { 1882 bp->b_error = error; 1883 biodone(bp); 1884 return (error); 1885 } 1886 if (bp->b_blkno == -1) /* no valid data */ 1887 clrbuf(bp); 1888 } 1889 if (bp->b_blkno < 0) { /* block is not on disk */ 1890 biodone(bp); 1891 return (0); 1892 } 1893 vp = ip->i_devvp; 1894 1895 error = VOP_STRATEGY(vp, bp); 1896 if (error) 1897 return error; 1898 1899 if (!BUF_ISREAD(bp)) 1900 return 0; 1901 1902 mp = wapbl_vptomp(vp); 1903 if (mp == NULL || mp->mnt_wapbl_replay == NULL || 1904 !WAPBL_REPLAY_ISOPEN(mp) || 1905 !WAPBL_REPLAY_CAN_READ(mp, bp->b_blkno, bp->b_bcount)) 1906 return 0; 1907 1908 error = biowait(bp); 1909 if (error) 1910 return error; 1911 1912 error = WAPBL_REPLAY_READ(mp, bp->b_data, bp->b_blkno, bp->b_bcount); 1913 if (error) { 1914 mutex_enter(&bufcache_lock); 1915 SET(bp->b_cflags, BC_INVAL); 1916 mutex_exit(&bufcache_lock); 1917 } 1918 return error; 1919 } 1920 1921 /* 1922 * Print out the contents of an inode. 1923 */ 1924 int 1925 ufs_print(void *v) 1926 { 1927 struct vop_print_args /* { 1928 struct vnode *a_vp; 1929 } */ *ap = v; 1930 struct vnode *vp; 1931 struct inode *ip; 1932 1933 vp = ap->a_vp; 1934 ip = VTOI(vp); 1935 printf("tag VT_UFS, ino %llu, on dev %llu, %llu", 1936 (unsigned long long)ip->i_number, 1937 (unsigned long long)major(ip->i_dev), 1938 (unsigned long long)minor(ip->i_dev)); 1939 printf(" flags 0x%x, nlink %d\n", 1940 ip->i_flag, ip->i_nlink); 1941 printf("\tmode 0%o, owner %d, group %d, size %qd", 1942 ip->i_mode, ip->i_uid, ip->i_gid, 1943 (long long)ip->i_size); 1944 if (vp->v_type == VFIFO) 1945 VOCALL(fifo_vnodeop_p, VOFFSET(vop_print), v); 1946 printf("\n"); 1947 return (0); 1948 } 1949 1950 /* 1951 * Read wrapper for special devices. 1952 */ 1953 int 1954 ufsspec_read(void *v) 1955 { 1956 struct vop_read_args /* { 1957 struct vnode *a_vp; 1958 struct uio *a_uio; 1959 int a_ioflag; 1960 kauth_cred_t a_cred; 1961 } */ *ap = v; 1962 1963 /* 1964 * Set access flag. 1965 */ 1966 if ((ap->a_vp->v_mount->mnt_flag & MNT_NODEVMTIME) == 0) 1967 VTOI(ap->a_vp)->i_flag |= IN_ACCESS; 1968 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_read), ap)); 1969 } 1970 1971 /* 1972 * Write wrapper for special devices. 1973 */ 1974 int 1975 ufsspec_write(void *v) 1976 { 1977 struct vop_write_args /* { 1978 struct vnode *a_vp; 1979 struct uio *a_uio; 1980 int a_ioflag; 1981 kauth_cred_t a_cred; 1982 } */ *ap = v; 1983 1984 /* 1985 * Set update and change flags. 1986 */ 1987 if ((ap->a_vp->v_mount->mnt_flag & MNT_NODEVMTIME) == 0) 1988 VTOI(ap->a_vp)->i_flag |= IN_MODIFY; 1989 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_write), ap)); 1990 } 1991 1992 /* 1993 * Close wrapper for special devices. 1994 * 1995 * Update the times on the inode then do device close. 1996 */ 1997 int 1998 ufsspec_close(void *v) 1999 { 2000 struct vop_close_args /* { 2001 struct vnode *a_vp; 2002 int a_fflag; 2003 kauth_cred_t a_cred; 2004 } */ *ap = v; 2005 struct vnode *vp; 2006 2007 vp = ap->a_vp; 2008 if (vrefcnt(vp) > 1) 2009 UFS_ITIMES(vp, NULL, NULL, NULL); 2010 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap)); 2011 } 2012 2013 /* 2014 * Read wrapper for fifo's 2015 */ 2016 int 2017 ufsfifo_read(void *v) 2018 { 2019 struct vop_read_args /* { 2020 struct vnode *a_vp; 2021 struct uio *a_uio; 2022 int a_ioflag; 2023 kauth_cred_t a_cred; 2024 } */ *ap = v; 2025 2026 /* 2027 * Set access flag. 2028 */ 2029 VTOI(ap->a_vp)->i_flag |= IN_ACCESS; 2030 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_read), ap)); 2031 } 2032 2033 /* 2034 * Write wrapper for fifo's. 2035 */ 2036 int 2037 ufsfifo_write(void *v) 2038 { 2039 struct vop_write_args /* { 2040 struct vnode *a_vp; 2041 struct uio *a_uio; 2042 int a_ioflag; 2043 kauth_cred_t a_cred; 2044 } */ *ap = v; 2045 2046 /* 2047 * Set update and change flags. 2048 */ 2049 VTOI(ap->a_vp)->i_flag |= IN_MODIFY; 2050 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_write), ap)); 2051 } 2052 2053 /* 2054 * Close wrapper for fifo's. 2055 * 2056 * Update the times on the inode then do device close. 2057 */ 2058 int 2059 ufsfifo_close(void *v) 2060 { 2061 struct vop_close_args /* { 2062 struct vnode *a_vp; 2063 int a_fflag; 2064 kauth_cred_t a_cred; 2065 } */ *ap = v; 2066 struct vnode *vp; 2067 2068 vp = ap->a_vp; 2069 if (vrefcnt(ap->a_vp) > 1) 2070 UFS_ITIMES(vp, NULL, NULL, NULL); 2071 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap)); 2072 } 2073 2074 /* 2075 * Return POSIX pathconf information applicable to ufs filesystems. 2076 */ 2077 int 2078 ufs_pathconf(void *v) 2079 { 2080 struct vop_pathconf_args /* { 2081 struct vnode *a_vp; 2082 int a_name; 2083 register_t *a_retval; 2084 } */ *ap = v; 2085 2086 switch (ap->a_name) { 2087 case _PC_LINK_MAX: 2088 *ap->a_retval = LINK_MAX; 2089 return (0); 2090 case _PC_NAME_MAX: 2091 *ap->a_retval = FFS_MAXNAMLEN; 2092 return (0); 2093 case _PC_PATH_MAX: 2094 *ap->a_retval = PATH_MAX; 2095 return (0); 2096 case _PC_PIPE_BUF: 2097 *ap->a_retval = PIPE_BUF; 2098 return (0); 2099 case _PC_CHOWN_RESTRICTED: 2100 *ap->a_retval = 1; 2101 return (0); 2102 case _PC_NO_TRUNC: 2103 *ap->a_retval = 1; 2104 return (0); 2105 #ifdef UFS_ACL 2106 case _PC_ACL_EXTENDED: 2107 if (ap->a_vp->v_mount->mnt_flag & MNT_POSIX1EACLS) 2108 *ap->a_retval = 1; 2109 else 2110 *ap->a_retval = 0; 2111 return 0; 2112 case _PC_ACL_NFS4: 2113 if (ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) 2114 *ap->a_retval = 1; 2115 else 2116 *ap->a_retval = 0; 2117 return 0; 2118 #endif 2119 case _PC_ACL_PATH_MAX: 2120 #ifdef UFS_ACL 2121 if (ap->a_vp->v_mount->mnt_flag & (MNT_POSIX1EACLS | MNT_NFS4ACLS)) 2122 *ap->a_retval = ACL_MAX_ENTRIES; 2123 else 2124 *ap->a_retval = 3; 2125 #else 2126 *ap->a_retval = 3; 2127 #endif 2128 return 0; 2129 case _PC_SYNC_IO: 2130 *ap->a_retval = 1; 2131 return (0); 2132 case _PC_FILESIZEBITS: 2133 *ap->a_retval = 42; 2134 return (0); 2135 case _PC_SYMLINK_MAX: 2136 *ap->a_retval = MAXPATHLEN; 2137 return (0); 2138 case _PC_2_SYMLINKS: 2139 *ap->a_retval = 1; 2140 return (0); 2141 default: 2142 return (EINVAL); 2143 } 2144 /* NOTREACHED */ 2145 } 2146 2147 /* 2148 * Advisory record locking support 2149 */ 2150 int 2151 ufs_advlock(void *v) 2152 { 2153 struct vop_advlock_args /* { 2154 struct vnode *a_vp; 2155 void * a_id; 2156 int a_op; 2157 struct flock *a_fl; 2158 int a_flags; 2159 } */ *ap = v; 2160 struct inode *ip; 2161 2162 ip = VTOI(ap->a_vp); 2163 return lf_advlock(ap, &ip->i_lockf, ip->i_size); 2164 } 2165 2166 /* 2167 * Initialize the vnode associated with a new inode, handle aliased 2168 * vnodes. 2169 */ 2170 void 2171 ufs_vinit(struct mount *mntp, int (**specops)(void *), int (**fifoops)(void *), 2172 struct vnode **vpp) 2173 { 2174 struct timeval tv; 2175 struct inode *ip; 2176 struct vnode *vp; 2177 dev_t rdev; 2178 struct ufsmount *ump; 2179 2180 vp = *vpp; 2181 ip = VTOI(vp); 2182 switch(vp->v_type = IFTOVT(ip->i_mode)) { 2183 case VCHR: 2184 case VBLK: 2185 vp->v_op = specops; 2186 ump = ip->i_ump; 2187 if (ump->um_fstype == UFS1) 2188 rdev = (dev_t)ufs_rw32(ip->i_ffs1_rdev, 2189 UFS_MPNEEDSWAP(ump)); 2190 else 2191 rdev = (dev_t)ufs_rw64(ip->i_ffs2_rdev, 2192 UFS_MPNEEDSWAP(ump)); 2193 spec_node_init(vp, rdev); 2194 break; 2195 case VFIFO: 2196 vp->v_op = fifoops; 2197 break; 2198 case VNON: 2199 case VBAD: 2200 case VSOCK: 2201 case VLNK: 2202 case VDIR: 2203 case VREG: 2204 break; 2205 } 2206 if (ip->i_number == UFS_ROOTINO) 2207 vp->v_vflag |= VV_ROOT; 2208 /* 2209 * Initialize modrev times 2210 */ 2211 getmicrouptime(&tv); 2212 ip->i_modrev = (uint64_t)(uint)tv.tv_sec << 32 2213 | tv.tv_usec * 4294u; 2214 *vpp = vp; 2215 } 2216 2217 /* 2218 * Allocate a new inode. 2219 */ 2220 static int 2221 ufs_makeinode(struct vattr *vap, struct vnode *dvp, 2222 const struct ufs_lookup_results *ulr, 2223 struct vnode **vpp, struct componentname *cnp) 2224 { 2225 struct inode *ip; 2226 struct direct *newdir; 2227 struct vnode *tvp; 2228 int error; 2229 2230 UFS_WAPBL_JUNLOCK_ASSERT(dvp->v_mount); 2231 2232 error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, NULL, &tvp); 2233 if (error) 2234 return error; 2235 error = vn_lock(tvp, LK_EXCLUSIVE); 2236 if (error) { 2237 vrele(tvp); 2238 return error; 2239 } 2240 *vpp = tvp; 2241 ip = VTOI(tvp); 2242 error = UFS_WAPBL_BEGIN(dvp->v_mount); 2243 if (error) { 2244 vput(tvp); 2245 return (error); 2246 } 2247 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 2248 ip->i_nlink = 1; 2249 DIP_ASSIGN(ip, nlink, 1); 2250 2251 /* Authorize setting SGID if needed. */ 2252 if (ip->i_mode & ISGID) { 2253 error = kauth_authorize_vnode(cnp->cn_cred, 2254 KAUTH_VNODE_WRITE_SECURITY, 2255 tvp, NULL, genfs_can_chmod(tvp, cnp->cn_cred, ip->i_uid, 2256 ip->i_gid, MAKEIMODE(vap->va_type, vap->va_mode))); 2257 if (error) { 2258 ip->i_mode &= ~ISGID; 2259 DIP_ASSIGN(ip, mode, ip->i_mode); 2260 } 2261 } 2262 2263 if (cnp->cn_flags & ISWHITEOUT) { 2264 ip->i_flags |= UF_OPAQUE; 2265 DIP_ASSIGN(ip, flags, ip->i_flags); 2266 } 2267 2268 /* 2269 * Make sure inode goes to disk before directory entry. 2270 */ 2271 if ((error = UFS_UPDATE(tvp, NULL, NULL, UPDATE_DIROP)) != 0) 2272 goto bad; 2273 #ifdef UFS_ACL 2274 struct lwp *l = curlwp; 2275 if (dvp->v_mount->mnt_flag & MNT_POSIX1EACLS) { 2276 error = ufs_do_posix1e_acl_inheritance_file(dvp, tvp, 2277 ip->i_mode, cnp->cn_cred, l); 2278 if (error) 2279 goto bad; 2280 } else if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) { 2281 error = ufs_do_nfs4_acl_inheritance(dvp, tvp, ip->i_mode, 2282 cnp->cn_cred, l); 2283 if (error) 2284 goto bad; 2285 } 2286 #endif /* !UFS_ACL */ 2287 newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK); 2288 ufs_makedirentry(ip, cnp, newdir); 2289 error = ufs_direnter(dvp, ulr, tvp, newdir, cnp, NULL); 2290 pool_cache_put(ufs_direct_cache, newdir); 2291 if (error) 2292 goto bad; 2293 *vpp = tvp; 2294 cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags); 2295 return (0); 2296 2297 bad: 2298 /* 2299 * Write error occurred trying to update the inode 2300 * or the directory so must deallocate the inode. 2301 */ 2302 ip->i_nlink = 0; 2303 DIP_ASSIGN(ip, nlink, 0); 2304 ip->i_flag |= IN_CHANGE; 2305 UFS_WAPBL_UPDATE(tvp, NULL, NULL, 0); 2306 UFS_WAPBL_END(dvp->v_mount); 2307 vput(tvp); 2308 return (error); 2309 } 2310 2311 /* 2312 * Allocate len bytes at offset off. 2313 */ 2314 int 2315 ufs_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, 2316 kauth_cred_t cred) 2317 { 2318 struct inode *ip = VTOI(vp); 2319 int error, delta, bshift, bsize; 2320 UVMHIST_FUNC("ufs_gop_alloc"); UVMHIST_CALLED(ubchist); 2321 2322 error = 0; 2323 bshift = vp->v_mount->mnt_fs_bshift; 2324 bsize = 1 << bshift; 2325 2326 delta = off & (bsize - 1); 2327 off -= delta; 2328 len += delta; 2329 2330 while (len > 0) { 2331 bsize = MIN(bsize, len); 2332 2333 error = UFS_BALLOC(vp, off, bsize, cred, flags, NULL); 2334 if (error) { 2335 goto out; 2336 } 2337 2338 /* 2339 * increase file size now, UFS_BALLOC() requires that 2340 * EOF be up-to-date before each call. 2341 */ 2342 2343 if (ip->i_size < off + bsize) { 2344 UVMHIST_LOG(ubchist, "vp %#jx old 0x%jx new 0x%x", 2345 (uintptr_t)vp, ip->i_size, off + bsize, 0); 2346 ip->i_size = off + bsize; 2347 DIP_ASSIGN(ip, size, ip->i_size); 2348 } 2349 2350 off += bsize; 2351 len -= bsize; 2352 } 2353 2354 out: 2355 UFS_WAPBL_UPDATE(vp, NULL, NULL, 0); 2356 return error; 2357 } 2358 2359 void 2360 ufs_gop_markupdate(struct vnode *vp, int flags) 2361 { 2362 u_int32_t mask = 0; 2363 2364 if ((flags & GOP_UPDATE_ACCESSED) != 0) { 2365 mask = IN_ACCESS; 2366 } 2367 if ((flags & GOP_UPDATE_MODIFIED) != 0) { 2368 if (vp->v_type == VREG) { 2369 mask |= IN_CHANGE | IN_UPDATE; 2370 } else { 2371 mask |= IN_MODIFY; 2372 } 2373 } 2374 if (mask) { 2375 struct inode *ip = VTOI(vp); 2376 2377 ip->i_flag |= mask; 2378 } 2379 } 2380 2381 int 2382 ufs_bufio(enum uio_rw rw, struct vnode *vp, void *buf, size_t len, off_t off, 2383 int ioflg, kauth_cred_t cred, size_t *aresid, struct lwp *l) 2384 { 2385 struct iovec iov; 2386 struct uio uio; 2387 int error; 2388 2389 KASSERT(ISSET(ioflg, IO_NODELOCKED)); 2390 KASSERT(VOP_ISLOCKED(vp)); 2391 KASSERT(rw != UIO_WRITE || VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 2392 KASSERT(rw != UIO_WRITE || vp->v_mount->mnt_wapbl == NULL || 2393 ISSET(ioflg, IO_JOURNALLOCKED)); 2394 2395 iov.iov_base = buf; 2396 iov.iov_len = len; 2397 uio.uio_iov = &iov; 2398 uio.uio_iovcnt = 1; 2399 uio.uio_resid = len; 2400 uio.uio_offset = off; 2401 uio.uio_rw = rw; 2402 UIO_SETUP_SYSSPACE(&uio); 2403 2404 switch (rw) { 2405 case UIO_READ: 2406 error = UFS_BUFRD(vp, &uio, ioflg, cred); 2407 break; 2408 case UIO_WRITE: 2409 error = UFS_BUFWR(vp, &uio, ioflg, cred); 2410 break; 2411 default: 2412 panic("invalid uio rw: %d", (int)rw); 2413 } 2414 2415 if (aresid) 2416 *aresid = uio.uio_resid; 2417 else if (uio.uio_resid && error == 0) 2418 error = EIO; 2419 2420 KASSERT(VOP_ISLOCKED(vp)); 2421 KASSERT(rw != UIO_WRITE || VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 2422 return error; 2423 } 2424