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