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