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