1 /* $NetBSD: lfs_alloc.c,v 1.130 2015/09/13 07:53:37 dholland 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.130 2015/09/13 07:53:37 dholland 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/lfs/ulfs_quotacommon.h>
84 #include <ufs/lfs/ulfs_inode.h>
85 #include <ufs/lfs/ulfsmount.h>
86 #include <ufs/lfs/ulfs_extern.h>
88 #include <ufs/lfs/lfs.h>
89 #include <ufs/lfs/lfs_accessors.h>
90 #include <ufs/lfs/lfs_extern.h>
91 #include <ufs/lfs/lfs_kernel.h>
93 /* Constants for inode free bitmap */
94 #define BMSHIFT 5 /* 2 ** 5 = 32 */
95 #define BMMASK ((1 << BMSHIFT) - 1)
96 #define SET_BITMAP_FREE(F, I) do { \
97 DLOG((DLOG_ALLOC, "lfs: ino %d wrd %d bit %d set\n", (int)(I), \
98 (int)((I) >> BMSHIFT), (int)((I) & BMMASK))); \
99 (F)->lfs_ino_bitmap[(I) >> BMSHIFT] |= (1 << ((I) & BMMASK)); \
101 #define CLR_BITMAP_FREE(F, I) do { \
102 DLOG((DLOG_ALLOC, "lfs: ino %d wrd %d bit %d clr\n", (int)(I), \
103 (int)((I) >> BMSHIFT), (int)((I) & BMMASK))); \
104 (F)->lfs_ino_bitmap[(I) >> BMSHIFT] &= ~(1 << ((I) & BMMASK)); \
107 #define ISSET_BITMAP_FREE(F, I) \
108 ((F)->lfs_ino_bitmap[(I) >> BMSHIFT] & (1 << ((I) & BMMASK)))
111 * Add a new block to the Ifile, to accommodate future file creations.
112 * Called with the segment lock held.
115 lfs_extend_ifile(struct lfs
*fs
, kauth_cred_t cred
)
122 struct buf
*bp
, *cbp
;
124 daddr_t i
, blkno
, xmax
;
125 ino_t oldlast
, maxino
;
132 blkno
= lfs_lblkno(fs
, ip
->i_size
);
133 if ((error
= lfs_balloc(vp
, ip
->i_size
, lfs_sb_getbsize(fs
), cred
, 0,
137 ip
->i_size
+= lfs_sb_getbsize(fs
);
138 lfs_dino_setsize(fs
, ip
->i_din
, ip
->i_size
);
139 uvm_vnp_setsize(vp
, ip
->i_size
);
141 maxino
= ((ip
->i_size
>> lfs_sb_getbshift(fs
)) - lfs_sb_getcleansz(fs
) -
142 lfs_sb_getsegtabsz(fs
)) * lfs_sb_getifpb(fs
);
143 fs
->lfs_ino_bitmap
= (lfs_bm_t
*)
144 realloc(fs
->lfs_ino_bitmap
, ((maxino
+ BMMASK
) >> BMSHIFT
) *
145 sizeof(lfs_bm_t
), M_SEGMENT
, M_WAITOK
);
146 KASSERT(fs
->lfs_ino_bitmap
!= NULL
);
148 i
= (blkno
- lfs_sb_getsegtabsz(fs
) - lfs_sb_getcleansz(fs
)) *
152 * We insert the new inodes at the head of the free list.
153 * Under normal circumstances, the free list is empty here,
154 * so we are also incidentally placing them at the end (which
155 * we must do if we are to keep them in order).
157 LFS_GET_HEADFREE(fs
, cip
, cbp
, &oldlast
);
158 LFS_PUT_HEADFREE(fs
, cip
, cbp
, i
);
160 if (lfs_sb_getfreehd(fs
) == LFS_UNUSED_INUM
)
161 panic("inode 0 allocated [2]");
162 #endif /* DIAGNOSTIC */
163 xmax
= i
+ lfs_sb_getifpb(fs
);
166 for (ifp64
= (IFILE64
*)bp
->b_data
; i
< xmax
; ++ifp64
) {
167 SET_BITMAP_FREE(fs
, i
);
168 ifp64
->if_version
= 1;
169 ifp64
->if_daddr
= LFS_UNUSED_DADDR
;
170 ifp64
->if_nextfree
= ++i
;
173 ifp64
->if_nextfree
= oldlast
;
174 } else if (lfs_sb_getversion(fs
) > 1) {
175 for (ifp32
= (IFILE32
*)bp
->b_data
; i
< xmax
; ++ifp32
) {
176 SET_BITMAP_FREE(fs
, i
);
177 ifp32
->if_version
= 1;
178 ifp32
->if_daddr
= LFS_UNUSED_DADDR
;
179 ifp32
->if_nextfree
= ++i
;
182 ifp32
->if_nextfree
= oldlast
;
184 for (ifp_v1
= (IFILE_V1
*)bp
->b_data
; i
< xmax
; ++ifp_v1
) {
185 SET_BITMAP_FREE(fs
, i
);
186 ifp_v1
->if_version
= 1;
187 ifp_v1
->if_daddr
= LFS_UNUSED_DADDR
;
188 ifp_v1
->if_nextfree
= ++i
;
191 ifp_v1
->if_nextfree
= oldlast
;
193 LFS_PUT_TAILFREE(fs
, cip
, cbp
, xmax
- 1);
195 (void) LFS_BWRITE_LOG(bp
); /* Ifile */
200 /* Allocate a new inode. */
202 /* VOP_BWRITE 2i times */
204 lfs_valloc(struct vnode
*pvp
, int mode
, kauth_cred_t cred
,
205 ino_t
*ino
, int *gen
)
208 struct buf
*bp
, *cbp
;
213 fs
= VTOI(pvp
)->i_lfs
;
217 ASSERT_NO_SEGLOCK(fs
);
219 lfs_seglock(fs
, SEGM_PROT
);
221 /* Get the head of the freelist. */
222 LFS_GET_HEADFREE(fs
, cip
, cbp
, ino
);
223 KASSERT(*ino
!= LFS_UNUSED_INUM
&& *ino
!= LFS_IFILE_INUM
);
225 DLOG((DLOG_ALLOC
, "lfs_valloc: allocate inode %" PRId64
"\n",
229 * Remove the inode from the free list and write the new start
230 * of the free list into the superblock.
232 CLR_BITMAP_FREE(fs
, *ino
);
233 LFS_IENTRY(ifp
, fs
, *ino
, bp
);
234 if (lfs_if_getdaddr(fs
, ifp
) != LFS_UNUSED_DADDR
)
235 panic("lfs_valloc: inuse inode %" PRId64
" on the free list",
237 LFS_PUT_HEADFREE(fs
, cip
, cbp
, lfs_if_getnextfree(fs
, ifp
));
238 DLOG((DLOG_ALLOC
, "lfs_valloc: headfree %" PRId64
" -> %ju\n",
239 *ino
, (uintmax_t)lfs_if_getnextfree(fs
, ifp
)));
241 /* version was updated by vfree */
242 *gen
= lfs_if_getversion(fs
, ifp
);
245 /* Extend IFILE so that the next lfs_valloc will succeed. */
246 if (lfs_sb_getfreehd(fs
) == LFS_UNUSED_INUM
) {
247 if ((error
= lfs_extend_ifile(fs
, cred
)) != 0) {
248 LFS_PUT_HEADFREE(fs
, cip
, cbp
, *ino
);
254 if (lfs_sb_getfreehd(fs
) == LFS_UNUSED_INUM
)
255 panic("inode 0 allocated [3]");
256 #endif /* DIAGNOSTIC */
258 /* Set superblock modified bit and increment file count. */
259 mutex_enter(&lfs_lock
);
261 mutex_exit(&lfs_lock
);
262 lfs_sb_addnfiles(fs
, 1);
270 * Allocate a new inode with given inode number and version.
273 lfs_valloc_fixed(struct lfs
*fs
, ino_t ino
, int vers
)
276 struct buf
*bp
, *cbp
;
277 ino_t headino
, thisino
, oldnext
;
280 /* If the Ifile is too short to contain this inum, extend it */
281 while (VTOI(fs
->lfs_ivnode
)->i_size
<= (ino
/
282 lfs_sb_getifpb(fs
) + lfs_sb_getcleansz(fs
) + lfs_sb_getsegtabsz(fs
))
283 << lfs_sb_getbshift(fs
)) {
284 lfs_extend_ifile(fs
, NOCRED
);
287 LFS_IENTRY(ifp
, fs
, ino
, bp
);
288 oldnext
= lfs_if_getnextfree(fs
, ifp
);
289 lfs_if_setversion(fs
, ifp
, vers
);
292 LFS_GET_HEADFREE(fs
, cip
, cbp
, &headino
);
293 if (headino
== ino
) {
294 LFS_PUT_HEADFREE(fs
, cip
, cbp
, oldnext
);
300 LFS_IENTRY(ifp
, fs
, thisino
, bp
);
301 nextfree
= lfs_if_getnextfree(fs
, ifp
);
302 if (nextfree
== ino
||
303 nextfree
== LFS_UNUSED_INUM
)
308 if (nextfree
== LFS_UNUSED_INUM
) {
312 lfs_if_setnextfree(fs
, ifp
, oldnext
);
321 * Find the highest-numbered allocated inode.
322 * This will be used to shrink the Ifile.
325 lfs_last_alloc_ino(struct lfs
*fs
)
329 maxino
= ((fs
->lfs_ivnode
->v_size
>> lfs_sb_getbshift(fs
)) -
330 lfs_sb_getcleansz(fs
) - lfs_sb_getsegtabsz(fs
)) * fs
->lfs_ifpb
;
331 for (ino
= maxino
- 1; ino
> LFS_UNUSED_INUM
; --ino
) {
332 if (ISSET_BITMAP_FREE(fs
, ino
) == 0)
340 * Find the previous (next lowest numbered) free inode, if any.
341 * If there is none, return LFS_UNUSED_INUM.
344 lfs_freelist_prev(struct lfs
*fs
, ino_t ino
)
346 ino_t tino
, bound
, bb
, freehdbb
;
348 if (lfs_sb_getfreehd(fs
) == LFS_UNUSED_INUM
) /* No free inodes at all */
349 return LFS_UNUSED_INUM
;
351 /* Search our own word first */
352 bound
= ino
& ~BMMASK
;
353 for (tino
= ino
- 1; tino
>= bound
&& tino
> LFS_UNUSED_INUM
; tino
--)
354 if (ISSET_BITMAP_FREE(fs
, tino
))
356 /* If there are no lower words to search, just return */
357 if (ino
>> BMSHIFT
== 0)
358 return LFS_UNUSED_INUM
;
361 * Find a word with a free inode in it. We have to be a bit
362 * careful here since ino_t is unsigned.
364 freehdbb
= (lfs_sb_getfreehd(fs
) >> BMSHIFT
);
365 for (bb
= (ino
>> BMSHIFT
) - 1; bb
>= freehdbb
&& bb
> 0; --bb
)
366 if (fs
->lfs_ino_bitmap
[bb
])
368 if (fs
->lfs_ino_bitmap
[bb
] == 0)
369 return LFS_UNUSED_INUM
;
371 /* Search the word we found */
372 for (tino
= (bb
<< BMSHIFT
) | BMMASK
; tino
>= (bb
<< BMSHIFT
) &&
373 tino
> LFS_UNUSED_INUM
; tino
--)
374 if (ISSET_BITMAP_FREE(fs
, tino
))
377 if (tino
<= LFS_IFILE_INUM
)
378 tino
= LFS_UNUSED_INUM
;
385 /* VOP_BWRITE 2i times */
387 lfs_vfree(struct vnode
*vp
, ino_t ino
, int mode
)
391 struct buf
*cbp
, *bp
;
398 /* Get the inode number and file system. */
403 ASSERT_NO_SEGLOCK(fs
);
404 DLOG((DLOG_ALLOC
, "lfs_vfree: free ino %lld\n", (long long)ino
));
406 /* Drain of pending writes */
407 mutex_enter(vp
->v_interlock
);
408 while (lfs_sb_getversion(fs
) > 1 && WRITEINPROG(vp
)) {
409 cv_wait(&vp
->v_cv
, vp
->v_interlock
);
411 mutex_exit(vp
->v_interlock
);
413 lfs_seglock(fs
, SEGM_PROT
);
415 lfs_unmark_vnode(vp
);
416 mutex_enter(&lfs_lock
);
417 if (vp
->v_uflag
& VU_DIROP
) {
418 vp
->v_uflag
&= ~VU_DIROP
;
421 TAILQ_REMOVE(&fs
->lfs_dchainhd
, ip
, i_lfs_dchain
);
422 wakeup(&fs
->lfs_dirvcount
);
423 wakeup(&lfs_dirvcount
);
424 mutex_exit(&lfs_lock
);
428 * If this inode is not going to be written any more, any
429 * segment accounting left over from its truncation needs
430 * to occur at the end of the next dirops flush. Attach
431 * them to the fs-wide list for that purpose.
433 if (LIST_FIRST(&ip
->i_lfs_segdhd
) != NULL
) {
436 while((sd
= LIST_FIRST(&ip
->i_lfs_segdhd
)) != NULL
) {
437 LIST_REMOVE(sd
, list
);
438 LIST_INSERT_HEAD(&fs
->lfs_segdhd
, sd
, list
);
443 * If it's not a dirop, we can finalize right away.
445 mutex_exit(&lfs_lock
);
446 lfs_finalize_ino_seguse(fs
, ip
);
449 mutex_enter(&lfs_lock
);
450 LFS_CLR_UINO(ip
, IN_ACCESSED
|IN_CLEANING
|IN_MODIFIED
);
451 mutex_exit(&lfs_lock
);
452 ip
->i_flag
&= ~IN_ALLMOD
;
453 ip
->i_lfs_iflags
|= LFSI_DELETED
;
456 * Set the ifile's inode entry to unused, increment its version number
457 * and link it onto the free chain.
459 SET_BITMAP_FREE(fs
, ino
);
460 LFS_IENTRY(ifp
, fs
, ino
, bp
);
461 old_iaddr
= lfs_if_getdaddr(fs
, ifp
);
462 lfs_if_setdaddr(fs
, ifp
, LFS_UNUSED_DADDR
);
463 lfs_if_setversion(fs
, ifp
, lfs_if_getversion(fs
, ifp
) + 1);
464 if (lfs_sb_getversion(fs
) == 1) {
467 LFS_GET_HEADFREE(fs
, cip
, cbp
, &nextfree
);
468 lfs_if_setnextfree(fs
, ifp
, nextfree
);
469 LFS_PUT_HEADFREE(fs
, cip
, cbp
, ino
);
470 (void) LFS_BWRITE_LOG(bp
); /* Ifile */
474 lfs_if_setnextfree(fs
, ifp
, LFS_UNUSED_INUM
);
475 (void) LFS_BWRITE_LOG(bp
); /* Ifile */
477 tino
= lfs_freelist_prev(fs
, ino
);
478 if (tino
== LFS_UNUSED_INUM
) {
481 /* Nothing free below us, put us on the head */
482 LFS_IENTRY(ifp
, fs
, ino
, bp
);
483 LFS_GET_HEADFREE(fs
, cip
, cbp
, &nextfree
);
484 lfs_if_setnextfree(fs
, ifp
, nextfree
);
485 LFS_PUT_HEADFREE(fs
, cip
, cbp
, ino
);
486 DLOG((DLOG_ALLOC
, "lfs_vfree: headfree %lld -> %lld\n",
487 (long long)nextfree
, (long long)ino
));
488 LFS_BWRITE_LOG(bp
); /* Ifile */
490 /* If the list was empty, set tail too */
491 LFS_GET_TAILFREE(fs
, cip
, cbp
, &otail
);
492 if (otail
== LFS_UNUSED_INUM
) {
493 LFS_PUT_TAILFREE(fs
, cip
, cbp
, ino
);
494 DLOG((DLOG_ALLOC
, "lfs_vfree: tailfree %lld "
495 "-> %lld\n", (long long)otail
,
500 * Insert this inode into the list after tino.
501 * We hold the segment lock so we don't have to
502 * worry about blocks being written out of order.
504 DLOG((DLOG_ALLOC
, "lfs_vfree: insert ino %lld "
505 " after %lld\n", ino
, tino
));
507 LFS_IENTRY(ifp
, fs
, tino
, bp
);
508 onf
= lfs_if_getnextfree(fs
, ifp
);
509 lfs_if_setnextfree(fs
, ifp
, ino
);
510 LFS_BWRITE_LOG(bp
); /* Ifile */
512 LFS_IENTRY(ifp
, fs
, ino
, bp
);
513 lfs_if_setnextfree(fs
, ifp
, onf
);
514 LFS_BWRITE_LOG(bp
); /* Ifile */
516 /* If we're last, put us on the tail */
517 if (onf
== LFS_UNUSED_INUM
) {
518 LFS_GET_TAILFREE(fs
, cip
, cbp
, &otail
);
519 LFS_PUT_TAILFREE(fs
, cip
, cbp
, ino
);
520 DLOG((DLOG_ALLOC
, "lfs_vfree: tailfree %lld "
521 "-> %lld\n", (long long)otail
,
527 if (ino
== LFS_UNUSED_INUM
) {
528 panic("inode 0 freed");
530 #endif /* DIAGNOSTIC */
531 if (old_iaddr
!= LFS_UNUSED_DADDR
) {
532 LFS_SEGENTRY(sup
, fs
, lfs_dtosn(fs
, old_iaddr
), bp
);
534 if (sup
->su_nbytes
< DINOSIZE(fs
)) {
535 printf("lfs_vfree: negative byte count"
536 " (segment %" PRIu32
" short by %d)\n",
537 lfs_dtosn(fs
, old_iaddr
),
540 panic("lfs_vfree: negative byte count");
541 sup
->su_nbytes
= DINOSIZE(fs
);
544 sup
->su_nbytes
-= DINOSIZE(fs
);
545 LFS_WRITESEGENTRY(sup
, fs
, lfs_dtosn(fs
, old_iaddr
), bp
); /* Ifile */
548 /* Set superblock modified bit and decrement file count. */
549 mutex_enter(&lfs_lock
);
551 mutex_exit(&lfs_lock
);
552 lfs_sb_subnfiles(fs
, 1);
560 * Sort the freelist and set up the free-inode bitmap.
561 * To be called by lfs_mountfs().
564 lfs_order_freelist(struct lfs
*fs
)
569 ino_t ino
, firstino
, lastino
, maxino
;
574 ASSERT_NO_SEGLOCK(fs
);
575 lfs_seglock(fs
, SEGM_PROT
);
577 maxino
= ((fs
->lfs_ivnode
->v_size
>> lfs_sb_getbshift(fs
)) -
578 lfs_sb_getcleansz(fs
) - lfs_sb_getsegtabsz(fs
)) * lfs_sb_getifpb(fs
);
580 malloc(((maxino
+ BMMASK
) >> BMSHIFT
) * sizeof(lfs_bm_t
),
581 M_SEGMENT
, M_WAITOK
| M_ZERO
);
582 KASSERT(fs
->lfs_ino_bitmap
!= NULL
);
584 firstino
= lastino
= LFS_UNUSED_INUM
;
585 for (ino
= 0; ino
< maxino
; ino
++) {
586 if (ino
% lfs_sb_getifpb(fs
) == 0)
587 LFS_IENTRY(ifp
, fs
, ino
, bp
);
589 LFS_IENTRY_NEXT(ifp
, fs
);
591 /* Don't put zero or ifile on the free list */
592 if (ino
== LFS_UNUSED_INUM
|| ino
== LFS_IFILE_INUM
)
596 /* Address orphaned files */
597 if (lfs_if_getnextfree(fs
, ifp
) == LFS_ORPHAN_NEXTFREE
&&
598 VFS_VGET(fs
->lfs_ivnode
->v_mount
, ino
, &vp
) == 0) {
601 segno
= lfs_dtosn(fs
, lfs_if_getdaddr(fs
, ifp
));
602 lfs_truncate(vp
, 0, 0, NOCRED
);
604 LFS_SEGENTRY(sup
, fs
, segno
, bp
);
605 KASSERT(sup
->su_nbytes
>= LFS_DINODE1_SIZE
);
606 sup
->su_nbytes
-= LFS_DINODE1_SIZE
;
607 LFS_WRITESEGENTRY(sup
, fs
, segno
, bp
);
609 /* Set up to fall through to next section */
610 lfs_if_setdaddr(fs
, ifp
, LFS_UNUSED_DADDR
);
612 LFS_IENTRY(ifp
, fs
, ino
, bp
);
616 if (lfs_if_getdaddr(fs
, ifp
) == LFS_UNUSED_DADDR
) {
617 if (firstino
== LFS_UNUSED_INUM
)
622 LFS_IENTRY(ifp
, fs
, lastino
, bp
);
623 lfs_if_setnextfree(fs
, ifp
, ino
);
626 LFS_IENTRY(ifp
, fs
, ino
, bp
);
630 SET_BITMAP_FREE(fs
, ino
);
633 if ((ino
+ 1) % lfs_sb_getifpb(fs
) == 0)
637 LFS_PUT_HEADFREE(fs
, cip
, bp
, firstino
);
638 LFS_PUT_TAILFREE(fs
, cip
, bp
, lastino
);
644 lfs_orphan(struct lfs
*fs
, ino_t ino
)
649 LFS_IENTRY(ifp
, fs
, ino
, bp
);
650 lfs_if_setnextfree(fs
, ifp
, LFS_ORPHAN_NEXTFREE
);