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 */
5 * Copyright (c) 2012 The NetBSD Foundation, Inc.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Taylor R Campbell.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
33 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
34 * All rights reserved.
36 * This code is derived from software contributed to The NetBSD Foundation
37 * by Konrad E. Schroder <perseant@hhhh.org>.
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
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.
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.
61 * Copyright (c) 1986, 1989, 1991, 1993, 1995
62 * The Regents of the University of California. All rights reserved.
64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions
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.
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
88 * @(#)lfs_vnops.c 8.13 (Berkeley) 6/10/95
91 #include <sys/cdefs.h>
92 __KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.16 2015/09/21 01:24:23 dholland Exp $");
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>
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>
113 #include <uvm/uvm_pmap.h>
114 #include <uvm/uvm_stat.h>
115 #include <uvm/uvm_pager.h>
117 #include <miscfs/fifofs/fifo.h>
118 #include <miscfs/genfs/genfs.h>
119 #include <miscfs/specfs/specdev.h>
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>
126 #include <ufs/lfs/lfs.h>
127 #include <ufs/lfs/lfs_accessors.h>
128 #include <ufs/lfs/lfs_extern.h>
131 * ulfs_gro_directory_empty_p: Return true if the directory vp is
132 * empty. dvp is its parent.
134 * vp and dvp must be locked and referenced.
137 ulfs_gro_directory_empty_p(struct mount
*mp
, kauth_cred_t cred
,
138 struct vnode
*vp
, struct vnode
*dvp
)
144 KASSERT(dvp
!= NULL
);
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
);
151 return ulfs_dirempty(VTOI(vp
), VTOI(dvp
)->i_number
, cred
);
155 * ulfs_gro_rename_check_possible: Check whether a rename is possible
156 * independent of credentials.
159 ulfs_gro_rename_check_possible(struct mount
*mp
,
160 struct vnode
*fdvp
, struct vnode
*fvp
,
161 struct vnode
*tdvp
, struct vnode
*tvp
)
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
);
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
));
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),
193 * ulfs_gro_rename_check_permitted: Check whether a rename is permitted
194 * given our credentials.
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
)
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
);
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
));
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));
231 * ulfs_gro_remove_check_possible: Check whether a remove is possible
232 * independent of credentials.
235 ulfs_gro_remove_check_possible(struct mount
*mp
,
236 struct vnode
*dvp
, struct vnode
*vp
)
241 KASSERT(dvp
!= NULL
);
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
);
251 return genfs_ufslike_remove_check_possible(
252 VTOI(dvp
)->i_flags
, VTOI(vp
)->i_flags
,
257 * ulfs_gro_remove_check_permitted: Check whether a remove is permitted
258 * given our credentials.
261 ulfs_gro_remove_check_permitted(struct mount
*mp
, kauth_cred_t cred
,
262 struct vnode
*dvp
, struct vnode
*vp
)
267 KASSERT(dvp
!= NULL
);
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
);
277 return genfs_ufslike_remove_check_permitted(cred
,
278 dvp
, VTOI(dvp
)->i_mode
, VTOI(dvp
)->i_uid
, vp
, VTOI(vp
)->i_uid
);
282 * ulfs_rename_ulr_overlap_p: True iff tulr overlaps with fulr so that
283 * entering a directory entry at tulr may move fulr.
286 ulfs_rename_ulr_overlap_p(const struct ulfs_lookup_results
*fulr
,
287 const struct ulfs_lookup_results
*tulr
)
289 doff_t from_prev_start
, from_prev_end
, to_start
, to_end
;
291 KASSERT(fulr
!= NULL
);
292 KASSERT(tulr
!= NULL
);
293 KASSERT(fulr
!= tulr
);
296 * fulr is from a DELETE lookup, so fulr->ulr_count is the size
297 * of the preceding entry (d_reclen).
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
);
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.
307 to_start
= tulr
->ulr_offset
;
308 KASSERT(tulr
->ulr_count
< (LFS_MAXDIRSIZE
- to_start
));
309 to_end
= (to_start
+ tulr
->ulr_count
);
312 (((to_start
<= from_prev_start
) && (from_prev_start
< to_end
)) ||
313 ((to_start
<= from_prev_end
) && (from_prev_end
< to_end
)));
317 * ulfs_direct_namlen: Return the namlen of the directory entry ep from
320 static int /* XXX int? uint8_t? */
321 ulfs_direct_namlen(const LFS_DIRHEADER
*ep
, const struct vnode
*vp
)
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
;
332 return lfs_dir_getnamlen(fs
, ep
);
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.
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
)
347 struct ulfsmount
*ump
;
348 /* XXX int is a silly type for this; blame ulfsmount::um_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. */
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
));
372 KASSERT(ump
!= NULL
);
373 KASSERT(ump
== VTOI(dvp
)->i_ump
);
374 KASSERT(fs
== VTOI(dvp
)->i_lfs
);
376 dirblksiz
= fs
->um_dirblksiz
;
377 KASSERT(0 < dirblksiz
);
378 KASSERT((dirblksiz
& (dirblksiz
- 1)) == 0);
380 /* A directory block may not span across multiple I/O blocks. */
381 KASSERT(dirblksiz
<= mp
->mnt_stat
.f_iosize
);
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
);
388 /* Compaction must happen only within a directory block. (*) */
389 KASSERT(search_start
<= search_end
);
390 KASSERT((search_end
- (search_start
&~ (dirblksiz
- 1))) <= dirblksiz
);
394 error
= ulfs_blkatoff(dvp
, (off_t
)search_start
, &dirbuf
, &bp
, false);
397 KASSERT(dirbuf
!= NULL
);
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).
405 KASSERT((search_end
- search_start
) <=
406 (bp
->b_bcount
- (search_start
& (mp
->mnt_stat
.f_iosize
- 1))));
408 prev_reclen
= fulr
->ulr_count
;
409 offset
= search_start
;
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.
417 KASSERT(search_start
<= offset
);
418 KASSERT(offset
< search_end
);
421 * Examine the directory entry at offset.
423 ep
= (LFS_DIRHEADER
*)(dirbuf
+ (offset
- search_start
));
424 reclen
= lfs_dir_getreclen(fs
, ep
);
426 if (lfs_dir_getino(fs
, ep
) == 0)
427 goto next
; /* Entry is unused. */
429 if (lfs_dir_getino(fs
, ep
) == ULFS_WINO
)
430 goto next
; /* Entry is whiteout. */
432 if (fcnp
->cn_namelen
!= ulfs_direct_namlen(ep
, dvp
))
433 goto next
; /* Wrong name length. */
435 if (memcmp(lfs_dir_nameptr(fs
, ep
), fcnp
->cn_nameptr
, fcnp
->cn_namelen
))
436 goto next
; /* Wrong name. */
442 if (! ((reclen
< search_end
) &&
443 (offset
< (search_end
- reclen
)))) {
445 return EIO
; /* XXX Panic? What? */
448 /* We may not move past the search end. */
449 KASSERT(reclen
< search_end
);
450 KASSERT(offset
< (search_end
- reclen
));
453 * We may not move across a directory block boundary;
456 KASSERT((offset
&~ (dirblksiz
- 1)) ==
457 ((offset
+ reclen
) &~ (dirblksiz
- 1)));
459 prev_reclen
= reclen
;
464 * Found the entry. Record where.
466 fulr
->ulr_offset
= offset
;
467 fulr
->ulr_reclen
= reclen
;
470 * Record the preceding record length, but not if we're at the
471 * start of a directory block.
473 fulr
->ulr_count
= ((offset
& (dirblksiz
- 1))? prev_reclen
: 0);
480 * ulfs_gro_remove: Rename an object over another link to itself,
481 * effectively removing just the original link.
484 ulfs_gro_remove(struct mount
*mp
, kauth_cred_t cred
,
485 struct vnode
*dvp
, struct componentname
*cnp
, void *de
, struct vnode
*vp
)
487 struct ulfs_lookup_results
*ulr
= de
;
491 KASSERT(dvp
!= NULL
);
492 KASSERT(cnp
!= NULL
);
493 KASSERT(ulr
!= NULL
);
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
);
504 /* XXX ulfs_dirremove decrements vp's link count for us. */
505 error
= ulfs_dirremove(dvp
, ulr
, VTOI(vp
), cnp
->cn_flags
, 0);
509 VN_KNOTE(dvp
, NOTE_WRITE
);
510 VN_KNOTE(vp
, (VTOI(vp
)->i_nlink
? NOTE_LINK
: NOTE_DELETE
));
517 * ulfs_gro_lookup: Look up and save the lookup results.
520 ulfs_gro_lookup(struct mount
*mp
, struct vnode
*dvp
,
521 struct componentname
*cnp
, void *de_ret
, struct vnode
**vp_ret
)
523 struct ulfs_lookup_results
*ulr_ret
= de_ret
;
524 struct vnode
*vp
= 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
);
535 /* Kludge cargo-culted from dholland's ulfs_rename. */
536 cnp
->cn_flags
&=~ MODMASK
;
537 cnp
->cn_flags
|= (LOCKPARENT
| LOCKLEAF
);
539 error
= relookup(dvp
, &vp
, cnp
, 0 /* dummy */);
540 if ((error
== 0) && (vp
== NULL
)) {
548 * Thanks to VFS insanity, relookup locks vp, which screws us
554 out
: *ulr_ret
= VTOI(dvp
)->i_crap
;
560 * ulfs_rmdired_p: Check whether the directory vp has been rmdired.
562 * vp must be locked and referenced.
565 ulfs_rmdired_p(struct vnode
*vp
)
569 KASSERT(VOP_ISLOCKED(vp
) == LK_EXCLUSIVE
);
570 KASSERT(vp
->v_type
== VDIR
);
572 /* XXX Is this correct? */
573 return (VTOI(vp
)->i_size
== 0);
577 * ulfs_read_dotdot: Store in *ino_ret the inode number of the parent
578 * of the directory vp.
581 ulfs_read_dotdot(struct vnode
*vp
, kauth_cred_t cred
, ino_t
*ino_ret
)
584 union lfs_dirtemplate dirbuf
;
585 LFS_DIRHEADER
*dotdot
;
590 KASSERT(ino_ret
!= NULL
);
591 KASSERT(vp
->v_type
== VDIR
);
593 KASSERT(VTOI(vp
) != NULL
);
594 KASSERT(VTOI(vp
)->i_lfs
!= NULL
);
595 fs
= VTOI(vp
)->i_lfs
;
597 error
= ulfs_bufio(UIO_READ
, vp
, &dirbuf
, sizeof dirbuf
, (off_t
)0,
598 IO_NODELOCKED
, cred
, NULL
, NULL
);
602 dotdot
= lfs_dirtemplate_dotdot(fs
, &dirbuf
);
603 name
= lfs_dirtemplate_dotdotname(fs
, &dirbuf
);
604 if (lfs_dir_getnamlen(fs
, dotdot
) != 2 ||
607 /* XXX Panic? Print warning? */
610 *ino_ret
= lfs_dir_getino(fs
, dotdot
);
615 * ulfs_gro_lock_directory: Lock the directory vp, but fail if it has
619 ulfs_gro_lock_directory(struct mount
*mp
, struct vnode
*vp
)
625 KASSERT(vp
->v_mount
== mp
);
627 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
629 if (ulfs_rmdired_p(vp
)) {
638 * ulfs_gro_genealogy: Analyze the genealogy of the source and target
642 ulfs_gro_genealogy(struct mount
*mp
, kauth_cred_t cred
,
643 struct vnode
*fdvp
, struct vnode
*tdvp
,
644 struct vnode
**intermediate_node_ret
)
646 struct vnode
*vp
, *dvp
;
647 ino_t dotdot_ino
= -1; /* XXX gcc 4.8: maybe-uninitialized */
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
);
661 * We need to provisionally lock tdvp to keep rmdir from
662 * deleting it -- or any ancestor -- at an inopportune moment.
664 error
= ulfs_gro_lock_directory(mp
, tdvp
);
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
));
678 /* Did we hit the root without finding fdvp? */
679 if (VTOI(vp
)->i_number
== ULFS_ROOTINO
) {
681 *intermediate_node_ret
= NULL
;
685 error
= ulfs_read_dotdot(vp
, cred
, &dotdot_ino
);
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. */
695 *intermediate_node_ret
= vp
;
699 /* Neither -- keep ascending the family tree. */
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.
706 * XXX This guarantees that vp's inode number will not
707 * be recycled, but why can't dotdot_ino be recycled?
710 error
= VFS_VGET(mp
, dotdot_ino
, &dvp
);
715 KASSERT(dvp
!= NULL
);
716 KASSERT(VOP_ISLOCKED(dvp
) == LK_EXCLUSIVE
);
719 if (vp
->v_type
!= VDIR
) {
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
730 if (ulfs_rmdired_p(vp
)) {
738 * ulfs_gro_rename: Actually perform the rename operation.
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
)
748 struct ulfs_lookup_results
*fulr
= fde
;
749 struct ulfs_lookup_results
*tulr
= tde
;
750 bool directory_p
, reparent_p
;
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
);
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
));
776 fs
= VTOI(fdvp
)->i_lfs
;
777 KASSERT(fs
== VTOI(tdvp
)->i_lfs
);
780 * We shall need to temporarily bump the link count, so make
781 * sure there is room to do so.
783 if ((nlink_t
)VTOI(fvp
)->i_nlink
>= LINK_MAX
)
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
)));
792 reparent_p
= (fdvp
!= tdvp
);
793 KASSERT(reparent_p
== (VTOI(fdvp
)->i_number
!= VTOI(tdvp
)->i_number
));
796 * Commence hacking of the data on disk.
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.
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
);
814 goto whymustithurtsomuch
;
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.
826 * Account for ".." in new directory.
827 * When source and destination have the same
828 * parent we don't fool with the link count.
830 if (directory_p
&& reparent_p
) {
831 if ((nlink_t
)VTOI(tdvp
)->i_nlink
>= LINK_MAX
) {
833 goto whymustithurtsomuch
;
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
);
842 * Link count update didn't take --
843 * back out the in-memory link count.
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
;
854 error
= ulfs_direnter(tdvp
, tulr
,
855 NULL
, tcnp
, VTOI(fvp
)->i_number
, LFS_IFTODT(VTOI(fvp
)->i_mode
),
858 if (directory_p
&& reparent_p
) {
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.
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
);
873 goto whymustithurtsomuch
;
877 /* XXX WTF? Why purge here? Why not purge others? */
881 * Make the target directory's entry for tcnp point at
884 * XXX ulfs_dirrewrite decrements tvp's link count, but
885 * doesn't touch the link count of the new inode. Go
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
);
893 goto whymustithurtsomuch
;
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
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
;
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'.
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.
923 * XXX The ulfs_dirempty call earlier does
924 * not guarantee anything about nlink.
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
);
933 goto whymustithurtsomuch
;
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.
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.
945 if (directory_p
&& reparent_p
) {
949 * The .. entry goes immediately after the . entry, so
950 * the position is the record length of the . entry,
951 * namely LFS_DIRECTSIZ(1).
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! */
958 goto whymustithurtsomuch
;
961 /* XXX WTF? Why purge here? Why not purge others? */
966 * 3) Unlink the source.
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.
975 if (!reparent_p
&& (tvp
== NULL
) &&
976 ulfs_rename_ulr_overlap_p(fulr
, tulr
)) {
977 error
= ulfs_rename_recalculate_fulr(fdvp
, fulr
, tulr
, fcnp
);
979 if (error
) /* XXX Try to back out changes? */
980 goto whymustithurtsomuch
;
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.
993 error
= ulfs_dirremove(fdvp
, fulr
, VTOI(fvp
), fcnp
->cn_flags
, 0);
996 goto whymustithurtsomuch
;
998 goto arghmybrainhurts
;
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.
1005 genfs_rename_knote(fdvp
, fvp
, tdvp
, tvp
,
1006 ((tvp
!= NULL
) && (VTOI(tvp
)->i_nlink
== 0)));
1008 genfs_rename_cache_purge(fdvp
, fvp
, tdvp
, tvp
);
1010 goto arghmybrainhurts
;
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
;
1024 * lfs_gro_rename: Actually perform the rename operation. Do a little
1025 * LFS bookkeeping and then defer to ulfs_gro_rename.
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
)
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
));
1058 error
= lfs_set_dirop(tdvp
, tvp
);
1065 error
= ulfs_gro_rename(mp
, cred
,
1066 fdvp
, fcnp
, fde
, fvp
,
1067 tdvp
, tcnp
, tde
, tvp
);
1075 lfs_unset_dirop(VFSTOULFS(mp
)->um_lfs
, tdvp
, "rename");
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
,
1098 * lfs_sane_rename: The hairiest vop, with the saner API.
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).
1109 * fdvp and tdvp may be the same, and must be referenced and unlocked.
1113 struct vnode
*fdvp
, struct componentname
*fcnp
,
1114 struct vnode
*tdvp
, struct componentname
*tcnp
,
1115 kauth_cred_t cred
, bool posixly_correct
)
1117 struct ulfs_lookup_results fulr
, tulr
;
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
1125 KASSERT(fcnp
!= NULL
);
1126 KASSERT(tcnp
!= NULL
);
1127 KASSERT(fcnp
!= tcnp
);
1128 KASSERT(fcnp
->cn_nameptr
!= NULL
);
1129 KASSERT(tcnp
->cn_nameptr
!= NULL
);
1131 if ((fcnp
->cn_flags
| tcnp
->cn_flags
) & ISDOTDOT
)
1132 return EINVAL
; /* XXX EISDIR? */
1133 if ((fcnp
->cn_namelen
== 1) && (fcnp
->cn_nameptr
[0] == '.'))
1135 if ((tcnp
->cn_namelen
== 1) && (tcnp
->cn_nameptr
[0] == '.'))
1138 return genfs_sane_rename(&lfs_genfs_rename_ops
,
1139 fdvp
, fcnp
, &fulr
, tdvp
, tcnp
, &tulr
,
1140 cred
, posixly_correct
);
1144 * lfs_rename: The hairiest vop, with the insanest API. Defer to
1145 * genfs_insane_rename immediately.
1151 return genfs_insane_rename(v
, &lfs_sane_rename
);