ufs_vnops.c revision 145138
1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, 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 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 35 */ 36 37#include <sys/cdefs.h> 38__FBSDID("$FreeBSD: head/sys/ufs/ufs/ufs_vnops.c 145138 2005-04-16 10:57:49Z pjd $"); 39 40#include "opt_mac.h" 41#include "opt_quota.h" 42#include "opt_suiddir.h" 43#include "opt_ufs.h" 44#include "opt_ffs.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/malloc.h> 49#include <sys/namei.h> 50#include <sys/kernel.h> 51#include <sys/fcntl.h> 52#include <sys/stat.h> 53#include <sys/bio.h> 54#include <sys/buf.h> 55#include <sys/mount.h> 56#include <sys/unistd.h> 57#include <sys/vnode.h> 58#include <sys/dirent.h> 59#include <sys/lockf.h> 60#include <sys/event.h> 61#include <sys/conf.h> 62#include <sys/acl.h> 63#include <sys/mac.h> 64#include <sys/jail.h> 65 66#include <machine/mutex.h> 67 68#include <sys/file.h> /* XXX */ 69 70#include <vm/vm.h> 71#include <vm/vm_extern.h> 72 73#include <fs/fifofs/fifo.h> 74 75#include <ufs/ufs/acl.h> 76#include <ufs/ufs/extattr.h> 77#include <ufs/ufs/quota.h> 78#include <ufs/ufs/inode.h> 79#include <ufs/ufs/dir.h> 80#include <ufs/ufs/ufsmount.h> 81#include <ufs/ufs/ufs_extern.h> 82#ifdef UFS_DIRHASH 83#include <ufs/ufs/dirhash.h> 84#endif 85 86#include <ufs/ffs/ffs_extern.h> 87 88static vop_access_t ufs_access; 89static vop_advlock_t ufs_advlock; 90static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *); 91static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *); 92static vop_close_t ufs_close; 93static vop_create_t ufs_create; 94static vop_getattr_t ufs_getattr; 95static vop_link_t ufs_link; 96static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *); 97static vop_mkdir_t ufs_mkdir; 98static vop_mknod_t ufs_mknod; 99static vop_open_t ufs_open; 100static vop_pathconf_t ufs_pathconf; 101static vop_print_t ufs_print; 102static vop_readlink_t ufs_readlink; 103static vop_remove_t ufs_remove; 104static vop_rename_t ufs_rename; 105static vop_rmdir_t ufs_rmdir; 106static vop_setattr_t ufs_setattr; 107static vop_strategy_t ufs_strategy; 108static vop_symlink_t ufs_symlink; 109static vop_whiteout_t ufs_whiteout; 110static vop_close_t ufsfifo_close; 111static vop_kqfilter_t ufsfifo_kqfilter; 112static int filt_ufsread(struct knote *kn, long hint); 113static int filt_ufswrite(struct knote *kn, long hint); 114static int filt_ufsvnode(struct knote *kn, long hint); 115static void filt_ufsdetach(struct knote *kn); 116static vop_kqfilter_t ufs_kqfilter; 117 118/* 119 * A virgin directory (no blushing please). 120 */ 121static struct dirtemplate mastertemplate = { 122 0, 12, DT_DIR, 1, ".", 123 0, DIRBLKSIZ - 12, DT_DIR, 2, ".." 124}; 125static struct odirtemplate omastertemplate = { 126 0, 12, 1, ".", 127 0, DIRBLKSIZ - 12, 2, ".." 128}; 129 130void 131ufs_itimes(vp) 132 struct vnode *vp; 133{ 134 struct inode *ip; 135 struct timespec ts; 136 137 ip = VTOI(vp); 138 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0) 139 return; 140 if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp)) 141 ip->i_flag |= IN_LAZYMOD; 142 else 143 ip->i_flag |= IN_MODIFIED; 144 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { 145 vfs_timestamp(&ts); 146 if (ip->i_flag & IN_ACCESS) { 147 DIP_SET(ip, i_atime, ts.tv_sec); 148 DIP_SET(ip, i_atimensec, ts.tv_nsec); 149 } 150 if (ip->i_flag & IN_UPDATE) { 151 DIP_SET(ip, i_mtime, ts.tv_sec); 152 DIP_SET(ip, i_mtimensec, ts.tv_nsec); 153 ip->i_modrev++; 154 } 155 if (ip->i_flag & IN_CHANGE) { 156 DIP_SET(ip, i_ctime, ts.tv_sec); 157 DIP_SET(ip, i_ctimensec, ts.tv_nsec); 158 } 159 } 160 ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); 161} 162 163/* 164 * Create a regular file 165 */ 166static int 167ufs_create(ap) 168 struct vop_create_args /* { 169 struct vnode *a_dvp; 170 struct vnode **a_vpp; 171 struct componentname *a_cnp; 172 struct vattr *a_vap; 173 } */ *ap; 174{ 175 int error; 176 177 error = 178 ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), 179 ap->a_dvp, ap->a_vpp, ap->a_cnp); 180 if (error) 181 return (error); 182 VN_KNOTE_UNLOCKED(ap->a_dvp, NOTE_WRITE); 183 return (0); 184} 185 186/* 187 * Mknod vnode call 188 */ 189/* ARGSUSED */ 190static int 191ufs_mknod(ap) 192 struct vop_mknod_args /* { 193 struct vnode *a_dvp; 194 struct vnode **a_vpp; 195 struct componentname *a_cnp; 196 struct vattr *a_vap; 197 } */ *ap; 198{ 199 struct vattr *vap = ap->a_vap; 200 struct vnode **vpp = ap->a_vpp; 201 struct inode *ip; 202 ino_t ino; 203 int error; 204 205 error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), 206 ap->a_dvp, vpp, ap->a_cnp); 207 if (error) 208 return (error); 209 VN_KNOTE_UNLOCKED(ap->a_dvp, NOTE_WRITE); 210 ip = VTOI(*vpp); 211 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 212 if (vap->va_rdev != VNOVAL) { 213 /* 214 * Want to be able to use this to make badblock 215 * inodes, so don't truncate the dev number. 216 */ 217 DIP_SET(ip, i_rdev, vap->va_rdev); 218 } 219 /* 220 * Remove inode, then reload it through VFS_VGET so it is 221 * checked to see if it is an alias of an existing entry in 222 * the inode cache. XXX I don't believe this is necessary now. 223 */ 224 (*vpp)->v_type = VNON; 225 ino = ip->i_number; /* Save this before vgone() invalidates ip. */ 226 vgone(*vpp); 227 vput(*vpp); 228 error = VFS_VGET(ap->a_dvp->v_mount, ino, LK_EXCLUSIVE, vpp); 229 if (error) { 230 *vpp = NULL; 231 return (error); 232 } 233 return (0); 234} 235 236/* 237 * Open called. 238 */ 239/* ARGSUSED */ 240static int 241ufs_open(struct vop_open_args *ap) 242{ 243 struct vnode *vp = ap->a_vp; 244 struct inode *ip; 245 246 if (vp->v_type == VCHR || vp->v_type == VBLK) 247 return (EOPNOTSUPP); 248 249 ip = VTOI(vp); 250 /* 251 * Files marked append-only must be opened for appending. 252 */ 253 if ((ip->i_flags & APPEND) && 254 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) 255 return (EPERM); 256 vnode_create_vobject(vp, DIP(ip, i_size), ap->a_td); 257 return (0); 258} 259 260/* 261 * Close called. 262 * 263 * Update the times on the inode. 264 */ 265/* ARGSUSED */ 266static int 267ufs_close(ap) 268 struct vop_close_args /* { 269 struct vnode *a_vp; 270 int a_fflag; 271 struct ucred *a_cred; 272 struct thread *a_td; 273 } */ *ap; 274{ 275 struct vnode *vp = ap->a_vp; 276 277 VI_LOCK(vp); 278 if (vp->v_usecount > 1) 279 ufs_itimes(vp); 280 VI_UNLOCK(vp); 281 return (0); 282} 283 284static int 285ufs_access(ap) 286 struct vop_access_args /* { 287 struct vnode *a_vp; 288 int a_mode; 289 struct ucred *a_cred; 290 struct thread *a_td; 291 } */ *ap; 292{ 293 struct vnode *vp = ap->a_vp; 294 struct inode *ip = VTOI(vp); 295 mode_t mode = ap->a_mode; 296 int error; 297#ifdef UFS_ACL 298 struct acl *acl; 299#endif 300 301 /* 302 * Disallow write attempts on read-only filesystems; 303 * unless the file is a socket, fifo, or a block or 304 * character device resident on the filesystem. 305 */ 306 if (mode & VWRITE) { 307 switch (vp->v_type) { 308 case VDIR: 309 case VLNK: 310 case VREG: 311 if (vp->v_mount->mnt_flag & MNT_RDONLY) 312 return (EROFS); 313#ifdef QUOTA 314 if ((error = getinoquota(ip)) != 0) 315 return (error); 316#endif 317 break; 318 default: 319 break; 320 } 321 } 322 323 /* If immutable bit set, nobody gets to write it. */ 324 if ((mode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) 325 return (EPERM); 326 327#ifdef UFS_ACL 328 if ((vp->v_mount->mnt_flag & MNT_ACLS) != 0) { 329 MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); 330 error = VOP_GETACL(vp, ACL_TYPE_ACCESS, acl, ap->a_cred, 331 ap->a_td); 332 switch (error) { 333 case EOPNOTSUPP: 334 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, 335 ip->i_gid, ap->a_mode, ap->a_cred, NULL); 336 break; 337 case 0: 338 error = vaccess_acl_posix1e(vp->v_type, ip->i_uid, 339 ip->i_gid, acl, ap->a_mode, ap->a_cred, NULL); 340 break; 341 default: 342 printf( 343"ufs_access(): Error retrieving ACL on object (%d).\n", 344 error); 345 /* 346 * XXX: Fall back until debugged. Should 347 * eventually possibly log an error, and return 348 * EPERM for safety. 349 */ 350 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, 351 ip->i_gid, ap->a_mode, ap->a_cred, NULL); 352 } 353 FREE(acl, M_ACL); 354 } else 355#endif /* !UFS_ACL */ 356 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid, 357 ap->a_mode, ap->a_cred, NULL); 358 return (error); 359} 360 361/* ARGSUSED */ 362static int 363ufs_getattr(ap) 364 struct vop_getattr_args /* { 365 struct vnode *a_vp; 366 struct vattr *a_vap; 367 struct ucred *a_cred; 368 struct thread *a_td; 369 } */ *ap; 370{ 371 struct vnode *vp = ap->a_vp; 372 struct inode *ip = VTOI(vp); 373 struct vattr *vap = ap->a_vap; 374 375 ufs_itimes(vp); 376 /* 377 * Copy from inode table 378 */ 379 vap->va_fsid = dev2udev(ip->i_dev); 380 vap->va_fileid = ip->i_number; 381 vap->va_mode = ip->i_mode & ~IFMT; 382 vap->va_nlink = ip->i_effnlink; 383 vap->va_uid = ip->i_uid; 384 vap->va_gid = ip->i_gid; 385 if (ip->i_ump->um_fstype == UFS1) { 386 vap->va_rdev = ip->i_din1->di_rdev; 387 vap->va_size = ip->i_din1->di_size; 388 vap->va_atime.tv_sec = ip->i_din1->di_atime; 389 vap->va_atime.tv_nsec = ip->i_din1->di_atimensec; 390 vap->va_mtime.tv_sec = ip->i_din1->di_mtime; 391 vap->va_mtime.tv_nsec = ip->i_din1->di_mtimensec; 392 vap->va_ctime.tv_sec = ip->i_din1->di_ctime; 393 vap->va_ctime.tv_nsec = ip->i_din1->di_ctimensec; 394 vap->va_birthtime.tv_sec = 0; 395 vap->va_birthtime.tv_nsec = 0; 396 vap->va_bytes = dbtob((u_quad_t)ip->i_din1->di_blocks); 397 } else { 398 vap->va_rdev = ip->i_din2->di_rdev; 399 vap->va_size = ip->i_din2->di_size; 400 vap->va_atime.tv_sec = ip->i_din2->di_atime; 401 vap->va_atime.tv_nsec = ip->i_din2->di_atimensec; 402 vap->va_mtime.tv_sec = ip->i_din2->di_mtime; 403 vap->va_mtime.tv_nsec = ip->i_din2->di_mtimensec; 404 vap->va_ctime.tv_sec = ip->i_din2->di_ctime; 405 vap->va_ctime.tv_nsec = ip->i_din2->di_ctimensec; 406 vap->va_birthtime.tv_sec = ip->i_din2->di_birthtime; 407 vap->va_birthtime.tv_nsec = ip->i_din2->di_birthnsec; 408 vap->va_bytes = dbtob((u_quad_t)ip->i_din2->di_blocks); 409 } 410 vap->va_flags = ip->i_flags; 411 vap->va_gen = ip->i_gen; 412 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; 413 vap->va_type = IFTOVT(ip->i_mode); 414 vap->va_filerev = ip->i_modrev; 415 return (0); 416} 417 418/* 419 * Set attribute vnode op. called from several syscalls 420 */ 421static int 422ufs_setattr(ap) 423 struct vop_setattr_args /* { 424 struct vnode *a_vp; 425 struct vattr *a_vap; 426 struct ucred *a_cred; 427 struct thread *a_td; 428 } */ *ap; 429{ 430 struct vattr *vap = ap->a_vap; 431 struct vnode *vp = ap->a_vp; 432 struct inode *ip = VTOI(vp); 433 struct ucred *cred = ap->a_cred; 434 struct thread *td = ap->a_td; 435 int error; 436 437 /* 438 * Check for unsettable attributes. 439 */ 440 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 441 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 442 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 443 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 444 return (EINVAL); 445 } 446 if (vap->va_flags != VNOVAL) { 447 if (vp->v_mount->mnt_flag & MNT_RDONLY) 448 return (EROFS); 449 /* 450 * Callers may only modify the file flags on objects they 451 * have VADMIN rights for. 452 */ 453 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 454 return (error); 455 /* 456 * Unprivileged processes are not permitted to unset system 457 * flags, or modify flags if any system flags are set. 458 * Privileged non-jail processes may not modify system flags 459 * if securelevel > 0 and any existing system flags are set. 460 * Privileged jail processes behave like privileged non-jail 461 * processes if the security.jail.chflags_allowed sysctl is 462 * is non-zero; otherwise, they behave like unprivileged 463 * processes. 464 */ 465 if (!suser_cred(cred, 466 jail_chflags_allowed ? SUSER_ALLOWJAIL : 0)) { 467 if (ip->i_flags 468 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { 469 error = securelevel_gt(cred, 0); 470 if (error) 471 return (error); 472 } 473 /* Snapshot flag cannot be set or cleared */ 474 if (((vap->va_flags & SF_SNAPSHOT) != 0 && 475 (ip->i_flags & SF_SNAPSHOT) == 0) || 476 ((vap->va_flags & SF_SNAPSHOT) == 0 && 477 (ip->i_flags & SF_SNAPSHOT) != 0)) 478 return (EPERM); 479 ip->i_flags = vap->va_flags; 480 DIP_SET(ip, i_flags, vap->va_flags); 481 } else { 482 if (ip->i_flags 483 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) || 484 (vap->va_flags & UF_SETTABLE) != vap->va_flags) 485 return (EPERM); 486 ip->i_flags &= SF_SETTABLE; 487 ip->i_flags |= (vap->va_flags & UF_SETTABLE); 488 DIP_SET(ip, i_flags, ip->i_flags); 489 } 490 ip->i_flag |= IN_CHANGE; 491 if (vap->va_flags & (IMMUTABLE | APPEND)) 492 return (0); 493 } 494 if (ip->i_flags & (IMMUTABLE | APPEND)) 495 return (EPERM); 496 /* 497 * Go through the fields and update iff not VNOVAL. 498 */ 499 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { 500 if (vp->v_mount->mnt_flag & MNT_RDONLY) 501 return (EROFS); 502 if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, 503 td)) != 0) 504 return (error); 505 } 506 if (vap->va_size != VNOVAL) { 507 /* 508 * Disallow write attempts on read-only filesystems; 509 * unless the file is a socket, fifo, or a block or 510 * character device resident on the filesystem. 511 */ 512 switch (vp->v_type) { 513 case VDIR: 514 return (EISDIR); 515 case VLNK: 516 case VREG: 517 if (vp->v_mount->mnt_flag & MNT_RDONLY) 518 return (EROFS); 519 if ((ip->i_flags & SF_SNAPSHOT) != 0) 520 return (EPERM); 521 break; 522 default: 523 break; 524 } 525 if ((error = UFS_TRUNCATE(vp, vap->va_size, IO_NORMAL, 526 cred, td)) != 0) 527 return (error); 528 } 529 if (vap->va_atime.tv_sec != VNOVAL || 530 vap->va_mtime.tv_sec != VNOVAL || 531 vap->va_birthtime.tv_sec != VNOVAL) { 532 if (vp->v_mount->mnt_flag & MNT_RDONLY) 533 return (EROFS); 534 if ((ip->i_flags & SF_SNAPSHOT) != 0) 535 return (EPERM); 536 /* 537 * From utimes(2): 538 * If times is NULL, ... The caller must be the owner of 539 * the file, have permission to write the file, or be the 540 * super-user. 541 * If times is non-NULL, ... The caller must be the owner of 542 * the file or be the super-user. 543 */ 544 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)) && 545 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || 546 (error = VOP_ACCESS(vp, VWRITE, cred, td)))) 547 return (error); 548 if (vap->va_atime.tv_sec != VNOVAL) 549 ip->i_flag |= IN_ACCESS; 550 if (vap->va_mtime.tv_sec != VNOVAL) 551 ip->i_flag |= IN_CHANGE | IN_UPDATE; 552 if (vap->va_birthtime.tv_sec != VNOVAL && 553 ip->i_ump->um_fstype == UFS2) 554 ip->i_flag |= IN_MODIFIED; 555 ufs_itimes(vp); 556 if (vap->va_atime.tv_sec != VNOVAL) { 557 DIP_SET(ip, i_atime, vap->va_atime.tv_sec); 558 DIP_SET(ip, i_atimensec, vap->va_atime.tv_nsec); 559 } 560 if (vap->va_mtime.tv_sec != VNOVAL) { 561 DIP_SET(ip, i_mtime, vap->va_mtime.tv_sec); 562 DIP_SET(ip, i_mtimensec, vap->va_mtime.tv_nsec); 563 } 564 if (vap->va_birthtime.tv_sec != VNOVAL && 565 ip->i_ump->um_fstype == UFS2) { 566 ip->i_din2->di_birthtime = vap->va_birthtime.tv_sec; 567 ip->i_din2->di_birthnsec = vap->va_birthtime.tv_nsec; 568 } 569 error = UFS_UPDATE(vp, 0); 570 if (error) 571 return (error); 572 } 573 error = 0; 574 if (vap->va_mode != (mode_t)VNOVAL) { 575 if (vp->v_mount->mnt_flag & MNT_RDONLY) 576 return (EROFS); 577 if ((ip->i_flags & SF_SNAPSHOT) != 0 && (vap->va_mode & 578 (S_IXUSR | S_IWUSR | S_IXGRP | S_IWGRP | S_IXOTH | S_IWOTH))) 579 return (EPERM); 580 error = ufs_chmod(vp, (int)vap->va_mode, cred, td); 581 } 582 VN_KNOTE_UNLOCKED(vp, NOTE_ATTRIB); 583 return (error); 584} 585 586/* 587 * Change the mode on a file. 588 * Inode must be locked before calling. 589 */ 590static int 591ufs_chmod(vp, mode, cred, td) 592 struct vnode *vp; 593 int mode; 594 struct ucred *cred; 595 struct thread *td; 596{ 597 struct inode *ip = VTOI(vp); 598 int error; 599 600 /* 601 * To modify the permissions on a file, must possess VADMIN 602 * for that file. 603 */ 604 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 605 return (error); 606 /* 607 * Privileged processes may set the sticky bit on non-directories, 608 * as well as set the setgid bit on a file with a group that the 609 * process is not a member of. Both of these are allowed in 610 * jail(8). 611 */ 612 if (vp->v_type != VDIR && (mode & S_ISTXT)) { 613 if (suser_cred(cred, SUSER_ALLOWJAIL)) 614 return (EFTYPE); 615 } 616 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) { 617 error = suser_cred(cred, SUSER_ALLOWJAIL); 618 if (error) 619 return (error); 620 } 621 ip->i_mode &= ~ALLPERMS; 622 ip->i_mode |= (mode & ALLPERMS); 623 DIP_SET(ip, i_mode, ip->i_mode); 624 ip->i_flag |= IN_CHANGE; 625 return (0); 626} 627 628/* 629 * Perform chown operation on inode ip; 630 * inode must be locked prior to call. 631 */ 632static int 633ufs_chown(vp, uid, gid, cred, td) 634 struct vnode *vp; 635 uid_t uid; 636 gid_t gid; 637 struct ucred *cred; 638 struct thread *td; 639{ 640 struct inode *ip = VTOI(vp); 641 uid_t ouid; 642 gid_t ogid; 643 int error = 0; 644#ifdef QUOTA 645 int i; 646 ufs2_daddr_t change; 647#endif 648 649 if (uid == (uid_t)VNOVAL) 650 uid = ip->i_uid; 651 if (gid == (gid_t)VNOVAL) 652 gid = ip->i_gid; 653 /* 654 * To modify the ownership of a file, must possess VADMIN 655 * for that file. 656 */ 657 if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) 658 return (error); 659 /* 660 * To change the owner of a file, or change the group of a file 661 * to a group of which we are not a member, the caller must 662 * have privilege. 663 */ 664 if ((uid != ip->i_uid || 665 (gid != ip->i_gid && !groupmember(gid, cred))) && 666 (error = suser_cred(cred, SUSER_ALLOWJAIL))) 667 return (error); 668 ogid = ip->i_gid; 669 ouid = ip->i_uid; 670#ifdef QUOTA 671 if ((error = getinoquota(ip)) != 0) 672 return (error); 673 if (ouid == uid) { 674 dqrele(vp, ip->i_dquot[USRQUOTA]); 675 ip->i_dquot[USRQUOTA] = NODQUOT; 676 } 677 if (ogid == gid) { 678 dqrele(vp, ip->i_dquot[GRPQUOTA]); 679 ip->i_dquot[GRPQUOTA] = NODQUOT; 680 } 681 change = DIP(ip, i_blocks); 682 (void) chkdq(ip, -change, cred, CHOWN); 683 (void) chkiq(ip, -1, cred, CHOWN); 684 for (i = 0; i < MAXQUOTAS; i++) { 685 dqrele(vp, ip->i_dquot[i]); 686 ip->i_dquot[i] = NODQUOT; 687 } 688#endif 689 ip->i_gid = gid; 690 DIP_SET(ip, i_gid, gid); 691 ip->i_uid = uid; 692 DIP_SET(ip, i_uid, uid); 693#ifdef QUOTA 694 if ((error = getinoquota(ip)) == 0) { 695 if (ouid == uid) { 696 dqrele(vp, ip->i_dquot[USRQUOTA]); 697 ip->i_dquot[USRQUOTA] = NODQUOT; 698 } 699 if (ogid == gid) { 700 dqrele(vp, ip->i_dquot[GRPQUOTA]); 701 ip->i_dquot[GRPQUOTA] = NODQUOT; 702 } 703 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) { 704 if ((error = chkiq(ip, 1, cred, CHOWN)) == 0) 705 goto good; 706 else 707 (void) chkdq(ip, -change, cred, CHOWN|FORCE); 708 } 709 for (i = 0; i < MAXQUOTAS; i++) { 710 dqrele(vp, ip->i_dquot[i]); 711 ip->i_dquot[i] = NODQUOT; 712 } 713 } 714 ip->i_gid = ogid; 715 DIP_SET(ip, i_gid, ogid); 716 ip->i_uid = ouid; 717 DIP_SET(ip, i_uid, ouid); 718 if (getinoquota(ip) == 0) { 719 if (ouid == uid) { 720 dqrele(vp, ip->i_dquot[USRQUOTA]); 721 ip->i_dquot[USRQUOTA] = NODQUOT; 722 } 723 if (ogid == gid) { 724 dqrele(vp, ip->i_dquot[GRPQUOTA]); 725 ip->i_dquot[GRPQUOTA] = NODQUOT; 726 } 727 (void) chkdq(ip, change, cred, FORCE|CHOWN); 728 (void) chkiq(ip, 1, cred, FORCE|CHOWN); 729 (void) getinoquota(ip); 730 } 731 return (error); 732good: 733 if (getinoquota(ip)) 734 panic("ufs_chown: lost quota"); 735#endif /* QUOTA */ 736 ip->i_flag |= IN_CHANGE; 737 if (suser_cred(cred, SUSER_ALLOWJAIL) && (ouid != uid || ogid != gid)) { 738 ip->i_mode &= ~(ISUID | ISGID); 739 DIP_SET(ip, i_mode, ip->i_mode); 740 } 741 return (0); 742} 743 744static int 745ufs_remove(ap) 746 struct vop_remove_args /* { 747 struct vnode *a_dvp; 748 struct vnode *a_vp; 749 struct componentname *a_cnp; 750 } */ *ap; 751{ 752 struct inode *ip; 753 struct vnode *vp = ap->a_vp; 754 struct vnode *dvp = ap->a_dvp; 755 int error; 756 757 ip = VTOI(vp); 758 if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || 759 (VTOI(dvp)->i_flags & APPEND)) { 760 error = EPERM; 761 goto out; 762 } 763 error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0); 764 if (ip->i_nlink <= 0) 765 vp->v_vflag |= VV_NOSYNC; 766 VN_KNOTE_UNLOCKED(vp, NOTE_DELETE); 767 VN_KNOTE_UNLOCKED(dvp, NOTE_WRITE); 768out: 769 return (error); 770} 771 772/* 773 * link vnode call 774 */ 775static int 776ufs_link(ap) 777 struct vop_link_args /* { 778 struct vnode *a_tdvp; 779 struct vnode *a_vp; 780 struct componentname *a_cnp; 781 } */ *ap; 782{ 783 struct vnode *vp = ap->a_vp; 784 struct vnode *tdvp = ap->a_tdvp; 785 struct componentname *cnp = ap->a_cnp; 786 struct inode *ip; 787 struct direct newdir; 788 int error; 789 790#ifdef DIAGNOSTIC 791 if ((cnp->cn_flags & HASBUF) == 0) 792 panic("ufs_link: no name"); 793#endif 794 if (tdvp->v_mount != vp->v_mount) { 795 error = EXDEV; 796 goto out; 797 } 798 ip = VTOI(vp); 799 if ((nlink_t)ip->i_nlink >= LINK_MAX) { 800 error = EMLINK; 801 goto out; 802 } 803 if (ip->i_flags & (IMMUTABLE | APPEND)) { 804 error = EPERM; 805 goto out; 806 } 807 ip->i_effnlink++; 808 ip->i_nlink++; 809 DIP_SET(ip, i_nlink, ip->i_nlink); 810 ip->i_flag |= IN_CHANGE; 811 if (DOINGSOFTDEP(vp)) 812 softdep_change_linkcnt(ip); 813 error = UFS_UPDATE(vp, !(DOINGSOFTDEP(vp) | DOINGASYNC(vp))); 814 if (!error) { 815 ufs_makedirentry(ip, cnp, &newdir); 816 error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL); 817 } 818 819 if (error) { 820 ip->i_effnlink--; 821 ip->i_nlink--; 822 DIP_SET(ip, i_nlink, ip->i_nlink); 823 ip->i_flag |= IN_CHANGE; 824 if (DOINGSOFTDEP(vp)) 825 softdep_change_linkcnt(ip); 826 } 827out: 828 VN_KNOTE_UNLOCKED(vp, NOTE_LINK); 829 VN_KNOTE_UNLOCKED(tdvp, NOTE_WRITE); 830 return (error); 831} 832 833/* 834 * whiteout vnode call 835 */ 836static int 837ufs_whiteout(ap) 838 struct vop_whiteout_args /* { 839 struct vnode *a_dvp; 840 struct componentname *a_cnp; 841 int a_flags; 842 } */ *ap; 843{ 844 struct vnode *dvp = ap->a_dvp; 845 struct componentname *cnp = ap->a_cnp; 846 struct direct newdir; 847 int error = 0; 848 849 switch (ap->a_flags) { 850 case LOOKUP: 851 /* 4.4 format directories support whiteout operations */ 852 if (dvp->v_mount->mnt_maxsymlinklen > 0) 853 return (0); 854 return (EOPNOTSUPP); 855 856 case CREATE: 857 /* create a new directory whiteout */ 858#ifdef DIAGNOSTIC 859 if ((cnp->cn_flags & SAVENAME) == 0) 860 panic("ufs_whiteout: missing name"); 861 if (dvp->v_mount->mnt_maxsymlinklen <= 0) 862 panic("ufs_whiteout: old format filesystem"); 863#endif 864 865 newdir.d_ino = WINO; 866 newdir.d_namlen = cnp->cn_namelen; 867 bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1); 868 newdir.d_type = DT_WHT; 869 error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL); 870 break; 871 872 case DELETE: 873 /* remove an existing directory whiteout */ 874#ifdef DIAGNOSTIC 875 if (dvp->v_mount->mnt_maxsymlinklen <= 0) 876 panic("ufs_whiteout: old format filesystem"); 877#endif 878 879 cnp->cn_flags &= ~DOWHITEOUT; 880 error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0); 881 break; 882 default: 883 panic("ufs_whiteout: unknown op"); 884 } 885 return (error); 886} 887 888/* 889 * Rename system call. 890 * rename("foo", "bar"); 891 * is essentially 892 * unlink("bar"); 893 * link("foo", "bar"); 894 * unlink("foo"); 895 * but ``atomically''. Can't do full commit without saving state in the 896 * inode on disk which isn't feasible at this time. Best we can do is 897 * always guarantee the target exists. 898 * 899 * Basic algorithm is: 900 * 901 * 1) Bump link count on source while we're linking it to the 902 * target. This also ensure the inode won't be deleted out 903 * from underneath us while we work (it may be truncated by 904 * a concurrent `trunc' or `open' for creation). 905 * 2) Link source to destination. If destination already exists, 906 * delete it first. 907 * 3) Unlink source reference to inode if still around. If a 908 * directory was moved and the parent of the destination 909 * is different from the source, patch the ".." entry in the 910 * directory. 911 */ 912static int 913ufs_rename(ap) 914 struct vop_rename_args /* { 915 struct vnode *a_fdvp; 916 struct vnode *a_fvp; 917 struct componentname *a_fcnp; 918 struct vnode *a_tdvp; 919 struct vnode *a_tvp; 920 struct componentname *a_tcnp; 921 } */ *ap; 922{ 923 struct vnode *tvp = ap->a_tvp; 924 struct vnode *tdvp = ap->a_tdvp; 925 struct vnode *fvp = ap->a_fvp; 926 struct vnode *fdvp = ap->a_fdvp; 927 struct componentname *tcnp = ap->a_tcnp; 928 struct componentname *fcnp = ap->a_fcnp; 929 struct thread *td = fcnp->cn_thread; 930 struct inode *ip, *xp, *dp; 931 struct direct newdir; 932 int doingdirectory = 0, oldparent = 0, newparent = 0; 933 int error = 0, ioflag; 934 935#ifdef DIAGNOSTIC 936 if ((tcnp->cn_flags & HASBUF) == 0 || 937 (fcnp->cn_flags & HASBUF) == 0) 938 panic("ufs_rename: no name"); 939#endif 940 /* 941 * Check for cross-device rename. 942 */ 943 if ((fvp->v_mount != tdvp->v_mount) || 944 (tvp && (fvp->v_mount != tvp->v_mount))) { 945 error = EXDEV; 946abortit: 947 if (tdvp == tvp) 948 vrele(tdvp); 949 else 950 vput(tdvp); 951 if (tvp) 952 vput(tvp); 953 vrele(fdvp); 954 vrele(fvp); 955 return (error); 956 } 957 958 if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || 959 (VTOI(tdvp)->i_flags & APPEND))) { 960 error = EPERM; 961 goto abortit; 962 } 963 964 /* 965 * Renaming a file to itself has no effect. The upper layers should 966 * not call us in that case. Temporarily just warn if they do. 967 */ 968 if (fvp == tvp) { 969 printf("ufs_rename: fvp == tvp (can't happen)\n"); 970 error = 0; 971 goto abortit; 972 } 973 974 if ((error = vn_lock(fvp, LK_EXCLUSIVE, td)) != 0) 975 goto abortit; 976 dp = VTOI(fdvp); 977 ip = VTOI(fvp); 978 if (ip->i_nlink >= LINK_MAX) { 979 VOP_UNLOCK(fvp, 0, td); 980 error = EMLINK; 981 goto abortit; 982 } 983 if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) 984 || (dp->i_flags & APPEND)) { 985 VOP_UNLOCK(fvp, 0, td); 986 error = EPERM; 987 goto abortit; 988 } 989 if ((ip->i_mode & IFMT) == IFDIR) { 990 /* 991 * Avoid ".", "..", and aliases of "." for obvious reasons. 992 */ 993 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') || 994 dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT || 995 (ip->i_flag & IN_RENAME)) { 996 VOP_UNLOCK(fvp, 0, td); 997 error = EINVAL; 998 goto abortit; 999 } 1000 ip->i_flag |= IN_RENAME; 1001 oldparent = dp->i_number; 1002 doingdirectory = 1; 1003 } 1004 VN_KNOTE_UNLOCKED(fdvp, NOTE_WRITE); /* XXX right place? */ 1005 vrele(fdvp); 1006 1007 /* 1008 * When the target exists, both the directory 1009 * and target vnodes are returned locked. 1010 */ 1011 dp = VTOI(tdvp); 1012 xp = NULL; 1013 if (tvp) 1014 xp = VTOI(tvp); 1015 1016 /* 1017 * 1) Bump link count while we're moving stuff 1018 * around. If we crash somewhere before 1019 * completing our work, the link count 1020 * may be wrong, but correctable. 1021 */ 1022 ip->i_effnlink++; 1023 ip->i_nlink++; 1024 DIP_SET(ip, i_nlink, ip->i_nlink); 1025 ip->i_flag |= IN_CHANGE; 1026 if (DOINGSOFTDEP(fvp)) 1027 softdep_change_linkcnt(ip); 1028 if ((error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) | 1029 DOINGASYNC(fvp)))) != 0) { 1030 VOP_UNLOCK(fvp, 0, td); 1031 goto bad; 1032 } 1033 1034 /* 1035 * If ".." must be changed (ie the directory gets a new 1036 * parent) then the source directory must not be in the 1037 * directory heirarchy above the target, as this would 1038 * orphan everything below the source directory. Also 1039 * the user must have write permission in the source so 1040 * as to be able to change "..". We must repeat the call 1041 * to namei, as the parent directory is unlocked by the 1042 * call to checkpath(). 1043 */ 1044 error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread); 1045 VOP_UNLOCK(fvp, 0, td); 1046 if (oldparent != dp->i_number) 1047 newparent = dp->i_number; 1048 if (doingdirectory && newparent) { 1049 if (error) /* write access check above */ 1050 goto bad; 1051 if (xp != NULL) 1052 vput(tvp); 1053 error = ufs_checkpath(ip, dp, tcnp->cn_cred); 1054 if (error) 1055 goto out; 1056 if ((tcnp->cn_flags & SAVESTART) == 0) 1057 panic("ufs_rename: lost to startdir"); 1058 VREF(tdvp); 1059 error = relookup(tdvp, &tvp, tcnp); 1060 if (error) 1061 goto out; 1062 vrele(tdvp); 1063 dp = VTOI(tdvp); 1064 xp = NULL; 1065 if (tvp) 1066 xp = VTOI(tvp); 1067 } 1068 /* 1069 * 2) If target doesn't exist, link the target 1070 * to the source and unlink the source. 1071 * Otherwise, rewrite the target directory 1072 * entry to reference the source inode and 1073 * expunge the original entry's existence. 1074 */ 1075 if (xp == NULL) { 1076 if (dp->i_dev != ip->i_dev) 1077 panic("ufs_rename: EXDEV"); 1078 /* 1079 * Account for ".." in new directory. 1080 * When source and destination have the same 1081 * parent we don't fool with the link count. 1082 */ 1083 if (doingdirectory && newparent) { 1084 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 1085 error = EMLINK; 1086 goto bad; 1087 } 1088 dp->i_effnlink++; 1089 dp->i_nlink++; 1090 DIP_SET(dp, i_nlink, dp->i_nlink); 1091 dp->i_flag |= IN_CHANGE; 1092 if (DOINGSOFTDEP(tdvp)) 1093 softdep_change_linkcnt(dp); 1094 error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) | 1095 DOINGASYNC(tdvp))); 1096 if (error) 1097 goto bad; 1098 } 1099 ufs_makedirentry(ip, tcnp, &newdir); 1100 error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL); 1101 if (error) { 1102 if (doingdirectory && newparent) { 1103 dp->i_effnlink--; 1104 dp->i_nlink--; 1105 DIP_SET(dp, i_nlink, dp->i_nlink); 1106 dp->i_flag |= IN_CHANGE; 1107 if (DOINGSOFTDEP(tdvp)) 1108 softdep_change_linkcnt(dp); 1109 (void)UFS_UPDATE(tdvp, 1); 1110 } 1111 goto bad; 1112 } 1113 VN_KNOTE_UNLOCKED(tdvp, NOTE_WRITE); 1114 vput(tdvp); 1115 } else { 1116 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) 1117 panic("ufs_rename: EXDEV"); 1118 /* 1119 * Short circuit rename(foo, foo). 1120 */ 1121 if (xp->i_number == ip->i_number) 1122 panic("ufs_rename: same file"); 1123 /* 1124 * If the parent directory is "sticky", then the caller 1125 * must possess VADMIN for the parent directory, or the 1126 * destination of the rename. This implements append-only 1127 * directories. 1128 */ 1129 if ((dp->i_mode & S_ISTXT) && 1130 VOP_ACCESS(tdvp, VADMIN, tcnp->cn_cred, td) && 1131 VOP_ACCESS(tvp, VADMIN, tcnp->cn_cred, td)) { 1132 error = EPERM; 1133 goto bad; 1134 } 1135 /* 1136 * Target must be empty if a directory and have no links 1137 * to it. Also, ensure source and target are compatible 1138 * (both directories, or both not directories). 1139 */ 1140 if ((xp->i_mode&IFMT) == IFDIR) { 1141 if ((xp->i_effnlink > 2) || 1142 !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) { 1143 error = ENOTEMPTY; 1144 goto bad; 1145 } 1146 if (!doingdirectory) { 1147 error = ENOTDIR; 1148 goto bad; 1149 } 1150 cache_purge(tdvp); 1151 } else if (doingdirectory) { 1152 error = EISDIR; 1153 goto bad; 1154 } 1155 error = ufs_dirrewrite(dp, xp, ip->i_number, 1156 IFTODT(ip->i_mode), 1157 (doingdirectory && newparent) ? newparent : doingdirectory); 1158 if (error) 1159 goto bad; 1160 if (doingdirectory) { 1161 if (!newparent) { 1162 dp->i_effnlink--; 1163 if (DOINGSOFTDEP(tdvp)) 1164 softdep_change_linkcnt(dp); 1165 } 1166 xp->i_effnlink--; 1167 if (DOINGSOFTDEP(tvp)) 1168 softdep_change_linkcnt(xp); 1169 } 1170 if (doingdirectory && !DOINGSOFTDEP(tvp)) { 1171 /* 1172 * Truncate inode. The only stuff left in the directory 1173 * is "." and "..". The "." reference is inconsequential 1174 * since we are quashing it. We have removed the "." 1175 * reference and the reference in the parent directory, 1176 * but there may be other hard links. The soft 1177 * dependency code will arrange to do these operations 1178 * after the parent directory entry has been deleted on 1179 * disk, so when running with that code we avoid doing 1180 * them now. 1181 */ 1182 if (!newparent) { 1183 dp->i_nlink--; 1184 DIP_SET(dp, i_nlink, dp->i_nlink); 1185 dp->i_flag |= IN_CHANGE; 1186 } 1187 xp->i_nlink--; 1188 DIP_SET(xp, i_nlink, xp->i_nlink); 1189 xp->i_flag |= IN_CHANGE; 1190 ioflag = IO_NORMAL; 1191 if (DOINGASYNC(tvp)) 1192 ioflag |= IO_SYNC; 1193 if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag, 1194 tcnp->cn_cred, tcnp->cn_thread)) != 0) 1195 goto bad; 1196 } 1197 VN_KNOTE_UNLOCKED(tdvp, NOTE_WRITE); 1198 vput(tdvp); 1199 VN_KNOTE_UNLOCKED(tvp, NOTE_DELETE); 1200 vput(tvp); 1201 xp = NULL; 1202 } 1203 1204 /* 1205 * 3) Unlink the source. 1206 */ 1207 fcnp->cn_flags &= ~MODMASK; 1208 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; 1209 if ((fcnp->cn_flags & SAVESTART) == 0) 1210 panic("ufs_rename: lost from startdir"); 1211 VREF(fdvp); 1212 error = relookup(fdvp, &fvp, fcnp); 1213 if (error == 0) 1214 vrele(fdvp); 1215 if (fvp != NULL) { 1216 xp = VTOI(fvp); 1217 dp = VTOI(fdvp); 1218 } else { 1219 /* 1220 * From name has disappeared. IN_RENAME is not sufficient 1221 * to protect against directory races due to timing windows, 1222 * so we have to remove the panic. XXX the only real way 1223 * to solve this issue is at a much higher level. By the 1224 * time we hit ufs_rename() it's too late. 1225 */ 1226#if 0 1227 if (doingdirectory) 1228 panic("ufs_rename: lost dir entry"); 1229#endif 1230 vrele(ap->a_fvp); 1231 return (0); 1232 } 1233 /* 1234 * Ensure that the directory entry still exists and has not 1235 * changed while the new name has been entered. If the source is 1236 * a file then the entry may have been unlinked or renamed. In 1237 * either case there is no further work to be done. If the source 1238 * is a directory then it cannot have been rmdir'ed; the IN_RENAME 1239 * flag ensures that it cannot be moved by another rename or removed 1240 * by a rmdir. 1241 */ 1242 if (xp != ip) { 1243 /* 1244 * From name resolves to a different inode. IN_RENAME is 1245 * not sufficient protection against timing window races 1246 * so we can't panic here. XXX the only real way 1247 * to solve this issue is at a much higher level. By the 1248 * time we hit ufs_rename() it's too late. 1249 */ 1250#if 0 1251 if (doingdirectory) 1252 panic("ufs_rename: lost dir entry"); 1253#endif 1254 } else { 1255 /* 1256 * If the source is a directory with a 1257 * new parent, the link count of the old 1258 * parent directory must be decremented 1259 * and ".." set to point to the new parent. 1260 */ 1261 if (doingdirectory && newparent) { 1262 xp->i_offset = mastertemplate.dot_reclen; 1263 ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0); 1264 cache_purge(fdvp); 1265 } 1266 error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0); 1267 xp->i_flag &= ~IN_RENAME; 1268 } 1269 VN_KNOTE_UNLOCKED(fvp, NOTE_RENAME); 1270 if (dp) 1271 vput(fdvp); 1272 if (xp) 1273 vput(fvp); 1274 vrele(ap->a_fvp); 1275 return (error); 1276 1277bad: 1278 if (xp) 1279 vput(ITOV(xp)); 1280 vput(ITOV(dp)); 1281out: 1282 if (doingdirectory) 1283 ip->i_flag &= ~IN_RENAME; 1284 if (vn_lock(fvp, LK_EXCLUSIVE, td) == 0) { 1285 ip->i_effnlink--; 1286 ip->i_nlink--; 1287 DIP_SET(ip, i_nlink, ip->i_nlink); 1288 ip->i_flag |= IN_CHANGE; 1289 ip->i_flag &= ~IN_RENAME; 1290 if (DOINGSOFTDEP(fvp)) 1291 softdep_change_linkcnt(ip); 1292 vput(fvp); 1293 } else 1294 vrele(fvp); 1295 return (error); 1296} 1297 1298/* 1299 * Mkdir system call 1300 */ 1301static int 1302ufs_mkdir(ap) 1303 struct vop_mkdir_args /* { 1304 struct vnode *a_dvp; 1305 struct vnode **a_vpp; 1306 struct componentname *a_cnp; 1307 struct vattr *a_vap; 1308 } */ *ap; 1309{ 1310 struct vnode *dvp = ap->a_dvp; 1311 struct vattr *vap = ap->a_vap; 1312 struct componentname *cnp = ap->a_cnp; 1313 struct inode *ip, *dp; 1314 struct vnode *tvp; 1315 struct buf *bp; 1316 struct dirtemplate dirtemplate, *dtp; 1317 struct direct newdir; 1318#ifdef UFS_ACL 1319 struct acl *acl, *dacl; 1320#endif 1321 int error, dmode; 1322 long blkoff; 1323 1324#ifdef DIAGNOSTIC 1325 if ((cnp->cn_flags & HASBUF) == 0) 1326 panic("ufs_mkdir: no name"); 1327#endif 1328 dp = VTOI(dvp); 1329 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 1330 error = EMLINK; 1331 goto out; 1332 } 1333 dmode = vap->va_mode & 0777; 1334 dmode |= IFDIR; 1335 /* 1336 * Must simulate part of ufs_makeinode here to acquire the inode, 1337 * but not have it entered in the parent directory. The entry is 1338 * made later after writing "." and ".." entries. 1339 */ 1340 error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp); 1341 if (error) 1342 goto out; 1343 ip = VTOI(tvp); 1344 ip->i_gid = dp->i_gid; 1345 DIP_SET(ip, i_gid, dp->i_gid); 1346#ifdef SUIDDIR 1347 { 1348#ifdef QUOTA 1349 struct ucred ucred, *ucp; 1350 ucp = cnp->cn_cred; 1351#endif 1352 /* 1353 * If we are hacking owners here, (only do this where told to) 1354 * and we are not giving it TO root, (would subvert quotas) 1355 * then go ahead and give it to the other user. 1356 * The new directory also inherits the SUID bit. 1357 * If user's UID and dir UID are the same, 1358 * 'give it away' so that the SUID is still forced on. 1359 */ 1360 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) && 1361 (dp->i_mode & ISUID) && dp->i_uid) { 1362 dmode |= ISUID; 1363 ip->i_uid = dp->i_uid; 1364 DIP_SET(ip, i_uid, dp->i_uid); 1365#ifdef QUOTA 1366 if (dp->i_uid != cnp->cn_cred->cr_uid) { 1367 /* 1368 * Make sure the correct user gets charged 1369 * for the space. 1370 * Make a dummy credential for the victim. 1371 * XXX This seems to never be accessed out of 1372 * our context so a stack variable is ok. 1373 */ 1374 ucred.cr_ref = 1; 1375 ucred.cr_uid = ip->i_uid; 1376 ucred.cr_ngroups = 1; 1377 ucred.cr_groups[0] = dp->i_gid; 1378 ucp = &ucred; 1379 } 1380#endif 1381 } else { 1382 ip->i_uid = cnp->cn_cred->cr_uid; 1383 DIP_SET(ip, i_uid, ip->i_uid); 1384 } 1385#ifdef QUOTA 1386 if ((error = getinoquota(ip)) || 1387 (error = chkiq(ip, 1, ucp, 0))) { 1388 UFS_VFREE(tvp, ip->i_number, dmode); 1389 vput(tvp); 1390 return (error); 1391 } 1392#endif 1393 } 1394#else /* !SUIDDIR */ 1395 ip->i_uid = cnp->cn_cred->cr_uid; 1396 DIP_SET(ip, i_uid, ip->i_uid); 1397#ifdef QUOTA 1398 if ((error = getinoquota(ip)) || 1399 (error = chkiq(ip, 1, cnp->cn_cred, 0))) { 1400 UFS_VFREE(tvp, ip->i_number, dmode); 1401 vput(tvp); 1402 return (error); 1403 } 1404#endif 1405#endif /* !SUIDDIR */ 1406 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 1407#ifdef UFS_ACL 1408 acl = dacl = NULL; 1409 if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) { 1410 MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); 1411 MALLOC(dacl, struct acl *, sizeof(*dacl), M_ACL, M_WAITOK); 1412 1413 /* 1414 * Retrieve default ACL from parent, if any. 1415 */ 1416 error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, 1417 cnp->cn_thread); 1418 switch (error) { 1419 case 0: 1420 /* 1421 * Retrieved a default ACL, so merge mode and ACL if 1422 * necessary. If the ACL is empty, fall through to 1423 * the "not defined or available" case. 1424 */ 1425 if (acl->acl_cnt != 0) { 1426 dmode = acl_posix1e_newfilemode(dmode, acl); 1427 ip->i_mode = dmode; 1428 DIP_SET(ip, i_mode, dmode); 1429 *dacl = *acl; 1430 ufs_sync_acl_from_inode(ip, acl); 1431 break; 1432 } 1433 /* FALLTHROUGH */ 1434 1435 case EOPNOTSUPP: 1436 /* 1437 * Just use the mode as-is. 1438 */ 1439 ip->i_mode = dmode; 1440 DIP_SET(ip, i_mode, dmode); 1441 FREE(acl, M_ACL); 1442 FREE(dacl, M_ACL); 1443 dacl = acl = NULL; 1444 break; 1445 1446 default: 1447 UFS_VFREE(tvp, ip->i_number, dmode); 1448 vput(tvp); 1449 FREE(acl, M_ACL); 1450 FREE(dacl, M_ACL); 1451 return (error); 1452 } 1453 } else { 1454#endif /* !UFS_ACL */ 1455 ip->i_mode = dmode; 1456 DIP_SET(ip, i_mode, dmode); 1457#ifdef UFS_ACL 1458 } 1459#endif 1460 tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ 1461 ip->i_effnlink = 2; 1462 ip->i_nlink = 2; 1463 DIP_SET(ip, i_nlink, 2); 1464 if (DOINGSOFTDEP(tvp)) 1465 softdep_change_linkcnt(ip); 1466 if (cnp->cn_flags & ISWHITEOUT) { 1467 ip->i_flags |= UF_OPAQUE; 1468 DIP_SET(ip, i_flags, ip->i_flags); 1469 } 1470 1471 /* 1472 * Bump link count in parent directory to reflect work done below. 1473 * Should be done before reference is created so cleanup is 1474 * possible if we crash. 1475 */ 1476 dp->i_effnlink++; 1477 dp->i_nlink++; 1478 DIP_SET(dp, i_nlink, dp->i_nlink); 1479 dp->i_flag |= IN_CHANGE; 1480 if (DOINGSOFTDEP(dvp)) 1481 softdep_change_linkcnt(dp); 1482 error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp))); 1483 if (error) 1484 goto bad; 1485#ifdef MAC 1486 if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) { 1487 error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount, 1488 dvp, tvp, cnp); 1489 if (error) 1490 goto bad; 1491 } 1492#endif 1493#ifdef UFS_ACL 1494 if (acl != NULL) { 1495 /* 1496 * XXX: If we abort now, will Soft Updates notify the extattr 1497 * code that the EAs for the file need to be released? 1498 */ 1499 error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cnp->cn_cred, 1500 cnp->cn_thread); 1501 if (error == 0) 1502 error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl, 1503 cnp->cn_cred, cnp->cn_thread); 1504 switch (error) { 1505 case 0: 1506 break; 1507 1508 case EOPNOTSUPP: 1509 /* 1510 * XXX: This should not happen, as EOPNOTSUPP above 1511 * was supposed to free acl. 1512 */ 1513 printf("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()\n"); 1514 /* 1515 panic("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()"); 1516 */ 1517 break; 1518 1519 default: 1520 FREE(acl, M_ACL); 1521 FREE(dacl, M_ACL); 1522 dacl = acl = NULL; 1523 goto bad; 1524 } 1525 FREE(acl, M_ACL); 1526 FREE(dacl, M_ACL); 1527 dacl = acl = NULL; 1528 } 1529#endif /* !UFS_ACL */ 1530 1531 /* 1532 * Initialize directory with "." and ".." from static template. 1533 */ 1534 if (dvp->v_mount->mnt_maxsymlinklen > 0) 1535 dtp = &mastertemplate; 1536 else 1537 dtp = (struct dirtemplate *)&omastertemplate; 1538 dirtemplate = *dtp; 1539 dirtemplate.dot_ino = ip->i_number; 1540 dirtemplate.dotdot_ino = dp->i_number; 1541 if ((error = UFS_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred, 1542 BA_CLRBUF, &bp)) != 0) 1543 goto bad; 1544 ip->i_size = DIRBLKSIZ; 1545 DIP_SET(ip, i_size, DIRBLKSIZ); 1546 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1547 vnode_pager_setsize(tvp, (u_long)ip->i_size); 1548 bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate); 1549 if (DOINGSOFTDEP(tvp)) { 1550 /* 1551 * Ensure that the entire newly allocated block is a 1552 * valid directory so that future growth within the 1553 * block does not have to ensure that the block is 1554 * written before the inode. 1555 */ 1556 blkoff = DIRBLKSIZ; 1557 while (blkoff < bp->b_bcount) { 1558 ((struct direct *) 1559 (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ; 1560 blkoff += DIRBLKSIZ; 1561 } 1562 } 1563 if ((error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | 1564 DOINGASYNC(tvp)))) != 0) { 1565 (void)bwrite(bp); 1566 goto bad; 1567 } 1568 /* 1569 * Directory set up, now install its entry in the parent directory. 1570 * 1571 * If we are not doing soft dependencies, then we must write out the 1572 * buffer containing the new directory body before entering the new 1573 * name in the parent. If we are doing soft dependencies, then the 1574 * buffer containing the new directory body will be passed to and 1575 * released in the soft dependency code after the code has attached 1576 * an appropriate ordering dependency to the buffer which ensures that 1577 * the buffer is written before the new name is written in the parent. 1578 */ 1579 if (DOINGASYNC(dvp)) 1580 bdwrite(bp); 1581 else if (!DOINGSOFTDEP(dvp) && ((error = bwrite(bp)))) 1582 goto bad; 1583 ufs_makedirentry(ip, cnp, &newdir); 1584 error = ufs_direnter(dvp, tvp, &newdir, cnp, bp); 1585 1586bad: 1587 if (error == 0) { 1588 VN_KNOTE_UNLOCKED(dvp, NOTE_WRITE | NOTE_LINK); 1589 *ap->a_vpp = tvp; 1590 } else { 1591#ifdef UFS_ACL 1592 if (acl != NULL) 1593 FREE(acl, M_ACL); 1594 if (dacl != NULL) 1595 FREE(dacl, M_ACL); 1596#endif 1597 dp->i_effnlink--; 1598 dp->i_nlink--; 1599 DIP_SET(dp, i_nlink, dp->i_nlink); 1600 dp->i_flag |= IN_CHANGE; 1601 if (DOINGSOFTDEP(dvp)) 1602 softdep_change_linkcnt(dp); 1603 /* 1604 * No need to do an explicit VOP_TRUNCATE here, vrele will 1605 * do this for us because we set the link count to 0. 1606 */ 1607 ip->i_effnlink = 0; 1608 ip->i_nlink = 0; 1609 DIP_SET(ip, i_nlink, 0); 1610 ip->i_flag |= IN_CHANGE; 1611 if (DOINGSOFTDEP(tvp)) 1612 softdep_change_linkcnt(ip); 1613 vput(tvp); 1614 } 1615out: 1616 return (error); 1617} 1618 1619/* 1620 * Rmdir system call. 1621 */ 1622static int 1623ufs_rmdir(ap) 1624 struct vop_rmdir_args /* { 1625 struct vnode *a_dvp; 1626 struct vnode *a_vp; 1627 struct componentname *a_cnp; 1628 } */ *ap; 1629{ 1630 struct vnode *vp = ap->a_vp; 1631 struct vnode *dvp = ap->a_dvp; 1632 struct componentname *cnp = ap->a_cnp; 1633 struct inode *ip, *dp; 1634 int error, ioflag; 1635 1636 ip = VTOI(vp); 1637 dp = VTOI(dvp); 1638 1639 /* 1640 * Do not remove a directory that is in the process of being renamed. 1641 * Verify the directory is empty (and valid). Rmdir ".." will not be 1642 * valid since ".." will contain a reference to the current directory 1643 * and thus be non-empty. Do not allow the removal of mounted on 1644 * directories (this can happen when an NFS exported filesystem 1645 * tries to remove a locally mounted on directory). 1646 */ 1647 error = 0; 1648 if (ip->i_flag & IN_RENAME) { 1649 error = EINVAL; 1650 goto out; 1651 } 1652 if (ip->i_effnlink != 2 || 1653 !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) { 1654 error = ENOTEMPTY; 1655 goto out; 1656 } 1657 if ((dp->i_flags & APPEND) 1658 || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) { 1659 error = EPERM; 1660 goto out; 1661 } 1662 if (vp->v_mountedhere != 0) { 1663 error = EINVAL; 1664 goto out; 1665 } 1666 /* 1667 * Delete reference to directory before purging 1668 * inode. If we crash in between, the directory 1669 * will be reattached to lost+found, 1670 */ 1671 dp->i_effnlink--; 1672 ip->i_effnlink--; 1673 if (DOINGSOFTDEP(vp)) { 1674 softdep_change_linkcnt(dp); 1675 softdep_change_linkcnt(ip); 1676 } 1677 error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1); 1678 if (error) { 1679 dp->i_effnlink++; 1680 ip->i_effnlink++; 1681 if (DOINGSOFTDEP(vp)) { 1682 softdep_change_linkcnt(dp); 1683 softdep_change_linkcnt(ip); 1684 } 1685 goto out; 1686 } 1687 VN_KNOTE_UNLOCKED(dvp, NOTE_WRITE | NOTE_LINK); 1688 cache_purge(dvp); 1689 /* 1690 * Truncate inode. The only stuff left in the directory is "." and 1691 * "..". The "." reference is inconsequential since we are quashing 1692 * it. The soft dependency code will arrange to do these operations 1693 * after the parent directory entry has been deleted on disk, so 1694 * when running with that code we avoid doing them now. 1695 */ 1696 if (!DOINGSOFTDEP(vp)) { 1697 dp->i_nlink--; 1698 DIP_SET(dp, i_nlink, dp->i_nlink); 1699 dp->i_flag |= IN_CHANGE; 1700 ip->i_nlink--; 1701 DIP_SET(ip, i_nlink, ip->i_nlink); 1702 ip->i_flag |= IN_CHANGE; 1703 ioflag = IO_NORMAL; 1704 if (DOINGASYNC(vp)) 1705 ioflag |= IO_SYNC; 1706 error = UFS_TRUNCATE(vp, (off_t)0, ioflag, cnp->cn_cred, 1707 cnp->cn_thread); 1708 } 1709 cache_purge(vp); 1710#ifdef UFS_DIRHASH 1711 /* Kill any active hash; i_effnlink == 0, so it will not come back. */ 1712 if (ip->i_dirhash != NULL) 1713 ufsdirhash_free(ip); 1714#endif 1715out: 1716 VN_KNOTE_UNLOCKED(vp, NOTE_DELETE); 1717 return (error); 1718} 1719 1720/* 1721 * symlink -- make a symbolic link 1722 */ 1723static int 1724ufs_symlink(ap) 1725 struct vop_symlink_args /* { 1726 struct vnode *a_dvp; 1727 struct vnode **a_vpp; 1728 struct componentname *a_cnp; 1729 struct vattr *a_vap; 1730 char *a_target; 1731 } */ *ap; 1732{ 1733 struct vnode *vp, **vpp = ap->a_vpp; 1734 struct inode *ip; 1735 int len, error; 1736 1737 error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, 1738 vpp, ap->a_cnp); 1739 if (error) 1740 return (error); 1741 VN_KNOTE_UNLOCKED(ap->a_dvp, NOTE_WRITE); 1742 vp = *vpp; 1743 len = strlen(ap->a_target); 1744 if (len < vp->v_mount->mnt_maxsymlinklen) { 1745 ip = VTOI(vp); 1746 bcopy(ap->a_target, SHORTLINK(ip), len); 1747 ip->i_size = len; 1748 DIP_SET(ip, i_size, len); 1749 ip->i_flag |= IN_CHANGE | IN_UPDATE; 1750 } else 1751 error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, 1752 UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, 1753 ap->a_cnp->cn_cred, NOCRED, (int *)0, (struct thread *)0); 1754 if (error) 1755 vput(vp); 1756 return (error); 1757} 1758 1759/* 1760 * Vnode op for reading directories. 1761 * 1762 * The routine below assumes that the on-disk format of a directory 1763 * is the same as that defined by <sys/dirent.h>. If the on-disk 1764 * format changes, then it will be necessary to do a conversion 1765 * from the on-disk format that read returns to the format defined 1766 * by <sys/dirent.h>. 1767 */ 1768int 1769ufs_readdir(ap) 1770 struct vop_readdir_args /* { 1771 struct vnode *a_vp; 1772 struct uio *a_uio; 1773 struct ucred *a_cred; 1774 int *a_eofflag; 1775 int *ncookies; 1776 u_long **a_cookies; 1777 } */ *ap; 1778{ 1779 struct uio *uio = ap->a_uio; 1780 int error; 1781 size_t count, lost; 1782 off_t off; 1783 1784 if (ap->a_ncookies != NULL) 1785 /* 1786 * Ensure that the block is aligned. The caller can use 1787 * the cookies to determine where in the block to start. 1788 */ 1789 uio->uio_offset &= ~(DIRBLKSIZ - 1); 1790 off = uio->uio_offset; 1791 count = uio->uio_resid; 1792 /* Make sure we don't return partial entries. */ 1793 if (count <= ((uio->uio_offset + count) & (DIRBLKSIZ -1))) 1794 return (EINVAL); 1795 count -= (uio->uio_offset + count) & (DIRBLKSIZ -1); 1796 lost = uio->uio_resid - count; 1797 uio->uio_resid = count; 1798 uio->uio_iov->iov_len = count; 1799# if (BYTE_ORDER == LITTLE_ENDIAN) 1800 if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) { 1801 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred); 1802 } else { 1803 struct dirent *dp, *edp; 1804 struct uio auio; 1805 struct iovec aiov; 1806 caddr_t dirbuf; 1807 int readcnt; 1808 u_char tmp; 1809 1810 auio = *uio; 1811 auio.uio_iov = &aiov; 1812 auio.uio_iovcnt = 1; 1813 auio.uio_segflg = UIO_SYSSPACE; 1814 aiov.iov_len = count; 1815 MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK); 1816 aiov.iov_base = dirbuf; 1817 error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred); 1818 if (error == 0) { 1819 readcnt = count - auio.uio_resid; 1820 edp = (struct dirent *)&dirbuf[readcnt]; 1821 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 1822 tmp = dp->d_namlen; 1823 dp->d_namlen = dp->d_type; 1824 dp->d_type = tmp; 1825 if (dp->d_reclen > 0) { 1826 dp = (struct dirent *) 1827 ((char *)dp + dp->d_reclen); 1828 } else { 1829 error = EIO; 1830 break; 1831 } 1832 } 1833 if (dp >= edp) 1834 error = uiomove(dirbuf, readcnt, uio); 1835 } 1836 FREE(dirbuf, M_TEMP); 1837 } 1838# else 1839 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred); 1840# endif 1841 if (!error && ap->a_ncookies != NULL) { 1842 struct dirent* dpStart; 1843 struct dirent* dpEnd; 1844 struct dirent* dp; 1845 int ncookies; 1846 u_long *cookies; 1847 u_long *cookiep; 1848 1849 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) 1850 panic("ufs_readdir: unexpected uio from NFS server"); 1851 dpStart = (struct dirent *) 1852 ((char *)uio->uio_iov->iov_base - (uio->uio_offset - off)); 1853 dpEnd = (struct dirent *) uio->uio_iov->iov_base; 1854 for (dp = dpStart, ncookies = 0; 1855 dp < dpEnd; 1856 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) 1857 ncookies++; 1858 MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP, 1859 M_WAITOK); 1860 for (dp = dpStart, cookiep = cookies; 1861 dp < dpEnd; 1862 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) { 1863 off += dp->d_reclen; 1864 *cookiep++ = (u_long) off; 1865 } 1866 *ap->a_ncookies = ncookies; 1867 *ap->a_cookies = cookies; 1868 } 1869 uio->uio_resid += lost; 1870 if (ap->a_eofflag) 1871 *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset; 1872 return (error); 1873} 1874 1875/* 1876 * Return target name of a symbolic link 1877 */ 1878static int 1879ufs_readlink(ap) 1880 struct vop_readlink_args /* { 1881 struct vnode *a_vp; 1882 struct uio *a_uio; 1883 struct ucred *a_cred; 1884 } */ *ap; 1885{ 1886 struct vnode *vp = ap->a_vp; 1887 struct inode *ip = VTOI(vp); 1888 doff_t isize; 1889 1890 isize = ip->i_size; 1891 if ((isize < vp->v_mount->mnt_maxsymlinklen) || 1892 DIP(ip, i_blocks) == 0) { /* XXX - for old fastlink support */ 1893 return (uiomove(SHORTLINK(ip), isize, ap->a_uio)); 1894 } 1895 return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); 1896} 1897 1898/* 1899 * Calculate the logical to physical mapping if not done already, 1900 * then call the device strategy routine. 1901 * 1902 * In order to be able to swap to a file, the ufs_bmaparray() operation may not 1903 * deadlock on memory. See ufs_bmap() for details. 1904 */ 1905static int 1906ufs_strategy(ap) 1907 struct vop_strategy_args /* { 1908 struct vnode *a_vp; 1909 struct buf *a_bp; 1910 } */ *ap; 1911{ 1912 struct buf *bp = ap->a_bp; 1913 struct vnode *vp = ap->a_vp; 1914 struct bufobj *bo; 1915 struct inode *ip; 1916 ufs2_daddr_t blkno; 1917 int error; 1918 1919 ip = VTOI(vp); 1920 if (bp->b_blkno == bp->b_lblkno) { 1921 error = ufs_bmaparray(vp, bp->b_lblkno, &blkno, bp, NULL, NULL); 1922 bp->b_blkno = blkno; 1923 if (error) { 1924 bp->b_error = error; 1925 bp->b_ioflags |= BIO_ERROR; 1926 bufdone(bp); 1927 return (error); 1928 } 1929 if ((long)bp->b_blkno == -1) 1930 vfs_bio_clrbuf(bp); 1931 } 1932 if ((long)bp->b_blkno == -1) { 1933 bufdone(bp); 1934 return (0); 1935 } 1936 bp->b_iooffset = dbtob(bp->b_blkno); 1937 bo = ip->i_umbufobj; 1938 BO_STRATEGY(bo, bp); 1939 return (0); 1940} 1941 1942/* 1943 * Print out the contents of an inode. 1944 */ 1945static int 1946ufs_print(ap) 1947 struct vop_print_args /* { 1948 struct vnode *a_vp; 1949 } */ *ap; 1950{ 1951 struct vnode *vp = ap->a_vp; 1952 struct inode *ip = VTOI(vp); 1953 1954 printf("\tino %lu, on dev %s", (u_long)ip->i_number, 1955 devtoname(ip->i_dev)); 1956 if (vp->v_type == VFIFO) 1957 fifo_printinfo(vp); 1958 printf("\n"); 1959 return (0); 1960} 1961 1962/* 1963 * Close wrapper for fifos. 1964 * 1965 * Update the times on the inode then do device close. 1966 */ 1967static int 1968ufsfifo_close(ap) 1969 struct vop_close_args /* { 1970 struct vnode *a_vp; 1971 int a_fflag; 1972 struct ucred *a_cred; 1973 struct thread *a_td; 1974 } */ *ap; 1975{ 1976 struct vnode *vp = ap->a_vp; 1977 1978 VI_LOCK(vp); 1979 if (vp->v_usecount > 1) 1980 ufs_itimes(vp); 1981 VI_UNLOCK(vp); 1982 return (fifo_specops.vop_close(ap)); 1983} 1984 1985/* 1986 * Kqfilter wrapper for fifos. 1987 * 1988 * Fall through to ufs kqfilter routines if needed 1989 */ 1990static int 1991ufsfifo_kqfilter(ap) 1992 struct vop_kqfilter_args *ap; 1993{ 1994 int error; 1995 1996 error = fifo_specops.vop_kqfilter(ap); 1997 if (error) 1998 error = ufs_kqfilter(ap); 1999 return (error); 2000} 2001 2002/* 2003 * Return POSIX pathconf information applicable to ufs filesystems. 2004 */ 2005static int 2006ufs_pathconf(ap) 2007 struct vop_pathconf_args /* { 2008 struct vnode *a_vp; 2009 int a_name; 2010 int *a_retval; 2011 } */ *ap; 2012{ 2013 int error; 2014 2015 error = 0; 2016 switch (ap->a_name) { 2017 case _PC_LINK_MAX: 2018 *ap->a_retval = LINK_MAX; 2019 break; 2020 case _PC_NAME_MAX: 2021 *ap->a_retval = NAME_MAX; 2022 break; 2023 case _PC_PATH_MAX: 2024 *ap->a_retval = PATH_MAX; 2025 break; 2026 case _PC_PIPE_BUF: 2027 *ap->a_retval = PIPE_BUF; 2028 break; 2029 case _PC_CHOWN_RESTRICTED: 2030 *ap->a_retval = 1; 2031 break; 2032 case _PC_NO_TRUNC: 2033 *ap->a_retval = 1; 2034 break; 2035 case _PC_ACL_EXTENDED: 2036#ifdef UFS_ACL 2037 if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS) 2038 *ap->a_retval = 1; 2039 else 2040 *ap->a_retval = 0; 2041#else 2042 *ap->a_retval = 0; 2043#endif 2044 break; 2045 case _PC_ACL_PATH_MAX: 2046#ifdef UFS_ACL 2047 if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS) 2048 *ap->a_retval = ACL_MAX_ENTRIES; 2049 else 2050 *ap->a_retval = 3; 2051#else 2052 *ap->a_retval = 3; 2053#endif 2054 break; 2055 case _PC_MAC_PRESENT: 2056#ifdef MAC 2057 if (ap->a_vp->v_mount->mnt_flag & MNT_MULTILABEL) 2058 *ap->a_retval = 1; 2059 else 2060 *ap->a_retval = 0; 2061#else 2062 *ap->a_retval = 0; 2063#endif 2064 break; 2065 case _PC_ASYNC_IO: 2066 /* _PC_ASYNC_IO should have been handled by upper layers. */ 2067 KASSERT(0, ("_PC_ASYNC_IO should not get here")); 2068 error = EINVAL; 2069 break; 2070 case _PC_PRIO_IO: 2071 *ap->a_retval = 0; 2072 break; 2073 case _PC_SYNC_IO: 2074 *ap->a_retval = 0; 2075 break; 2076 case _PC_ALLOC_SIZE_MIN: 2077 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize; 2078 break; 2079 case _PC_FILESIZEBITS: 2080 *ap->a_retval = 64; 2081 break; 2082 case _PC_REC_INCR_XFER_SIZE: 2083 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; 2084 break; 2085 case _PC_REC_MAX_XFER_SIZE: 2086 *ap->a_retval = -1; /* means ``unlimited'' */ 2087 break; 2088 case _PC_REC_MIN_XFER_SIZE: 2089 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; 2090 break; 2091 case _PC_REC_XFER_ALIGN: 2092 *ap->a_retval = PAGE_SIZE; 2093 break; 2094 case _PC_SYMLINK_MAX: 2095 *ap->a_retval = MAXPATHLEN; 2096 break; 2097 2098 default: 2099 error = EINVAL; 2100 break; 2101 } 2102 return (error); 2103} 2104 2105/* 2106 * Advisory record locking support 2107 */ 2108static int 2109ufs_advlock(ap) 2110 struct vop_advlock_args /* { 2111 struct vnode *a_vp; 2112 caddr_t a_id; 2113 int a_op; 2114 struct flock *a_fl; 2115 int a_flags; 2116 } */ *ap; 2117{ 2118 struct inode *ip = VTOI(ap->a_vp); 2119 2120 return (lf_advlock(ap, &(ip->i_lockf), ip->i_size)); 2121} 2122 2123/* 2124 * Initialize the vnode associated with a new inode, handle aliased 2125 * vnodes. 2126 */ 2127int 2128ufs_vinit(mntp, fifoops, vpp) 2129 struct mount *mntp; 2130 struct vop_vector *fifoops; 2131 struct vnode **vpp; 2132{ 2133 struct inode *ip; 2134 struct vnode *vp; 2135 2136 vp = *vpp; 2137 ip = VTOI(vp); 2138 vp->v_type = IFTOVT(ip->i_mode); 2139 if (vp->v_type == VFIFO) 2140 vp->v_op = fifoops; 2141 ASSERT_VOP_LOCKED(vp, "ufs_vinit"); 2142 if (ip->i_number == ROOTINO) 2143 vp->v_vflag |= VV_ROOT; 2144 ip->i_modrev = init_va_filerev(); 2145 *vpp = vp; 2146 return (0); 2147} 2148 2149/* 2150 * Allocate a new inode. 2151 * Vnode dvp must be locked. 2152 */ 2153static int 2154ufs_makeinode(mode, dvp, vpp, cnp) 2155 int mode; 2156 struct vnode *dvp; 2157 struct vnode **vpp; 2158 struct componentname *cnp; 2159{ 2160 struct inode *ip, *pdir; 2161 struct direct newdir; 2162 struct vnode *tvp; 2163#ifdef UFS_ACL 2164 struct acl *acl; 2165#endif 2166 int error; 2167 2168 pdir = VTOI(dvp); 2169#ifdef DIAGNOSTIC 2170 if ((cnp->cn_flags & HASBUF) == 0) 2171 panic("ufs_makeinode: no name"); 2172#endif 2173 *vpp = NULL; 2174 if ((mode & IFMT) == 0) 2175 mode |= IFREG; 2176 2177 error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp); 2178 if (error) 2179 return (error); 2180 ip = VTOI(tvp); 2181 ip->i_gid = pdir->i_gid; 2182 DIP_SET(ip, i_gid, pdir->i_gid); 2183#ifdef SUIDDIR 2184 { 2185#ifdef QUOTA 2186 struct ucred ucred, *ucp; 2187 ucp = cnp->cn_cred; 2188#endif 2189 /* 2190 * If we are not the owner of the directory, 2191 * and we are hacking owners here, (only do this where told to) 2192 * and we are not giving it TO root, (would subvert quotas) 2193 * then go ahead and give it to the other user. 2194 * Note that this drops off the execute bits for security. 2195 */ 2196 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) && 2197 (pdir->i_mode & ISUID) && 2198 (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) { 2199 ip->i_uid = pdir->i_uid; 2200 DIP_SET(ip, i_uid, ip->i_uid); 2201 mode &= ~07111; 2202#ifdef QUOTA 2203 /* 2204 * Make sure the correct user gets charged 2205 * for the space. 2206 * Quickly knock up a dummy credential for the victim. 2207 * XXX This seems to never be accessed out of our 2208 * context so a stack variable is ok. 2209 */ 2210 ucred.cr_ref = 1; 2211 ucred.cr_uid = ip->i_uid; 2212 ucred.cr_ngroups = 1; 2213 ucred.cr_groups[0] = pdir->i_gid; 2214 ucp = &ucred; 2215#endif 2216 } else { 2217 ip->i_uid = cnp->cn_cred->cr_uid; 2218 DIP_SET(ip, i_uid, ip->i_uid); 2219 } 2220 2221#ifdef QUOTA 2222 if ((error = getinoquota(ip)) || 2223 (error = chkiq(ip, 1, ucp, 0))) { 2224 UFS_VFREE(tvp, ip->i_number, mode); 2225 vput(tvp); 2226 return (error); 2227 } 2228#endif 2229 } 2230#else /* !SUIDDIR */ 2231 ip->i_uid = cnp->cn_cred->cr_uid; 2232 DIP_SET(ip, i_uid, ip->i_uid); 2233#ifdef QUOTA 2234 if ((error = getinoquota(ip)) || 2235 (error = chkiq(ip, 1, cnp->cn_cred, 0))) { 2236 UFS_VFREE(tvp, ip->i_number, mode); 2237 vput(tvp); 2238 return (error); 2239 } 2240#endif 2241#endif /* !SUIDDIR */ 2242 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; 2243#ifdef UFS_ACL 2244 acl = NULL; 2245 if ((dvp->v_mount->mnt_flag & MNT_ACLS) != 0) { 2246 MALLOC(acl, struct acl *, sizeof(*acl), M_ACL, M_WAITOK); 2247 2248 /* 2249 * Retrieve default ACL for parent, if any. 2250 */ 2251 error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cnp->cn_cred, 2252 cnp->cn_thread); 2253 switch (error) { 2254 case 0: 2255 /* 2256 * Retrieved a default ACL, so merge mode and ACL if 2257 * necessary. 2258 */ 2259 if (acl->acl_cnt != 0) { 2260 /* 2261 * Two possible ways for default ACL to not 2262 * be present. First, the EA can be 2263 * undefined, or second, the default ACL can 2264 * be blank. If it's blank, fall through to 2265 * the it's not defined case. 2266 */ 2267 mode = acl_posix1e_newfilemode(mode, acl); 2268 ip->i_mode = mode; 2269 DIP_SET(ip, i_mode, mode); 2270 ufs_sync_acl_from_inode(ip, acl); 2271 break; 2272 } 2273 /* FALLTHROUGH */ 2274 2275 case EOPNOTSUPP: 2276 /* 2277 * Just use the mode as-is. 2278 */ 2279 ip->i_mode = mode; 2280 DIP_SET(ip, i_mode, mode); 2281 FREE(acl, M_ACL); 2282 acl = NULL; 2283 break; 2284 2285 default: 2286 UFS_VFREE(tvp, ip->i_number, mode); 2287 vput(tvp); 2288 FREE(acl, M_ACL); 2289 acl = NULL; 2290 return (error); 2291 } 2292 } else { 2293#endif 2294 ip->i_mode = mode; 2295 DIP_SET(ip, i_mode, mode); 2296#ifdef UFS_ACL 2297 } 2298#endif 2299 tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ 2300 ip->i_effnlink = 1; 2301 ip->i_nlink = 1; 2302 DIP_SET(ip, i_nlink, 1); 2303 if (DOINGSOFTDEP(tvp)) 2304 softdep_change_linkcnt(ip); 2305 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && 2306 suser_cred(cnp->cn_cred, SUSER_ALLOWJAIL)) { 2307 ip->i_mode &= ~ISGID; 2308 DIP_SET(ip, i_mode, ip->i_mode); 2309 } 2310 2311 if (cnp->cn_flags & ISWHITEOUT) { 2312 ip->i_flags |= UF_OPAQUE; 2313 DIP_SET(ip, i_flags, ip->i_flags); 2314 } 2315 2316 /* 2317 * Make sure inode goes to disk before directory entry. 2318 */ 2319 error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp))); 2320 if (error) 2321 goto bad; 2322#ifdef MAC 2323 if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) { 2324 error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount, 2325 dvp, tvp, cnp); 2326 if (error) 2327 goto bad; 2328 } 2329#endif 2330#ifdef UFS_ACL 2331 if (acl != NULL) { 2332 /* 2333 * XXX: If we abort now, will Soft Updates notify the extattr 2334 * code that the EAs for the file need to be released? 2335 */ 2336 error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cnp->cn_cred, 2337 cnp->cn_thread); 2338 switch (error) { 2339 case 0: 2340 break; 2341 2342 case EOPNOTSUPP: 2343 /* 2344 * XXX: This should not happen, as EOPNOTSUPP above was 2345 * supposed to free acl. 2346 */ 2347 printf("ufs_makeinode: VOP_GETACL() but no " 2348 "VOP_SETACL()\n"); 2349 /* panic("ufs_makeinode: VOP_GETACL() but no " 2350 "VOP_SETACL()"); */ 2351 break; 2352 2353 default: 2354 FREE(acl, M_ACL); 2355 goto bad; 2356 } 2357 FREE(acl, M_ACL); 2358 } 2359#endif /* !UFS_ACL */ 2360 ufs_makedirentry(ip, cnp, &newdir); 2361 error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL); 2362 if (error) 2363 goto bad; 2364 *vpp = tvp; 2365 return (0); 2366 2367bad: 2368 /* 2369 * Write error occurred trying to update the inode 2370 * or the directory so must deallocate the inode. 2371 */ 2372 ip->i_effnlink = 0; 2373 ip->i_nlink = 0; 2374 DIP_SET(ip, i_nlink, 0); 2375 ip->i_flag |= IN_CHANGE; 2376 if (DOINGSOFTDEP(tvp)) 2377 softdep_change_linkcnt(ip); 2378 vput(tvp); 2379 return (error); 2380} 2381 2382static struct filterops ufsread_filtops = 2383 { 1, NULL, filt_ufsdetach, filt_ufsread }; 2384static struct filterops ufswrite_filtops = 2385 { 1, NULL, filt_ufsdetach, filt_ufswrite }; 2386static struct filterops ufsvnode_filtops = 2387 { 1, NULL, filt_ufsdetach, filt_ufsvnode }; 2388 2389static int 2390ufs_kqfilter(ap) 2391 struct vop_kqfilter_args /* { 2392 struct vnode *a_vp; 2393 struct knote *a_kn; 2394 } */ *ap; 2395{ 2396 struct vnode *vp = ap->a_vp; 2397 struct knote *kn = ap->a_kn; 2398 2399 switch (kn->kn_filter) { 2400 case EVFILT_READ: 2401 kn->kn_fop = &ufsread_filtops; 2402 break; 2403 case EVFILT_WRITE: 2404 kn->kn_fop = &ufswrite_filtops; 2405 break; 2406 case EVFILT_VNODE: 2407 kn->kn_fop = &ufsvnode_filtops; 2408 break; 2409 default: 2410 return (1); 2411 } 2412 2413 kn->kn_hook = (caddr_t)vp; 2414 2415 if (vp->v_pollinfo == NULL) 2416 v_addpollinfo(vp); 2417 if (vp->v_pollinfo == NULL) 2418 return ENOMEM; 2419 knlist_add(&vp->v_pollinfo->vpi_selinfo.si_note, kn, 0); 2420 2421 return (0); 2422} 2423 2424static void 2425filt_ufsdetach(struct knote *kn) 2426{ 2427 struct vnode *vp = (struct vnode *)kn->kn_hook; 2428 2429 KASSERT(vp->v_pollinfo != NULL, ("Mising v_pollinfo")); 2430 knlist_remove(&vp->v_pollinfo->vpi_selinfo.si_note, kn, 0); 2431} 2432 2433/*ARGSUSED*/ 2434static int 2435filt_ufsread(struct knote *kn, long hint) 2436{ 2437 struct vnode *vp = (struct vnode *)kn->kn_hook; 2438 struct inode *ip = VTOI(vp); 2439 2440 /* 2441 * filesystem is gone, so set the EOF flag and schedule 2442 * the knote for deletion. 2443 */ 2444 if (hint == NOTE_REVOKE) { 2445 kn->kn_flags |= (EV_EOF | EV_ONESHOT); 2446 return (1); 2447 } 2448 2449 kn->kn_data = ip->i_size - kn->kn_fp->f_offset; 2450 return (kn->kn_data != 0); 2451} 2452 2453/*ARGSUSED*/ 2454static int 2455filt_ufswrite(struct knote *kn, long hint) 2456{ 2457 2458 /* 2459 * filesystem is gone, so set the EOF flag and schedule 2460 * the knote for deletion. 2461 */ 2462 if (hint == NOTE_REVOKE) 2463 kn->kn_flags |= (EV_EOF | EV_ONESHOT); 2464 2465 kn->kn_data = 0; 2466 return (1); 2467} 2468 2469static int 2470filt_ufsvnode(struct knote *kn, long hint) 2471{ 2472 2473 if (kn->kn_sfflags & hint) 2474 kn->kn_fflags |= hint; 2475 if (hint == NOTE_REVOKE) { 2476 kn->kn_flags |= EV_EOF; 2477 return (1); 2478 } 2479 return (kn->kn_fflags != 0); 2480} 2481 2482/* Global vfs data structures for ufs. */ 2483struct vop_vector ufs_vnodeops = { 2484 .vop_default = &default_vnodeops, 2485 .vop_fsync = VOP_PANIC, 2486 .vop_read = VOP_PANIC, 2487 .vop_reallocblks = VOP_PANIC, 2488 .vop_write = VOP_PANIC, 2489 .vop_access = ufs_access, 2490 .vop_advlock = ufs_advlock, 2491 .vop_bmap = ufs_bmap, 2492 .vop_cachedlookup = ufs_lookup, 2493 .vop_close = ufs_close, 2494 .vop_create = ufs_create, 2495 .vop_getattr = ufs_getattr, 2496 .vop_inactive = ufs_inactive, 2497 .vop_link = ufs_link, 2498 .vop_lookup = vfs_cache_lookup, 2499 .vop_mkdir = ufs_mkdir, 2500 .vop_mknod = ufs_mknod, 2501 .vop_open = ufs_open, 2502 .vop_pathconf = ufs_pathconf, 2503 .vop_poll = vop_stdpoll, 2504 .vop_kqfilter = ufs_kqfilter, 2505 .vop_print = ufs_print, 2506 .vop_readdir = ufs_readdir, 2507 .vop_readlink = ufs_readlink, 2508 .vop_reclaim = ufs_reclaim, 2509 .vop_remove = ufs_remove, 2510 .vop_rename = ufs_rename, 2511 .vop_rmdir = ufs_rmdir, 2512 .vop_setattr = ufs_setattr, 2513#ifdef MAC 2514 .vop_setlabel = vop_stdsetlabel_ea, 2515#endif 2516 .vop_strategy = ufs_strategy, 2517 .vop_symlink = ufs_symlink, 2518 .vop_whiteout = ufs_whiteout, 2519#ifdef UFS_EXTATTR 2520 .vop_getextattr = ufs_getextattr, 2521 .vop_deleteextattr = ufs_deleteextattr, 2522 .vop_setextattr = ufs_setextattr, 2523#endif 2524#ifdef UFS_ACL 2525 .vop_getacl = ufs_getacl, 2526 .vop_setacl = ufs_setacl, 2527 .vop_aclcheck = ufs_aclcheck, 2528#endif 2529}; 2530 2531struct vop_vector ufs_fifoops = { 2532 .vop_default = &fifo_specops, 2533 .vop_fsync = VOP_PANIC, 2534 .vop_access = ufs_access, 2535 .vop_close = ufsfifo_close, 2536 .vop_getattr = ufs_getattr, 2537 .vop_inactive = ufs_inactive, 2538 .vop_kqfilter = ufsfifo_kqfilter, 2539 .vop_print = ufs_print, 2540 .vop_read = VOP_PANIC, 2541 .vop_reclaim = ufs_reclaim, 2542 .vop_setattr = ufs_setattr, 2543#ifdef MAC 2544 .vop_setlabel = vop_stdsetlabel_ea, 2545#endif 2546 .vop_write = VOP_PANIC, 2547#ifdef UFS_EXTATTR 2548 .vop_getextattr = ufs_getextattr, 2549 .vop_deleteextattr = ufs_deleteextattr, 2550 .vop_setextattr = ufs_setextattr, 2551#endif 2552#ifdef UFS_ACL 2553 .vop_getacl = ufs_getacl, 2554 .vop_setacl = ufs_setacl, 2555 .vop_aclcheck = ufs_aclcheck, 2556#endif 2557}; 2558