1 /* $NetBSD: lfs_rename.c,v 1.16 2015/09/21 01:24:23 dholland Exp $ */ 2 /* from NetBSD: ufs_rename.c,v 1.6 2013/01/22 09:39:18 dholland Exp */ 3 4 /*- 5 * Copyright (c) 2012 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Taylor R Campbell. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /*- 33 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Konrad E. Schroder <perseant@hhhh.org>. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 58 * POSSIBILITY OF SUCH DAMAGE. 59 */ 60 /* 61 * Copyright (c) 1986, 1989, 1991, 1993, 1995 62 * The Regents of the University of California. All rights reserved. 63 * 64 * Redistribution and use in source and binary forms, with or without 65 * modification, are permitted provided that the following conditions 66 * are met: 67 * 1. Redistributions of source code must retain the above copyright 68 * notice, this list of conditions and the following disclaimer. 69 * 2. Redistributions in binary form must reproduce the above copyright 70 * notice, this list of conditions and the following disclaimer in the 71 * documentation and/or other materials provided with the distribution. 72 * 3. Neither the name of the University nor the names of its contributors 73 * may be used to endorse or promote products derived from this software 74 * without specific prior written permission. 75 * 76 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 77 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 78 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 79 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 80 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 81 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 82 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 83 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 84 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 85 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 86 * SUCH DAMAGE. 87 * 88 * @(#)lfs_vnops.c 8.13 (Berkeley) 6/10/95 89 */ 90 91 #include <sys/cdefs.h> 92 __KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.16 2015/09/21 01:24:23 dholland Exp $"); 93 94 #include <sys/param.h> 95 #include <sys/systm.h> 96 #include <sys/errno.h> 97 #include <sys/namei.h> 98 #include <sys/resourcevar.h> 99 #include <sys/kernel.h> 100 #include <sys/file.h> 101 #include <sys/stat.h> 102 #include <sys/buf.h> 103 #include <sys/proc.h> 104 #include <sys/mount.h> 105 #include <sys/vnode.h> 106 #include <sys/vnode_if.h> 107 #include <sys/pool.h> 108 #include <sys/signalvar.h> 109 #include <sys/kauth.h> 110 #include <sys/syslog.h> 111 112 #include <uvm/uvm.h> 113 #include <uvm/uvm_pmap.h> 114 #include <uvm/uvm_stat.h> 115 #include <uvm/uvm_pager.h> 116 117 #include <miscfs/fifofs/fifo.h> 118 #include <miscfs/genfs/genfs.h> 119 #include <miscfs/specfs/specdev.h> 120 121 #include <ufs/lfs/ulfs_inode.h> 122 #include <ufs/lfs/ulfsmount.h> 123 #include <ufs/lfs/ulfs_bswap.h> 124 #include <ufs/lfs/ulfs_extern.h> 125 126 #include <ufs/lfs/lfs.h> 127 #include <ufs/lfs/lfs_accessors.h> 128 #include <ufs/lfs/lfs_extern.h> 129 130 /* 131 * ulfs_gro_directory_empty_p: Return true if the directory vp is 132 * empty. dvp is its parent. 133 * 134 * vp and dvp must be locked and referenced. 135 */ 136 static bool 137 ulfs_gro_directory_empty_p(struct mount *mp, kauth_cred_t cred, 138 struct vnode *vp, struct vnode *dvp) 139 { 140 141 (void)mp; 142 KASSERT(mp != NULL); 143 KASSERT(vp != NULL); 144 KASSERT(dvp != NULL); 145 KASSERT(vp != dvp); 146 KASSERT(vp->v_mount == mp); 147 KASSERT(dvp->v_mount == mp); 148 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 149 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 150 151 return ulfs_dirempty(VTOI(vp), VTOI(dvp)->i_number, cred); 152 } 153 154 /* 155 * ulfs_gro_rename_check_possible: Check whether a rename is possible 156 * independent of credentials. 157 */ 158 static int 159 ulfs_gro_rename_check_possible(struct mount *mp, 160 struct vnode *fdvp, struct vnode *fvp, 161 struct vnode *tdvp, struct vnode *tvp) 162 { 163 164 (void)mp; 165 KASSERT(mp != NULL); 166 KASSERT(fdvp != NULL); 167 KASSERT(fvp != NULL); 168 KASSERT(tdvp != NULL); 169 KASSERT(fdvp != fvp); 170 KASSERT(fdvp != tvp); 171 KASSERT(tdvp != fvp); 172 KASSERT(tdvp != tvp); 173 KASSERT(fvp != tvp); 174 KASSERT(fdvp->v_type == VDIR); 175 KASSERT(tdvp->v_type == VDIR); 176 KASSERT(fdvp->v_mount == mp); 177 KASSERT(fvp->v_mount == mp); 178 KASSERT(tdvp->v_mount == mp); 179 KASSERT((tvp == NULL) || (tvp->v_mount == mp)); 180 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 181 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 182 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 183 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 184 185 return genfs_ufslike_rename_check_possible( 186 VTOI(fdvp)->i_flags, VTOI(fvp)->i_flags, 187 VTOI(tdvp)->i_flags, (tvp? VTOI(tvp)->i_flags : 0), 188 (tvp != NULL), 189 IMMUTABLE, APPEND); 190 } 191 192 /* 193 * ulfs_gro_rename_check_permitted: Check whether a rename is permitted 194 * given our credentials. 195 */ 196 static int 197 ulfs_gro_rename_check_permitted(struct mount *mp, kauth_cred_t cred, 198 struct vnode *fdvp, struct vnode *fvp, 199 struct vnode *tdvp, struct vnode *tvp) 200 { 201 202 (void)mp; 203 KASSERT(mp != NULL); 204 KASSERT(fdvp != NULL); 205 KASSERT(fvp != NULL); 206 KASSERT(tdvp != NULL); 207 KASSERT(fdvp != fvp); 208 KASSERT(fdvp != tvp); 209 KASSERT(tdvp != fvp); 210 KASSERT(tdvp != tvp); 211 KASSERT(fvp != tvp); 212 KASSERT(fdvp->v_type == VDIR); 213 KASSERT(tdvp->v_type == VDIR); 214 KASSERT(fdvp->v_mount == mp); 215 KASSERT(fvp->v_mount == mp); 216 KASSERT(tdvp->v_mount == mp); 217 KASSERT((tvp == NULL) || (tvp->v_mount == mp)); 218 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 219 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 220 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 221 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 222 223 return genfs_ufslike_rename_check_permitted(cred, 224 fdvp, VTOI(fdvp)->i_mode, VTOI(fdvp)->i_uid, 225 fvp, VTOI(fvp)->i_uid, 226 tdvp, VTOI(tdvp)->i_mode, VTOI(tdvp)->i_uid, 227 tvp, (tvp? VTOI(tvp)->i_uid : 0)); 228 } 229 230 /* 231 * ulfs_gro_remove_check_possible: Check whether a remove is possible 232 * independent of credentials. 233 */ 234 static int 235 ulfs_gro_remove_check_possible(struct mount *mp, 236 struct vnode *dvp, struct vnode *vp) 237 { 238 239 (void)mp; 240 KASSERT(mp != NULL); 241 KASSERT(dvp != NULL); 242 KASSERT(vp != NULL); 243 KASSERT(dvp != vp); 244 KASSERT(dvp->v_type == VDIR); 245 KASSERT(vp->v_type != VDIR); 246 KASSERT(dvp->v_mount == mp); 247 KASSERT(vp->v_mount == mp); 248 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 249 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 250 251 return genfs_ufslike_remove_check_possible( 252 VTOI(dvp)->i_flags, VTOI(vp)->i_flags, 253 IMMUTABLE, APPEND); 254 } 255 256 /* 257 * ulfs_gro_remove_check_permitted: Check whether a remove is permitted 258 * given our credentials. 259 */ 260 static int 261 ulfs_gro_remove_check_permitted(struct mount *mp, kauth_cred_t cred, 262 struct vnode *dvp, struct vnode *vp) 263 { 264 265 (void)mp; 266 KASSERT(mp != NULL); 267 KASSERT(dvp != NULL); 268 KASSERT(vp != NULL); 269 KASSERT(dvp != vp); 270 KASSERT(dvp->v_type == VDIR); 271 KASSERT(vp->v_type != VDIR); 272 KASSERT(dvp->v_mount == mp); 273 KASSERT(vp->v_mount == mp); 274 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 275 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 276 277 return genfs_ufslike_remove_check_permitted(cred, 278 dvp, VTOI(dvp)->i_mode, VTOI(dvp)->i_uid, vp, VTOI(vp)->i_uid); 279 } 280 281 /* 282 * ulfs_rename_ulr_overlap_p: True iff tulr overlaps with fulr so that 283 * entering a directory entry at tulr may move fulr. 284 */ 285 static bool 286 ulfs_rename_ulr_overlap_p(const struct ulfs_lookup_results *fulr, 287 const struct ulfs_lookup_results *tulr) 288 { 289 doff_t from_prev_start, from_prev_end, to_start, to_end; 290 291 KASSERT(fulr != NULL); 292 KASSERT(tulr != NULL); 293 KASSERT(fulr != tulr); 294 295 /* 296 * fulr is from a DELETE lookup, so fulr->ulr_count is the size 297 * of the preceding entry (d_reclen). 298 */ 299 from_prev_end = fulr->ulr_offset; 300 KASSERT(fulr->ulr_count <= from_prev_end); 301 from_prev_start = (from_prev_end - fulr->ulr_count); 302 303 /* 304 * tulr is from a RENAME lookup, so tulr->ulr_count is the size 305 * of the free space for an entry that we are about to fill. 306 */ 307 to_start = tulr->ulr_offset; 308 KASSERT(tulr->ulr_count < (LFS_MAXDIRSIZE - to_start)); 309 to_end = (to_start + tulr->ulr_count); 310 311 return 312 (((to_start <= from_prev_start) && (from_prev_start < to_end)) || 313 ((to_start <= from_prev_end) && (from_prev_end < to_end))); 314 } 315 316 /* 317 * ulfs_direct_namlen: Return the namlen of the directory entry ep from 318 * the directory vp. 319 */ 320 static int /* XXX int? uint8_t? */ 321 ulfs_direct_namlen(const LFS_DIRHEADER *ep, const struct vnode *vp) 322 { 323 struct lfs *fs; 324 325 KASSERT(ep != NULL); 326 KASSERT(vp != NULL); 327 KASSERT(VTOI(vp) != NULL); 328 KASSERT(VTOI(vp)->i_ump != NULL); 329 KASSERT(VTOI(vp)->i_lfs != NULL); 330 fs = VTOI(vp)->i_lfs; 331 332 return lfs_dir_getnamlen(fs, ep); 333 } 334 335 /* 336 * ulfs_rename_recalculate_fulr: If we have just entered a directory into 337 * dvp at tulr, and we were about to remove one at fulr for an entry 338 * named fcnp, fulr may be invalid. So, if necessary, recalculate it. 339 */ 340 static int 341 ulfs_rename_recalculate_fulr(struct vnode *dvp, 342 struct ulfs_lookup_results *fulr, const struct ulfs_lookup_results *tulr, 343 const struct componentname *fcnp) 344 { 345 struct mount *mp; 346 struct lfs *fs; 347 struct ulfsmount *ump; 348 /* XXX int is a silly type for this; blame ulfsmount::um_dirblksiz. */ 349 int dirblksiz; 350 doff_t search_start, search_end; 351 doff_t offset; /* Offset of entry we're examining. */ 352 struct buf *bp; /* I/O block we're examining. */ 353 char *dirbuf; /* Pointer into directory at search_start. */ 354 LFS_DIRHEADER *ep; /* Pointer to the entry we're examining. */ 355 /* XXX direct::d_reclen is 16-bit; 356 * ulfs_lookup_results::ulr_reclen is 32-bit. Blah. */ 357 uint32_t reclen; /* Length of the entry we're examining. */ 358 uint32_t prev_reclen; /* Length of the preceding entry. */ 359 int error; 360 361 KASSERT(dvp != NULL); 362 KASSERT(dvp->v_mount != NULL); 363 KASSERT(VTOI(dvp) != NULL); 364 KASSERT(fulr != NULL); 365 KASSERT(tulr != NULL); 366 KASSERT(fulr != tulr); 367 KASSERT(ulfs_rename_ulr_overlap_p(fulr, tulr)); 368 369 mp = dvp->v_mount; 370 ump = VFSTOULFS(mp); 371 fs = ump->um_lfs; 372 KASSERT(ump != NULL); 373 KASSERT(ump == VTOI(dvp)->i_ump); 374 KASSERT(fs == VTOI(dvp)->i_lfs); 375 376 dirblksiz = fs->um_dirblksiz; 377 KASSERT(0 < dirblksiz); 378 KASSERT((dirblksiz & (dirblksiz - 1)) == 0); 379 380 /* A directory block may not span across multiple I/O blocks. */ 381 KASSERT(dirblksiz <= mp->mnt_stat.f_iosize); 382 383 /* Find the bounds of the search. */ 384 search_start = tulr->ulr_offset; 385 KASSERT(fulr->ulr_reclen < (LFS_MAXDIRSIZE - fulr->ulr_offset)); 386 search_end = (fulr->ulr_offset + fulr->ulr_reclen); 387 388 /* Compaction must happen only within a directory block. (*) */ 389 KASSERT(search_start <= search_end); 390 KASSERT((search_end - (search_start &~ (dirblksiz - 1))) <= dirblksiz); 391 392 dirbuf = NULL; 393 bp = NULL; 394 error = ulfs_blkatoff(dvp, (off_t)search_start, &dirbuf, &bp, false); 395 if (error) 396 return error; 397 KASSERT(dirbuf != NULL); 398 KASSERT(bp != NULL); 399 400 /* 401 * Guarantee we sha'n't go past the end of the buffer we got. 402 * dirbuf is bp->b_data + (search_start & (iosize - 1)), and 403 * the valid range is [bp->b_data, bp->b_data + bp->b_bcount). 404 */ 405 KASSERT((search_end - search_start) <= 406 (bp->b_bcount - (search_start & (mp->mnt_stat.f_iosize - 1)))); 407 408 prev_reclen = fulr->ulr_count; 409 offset = search_start; 410 411 /* 412 * Search from search_start to search_end for the entry matching 413 * fcnp, which must be there because we found it before and it 414 * should only at most have moved earlier. 415 */ 416 for (;;) { 417 KASSERT(search_start <= offset); 418 KASSERT(offset < search_end); 419 420 /* 421 * Examine the directory entry at offset. 422 */ 423 ep = (LFS_DIRHEADER *)(dirbuf + (offset - search_start)); 424 reclen = lfs_dir_getreclen(fs, ep); 425 426 if (lfs_dir_getino(fs, ep) == 0) 427 goto next; /* Entry is unused. */ 428 429 if (lfs_dir_getino(fs, ep) == ULFS_WINO) 430 goto next; /* Entry is whiteout. */ 431 432 if (fcnp->cn_namelen != ulfs_direct_namlen(ep, dvp)) 433 goto next; /* Wrong name length. */ 434 435 if (memcmp(lfs_dir_nameptr(fs, ep), fcnp->cn_nameptr, fcnp->cn_namelen)) 436 goto next; /* Wrong name. */ 437 438 /* Got it! */ 439 break; 440 441 next: 442 if (! ((reclen < search_end) && 443 (offset < (search_end - reclen)))) { 444 brelse(bp, 0); 445 return EIO; /* XXX Panic? What? */ 446 } 447 448 /* We may not move past the search end. */ 449 KASSERT(reclen < search_end); 450 KASSERT(offset < (search_end - reclen)); 451 452 /* 453 * We may not move across a directory block boundary; 454 * see (*) above. 455 */ 456 KASSERT((offset &~ (dirblksiz - 1)) == 457 ((offset + reclen) &~ (dirblksiz - 1))); 458 459 prev_reclen = reclen; 460 offset += reclen; 461 } 462 463 /* 464 * Found the entry. Record where. 465 */ 466 fulr->ulr_offset = offset; 467 fulr->ulr_reclen = reclen; 468 469 /* 470 * Record the preceding record length, but not if we're at the 471 * start of a directory block. 472 */ 473 fulr->ulr_count = ((offset & (dirblksiz - 1))? prev_reclen : 0); 474 475 brelse(bp, 0); 476 return 0; 477 } 478 479 /* 480 * ulfs_gro_remove: Rename an object over another link to itself, 481 * effectively removing just the original link. 482 */ 483 static int 484 ulfs_gro_remove(struct mount *mp, kauth_cred_t cred, 485 struct vnode *dvp, struct componentname *cnp, void *de, struct vnode *vp) 486 { 487 struct ulfs_lookup_results *ulr = de; 488 int error; 489 490 KASSERT(mp != NULL); 491 KASSERT(dvp != NULL); 492 KASSERT(cnp != NULL); 493 KASSERT(ulr != NULL); 494 KASSERT(vp != NULL); 495 KASSERT(dvp != vp); 496 KASSERT(dvp->v_mount == mp); 497 KASSERT(vp->v_mount == mp); 498 KASSERT(dvp->v_type == VDIR); 499 KASSERT(vp->v_type != VDIR); 500 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 501 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 502 KASSERT(cnp->cn_nameiop == DELETE); 503 504 /* XXX ulfs_dirremove decrements vp's link count for us. */ 505 error = ulfs_dirremove(dvp, ulr, VTOI(vp), cnp->cn_flags, 0); 506 if (error) 507 goto out1; 508 509 VN_KNOTE(dvp, NOTE_WRITE); 510 VN_KNOTE(vp, (VTOI(vp)->i_nlink? NOTE_LINK : NOTE_DELETE)); 511 512 out1: 513 return error; 514 } 515 516 /* 517 * ulfs_gro_lookup: Look up and save the lookup results. 518 */ 519 static int 520 ulfs_gro_lookup(struct mount *mp, struct vnode *dvp, 521 struct componentname *cnp, void *de_ret, struct vnode **vp_ret) 522 { 523 struct ulfs_lookup_results *ulr_ret = de_ret; 524 struct vnode *vp = NULL; 525 int error; 526 527 (void)mp; 528 KASSERT(mp != NULL); 529 KASSERT(dvp != NULL); 530 KASSERT(cnp != NULL); 531 KASSERT(ulr_ret != NULL); 532 KASSERT(vp_ret != NULL); 533 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 534 535 /* Kludge cargo-culted from dholland's ulfs_rename. */ 536 cnp->cn_flags &=~ MODMASK; 537 cnp->cn_flags |= (LOCKPARENT | LOCKLEAF); 538 539 error = relookup(dvp, &vp, cnp, 0 /* dummy */); 540 if ((error == 0) && (vp == NULL)) { 541 error = ENOENT; 542 goto out; 543 } else if (error) { 544 return error; 545 } 546 547 /* 548 * Thanks to VFS insanity, relookup locks vp, which screws us 549 * in various ways. 550 */ 551 KASSERT(vp != NULL); 552 VOP_UNLOCK(vp); 553 554 out: *ulr_ret = VTOI(dvp)->i_crap; 555 *vp_ret = vp; 556 return error; 557 } 558 559 /* 560 * ulfs_rmdired_p: Check whether the directory vp has been rmdired. 561 * 562 * vp must be locked and referenced. 563 */ 564 static bool 565 ulfs_rmdired_p(struct vnode *vp) 566 { 567 568 KASSERT(vp != NULL); 569 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 570 KASSERT(vp->v_type == VDIR); 571 572 /* XXX Is this correct? */ 573 return (VTOI(vp)->i_size == 0); 574 } 575 576 /* 577 * ulfs_read_dotdot: Store in *ino_ret the inode number of the parent 578 * of the directory vp. 579 */ 580 static int 581 ulfs_read_dotdot(struct vnode *vp, kauth_cred_t cred, ino_t *ino_ret) 582 { 583 struct lfs *fs; 584 union lfs_dirtemplate dirbuf; 585 LFS_DIRHEADER *dotdot; 586 const char *name; 587 int error; 588 589 KASSERT(vp != NULL); 590 KASSERT(ino_ret != NULL); 591 KASSERT(vp->v_type == VDIR); 592 593 KASSERT(VTOI(vp) != NULL); 594 KASSERT(VTOI(vp)->i_lfs != NULL); 595 fs = VTOI(vp)->i_lfs; 596 597 error = ulfs_bufio(UIO_READ, vp, &dirbuf, sizeof dirbuf, (off_t)0, 598 IO_NODELOCKED, cred, NULL, NULL); 599 if (error) 600 return error; 601 602 dotdot = lfs_dirtemplate_dotdot(fs, &dirbuf); 603 name = lfs_dirtemplate_dotdotname(fs, &dirbuf); 604 if (lfs_dir_getnamlen(fs, dotdot) != 2 || 605 name[0] != '.' || 606 name[1] != '.') 607 /* XXX Panic? Print warning? */ 608 return ENOTDIR; 609 610 *ino_ret = lfs_dir_getino(fs, dotdot); 611 return 0; 612 } 613 614 /* 615 * ulfs_gro_lock_directory: Lock the directory vp, but fail if it has 616 * been rmdir'd. 617 */ 618 static int 619 ulfs_gro_lock_directory(struct mount *mp, struct vnode *vp) 620 { 621 622 (void)mp; 623 KASSERT(mp != NULL); 624 KASSERT(vp != NULL); 625 KASSERT(vp->v_mount == mp); 626 627 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 628 629 if (ulfs_rmdired_p(vp)) { 630 VOP_UNLOCK(vp); 631 return ENOENT; 632 } 633 634 return 0; 635 } 636 637 /* 638 * ulfs_gro_genealogy: Analyze the genealogy of the source and target 639 * directories. 640 */ 641 static int 642 ulfs_gro_genealogy(struct mount *mp, kauth_cred_t cred, 643 struct vnode *fdvp, struct vnode *tdvp, 644 struct vnode **intermediate_node_ret) 645 { 646 struct vnode *vp, *dvp; 647 ino_t dotdot_ino = -1; /* XXX gcc 4.8: maybe-uninitialized */ 648 int error; 649 650 KASSERT(mp != NULL); 651 KASSERT(fdvp != NULL); 652 KASSERT(tdvp != NULL); 653 KASSERT(fdvp != tdvp); 654 KASSERT(intermediate_node_ret != NULL); 655 KASSERT(fdvp->v_mount == mp); 656 KASSERT(tdvp->v_mount == mp); 657 KASSERT(fdvp->v_type == VDIR); 658 KASSERT(tdvp->v_type == VDIR); 659 660 /* 661 * We need to provisionally lock tdvp to keep rmdir from 662 * deleting it -- or any ancestor -- at an inopportune moment. 663 */ 664 error = ulfs_gro_lock_directory(mp, tdvp); 665 if (error) 666 return error; 667 668 vp = tdvp; 669 vref(vp); 670 671 for (;;) { 672 KASSERT(vp != NULL); 673 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 674 KASSERT(vp->v_mount == mp); 675 KASSERT(vp->v_type == VDIR); 676 KASSERT(!ulfs_rmdired_p(vp)); 677 678 /* Did we hit the root without finding fdvp? */ 679 if (VTOI(vp)->i_number == ULFS_ROOTINO) { 680 vput(vp); 681 *intermediate_node_ret = NULL; 682 return 0; 683 } 684 685 error = ulfs_read_dotdot(vp, cred, &dotdot_ino); 686 if (error) { 687 vput(vp); 688 return error; 689 } 690 691 /* Did we find that fdvp is an ancestor of tdvp? */ 692 if (VTOI(fdvp)->i_number == dotdot_ino) { 693 /* Unlock vp, but keep it referenced. */ 694 VOP_UNLOCK(vp); 695 *intermediate_node_ret = vp; 696 return 0; 697 } 698 699 /* Neither -- keep ascending the family tree. */ 700 701 /* 702 * Unlock vp so that we can lock the parent, but keep 703 * vp referenced until after we have found the parent, 704 * so that dotdot_ino will not be recycled. 705 * 706 * XXX This guarantees that vp's inode number will not 707 * be recycled, but why can't dotdot_ino be recycled? 708 */ 709 VOP_UNLOCK(vp); 710 error = VFS_VGET(mp, dotdot_ino, &dvp); 711 vrele(vp); 712 if (error) 713 return error; 714 715 KASSERT(dvp != NULL); 716 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 717 vp = dvp; 718 719 if (vp->v_type != VDIR) { 720 /* 721 * XXX Panic? Print a warning? Can this 722 * happen if we lose the race I suspect to 723 * exist above, and the `..' inode number has 724 * been recycled? 725 */ 726 vput(vp); 727 return ENOTDIR; 728 } 729 730 if (ulfs_rmdired_p(vp)) { 731 vput(vp); 732 return ENOENT; 733 } 734 } 735 } 736 737 /* 738 * ulfs_gro_rename: Actually perform the rename operation. 739 */ 740 static int 741 ulfs_gro_rename(struct mount *mp, kauth_cred_t cred, 742 struct vnode *fdvp, struct componentname *fcnp, 743 void *fde, struct vnode *fvp, 744 struct vnode *tdvp, struct componentname *tcnp, 745 void *tde, struct vnode *tvp) 746 { 747 struct lfs *fs; 748 struct ulfs_lookup_results *fulr = fde; 749 struct ulfs_lookup_results *tulr = tde; 750 bool directory_p, reparent_p; 751 int error; 752 753 KASSERT(mp != NULL); 754 KASSERT(fdvp != NULL); 755 KASSERT(fcnp != NULL); 756 KASSERT(fulr != NULL); 757 KASSERT(fvp != NULL); 758 KASSERT(tdvp != NULL); 759 KASSERT(tcnp != NULL); 760 KASSERT(tulr != NULL); 761 KASSERT(fulr != tulr); 762 KASSERT(fdvp != fvp); 763 KASSERT(fdvp != tvp); 764 KASSERT(tdvp != fvp); 765 KASSERT(tdvp != tvp); 766 KASSERT(fvp != tvp); 767 KASSERT(fdvp->v_mount == mp); 768 KASSERT(fvp->v_mount == mp); 769 KASSERT(tdvp->v_mount == mp); 770 KASSERT((tvp == NULL) || (tvp->v_mount == mp)); 771 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 772 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 773 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 774 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 775 776 fs = VTOI(fdvp)->i_lfs; 777 KASSERT(fs == VTOI(tdvp)->i_lfs); 778 779 /* 780 * We shall need to temporarily bump the link count, so make 781 * sure there is room to do so. 782 */ 783 if ((nlink_t)VTOI(fvp)->i_nlink >= LINK_MAX) 784 return EMLINK; 785 786 directory_p = (fvp->v_type == VDIR); 787 KASSERT(directory_p == ((VTOI(fvp)->i_mode & LFS_IFMT) == LFS_IFDIR)); 788 KASSERT((tvp == NULL) || (directory_p == (tvp->v_type == VDIR))); 789 KASSERT((tvp == NULL) || (directory_p == 790 ((VTOI(tvp)->i_mode & LFS_IFMT) == LFS_IFDIR))); 791 792 reparent_p = (fdvp != tdvp); 793 KASSERT(reparent_p == (VTOI(fdvp)->i_number != VTOI(tdvp)->i_number)); 794 795 /* 796 * Commence hacking of the data on disk. 797 */ 798 799 error = 0; 800 801 /* 802 * 1) Bump link count while we're moving stuff 803 * around. If we crash somewhere before 804 * completing our work, the link count 805 * may be wrong, but correctable. 806 */ 807 808 KASSERT((nlink_t)VTOI(fvp)->i_nlink < LINK_MAX); 809 VTOI(fvp)->i_nlink++; 810 DIP_ASSIGN(VTOI(fvp), nlink, VTOI(fvp)->i_nlink); 811 VTOI(fvp)->i_flag |= IN_CHANGE; 812 error = lfs_update(fvp, NULL, NULL, UPDATE_DIROP); 813 if (error) 814 goto whymustithurtsomuch; 815 816 /* 817 * 2) If target doesn't exist, link the target 818 * to the source and unlink the source. 819 * Otherwise, rewrite the target directory 820 * entry to reference the source inode and 821 * expunge the original entry's existence. 822 */ 823 824 if (tvp == NULL) { 825 /* 826 * Account for ".." in new directory. 827 * When source and destination have the same 828 * parent we don't fool with the link count. 829 */ 830 if (directory_p && reparent_p) { 831 if ((nlink_t)VTOI(tdvp)->i_nlink >= LINK_MAX) { 832 error = EMLINK; 833 goto whymustithurtsomuch; 834 } 835 KASSERT((nlink_t)VTOI(tdvp)->i_nlink < LINK_MAX); 836 VTOI(tdvp)->i_nlink++; 837 DIP_ASSIGN(VTOI(tdvp), nlink, VTOI(tdvp)->i_nlink); 838 VTOI(tdvp)->i_flag |= IN_CHANGE; 839 error = lfs_update(tdvp, NULL, NULL, UPDATE_DIROP); 840 if (error) { 841 /* 842 * Link count update didn't take -- 843 * back out the in-memory link count. 844 */ 845 KASSERT(0 < VTOI(tdvp)->i_nlink); 846 VTOI(tdvp)->i_nlink--; 847 DIP_ASSIGN(VTOI(tdvp), nlink, 848 VTOI(tdvp)->i_nlink); 849 VTOI(tdvp)->i_flag |= IN_CHANGE; 850 goto whymustithurtsomuch; 851 } 852 } 853 854 error = ulfs_direnter(tdvp, tulr, 855 NULL, tcnp, VTOI(fvp)->i_number, LFS_IFTODT(VTOI(fvp)->i_mode), 856 NULL); 857 if (error) { 858 if (directory_p && reparent_p) { 859 /* 860 * Directory update didn't take, but 861 * the link count update did -- back 862 * out the in-memory link count and the 863 * on-disk link count. 864 */ 865 KASSERT(0 < VTOI(tdvp)->i_nlink); 866 VTOI(tdvp)->i_nlink--; 867 DIP_ASSIGN(VTOI(tdvp), nlink, 868 VTOI(tdvp)->i_nlink); 869 VTOI(tdvp)->i_flag |= IN_CHANGE; 870 (void)lfs_update(tdvp, NULL, NULL, 871 UPDATE_WAIT | UPDATE_DIROP); 872 } 873 goto whymustithurtsomuch; 874 } 875 } else { 876 if (directory_p) 877 /* XXX WTF? Why purge here? Why not purge others? */ 878 cache_purge(tdvp); 879 880 /* 881 * Make the target directory's entry for tcnp point at 882 * the source node. 883 * 884 * XXX ulfs_dirrewrite decrements tvp's link count, but 885 * doesn't touch the link count of the new inode. Go 886 * figure. 887 */ 888 error = ulfs_dirrewrite(VTOI(tdvp), tulr->ulr_offset, 889 VTOI(tvp), VTOI(fvp)->i_number, LFS_IFTODT(VTOI(fvp)->i_mode), 890 ((directory_p && reparent_p) ? reparent_p : directory_p), 891 IN_CHANGE | IN_UPDATE); 892 if (error) 893 goto whymustithurtsomuch; 894 895 /* 896 * If the source and target are directories, and the 897 * target is in the same directory as the source, 898 * decrement the link count of the common parent 899 * directory, since we are removing the target from 900 * that directory. 901 */ 902 if (directory_p && !reparent_p) { 903 KASSERT(fdvp == tdvp); 904 /* XXX check, don't kassert */ 905 KASSERT(0 < VTOI(tdvp)->i_nlink); 906 VTOI(tdvp)->i_nlink--; 907 DIP_ASSIGN(VTOI(tdvp), nlink, VTOI(tdvp)->i_nlink); 908 VTOI(tdvp)->i_flag |= IN_CHANGE; 909 } 910 911 if (directory_p) { 912 /* 913 * XXX I don't understand the following comment 914 * from ulfs_rename -- in particular, the part 915 * about `there may be other hard links'. 916 * 917 * Truncate inode. The only stuff left in the directory 918 * is "." and "..". The "." reference is inconsequential 919 * since we are quashing it. We have removed the "." 920 * reference and the reference in the parent directory, 921 * but there may be other hard links. 922 * 923 * XXX The ulfs_dirempty call earlier does 924 * not guarantee anything about nlink. 925 */ 926 if (VTOI(tvp)->i_nlink != 1) 927 ulfs_dirbad(VTOI(tvp), (doff_t)0, 928 "hard-linked directory"); 929 VTOI(tvp)->i_nlink = 0; 930 DIP_ASSIGN(VTOI(tvp), nlink, 0); 931 error = lfs_truncate(tvp, (off_t)0, IO_SYNC, cred); 932 if (error) 933 goto whymustithurtsomuch; 934 } 935 } 936 937 /* 938 * If the source is a directory with a new parent, the link 939 * count of the old parent directory must be decremented and 940 * ".." set to point to the new parent. 941 * 942 * XXX ulfs_dirrewrite updates the link count of fdvp, but not 943 * the link count of fvp or the link count of tdvp. Go figure. 944 */ 945 if (directory_p && reparent_p) { 946 off_t position; 947 948 /* 949 * The .. entry goes immediately after the . entry, so 950 * the position is the record length of the . entry, 951 * namely LFS_DIRECTSIZ(1). 952 */ 953 position = LFS_DIRECTSIZ(fs, 1); 954 error = ulfs_dirrewrite(VTOI(fvp), position, 955 VTOI(fdvp), VTOI(tdvp)->i_number, LFS_DT_DIR, 0, IN_CHANGE); 956 #if 0 /* XXX This branch was not in ulfs_rename! */ 957 if (error) 958 goto whymustithurtsomuch; 959 #endif 960 961 /* XXX WTF? Why purge here? Why not purge others? */ 962 cache_purge(fdvp); 963 } 964 965 /* 966 * 3) Unlink the source. 967 */ 968 969 /* 970 * ulfs_direnter may compact the directory in the process of 971 * inserting a new entry. That may invalidate fulr, which we 972 * need in order to remove the old entry. In that case, we 973 * need to recalculate what fulr should be. 974 */ 975 if (!reparent_p && (tvp == NULL) && 976 ulfs_rename_ulr_overlap_p(fulr, tulr)) { 977 error = ulfs_rename_recalculate_fulr(fdvp, fulr, tulr, fcnp); 978 #if 0 /* XXX */ 979 if (error) /* XXX Try to back out changes? */ 980 goto whymustithurtsomuch; 981 #endif 982 } 983 984 /* 985 * XXX 0 means !isrmdir. But can't this be an rmdir? 986 * XXX Well, turns out that argument to ulfs_dirremove is ignored... 987 * XXX And it turns out ulfs_dirremove updates the link count of fvp. 988 * XXX But it doesn't update the link count of fdvp. Go figure. 989 * XXX fdvp's link count is updated in ulfs_dirrewrite instead. 990 * XXX Actually, sometimes it doesn't update fvp's link count. 991 * XXX I hate the world. 992 */ 993 error = ulfs_dirremove(fdvp, fulr, VTOI(fvp), fcnp->cn_flags, 0); 994 if (error) 995 #if 0 /* XXX */ 996 goto whymustithurtsomuch; 997 #endif 998 goto arghmybrainhurts; 999 1000 /* 1001 * XXX Perhaps this should go at the top, in case the file 1002 * system is modified but incompletely so because of an 1003 * intermediate error. 1004 */ 1005 genfs_rename_knote(fdvp, fvp, tdvp, tvp, 1006 ((tvp != NULL) && (VTOI(tvp)->i_nlink == 0))); 1007 #if 0 /* XXX */ 1008 genfs_rename_cache_purge(fdvp, fvp, tdvp, tvp); 1009 #endif 1010 goto arghmybrainhurts; 1011 1012 whymustithurtsomuch: 1013 KASSERT(0 < VTOI(fvp)->i_nlink); 1014 VTOI(fvp)->i_nlink--; 1015 DIP_ASSIGN(VTOI(fvp), nlink, VTOI(fvp)->i_nlink); 1016 VTOI(fvp)->i_flag |= IN_CHANGE; 1017 1018 arghmybrainhurts: 1019 /*ihateyou:*/ 1020 return error; 1021 } 1022 1023 /* 1024 * lfs_gro_rename: Actually perform the rename operation. Do a little 1025 * LFS bookkeeping and then defer to ulfs_gro_rename. 1026 */ 1027 static int 1028 lfs_gro_rename(struct mount *mp, kauth_cred_t cred, 1029 struct vnode *fdvp, struct componentname *fcnp, 1030 void *fde, struct vnode *fvp, 1031 struct vnode *tdvp, struct componentname *tcnp, 1032 void *tde, struct vnode *tvp) 1033 { 1034 int error; 1035 1036 KASSERT(mp != NULL); 1037 KASSERT(fdvp != NULL); 1038 KASSERT(fcnp != NULL); 1039 KASSERT(fde != NULL); 1040 KASSERT(fvp != NULL); 1041 KASSERT(tdvp != NULL); 1042 KASSERT(tcnp != NULL); 1043 KASSERT(tde != NULL); 1044 KASSERT(fdvp != fvp); 1045 KASSERT(fdvp != tvp); 1046 KASSERT(tdvp != fvp); 1047 KASSERT(tdvp != tvp); 1048 KASSERT(fvp != tvp); 1049 KASSERT(fdvp->v_mount == mp); 1050 KASSERT(fvp->v_mount == mp); 1051 KASSERT(tdvp->v_mount == mp); 1052 KASSERT((tvp == NULL) || (tvp->v_mount == mp)); 1053 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 1054 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 1055 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 1056 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 1057 1058 error = lfs_set_dirop(tdvp, tvp); 1059 if (error != 0) 1060 return error; 1061 1062 MARK_VNODE(fdvp); 1063 MARK_VNODE(fvp); 1064 1065 error = ulfs_gro_rename(mp, cred, 1066 fdvp, fcnp, fde, fvp, 1067 tdvp, tcnp, tde, tvp); 1068 1069 UNMARK_VNODE(fdvp); 1070 UNMARK_VNODE(fvp); 1071 UNMARK_VNODE(tdvp); 1072 if (tvp) { 1073 UNMARK_VNODE(tvp); 1074 } 1075 lfs_unset_dirop(VFSTOULFS(mp)->um_lfs, tdvp, "rename"); 1076 vrele(tdvp); 1077 if (tvp) { 1078 vrele(tvp); 1079 } 1080 1081 return error; 1082 } 1083 1084 static const struct genfs_rename_ops lfs_genfs_rename_ops = { 1085 .gro_directory_empty_p = ulfs_gro_directory_empty_p, 1086 .gro_rename_check_possible = ulfs_gro_rename_check_possible, 1087 .gro_rename_check_permitted = ulfs_gro_rename_check_permitted, 1088 .gro_remove_check_possible = ulfs_gro_remove_check_possible, 1089 .gro_remove_check_permitted = ulfs_gro_remove_check_permitted, 1090 .gro_rename = lfs_gro_rename, 1091 .gro_remove = ulfs_gro_remove, 1092 .gro_lookup = ulfs_gro_lookup, 1093 .gro_genealogy = ulfs_gro_genealogy, 1094 .gro_lock_directory = ulfs_gro_lock_directory, 1095 }; 1096 1097 /* 1098 * lfs_sane_rename: The hairiest vop, with the saner API. 1099 * 1100 * Arguments: 1101 * 1102 * . fdvp (from directory vnode), 1103 * . fcnp (from component name), 1104 * . tdvp (to directory vnode), 1105 * . tcnp (to component name), 1106 * . cred (credentials structure), and 1107 * . posixly_correct (flag for behaviour if target & source link same file). 1108 * 1109 * fdvp and tdvp may be the same, and must be referenced and unlocked. 1110 */ 1111 static int 1112 lfs_sane_rename( 1113 struct vnode *fdvp, struct componentname *fcnp, 1114 struct vnode *tdvp, struct componentname *tcnp, 1115 kauth_cred_t cred, bool posixly_correct) 1116 { 1117 struct ulfs_lookup_results fulr, tulr; 1118 1119 /* 1120 * XXX Provisional kludge -- ulfs_lookup does not reject rename 1121 * of . or .. (from or to), so we hack it here. This is not 1122 * the right place: it should be caller's responsibility to 1123 * reject this case. 1124 */ 1125 KASSERT(fcnp != NULL); 1126 KASSERT(tcnp != NULL); 1127 KASSERT(fcnp != tcnp); 1128 KASSERT(fcnp->cn_nameptr != NULL); 1129 KASSERT(tcnp->cn_nameptr != NULL); 1130 1131 if ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT) 1132 return EINVAL; /* XXX EISDIR? */ 1133 if ((fcnp->cn_namelen == 1) && (fcnp->cn_nameptr[0] == '.')) 1134 return EINVAL; 1135 if ((tcnp->cn_namelen == 1) && (tcnp->cn_nameptr[0] == '.')) 1136 return EINVAL; 1137 1138 return genfs_sane_rename(&lfs_genfs_rename_ops, 1139 fdvp, fcnp, &fulr, tdvp, tcnp, &tulr, 1140 cred, posixly_correct); 1141 } 1142 1143 /* 1144 * lfs_rename: The hairiest vop, with the insanest API. Defer to 1145 * genfs_insane_rename immediately. 1146 */ 1147 int 1148 lfs_rename(void *v) 1149 { 1150 1151 return genfs_insane_rename(v, &lfs_sane_rename); 1152 } 1153