1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1994 Jan-Simon Pendry 5 * Copyright (c) 1994 6 * The Regents of the University of California. All rights reserved. 7 * Copyright (c) 2005, 2006, 2012 Masanori Ozawa <ozawa@ongs.co.jp>, ONGS Inc. 8 * Copyright (c) 2006, 2012 Daichi Goto <daichi@freebsd.org> 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Jan-Simon Pendry. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)union_subr.c 8.20 (Berkeley) 5/20/95 38 * $FreeBSD$ 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/ktr.h> 45 #include <sys/lock.h> 46 #include <sys/mutex.h> 47 #include <sys/malloc.h> 48 #include <sys/mount.h> 49 #include <sys/namei.h> 50 #include <sys/proc.h> 51 #include <sys/vnode.h> 52 #include <sys/dirent.h> 53 #include <sys/fcntl.h> 54 #include <sys/filedesc.h> 55 #include <sys/stat.h> 56 #include <sys/sysctl.h> 57 #include <sys/taskqueue.h> 58 #include <sys/resourcevar.h> 59 60 #include <security/mac/mac_framework.h> 61 62 #include <vm/uma.h> 63 64 #include <fs/unionfs/union.h> 65 66 #define NUNIONFSNODECACHE 16 67 68 static MALLOC_DEFINE(M_UNIONFSHASH, "UNIONFS hash", "UNIONFS hash table"); 69 MALLOC_DEFINE(M_UNIONFSNODE, "UNIONFS node", "UNIONFS vnode private part"); 70 MALLOC_DEFINE(M_UNIONFSPATH, "UNIONFS path", "UNIONFS path private part"); 71 72 static struct task unionfs_deferred_rele_task; 73 static struct mtx unionfs_deferred_rele_lock; 74 static STAILQ_HEAD(, unionfs_node) unionfs_deferred_rele_list = 75 STAILQ_HEAD_INITIALIZER(unionfs_deferred_rele_list); 76 static TASKQUEUE_DEFINE_THREAD(unionfs_rele); 77 78 unsigned int unionfs_ndeferred = 0; 79 SYSCTL_UINT(_vfs, OID_AUTO, unionfs_ndeferred, CTLFLAG_RD, 80 &unionfs_ndeferred, 0, "unionfs deferred vnode release"); 81 82 static void unionfs_deferred_rele(void *, int); 83 84 /* 85 * Initialize 86 */ 87 int 88 unionfs_init(struct vfsconf *vfsp) 89 { 90 UNIONFSDEBUG("unionfs_init\n"); /* printed during system boot */ 91 TASK_INIT(&unionfs_deferred_rele_task, 0, unionfs_deferred_rele, NULL); 92 mtx_init(&unionfs_deferred_rele_lock, "uniondefr", NULL, MTX_DEF); 93 return (0); 94 } 95 96 /* 97 * Uninitialize 98 */ 99 int 100 unionfs_uninit(struct vfsconf *vfsp) 101 { 102 taskqueue_quiesce(taskqueue_unionfs_rele); 103 taskqueue_free(taskqueue_unionfs_rele); 104 mtx_destroy(&unionfs_deferred_rele_lock); 105 return (0); 106 } 107 108 static void 109 unionfs_deferred_rele(void *arg __unused, int pending __unused) 110 { 111 STAILQ_HEAD(, unionfs_node) local_rele_list; 112 struct unionfs_node *unp, *tunp; 113 unsigned int ndeferred; 114 115 ndeferred = 0; 116 STAILQ_INIT(&local_rele_list); 117 mtx_lock(&unionfs_deferred_rele_lock); 118 STAILQ_CONCAT(&local_rele_list, &unionfs_deferred_rele_list); 119 mtx_unlock(&unionfs_deferred_rele_lock); 120 STAILQ_FOREACH_SAFE(unp, &local_rele_list, un_rele, tunp) { 121 ++ndeferred; 122 MPASS(unp->un_dvp != NULL); 123 vrele(unp->un_dvp); 124 free(unp, M_UNIONFSNODE); 125 } 126 127 /* We expect this function to be single-threaded, thus no atomic */ 128 unionfs_ndeferred += ndeferred; 129 } 130 131 static struct unionfs_node_hashhead * 132 unionfs_get_hashhead(struct vnode *dvp, char *path) 133 { 134 struct unionfs_node *unp; 135 int count; 136 char hash; 137 138 hash = 0; 139 unp = VTOUNIONFS(dvp); 140 if (path != NULL) { 141 for (count = 0; path[count]; count++) 142 hash += path[count]; 143 } 144 145 return (&(unp->un_hashtbl[hash & (unp->un_hashmask)])); 146 } 147 148 /* 149 * Get the cached vnode. 150 */ 151 static struct vnode * 152 unionfs_get_cached_vnode(struct vnode *uvp, struct vnode *lvp, 153 struct vnode *dvp, char *path) 154 { 155 struct unionfs_node_hashhead *hd; 156 struct unionfs_node *unp; 157 struct vnode *vp; 158 159 KASSERT((uvp == NULLVP || uvp->v_type == VDIR), 160 ("unionfs_get_cached_vnode: v_type != VDIR")); 161 KASSERT((lvp == NULLVP || lvp->v_type == VDIR), 162 ("unionfs_get_cached_vnode: v_type != VDIR")); 163 164 VI_LOCK(dvp); 165 hd = unionfs_get_hashhead(dvp, path); 166 LIST_FOREACH(unp, hd, un_hash) { 167 if (!strcmp(unp->un_path, path)) { 168 vp = UNIONFSTOV(unp); 169 VI_LOCK_FLAGS(vp, MTX_DUPOK); 170 VI_UNLOCK(dvp); 171 vp->v_iflag &= ~VI_OWEINACT; 172 if (VN_IS_DOOMED(vp) || 173 ((vp->v_iflag & VI_DOINGINACT) != 0)) { 174 VI_UNLOCK(vp); 175 vp = NULLVP; 176 } else 177 VI_UNLOCK(vp); 178 return (vp); 179 } 180 } 181 VI_UNLOCK(dvp); 182 183 return (NULLVP); 184 } 185 186 /* 187 * Add the new vnode into cache. 188 */ 189 static struct vnode * 190 unionfs_ins_cached_vnode(struct unionfs_node *uncp, 191 struct vnode *dvp, char *path) 192 { 193 struct unionfs_node_hashhead *hd; 194 struct unionfs_node *unp; 195 struct vnode *vp; 196 197 KASSERT((uncp->un_uppervp==NULLVP || uncp->un_uppervp->v_type==VDIR), 198 ("unionfs_ins_cached_vnode: v_type != VDIR")); 199 KASSERT((uncp->un_lowervp==NULLVP || uncp->un_lowervp->v_type==VDIR), 200 ("unionfs_ins_cached_vnode: v_type != VDIR")); 201 202 VI_LOCK(dvp); 203 hd = unionfs_get_hashhead(dvp, path); 204 LIST_FOREACH(unp, hd, un_hash) { 205 if (!strcmp(unp->un_path, path)) { 206 vp = UNIONFSTOV(unp); 207 VI_LOCK_FLAGS(vp, MTX_DUPOK); 208 vp->v_iflag &= ~VI_OWEINACT; 209 if (VN_IS_DOOMED(vp) || 210 ((vp->v_iflag & VI_DOINGINACT) != 0)) { 211 LIST_INSERT_HEAD(hd, uncp, un_hash); 212 VI_UNLOCK(vp); 213 vp = NULLVP; 214 } else 215 VI_UNLOCK(vp); 216 VI_UNLOCK(dvp); 217 return (vp); 218 } 219 } 220 221 LIST_INSERT_HEAD(hd, uncp, un_hash); 222 VI_UNLOCK(dvp); 223 224 return (NULLVP); 225 } 226 227 /* 228 * Remove the vnode. 229 */ 230 static void 231 unionfs_rem_cached_vnode(struct unionfs_node *unp, struct vnode *dvp) 232 { 233 KASSERT((unp != NULL), ("unionfs_rem_cached_vnode: null node")); 234 KASSERT((dvp != NULLVP), 235 ("unionfs_rem_cached_vnode: null parent vnode")); 236 KASSERT((unp->un_hash.le_prev != NULL), 237 ("unionfs_rem_cached_vnode: null hash")); 238 239 VI_LOCK(dvp); 240 LIST_REMOVE(unp, un_hash); 241 unp->un_hash.le_next = NULL; 242 unp->un_hash.le_prev = NULL; 243 VI_UNLOCK(dvp); 244 } 245 246 /* 247 * Make a new or get existing unionfs node. 248 * 249 * uppervp and lowervp should be unlocked. Because if new unionfs vnode is 250 * locked, uppervp or lowervp is locked too. In order to prevent dead lock, 251 * you should not lock plurality simultaneously. 252 */ 253 int 254 unionfs_nodeget(struct mount *mp, struct vnode *uppervp, 255 struct vnode *lowervp, struct vnode *dvp, struct vnode **vpp, 256 struct componentname *cnp, struct thread *td) 257 { 258 char *path; 259 struct unionfs_mount *ump; 260 struct unionfs_node *unp; 261 struct vnode *vp; 262 int error; 263 int lkflags; 264 enum vtype vt; 265 266 ump = MOUNTTOUNIONFSMOUNT(mp); 267 lkflags = (cnp ? cnp->cn_lkflags : 0); 268 path = (cnp ? cnp->cn_nameptr : NULL); 269 *vpp = NULLVP; 270 271 if (uppervp == NULLVP && lowervp == NULLVP) 272 panic("unionfs_nodeget: upper and lower is null"); 273 274 vt = (uppervp != NULLVP ? uppervp->v_type : lowervp->v_type); 275 276 /* If it has no ISLASTCN flag, path check is skipped. */ 277 if (cnp && !(cnp->cn_flags & ISLASTCN)) 278 path = NULL; 279 280 /* check the cache */ 281 if (path != NULL && dvp != NULLVP && vt == VDIR) { 282 vp = unionfs_get_cached_vnode(uppervp, lowervp, dvp, path); 283 if (vp != NULLVP) { 284 vref(vp); 285 *vpp = vp; 286 goto unionfs_nodeget_out; 287 } 288 } 289 290 if ((uppervp == NULLVP || ump->um_uppervp != uppervp) || 291 (lowervp == NULLVP || ump->um_lowervp != lowervp)) { 292 /* dvp will be NULLVP only in case of root vnode. */ 293 if (dvp == NULLVP) 294 return (EINVAL); 295 } 296 unp = malloc(sizeof(struct unionfs_node), 297 M_UNIONFSNODE, M_WAITOK | M_ZERO); 298 299 error = getnewvnode("unionfs", mp, &unionfs_vnodeops, &vp); 300 if (error != 0) { 301 free(unp, M_UNIONFSNODE); 302 return (error); 303 } 304 error = insmntque(vp, mp); /* XXX: Too early for mpsafe fs */ 305 if (error != 0) { 306 free(unp, M_UNIONFSNODE); 307 return (error); 308 } 309 if (dvp != NULLVP) 310 vref(dvp); 311 if (uppervp != NULLVP) 312 vref(uppervp); 313 if (lowervp != NULLVP) 314 vref(lowervp); 315 316 if (vt == VDIR) 317 unp->un_hashtbl = hashinit(NUNIONFSNODECACHE, M_UNIONFSHASH, 318 &(unp->un_hashmask)); 319 320 unp->un_vnode = vp; 321 unp->un_uppervp = uppervp; 322 unp->un_lowervp = lowervp; 323 unp->un_dvp = dvp; 324 if (uppervp != NULLVP) 325 vp->v_vnlock = uppervp->v_vnlock; 326 else 327 vp->v_vnlock = lowervp->v_vnlock; 328 329 if (path != NULL) { 330 unp->un_path = malloc(cnp->cn_namelen + 1, 331 M_UNIONFSPATH, M_WAITOK | M_ZERO); 332 bcopy(cnp->cn_nameptr, unp->un_path, cnp->cn_namelen); 333 unp->un_path[cnp->cn_namelen] = '\0'; 334 unp->un_pathlen = cnp->cn_namelen; 335 } 336 vp->v_type = vt; 337 vp->v_data = unp; 338 339 if ((uppervp != NULLVP && ump->um_uppervp == uppervp) && 340 (lowervp != NULLVP && ump->um_lowervp == lowervp)) 341 vp->v_vflag |= VV_ROOT; 342 343 if (path != NULL && dvp != NULLVP && vt == VDIR) 344 *vpp = unionfs_ins_cached_vnode(unp, dvp, path); 345 if ((*vpp) != NULLVP) { 346 if (dvp != NULLVP) 347 vrele(dvp); 348 if (uppervp != NULLVP) 349 vrele(uppervp); 350 if (lowervp != NULLVP) 351 vrele(lowervp); 352 353 unp->un_uppervp = NULLVP; 354 unp->un_lowervp = NULLVP; 355 unp->un_dvp = NULLVP; 356 vrele(vp); 357 vp = *vpp; 358 vref(vp); 359 } else 360 *vpp = vp; 361 362 unionfs_nodeget_out: 363 if (lkflags & LK_TYPE_MASK) 364 vn_lock(vp, lkflags | LK_RETRY); 365 366 return (0); 367 } 368 369 /* 370 * Clean up the unionfs node. 371 */ 372 void 373 unionfs_noderem(struct vnode *vp, struct thread *td) 374 { 375 struct unionfs_node *unp, *unp_t1, *unp_t2; 376 struct unionfs_node_hashhead *hd; 377 struct unionfs_node_status *unsp, *unsp_tmp; 378 struct vnode *lvp; 379 struct vnode *uvp; 380 struct vnode *dvp; 381 int count; 382 383 /* 384 * Use the interlock to protect the clearing of v_data to 385 * prevent faults in unionfs_lock(). 386 */ 387 VI_LOCK(vp); 388 unp = VTOUNIONFS(vp); 389 lvp = unp->un_lowervp; 390 uvp = unp->un_uppervp; 391 dvp = unp->un_dvp; 392 unp->un_lowervp = unp->un_uppervp = NULLVP; 393 vp->v_vnlock = &(vp->v_lock); 394 vp->v_data = NULL; 395 vp->v_object = NULL; 396 if (vp->v_writecount > 0) { 397 if (uvp != NULL) 398 VOP_ADD_WRITECOUNT(uvp, -vp->v_writecount); 399 else if (lvp != NULL) 400 VOP_ADD_WRITECOUNT(lvp, -vp->v_writecount); 401 } else if (vp->v_writecount < 0) 402 vp->v_writecount = 0; 403 VI_UNLOCK(vp); 404 405 if (lvp != NULLVP) 406 VOP_UNLOCK(lvp); 407 if (uvp != NULLVP) 408 VOP_UNLOCK(uvp); 409 410 if (dvp != NULLVP && unp->un_hash.le_prev != NULL) 411 unionfs_rem_cached_vnode(unp, dvp); 412 413 if (lockmgr(vp->v_vnlock, LK_EXCLUSIVE, VI_MTX(vp)) != 0) 414 panic("the lock for deletion is unacquirable."); 415 416 if (lvp != NULLVP) 417 vrele(lvp); 418 if (uvp != NULLVP) 419 vrele(uvp); 420 if (unp->un_path != NULL) { 421 free(unp->un_path, M_UNIONFSPATH); 422 unp->un_path = NULL; 423 unp->un_pathlen = 0; 424 } 425 426 if (unp->un_hashtbl != NULL) { 427 for (count = 0; count <= unp->un_hashmask; count++) { 428 hd = unp->un_hashtbl + count; 429 LIST_FOREACH_SAFE(unp_t1, hd, un_hash, unp_t2) { 430 LIST_REMOVE(unp_t1, un_hash); 431 unp_t1->un_hash.le_next = NULL; 432 unp_t1->un_hash.le_prev = NULL; 433 } 434 } 435 hashdestroy(unp->un_hashtbl, M_UNIONFSHASH, unp->un_hashmask); 436 } 437 438 LIST_FOREACH_SAFE(unsp, &(unp->un_unshead), uns_list, unsp_tmp) { 439 LIST_REMOVE(unsp, uns_list); 440 free(unsp, M_TEMP); 441 } 442 if (dvp != NULLVP) { 443 mtx_lock(&unionfs_deferred_rele_lock); 444 STAILQ_INSERT_TAIL(&unionfs_deferred_rele_list, unp, un_rele); 445 mtx_unlock(&unionfs_deferred_rele_lock); 446 taskqueue_enqueue(taskqueue_unionfs_rele, 447 &unionfs_deferred_rele_task); 448 } else 449 free(unp, M_UNIONFSNODE); 450 } 451 452 /* 453 * Get the unionfs node status. 454 * You need exclusive lock this vnode. 455 */ 456 void 457 unionfs_get_node_status(struct unionfs_node *unp, struct thread *td, 458 struct unionfs_node_status **unspp) 459 { 460 struct unionfs_node_status *unsp; 461 pid_t pid; 462 463 pid = td->td_proc->p_pid; 464 465 KASSERT(NULL != unspp, ("null pointer")); 466 ASSERT_VOP_ELOCKED(UNIONFSTOV(unp), "unionfs_get_node_status"); 467 468 LIST_FOREACH(unsp, &(unp->un_unshead), uns_list) { 469 if (unsp->uns_pid == pid) { 470 *unspp = unsp; 471 return; 472 } 473 } 474 475 /* create a new unionfs node status */ 476 unsp = malloc(sizeof(struct unionfs_node_status), 477 M_TEMP, M_WAITOK | M_ZERO); 478 479 unsp->uns_pid = pid; 480 LIST_INSERT_HEAD(&(unp->un_unshead), unsp, uns_list); 481 482 *unspp = unsp; 483 } 484 485 /* 486 * Remove the unionfs node status, if you can. 487 * You need exclusive lock this vnode. 488 */ 489 void 490 unionfs_tryrem_node_status(struct unionfs_node *unp, 491 struct unionfs_node_status *unsp) 492 { 493 KASSERT(NULL != unsp, ("null pointer")); 494 ASSERT_VOP_ELOCKED(UNIONFSTOV(unp), "unionfs_get_node_status"); 495 496 if (0 < unsp->uns_lower_opencnt || 0 < unsp->uns_upper_opencnt) 497 return; 498 499 LIST_REMOVE(unsp, uns_list); 500 free(unsp, M_TEMP); 501 } 502 503 /* 504 * Create upper node attr. 505 */ 506 void 507 unionfs_create_uppervattr_core(struct unionfs_mount *ump, struct vattr *lva, 508 struct vattr *uva, struct thread *td) 509 { 510 VATTR_NULL(uva); 511 uva->va_type = lva->va_type; 512 uva->va_atime = lva->va_atime; 513 uva->va_mtime = lva->va_mtime; 514 uva->va_ctime = lva->va_ctime; 515 516 switch (ump->um_copymode) { 517 case UNIONFS_TRANSPARENT: 518 uva->va_mode = lva->va_mode; 519 uva->va_uid = lva->va_uid; 520 uva->va_gid = lva->va_gid; 521 break; 522 case UNIONFS_MASQUERADE: 523 if (ump->um_uid == lva->va_uid) { 524 uva->va_mode = lva->va_mode & 077077; 525 uva->va_mode |= (lva->va_type == VDIR ? 526 ump->um_udir : ump->um_ufile) & 0700; 527 uva->va_uid = lva->va_uid; 528 uva->va_gid = lva->va_gid; 529 } else { 530 uva->va_mode = (lva->va_type == VDIR ? 531 ump->um_udir : ump->um_ufile); 532 uva->va_uid = ump->um_uid; 533 uva->va_gid = ump->um_gid; 534 } 535 break; 536 default: /* UNIONFS_TRADITIONAL */ 537 uva->va_mode = 0777 & ~td->td_proc->p_pd->pd_cmask; 538 uva->va_uid = ump->um_uid; 539 uva->va_gid = ump->um_gid; 540 break; 541 } 542 } 543 544 /* 545 * Create upper node attr. 546 */ 547 int 548 unionfs_create_uppervattr(struct unionfs_mount *ump, struct vnode *lvp, 549 struct vattr *uva, struct ucred *cred, struct thread *td) 550 { 551 struct vattr lva; 552 int error; 553 554 if ((error = VOP_GETATTR(lvp, &lva, cred))) 555 return (error); 556 557 unionfs_create_uppervattr_core(ump, &lva, uva, td); 558 559 return (error); 560 } 561 562 /* 563 * relookup 564 * 565 * dvp should be locked on entry and will be locked on return. 566 * 567 * If an error is returned, *vpp will be invalid, otherwise it will hold a 568 * locked, referenced vnode. If *vpp == dvp then remember that only one 569 * LK_EXCLUSIVE lock is held. 570 */ 571 int 572 unionfs_relookup(struct vnode *dvp, struct vnode **vpp, 573 struct componentname *cnp, struct componentname *cn, struct thread *td, 574 char *path, int pathlen, u_long nameiop) 575 { 576 int error; 577 578 cn->cn_namelen = pathlen; 579 cn->cn_pnbuf = path; 580 cn->cn_nameiop = nameiop; 581 cn->cn_flags = (LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | ISLASTCN); 582 cn->cn_lkflags = LK_EXCLUSIVE; 583 cn->cn_thread = td; 584 cn->cn_cred = cnp->cn_cred; 585 cn->cn_nameptr = cn->cn_pnbuf; 586 587 if (nameiop == DELETE) 588 cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART)); 589 else if (RENAME == nameiop) 590 cn->cn_flags |= (cnp->cn_flags & SAVESTART); 591 else if (nameiop == CREATE) 592 cn->cn_flags |= NOCACHE; 593 594 vref(dvp); 595 VOP_UNLOCK(dvp); 596 597 if ((error = relookup(dvp, vpp, cn))) { 598 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 599 } else 600 vrele(dvp); 601 602 KASSERT((cn->cn_flags & HASBUF) != 0, 603 ("%s: HASBUF cleared", __func__)); 604 KASSERT((cn->cn_flags & SAVENAME) != 0, 605 ("%s: SAVENAME cleared", __func__)); 606 KASSERT(cn->cn_pnbuf == path, ("%s: cn_pnbuf changed", __func__)); 607 608 return (error); 609 } 610 611 /* 612 * relookup for CREATE namei operation. 613 * 614 * dvp is unionfs vnode. dvp should be locked. 615 * 616 * If it called 'unionfs_copyfile' function by unionfs_link etc, 617 * VOP_LOOKUP information is broken. 618 * So it need relookup in order to create link etc. 619 */ 620 int 621 unionfs_relookup_for_create(struct vnode *dvp, struct componentname *cnp, 622 struct thread *td) 623 { 624 struct vnode *udvp; 625 struct vnode *vp; 626 struct componentname cn; 627 int error; 628 629 udvp = UNIONFSVPTOUPPERVP(dvp); 630 vp = NULLVP; 631 632 error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr, 633 cnp->cn_namelen, CREATE); 634 if (error) 635 return (error); 636 637 if (vp != NULLVP) { 638 if (udvp == vp) 639 vrele(vp); 640 else 641 vput(vp); 642 643 error = EEXIST; 644 } 645 646 return (error); 647 } 648 649 /* 650 * relookup for DELETE namei operation. 651 * 652 * dvp is unionfs vnode. dvp should be locked. 653 */ 654 int 655 unionfs_relookup_for_delete(struct vnode *dvp, struct componentname *cnp, 656 struct thread *td) 657 { 658 struct vnode *udvp; 659 struct vnode *vp; 660 struct componentname cn; 661 int error; 662 663 udvp = UNIONFSVPTOUPPERVP(dvp); 664 vp = NULLVP; 665 666 error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr, 667 cnp->cn_namelen, DELETE); 668 if (error) 669 return (error); 670 671 if (vp == NULLVP) 672 error = ENOENT; 673 else { 674 if (udvp == vp) 675 vrele(vp); 676 else 677 vput(vp); 678 } 679 680 return (error); 681 } 682 683 /* 684 * relookup for RENAME namei operation. 685 * 686 * dvp is unionfs vnode. dvp should be locked. 687 */ 688 int 689 unionfs_relookup_for_rename(struct vnode *dvp, struct componentname *cnp, 690 struct thread *td) 691 { 692 struct vnode *udvp; 693 struct vnode *vp; 694 struct componentname cn; 695 int error; 696 697 udvp = UNIONFSVPTOUPPERVP(dvp); 698 vp = NULLVP; 699 700 error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr, 701 cnp->cn_namelen, RENAME); 702 if (error) 703 return (error); 704 705 if (vp != NULLVP) { 706 if (udvp == vp) 707 vrele(vp); 708 else 709 vput(vp); 710 } 711 712 return (error); 713 } 714 715 /* 716 * Update the unionfs_node. 717 * 718 * uvp is new locked upper vnode. unionfs vnode's lock will be exchanged to the 719 * uvp's lock and lower's lock will be unlocked. 720 */ 721 static void 722 unionfs_node_update(struct unionfs_node *unp, struct vnode *uvp, 723 struct thread *td) 724 { 725 struct vnode *vp; 726 struct vnode *lvp; 727 struct vnode *dvp; 728 unsigned count, lockrec; 729 730 vp = UNIONFSTOV(unp); 731 lvp = unp->un_lowervp; 732 ASSERT_VOP_ELOCKED(lvp, "unionfs_node_update"); 733 dvp = unp->un_dvp; 734 735 /* 736 * lock update 737 */ 738 VI_LOCK(vp); 739 unp->un_uppervp = uvp; 740 vp->v_vnlock = uvp->v_vnlock; 741 VI_UNLOCK(vp); 742 lockrec = lvp->v_vnlock->lk_recurse; 743 for (count = 0; count < lockrec; count++) 744 vn_lock(uvp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY); 745 746 /* 747 * cache update 748 */ 749 if (unp->un_path != NULL && dvp != NULLVP && vp->v_type == VDIR) { 750 static struct unionfs_node_hashhead *hd; 751 752 VI_LOCK(dvp); 753 hd = unionfs_get_hashhead(dvp, unp->un_path); 754 LIST_REMOVE(unp, un_hash); 755 LIST_INSERT_HEAD(hd, unp, un_hash); 756 VI_UNLOCK(dvp); 757 } 758 } 759 760 /* 761 * Create a new shadow dir. 762 * 763 * udvp should be locked on entry and will be locked on return. 764 * 765 * If no error returned, unp will be updated. 766 */ 767 int 768 unionfs_mkshadowdir(struct unionfs_mount *ump, struct vnode *udvp, 769 struct unionfs_node *unp, struct componentname *cnp, struct thread *td) 770 { 771 struct vnode *lvp; 772 struct vnode *uvp; 773 struct vattr va; 774 struct vattr lva; 775 struct nameidata nd; 776 struct mount *mp; 777 struct ucred *cred; 778 struct ucred *credbk; 779 struct uidinfo *rootinfo; 780 int error; 781 782 if (unp->un_uppervp != NULLVP) 783 return (EEXIST); 784 785 lvp = unp->un_lowervp; 786 uvp = NULLVP; 787 credbk = cnp->cn_cred; 788 789 /* Authority change to root */ 790 rootinfo = uifind((uid_t)0); 791 cred = crdup(cnp->cn_cred); 792 /* 793 * The calls to chgproccnt() are needed to compensate for change_ruid() 794 * calling chgproccnt(). 795 */ 796 chgproccnt(cred->cr_ruidinfo, 1, 0); 797 change_euid(cred, rootinfo); 798 change_ruid(cred, rootinfo); 799 change_svuid(cred, (uid_t)0); 800 uifree(rootinfo); 801 cnp->cn_cred = cred; 802 803 memset(&nd.ni_cnd, 0, sizeof(struct componentname)); 804 NDPREINIT(&nd); 805 806 if ((error = VOP_GETATTR(lvp, &lva, cnp->cn_cred))) 807 goto unionfs_mkshadowdir_abort; 808 809 if ((error = unionfs_relookup(udvp, &uvp, cnp, &nd.ni_cnd, td, 810 cnp->cn_nameptr, cnp->cn_namelen, CREATE))) 811 goto unionfs_mkshadowdir_abort; 812 if (uvp != NULLVP) { 813 if (udvp == uvp) 814 vrele(uvp); 815 else 816 vput(uvp); 817 818 error = EEXIST; 819 goto unionfs_mkshadowdir_abort; 820 } 821 822 if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH))) 823 goto unionfs_mkshadowdir_abort; 824 unionfs_create_uppervattr_core(ump, &lva, &va, td); 825 826 error = VOP_MKDIR(udvp, &uvp, &nd.ni_cnd, &va); 827 828 if (!error) { 829 unionfs_node_update(unp, uvp, td); 830 831 /* 832 * XXX The bug which cannot set uid/gid was corrected. 833 * Ignore errors. 834 */ 835 va.va_type = VNON; 836 VOP_SETATTR(uvp, &va, nd.ni_cnd.cn_cred); 837 } 838 vn_finished_write(mp); 839 840 unionfs_mkshadowdir_abort: 841 cnp->cn_cred = credbk; 842 chgproccnt(cred->cr_ruidinfo, -1, 0); 843 crfree(cred); 844 845 return (error); 846 } 847 848 /* 849 * Create a new whiteout. 850 * 851 * dvp should be locked on entry and will be locked on return. 852 */ 853 int 854 unionfs_mkwhiteout(struct vnode *dvp, struct componentname *cnp, 855 struct thread *td, char *path, int pathlen) 856 { 857 struct vnode *wvp; 858 struct nameidata nd; 859 struct mount *mp; 860 int error; 861 862 wvp = NULLVP; 863 NDPREINIT(&nd); 864 if ((error = unionfs_relookup(dvp, &wvp, cnp, &nd.ni_cnd, td, path, 865 pathlen, CREATE))) { 866 return (error); 867 } 868 if (wvp != NULLVP) { 869 if (dvp == wvp) 870 vrele(wvp); 871 else 872 vput(wvp); 873 874 return (EEXIST); 875 } 876 877 if ((error = vn_start_write(dvp, &mp, V_WAIT | PCATCH))) 878 goto unionfs_mkwhiteout_free_out; 879 error = VOP_WHITEOUT(dvp, &nd.ni_cnd, CREATE); 880 881 vn_finished_write(mp); 882 883 unionfs_mkwhiteout_free_out: 884 return (error); 885 } 886 887 /* 888 * Create a new vnode for create a new shadow file. 889 * 890 * If an error is returned, *vpp will be invalid, otherwise it will hold a 891 * locked, referenced and opened vnode. 892 * 893 * unp is never updated. 894 */ 895 static int 896 unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp, 897 struct unionfs_node *unp, struct vattr *uvap, struct thread *td) 898 { 899 struct unionfs_mount *ump; 900 struct vnode *vp; 901 struct vnode *lvp; 902 struct ucred *cred; 903 struct vattr lva; 904 struct nameidata nd; 905 int fmode; 906 int error; 907 908 ump = MOUNTTOUNIONFSMOUNT(UNIONFSTOV(unp)->v_mount); 909 vp = NULLVP; 910 lvp = unp->un_lowervp; 911 cred = td->td_ucred; 912 fmode = FFLAGS(O_WRONLY | O_CREAT | O_TRUNC | O_EXCL); 913 error = 0; 914 915 if ((error = VOP_GETATTR(lvp, &lva, cred)) != 0) 916 return (error); 917 unionfs_create_uppervattr_core(ump, &lva, uvap, td); 918 919 if (unp->un_path == NULL) 920 panic("unionfs: un_path is null"); 921 922 nd.ni_cnd.cn_namelen = unp->un_pathlen; 923 nd.ni_cnd.cn_pnbuf = unp->un_path; 924 nd.ni_cnd.cn_nameiop = CREATE; 925 nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | 926 ISLASTCN; 927 nd.ni_cnd.cn_lkflags = LK_EXCLUSIVE; 928 nd.ni_cnd.cn_thread = td; 929 nd.ni_cnd.cn_cred = cred; 930 nd.ni_cnd.cn_nameptr = nd.ni_cnd.cn_pnbuf; 931 NDPREINIT(&nd); 932 933 vref(udvp); 934 if ((error = relookup(udvp, &vp, &nd.ni_cnd)) != 0) 935 goto unionfs_vn_create_on_upper_free_out2; 936 vrele(udvp); 937 938 if (vp != NULLVP) { 939 if (vp == udvp) 940 vrele(vp); 941 else 942 vput(vp); 943 error = EEXIST; 944 goto unionfs_vn_create_on_upper_free_out1; 945 } 946 947 if ((error = VOP_CREATE(udvp, &vp, &nd.ni_cnd, uvap)) != 0) 948 goto unionfs_vn_create_on_upper_free_out1; 949 950 if ((error = VOP_OPEN(vp, fmode, cred, td, NULL)) != 0) { 951 vput(vp); 952 goto unionfs_vn_create_on_upper_free_out1; 953 } 954 error = VOP_ADD_WRITECOUNT(vp, 1); 955 CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", 956 __func__, vp, vp->v_writecount); 957 if (error == 0) { 958 *vpp = vp; 959 } else { 960 VOP_CLOSE(vp, fmode, cred, td); 961 } 962 963 unionfs_vn_create_on_upper_free_out1: 964 VOP_UNLOCK(udvp); 965 966 unionfs_vn_create_on_upper_free_out2: 967 KASSERT((nd.ni_cnd.cn_flags & HASBUF) != 0, 968 ("%s: HASBUF cleared", __func__)); 969 KASSERT((nd.ni_cnd.cn_flags & SAVENAME) != 0, 970 ("%s: SAVENAME cleared", __func__)); 971 KASSERT(nd.ni_cnd.cn_pnbuf == unp->un_path, 972 ("%s: cn_pnbuf changed", __func__)); 973 974 return (error); 975 } 976 977 /* 978 * Copy from lvp to uvp. 979 * 980 * lvp and uvp should be locked and opened on entry and will be locked and 981 * opened on return. 982 */ 983 static int 984 unionfs_copyfile_core(struct vnode *lvp, struct vnode *uvp, 985 struct ucred *cred, struct thread *td) 986 { 987 char *buf; 988 struct uio uio; 989 struct iovec iov; 990 off_t offset; 991 int count; 992 int error; 993 int bufoffset; 994 995 error = 0; 996 memset(&uio, 0, sizeof(uio)); 997 998 uio.uio_td = td; 999 uio.uio_segflg = UIO_SYSSPACE; 1000 uio.uio_offset = 0; 1001 1002 buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK); 1003 1004 while (error == 0) { 1005 offset = uio.uio_offset; 1006 1007 uio.uio_iov = &iov; 1008 uio.uio_iovcnt = 1; 1009 iov.iov_base = buf; 1010 iov.iov_len = MAXBSIZE; 1011 uio.uio_resid = iov.iov_len; 1012 uio.uio_rw = UIO_READ; 1013 1014 if ((error = VOP_READ(lvp, &uio, 0, cred)) != 0) 1015 break; 1016 if ((count = MAXBSIZE - uio.uio_resid) == 0) 1017 break; 1018 1019 bufoffset = 0; 1020 while (bufoffset < count) { 1021 uio.uio_iov = &iov; 1022 uio.uio_iovcnt = 1; 1023 iov.iov_base = buf + bufoffset; 1024 iov.iov_len = count - bufoffset; 1025 uio.uio_offset = offset + bufoffset; 1026 uio.uio_resid = iov.iov_len; 1027 uio.uio_rw = UIO_WRITE; 1028 1029 if ((error = VOP_WRITE(uvp, &uio, 0, cred)) != 0) 1030 break; 1031 1032 bufoffset += (count - bufoffset) - uio.uio_resid; 1033 } 1034 1035 uio.uio_offset = offset + bufoffset; 1036 } 1037 1038 free(buf, M_TEMP); 1039 1040 return (error); 1041 } 1042 1043 /* 1044 * Copy file from lower to upper. 1045 * 1046 * If you need copy of the contents, set 1 to docopy. Otherwise, set 0 to 1047 * docopy. 1048 * 1049 * If no error returned, unp will be updated. 1050 */ 1051 int 1052 unionfs_copyfile(struct unionfs_node *unp, int docopy, struct ucred *cred, 1053 struct thread *td) 1054 { 1055 struct mount *mp; 1056 struct vnode *udvp; 1057 struct vnode *lvp; 1058 struct vnode *uvp; 1059 struct vattr uva; 1060 int error; 1061 1062 lvp = unp->un_lowervp; 1063 uvp = NULLVP; 1064 1065 if ((UNIONFSTOV(unp)->v_mount->mnt_flag & MNT_RDONLY)) 1066 return (EROFS); 1067 if (unp->un_dvp == NULLVP) 1068 return (EINVAL); 1069 if (unp->un_uppervp != NULLVP) 1070 return (EEXIST); 1071 udvp = VTOUNIONFS(unp->un_dvp)->un_uppervp; 1072 if (udvp == NULLVP) 1073 return (EROFS); 1074 if ((udvp->v_mount->mnt_flag & MNT_RDONLY)) 1075 return (EROFS); 1076 1077 error = VOP_ACCESS(lvp, VREAD, cred, td); 1078 if (error != 0) 1079 return (error); 1080 1081 if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0) 1082 return (error); 1083 error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, td); 1084 if (error != 0) { 1085 vn_finished_write(mp); 1086 return (error); 1087 } 1088 1089 if (docopy != 0) { 1090 error = VOP_OPEN(lvp, FREAD, cred, td, NULL); 1091 if (error == 0) { 1092 error = unionfs_copyfile_core(lvp, uvp, cred, td); 1093 VOP_CLOSE(lvp, FREAD, cred, td); 1094 } 1095 } 1096 VOP_CLOSE(uvp, FWRITE, cred, td); 1097 VOP_ADD_WRITECOUNT_CHECKED(uvp, -1); 1098 CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", 1099 __func__, uvp, uvp->v_writecount); 1100 1101 vn_finished_write(mp); 1102 1103 if (error == 0) { 1104 /* Reset the attributes. Ignore errors. */ 1105 uva.va_type = VNON; 1106 VOP_SETATTR(uvp, &uva, cred); 1107 } 1108 1109 unionfs_node_update(unp, uvp, td); 1110 1111 return (error); 1112 } 1113 1114 /* 1115 * It checks whether vp can rmdir. (check empty) 1116 * 1117 * vp is unionfs vnode. 1118 * vp should be locked. 1119 */ 1120 int 1121 unionfs_check_rmdir(struct vnode *vp, struct ucred *cred, struct thread *td) 1122 { 1123 struct vnode *uvp; 1124 struct vnode *lvp; 1125 struct vnode *tvp; 1126 struct dirent *dp; 1127 struct dirent *edp; 1128 struct componentname cn; 1129 struct iovec iov; 1130 struct uio uio; 1131 struct vattr va; 1132 int error; 1133 int eofflag; 1134 int lookuperr; 1135 1136 /* 1137 * The size of buf needs to be larger than DIRBLKSIZ. 1138 */ 1139 char buf[256 * 6]; 1140 1141 ASSERT_VOP_ELOCKED(vp, "unionfs_check_rmdir"); 1142 1143 eofflag = 0; 1144 uvp = UNIONFSVPTOUPPERVP(vp); 1145 lvp = UNIONFSVPTOLOWERVP(vp); 1146 1147 /* check opaque */ 1148 if ((error = VOP_GETATTR(uvp, &va, cred)) != 0) 1149 return (error); 1150 if (va.va_flags & OPAQUE) 1151 return (0); 1152 1153 /* open vnode */ 1154 #ifdef MAC 1155 if ((error = mac_vnode_check_open(cred, vp, VEXEC|VREAD)) != 0) 1156 return (error); 1157 #endif 1158 if ((error = VOP_ACCESS(vp, VEXEC|VREAD, cred, td)) != 0) 1159 return (error); 1160 if ((error = VOP_OPEN(vp, FREAD, cred, td, NULL)) != 0) 1161 return (error); 1162 1163 uio.uio_rw = UIO_READ; 1164 uio.uio_segflg = UIO_SYSSPACE; 1165 uio.uio_td = td; 1166 uio.uio_offset = 0; 1167 1168 #ifdef MAC 1169 error = mac_vnode_check_readdir(td->td_ucred, lvp); 1170 #endif 1171 while (!error && !eofflag) { 1172 iov.iov_base = buf; 1173 iov.iov_len = sizeof(buf); 1174 uio.uio_iov = &iov; 1175 uio.uio_iovcnt = 1; 1176 uio.uio_resid = iov.iov_len; 1177 1178 error = VOP_READDIR(lvp, &uio, cred, &eofflag, NULL, NULL); 1179 if (error != 0) 1180 break; 1181 if (eofflag == 0 && uio.uio_resid == sizeof(buf)) { 1182 #ifdef DIAGNOSTIC 1183 panic("bad readdir response from lower FS."); 1184 #endif 1185 break; 1186 } 1187 1188 edp = (struct dirent*)&buf[sizeof(buf) - uio.uio_resid]; 1189 for (dp = (struct dirent*)buf; !error && dp < edp; 1190 dp = (struct dirent*)((caddr_t)dp + dp->d_reclen)) { 1191 if (dp->d_type == DT_WHT || dp->d_fileno == 0 || 1192 (dp->d_namlen == 1 && dp->d_name[0] == '.') || 1193 (dp->d_namlen == 2 && !bcmp(dp->d_name, "..", 2))) 1194 continue; 1195 1196 cn.cn_namelen = dp->d_namlen; 1197 cn.cn_pnbuf = NULL; 1198 cn.cn_nameptr = dp->d_name; 1199 cn.cn_nameiop = LOOKUP; 1200 cn.cn_flags = LOCKPARENT | LOCKLEAF | SAVENAME | 1201 RDONLY | ISLASTCN; 1202 cn.cn_lkflags = LK_EXCLUSIVE; 1203 cn.cn_thread = td; 1204 cn.cn_cred = cred; 1205 1206 /* 1207 * check entry in lower. 1208 * Sometimes, readdir function returns 1209 * wrong entry. 1210 */ 1211 lookuperr = VOP_LOOKUP(lvp, &tvp, &cn); 1212 1213 if (!lookuperr) 1214 vput(tvp); 1215 else 1216 continue; /* skip entry */ 1217 1218 /* 1219 * check entry 1220 * If it has no exist/whiteout entry in upper, 1221 * directory is not empty. 1222 */ 1223 cn.cn_flags = LOCKPARENT | LOCKLEAF | SAVENAME | 1224 RDONLY | ISLASTCN; 1225 lookuperr = VOP_LOOKUP(uvp, &tvp, &cn); 1226 1227 if (!lookuperr) 1228 vput(tvp); 1229 1230 /* ignore exist or whiteout entry */ 1231 if (!lookuperr || 1232 (lookuperr == ENOENT && (cn.cn_flags & ISWHITEOUT))) 1233 continue; 1234 1235 error = ENOTEMPTY; 1236 } 1237 } 1238 1239 /* close vnode */ 1240 VOP_CLOSE(vp, FREAD, cred, td); 1241 1242 return (error); 1243 } 1244 1245 #ifdef DIAGNOSTIC 1246 1247 struct vnode * 1248 unionfs_checkuppervp(struct vnode *vp, char *fil, int lno) 1249 { 1250 struct unionfs_node *unp; 1251 1252 unp = VTOUNIONFS(vp); 1253 1254 #ifdef notyet 1255 if (vp->v_op != unionfs_vnodeop_p) { 1256 printf("unionfs_checkuppervp: on non-unionfs-node.\n"); 1257 #ifdef KDB 1258 kdb_enter(KDB_WHY_UNIONFS, 1259 "unionfs_checkuppervp: on non-unionfs-node.\n"); 1260 #endif 1261 panic("unionfs_checkuppervp"); 1262 } 1263 #endif 1264 return (unp->un_uppervp); 1265 } 1266 1267 struct vnode * 1268 unionfs_checklowervp(struct vnode *vp, char *fil, int lno) 1269 { 1270 struct unionfs_node *unp; 1271 1272 unp = VTOUNIONFS(vp); 1273 1274 #ifdef notyet 1275 if (vp->v_op != unionfs_vnodeop_p) { 1276 printf("unionfs_checklowervp: on non-unionfs-node.\n"); 1277 #ifdef KDB 1278 kdb_enter(KDB_WHY_UNIONFS, 1279 "unionfs_checklowervp: on non-unionfs-node.\n"); 1280 #endif 1281 panic("unionfs_checklowervp"); 1282 } 1283 #endif 1284 return (unp->un_lowervp); 1285 } 1286 #endif 1287