1 /* $NetBSD: lfs_alloc.c,v 1.108 2009/09/13 05:17:37 tsutsui Exp $ */
4 * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Konrad E. Schroder <perseant@hhhh.org>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (c) 1991, 1993
33 * The Regents of the University of California. All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * @(#)lfs_alloc.c 8.4 (Berkeley) 1/4/94
62 #include <sys/cdefs.h>
63 __KERNEL_RCSID(0, "$NetBSD: lfs_alloc.c,v 1.108 2009/09/13 05:17:37 tsutsui Exp $");
65 #if defined(_KERNEL_OPT)
66 #include "opt_quota.h"
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/kernel.h>
74 #include <sys/vnode.h>
75 #include <sys/syslog.h>
76 #include <sys/mount.h>
77 #include <sys/malloc.h>
81 #include <sys/kauth.h>
83 #include <ufs/ufs/quota.h>
84 #include <ufs/ufs/inode.h>
85 #include <ufs/ufs/ufsmount.h>
86 #include <ufs/ufs/ufs_extern.h>
88 #include <ufs/lfs/lfs.h>
89 #include <ufs/lfs/lfs_extern.h>
91 /* Constants for inode free bitmap */
92 #define BMSHIFT 5 /* 2 ** 5 = 32 */
93 #define BMMASK ((1 << BMSHIFT) - 1)
94 #define SET_BITMAP_FREE(F, I) do { \
95 DLOG((DLOG_ALLOC, "lfs: ino %d wrd %d bit %d set\n", (int)(I), \
96 (int)((I) >> BMSHIFT), (int)((I) & BMMASK))); \
97 (F)->lfs_ino_bitmap[(I) >> BMSHIFT] |= (1 << ((I) & BMMASK)); \
99 #define CLR_BITMAP_FREE(F, I) do { \
100 DLOG((DLOG_ALLOC, "lfs: ino %d wrd %d bit %d clr\n", (int)(I), \
101 (int)((I) >> BMSHIFT), (int)((I) & BMMASK))); \
102 (F)->lfs_ino_bitmap[(I) >> BMSHIFT] &= ~(1 << ((I) & BMMASK)); \
105 #define ISSET_BITMAP_FREE(F, I) \
106 ((F)->lfs_ino_bitmap[(I) >> BMSHIFT] & (1 << ((I) & BMMASK)))
109 * Add a new block to the Ifile, to accommodate future file creations.
110 * Called with the segment lock held.
113 lfs_extend_ifile(struct lfs
*fs
, kauth_cred_t cred
)
119 struct buf
*bp
, *cbp
;
121 daddr_t i
, blkno
, xmax
;
122 ino_t oldlast
, maxino
;
129 blkno
= lblkno(fs
, ip
->i_size
);
130 if ((error
= lfs_balloc(vp
, ip
->i_size
, fs
->lfs_bsize
, cred
, 0,
134 ip
->i_size
+= fs
->lfs_bsize
;
135 ip
->i_ffs1_size
= ip
->i_size
;
136 uvm_vnp_setsize(vp
, ip
->i_size
);
138 maxino
= ((ip
->i_size
>> fs
->lfs_bshift
) - fs
->lfs_cleansz
-
139 fs
->lfs_segtabsz
) * fs
->lfs_ifpb
;
140 fs
->lfs_ino_bitmap
= (lfs_bm_t
*)
141 realloc(fs
->lfs_ino_bitmap
, ((maxino
+ BMMASK
) >> BMSHIFT
) *
142 sizeof(lfs_bm_t
), M_SEGMENT
, M_WAITOK
);
143 KASSERT(fs
->lfs_ino_bitmap
!= NULL
);
145 i
= (blkno
- fs
->lfs_segtabsz
- fs
->lfs_cleansz
) *
149 * We insert the new inodes at the head of the free list.
150 * Under normal circumstances, the free list is empty here,
151 * so we are also incidentally placing them at the end (which
152 * we must do if we are to keep them in order).
154 LFS_GET_HEADFREE(fs
, cip
, cbp
, &oldlast
);
155 LFS_PUT_HEADFREE(fs
, cip
, cbp
, i
);
157 if (fs
->lfs_freehd
== LFS_UNUSED_INUM
)
158 panic("inode 0 allocated [2]");
159 #endif /* DIAGNOSTIC */
160 xmax
= i
+ fs
->lfs_ifpb
;
162 if (fs
->lfs_version
== 1) {
163 for (ifp_v1
= (IFILE_V1
*)bp
->b_data
; i
< xmax
; ++ifp_v1
) {
164 SET_BITMAP_FREE(fs
, i
);
165 ifp_v1
->if_version
= 1;
166 ifp_v1
->if_daddr
= LFS_UNUSED_DADDR
;
167 ifp_v1
->if_nextfree
= ++i
;
170 ifp_v1
->if_nextfree
= oldlast
;
172 for (ifp
= (IFILE
*)bp
->b_data
; i
< xmax
; ++ifp
) {
173 SET_BITMAP_FREE(fs
, i
);
175 ifp
->if_daddr
= LFS_UNUSED_DADDR
;
176 ifp
->if_nextfree
= ++i
;
179 ifp
->if_nextfree
= oldlast
;
181 LFS_PUT_TAILFREE(fs
, cip
, cbp
, xmax
- 1);
183 (void) LFS_BWRITE_LOG(bp
); /* Ifile */
188 /* Allocate a new inode. */
190 /* VOP_BWRITE 2i times */
192 lfs_valloc(struct vnode
*pvp
, int mode
, kauth_cred_t cred
,
196 struct buf
*bp
, *cbp
;
203 fs
= VTOI(pvp
)->i_lfs
;
207 ASSERT_NO_SEGLOCK(fs
);
209 lfs_seglock(fs
, SEGM_PROT
);
210 vn_lock(fs
->lfs_ivnode
, LK_EXCLUSIVE
);
212 /* Get the head of the freelist. */
213 LFS_GET_HEADFREE(fs
, cip
, cbp
, &new_ino
);
214 KASSERT(new_ino
!= LFS_UNUSED_INUM
&& new_ino
!= LFS_IFILE_INUM
);
216 DLOG((DLOG_ALLOC
, "lfs_valloc: allocate inode %lld\n",
217 (long long)new_ino
));
220 * Remove the inode from the free list and write the new start
221 * of the free list into the superblock.
223 CLR_BITMAP_FREE(fs
, new_ino
);
224 LFS_IENTRY(ifp
, fs
, new_ino
, bp
);
225 if (ifp
->if_daddr
!= LFS_UNUSED_DADDR
)
226 panic("lfs_valloc: inuse inode %llu on the free list",
227 (unsigned long long)new_ino
);
228 LFS_PUT_HEADFREE(fs
, cip
, cbp
, ifp
->if_nextfree
);
229 DLOG((DLOG_ALLOC
, "lfs_valloc: headfree %lld -> %lld\n",
230 (long long)new_ino
, (long long)ifp
->if_nextfree
));
232 new_gen
= ifp
->if_version
; /* version was updated by vfree */
235 /* Extend IFILE so that the next lfs_valloc will succeed. */
236 if (fs
->lfs_freehd
== LFS_UNUSED_INUM
) {
237 if ((error
= lfs_extend_ifile(fs
, cred
)) != 0) {
238 LFS_PUT_HEADFREE(fs
, cip
, cbp
, new_ino
);
239 VOP_UNLOCK(fs
->lfs_ivnode
, 0);
245 if (fs
->lfs_freehd
== LFS_UNUSED_INUM
)
246 panic("inode 0 allocated [3]");
247 #endif /* DIAGNOSTIC */
249 /* Set superblock modified bit and increment file count. */
250 mutex_enter(&lfs_lock
);
252 mutex_exit(&lfs_lock
);
255 VOP_UNLOCK(fs
->lfs_ivnode
, 0);
258 return lfs_ialloc(fs
, pvp
, new_ino
, new_gen
, vpp
);
262 * Finish allocating a new inode, given an inode and generation number.
265 lfs_ialloc(struct lfs
*fs
, struct vnode
*pvp
, ino_t new_ino
, int new_gen
,
271 ASSERT_NO_SEGLOCK(fs
);
274 mutex_enter(&ufs_hashlock
);
275 /* Create an inode to associate with the vnode. */
276 lfs_vcreate(pvp
->v_mount
, new_ino
, vp
);
279 mutex_enter(&lfs_lock
);
280 LFS_SET_UINO(ip
, IN_CHANGE
);
281 mutex_exit(&lfs_lock
);
282 /* on-disk structure has been zeroed out by lfs_vcreate */
283 ip
->i_din
.ffs1_din
->di_inumber
= new_ino
;
285 /* Note no blocks yet */
286 ip
->i_lfs_hiblk
= -1;
288 /* Set a new generation number for this inode. */
291 ip
->i_ffs1_gen
= new_gen
;
294 /* Insert into the inode hash table. */
296 mutex_exit(&ufs_hashlock
);
298 ufs_vinit(vp
->v_mount
, lfs_specop_p
, lfs_fifoop_p
, vpp
);
302 memset(ip
->i_lfs_fragsize
, 0, NDADDR
* sizeof(*ip
->i_lfs_fragsize
));
304 uvm_vnp_setsize(vp
, 0);
306 genfs_node_init(vp
, &lfs_genfsops
);
311 /* Create a new vnode/inode pair and initialize what fields we can. */
313 lfs_vcreate(struct mount
*mp
, ino_t ino
, struct vnode
*vp
)
316 struct ufs1_dinode
*dp
;
317 struct ufsmount
*ump
;
319 /* Get a pointer to the private mount structure. */
322 ASSERT_NO_SEGLOCK(ump
->um_lfs
);
324 /* Initialize the inode. */
325 ip
= pool_get(&lfs_inode_pool
, PR_WAITOK
);
326 memset(ip
, 0, sizeof(*ip
));
327 dp
= pool_get(&lfs_dinode_pool
, PR_WAITOK
);
328 memset(dp
, 0, sizeof(*dp
));
329 ip
->inode_ext
.lfs
= pool_get(&lfs_inoext_pool
, PR_WAITOK
);
330 memset(ip
->inode_ext
.lfs
, 0, sizeof(*ip
->inode_ext
.lfs
));
332 ip
->i_din
.ffs1_din
= dp
;
335 ip
->i_devvp
= ump
->um_devvp
;
336 ip
->i_dev
= ump
->um_dev
;
337 ip
->i_number
= dp
->di_inumber
= ino
;
338 ip
->i_lfs
= ump
->um_lfs
;
339 ip
->i_lfs_effnblks
= 0;
340 SPLAY_INIT(&ip
->i_lfs_lbtree
);
341 ip
->i_lfs_nbtree
= 0;
342 LIST_INIT(&ip
->i_lfs_segdhd
);
350 * Find the highest-numbered allocated inode.
351 * This will be used to shrink the Ifile.
354 lfs_last_alloc_ino(struct lfs
*fs
)
358 maxino
= ((fs
->lfs_ivnode
->v_size
>> fs
->lfs_bshift
) -
359 fs
->lfs_cleansz
- fs
->lfs_segtabsz
) * fs
->lfs_ifpb
;
360 for (ino
= maxino
- 1; ino
> LFS_UNUSED_INUM
; --ino
) {
361 if (ISSET_BITMAP_FREE(fs
, ino
) == 0)
369 * Find the previous (next lowest numbered) free inode, if any.
370 * If there is none, return LFS_UNUSED_INUM.
373 lfs_freelist_prev(struct lfs
*fs
, ino_t ino
)
375 ino_t tino
, bound
, bb
, freehdbb
;
377 if (fs
->lfs_freehd
== LFS_UNUSED_INUM
) /* No free inodes at all */
378 return LFS_UNUSED_INUM
;
380 /* Search our own word first */
381 bound
= ino
& ~BMMASK
;
382 for (tino
= ino
- 1; tino
>= bound
&& tino
> LFS_UNUSED_INUM
; tino
--)
383 if (ISSET_BITMAP_FREE(fs
, tino
))
385 /* If there are no lower words to search, just return */
386 if (ino
>> BMSHIFT
== 0)
387 return LFS_UNUSED_INUM
;
390 * Find a word with a free inode in it. We have to be a bit
391 * careful here since ino_t is unsigned.
393 freehdbb
= (fs
->lfs_freehd
>> BMSHIFT
);
394 for (bb
= (ino
>> BMSHIFT
) - 1; bb
>= freehdbb
&& bb
> 0; --bb
)
395 if (fs
->lfs_ino_bitmap
[bb
])
397 if (fs
->lfs_ino_bitmap
[bb
] == 0)
398 return LFS_UNUSED_INUM
;
400 /* Search the word we found */
401 for (tino
= (bb
<< BMSHIFT
) | BMMASK
; tino
>= (bb
<< BMSHIFT
) &&
402 tino
> LFS_UNUSED_INUM
; tino
--)
403 if (ISSET_BITMAP_FREE(fs
, tino
))
406 if (tino
<= LFS_IFILE_INUM
)
407 tino
= LFS_UNUSED_INUM
;
414 /* VOP_BWRITE 2i times */
416 lfs_vfree(struct vnode
*vp
, ino_t ino
, int mode
)
420 struct buf
*cbp
, *bp
;
427 /* Get the inode number and file system. */
432 ASSERT_NO_SEGLOCK(fs
);
433 DLOG((DLOG_ALLOC
, "lfs_vfree: free ino %lld\n", (long long)ino
));
435 /* Drain of pending writes */
436 mutex_enter(&vp
->v_interlock
);
437 while (fs
->lfs_version
> 1 && WRITEINPROG(vp
)) {
438 cv_wait(&vp
->v_cv
, &vp
->v_interlock
);
440 mutex_exit(&vp
->v_interlock
);
442 lfs_seglock(fs
, SEGM_PROT
);
443 vn_lock(fs
->lfs_ivnode
, LK_EXCLUSIVE
);
445 lfs_unmark_vnode(vp
);
446 mutex_enter(&lfs_lock
);
447 if (vp
->v_uflag
& VU_DIROP
) {
448 vp
->v_uflag
&= ~VU_DIROP
;
451 TAILQ_REMOVE(&fs
->lfs_dchainhd
, ip
, i_lfs_dchain
);
452 wakeup(&fs
->lfs_dirvcount
);
453 wakeup(&lfs_dirvcount
);
454 mutex_exit(&lfs_lock
);
458 * If this inode is not going to be written any more, any
459 * segment accounting left over from its truncation needs
460 * to occur at the end of the next dirops flush. Attach
461 * them to the fs-wide list for that purpose.
463 if (LIST_FIRST(&ip
->i_lfs_segdhd
) != NULL
) {
466 while((sd
= LIST_FIRST(&ip
->i_lfs_segdhd
)) != NULL
) {
467 LIST_REMOVE(sd
, list
);
468 LIST_INSERT_HEAD(&fs
->lfs_segdhd
, sd
, list
);
473 * If it's not a dirop, we can finalize right away.
475 mutex_exit(&lfs_lock
);
476 lfs_finalize_ino_seguse(fs
, ip
);
479 mutex_enter(&lfs_lock
);
480 LFS_CLR_UINO(ip
, IN_ACCESSED
|IN_CLEANING
|IN_MODIFIED
);
481 mutex_exit(&lfs_lock
);
482 ip
->i_flag
&= ~IN_ALLMOD
;
483 ip
->i_lfs_iflags
|= LFSI_DELETED
;
486 * Set the ifile's inode entry to unused, increment its version number
487 * and link it onto the free chain.
489 SET_BITMAP_FREE(fs
, ino
);
490 LFS_IENTRY(ifp
, fs
, ino
, bp
);
491 old_iaddr
= ifp
->if_daddr
;
492 ifp
->if_daddr
= LFS_UNUSED_DADDR
;
494 if (fs
->lfs_version
== 1) {
495 LFS_GET_HEADFREE(fs
, cip
, cbp
, &(ifp
->if_nextfree
));
496 LFS_PUT_HEADFREE(fs
, cip
, cbp
, ino
);
497 (void) LFS_BWRITE_LOG(bp
); /* Ifile */
501 ifp
->if_nextfree
= LFS_UNUSED_INUM
;
502 (void) LFS_BWRITE_LOG(bp
); /* Ifile */
504 tino
= lfs_freelist_prev(fs
, ino
);
505 if (tino
== LFS_UNUSED_INUM
) {
506 /* Nothing free below us, put us on the head */
507 LFS_IENTRY(ifp
, fs
, ino
, bp
);
508 LFS_GET_HEADFREE(fs
, cip
, cbp
, &(ifp
->if_nextfree
));
509 LFS_PUT_HEADFREE(fs
, cip
, cbp
, ino
);
510 DLOG((DLOG_ALLOC
, "lfs_vfree: headfree %lld -> %lld\n",
511 (long long)ifp
->if_nextfree
, (long long)ino
));
512 LFS_BWRITE_LOG(bp
); /* Ifile */
514 /* If the list was empty, set tail too */
515 LFS_GET_TAILFREE(fs
, cip
, cbp
, &otail
);
516 if (otail
== LFS_UNUSED_INUM
) {
517 LFS_PUT_TAILFREE(fs
, cip
, cbp
, ino
);
518 DLOG((DLOG_ALLOC
, "lfs_vfree: tailfree %lld "
519 "-> %lld\n", (long long)otail
,
524 * Insert this inode into the list after tino.
525 * We hold the segment lock so we don't have to
526 * worry about blocks being written out of order.
528 DLOG((DLOG_ALLOC
, "lfs_vfree: insert ino %lld "
529 " after %lld\n", ino
, tino
));
531 LFS_IENTRY(ifp
, fs
, tino
, bp
);
532 onf
= ifp
->if_nextfree
;
533 ifp
->if_nextfree
= ino
;
534 LFS_BWRITE_LOG(bp
); /* Ifile */
536 LFS_IENTRY(ifp
, fs
, ino
, bp
);
537 ifp
->if_nextfree
= onf
;
538 LFS_BWRITE_LOG(bp
); /* Ifile */
540 /* If we're last, put us on the tail */
541 if (onf
== LFS_UNUSED_INUM
) {
542 LFS_GET_TAILFREE(fs
, cip
, cbp
, &otail
);
543 LFS_PUT_TAILFREE(fs
, cip
, cbp
, ino
);
544 DLOG((DLOG_ALLOC
, "lfs_vfree: tailfree %lld "
545 "-> %lld\n", (long long)otail
,
551 if (ino
== LFS_UNUSED_INUM
) {
552 panic("inode 0 freed");
554 #endif /* DIAGNOSTIC */
555 if (old_iaddr
!= LFS_UNUSED_DADDR
) {
556 LFS_SEGENTRY(sup
, fs
, dtosn(fs
, old_iaddr
), bp
);
558 if (sup
->su_nbytes
< sizeof (struct ufs1_dinode
)) {
559 printf("lfs_vfree: negative byte count"
560 " (segment %" PRIu32
" short by %d)\n",
561 dtosn(fs
, old_iaddr
),
562 (int)sizeof (struct ufs1_dinode
) -
564 panic("lfs_vfree: negative byte count");
565 sup
->su_nbytes
= sizeof (struct ufs1_dinode
);
568 sup
->su_nbytes
-= sizeof (struct ufs1_dinode
);
569 LFS_WRITESEGENTRY(sup
, fs
, dtosn(fs
, old_iaddr
), bp
); /* Ifile */
572 /* Set superblock modified bit and decrement file count. */
573 mutex_enter(&lfs_lock
);
575 mutex_exit(&lfs_lock
);
578 VOP_UNLOCK(fs
->lfs_ivnode
, 0);
585 * Sort the freelist and set up the free-inode bitmap.
586 * To be called by lfs_mountfs().
589 lfs_order_freelist(struct lfs
*fs
)
594 ino_t ino
, firstino
, lastino
, maxino
;
599 ASSERT_NO_SEGLOCK(fs
);
600 lfs_seglock(fs
, SEGM_PROT
);
602 maxino
= ((fs
->lfs_ivnode
->v_size
>> fs
->lfs_bshift
) -
603 fs
->lfs_cleansz
- fs
->lfs_segtabsz
) * fs
->lfs_ifpb
;
604 fs
->lfs_ino_bitmap
= (lfs_bm_t
*)
605 malloc(((maxino
+ BMMASK
) >> BMSHIFT
) * sizeof(lfs_bm_t
),
606 M_SEGMENT
, M_WAITOK
| M_ZERO
);
607 KASSERT(fs
->lfs_ino_bitmap
!= NULL
);
609 firstino
= lastino
= LFS_UNUSED_INUM
;
610 for (ino
= 0; ino
< maxino
; ino
++) {
611 if (ino
% fs
->lfs_ifpb
== 0)
612 LFS_IENTRY(ifp
, fs
, ino
, bp
);
616 /* Don't put zero or ifile on the free list */
617 if (ino
== LFS_UNUSED_INUM
|| ino
== LFS_IFILE_INUM
)
621 /* Address orphaned files */
622 if (ifp
->if_nextfree
== LFS_ORPHAN_NEXTFREE
&&
623 VFS_VGET(fs
->lfs_ivnode
->v_mount
, ino
, &vp
) == 0) {
624 lfs_truncate(vp
, 0, 0, NOCRED
);
626 LFS_SEGENTRY(sup
, fs
, dtosn(fs
, ifp
->if_daddr
), bp
);
627 KASSERT(sup
->su_nbytes
>= DINODE1_SIZE
);
628 sup
->su_nbytes
-= DINODE1_SIZE
;
629 LFS_WRITESEGENTRY(sup
, fs
, dtosn(fs
, ifp
->if_daddr
), bp
);
631 /* Set up to fall through to next section */
632 ifp
->if_daddr
= LFS_UNUSED_DADDR
;
634 LFS_IENTRY(ifp
, fs
, ino
, bp
);
638 if (ifp
->if_daddr
== LFS_UNUSED_DADDR
) {
639 if (firstino
== LFS_UNUSED_INUM
)
644 LFS_IENTRY(ifp
, fs
, lastino
, bp
);
645 ifp
->if_nextfree
= ino
;
648 LFS_IENTRY(ifp
, fs
, ino
, bp
);
652 SET_BITMAP_FREE(fs
, ino
);
655 if ((ino
+ 1) % fs
->lfs_ifpb
== 0)
659 LFS_PUT_HEADFREE(fs
, cip
, bp
, firstino
);
660 LFS_PUT_TAILFREE(fs
, cip
, bp
, lastino
);
666 lfs_orphan(struct lfs
*fs
, ino_t ino
)
671 LFS_IENTRY(ifp
, fs
, ino
, bp
);
672 ifp
->if_nextfree
= LFS_ORPHAN_NEXTFREE
;