1 /* $NetBSD: ffs_alloc.c,v 1.28 2015/03/29 05:52:59 agc Exp $ */
2 /* From: NetBSD: ffs_alloc.c,v 1.50 2001/09/06 02:16:01 lukem Exp */
5 * Copyright (c) 2002 Networks Associates Technology, Inc.
8 * This software was developed for the FreeBSD Project by Marshall
9 * Kirk McKusick and Network Associates Laboratories, the Security
10 * Research Division of Network Associates, Inc. under DARPA/SPAWAR
11 * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
14 * Copyright (c) 1982, 1986, 1989, 1993
15 * The Regents of the University of California. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * @(#)ffs_alloc.c 8.19 (Berkeley) 7/13/95
44 #if HAVE_NBTOOL_CONFIG_H
45 #include "nbtool_config.h"
48 #include <sys/cdefs.h>
49 #if defined(__RCSID) && !defined(__lint)
50 __RCSID("$NetBSD: ffs_alloc.c,v 1.28 2015/03/29 05:52:59 agc Exp $");
53 #include <sys/param.h>
60 #include <ufs/ufs/dinode.h>
61 #include <ufs/ufs/ufs_bswap.h>
62 #include <ufs/ffs/fs.h>
65 #include "ffs/ufs_inode.h"
66 #include "ffs/ffs_extern.h"
69 static int scanc(u_int
, const u_char
*, const u_char
*, int);
71 static daddr_t
ffs_alloccg(struct inode
*, int, daddr_t
, int);
72 static daddr_t
ffs_alloccgblk(struct inode
*, struct buf
*, daddr_t
);
73 static daddr_t
ffs_hashalloc(struct inode
*, int, daddr_t
, int,
74 daddr_t (*)(struct inode
*, int, daddr_t
, int));
75 static int32_t ffs_mapsearch(struct fs
*, struct cg
*, daddr_t
, int);
78 extern const int inside
[], around
[];
79 extern const u_char
* const fragtbl
[];
82 * Allocate a block in the file system.
84 * The size of the requested block is given, which must be some
85 * multiple of fs_fsize and <= fs_bsize.
86 * A preference may be optionally specified. If a preference is given
87 * the following hierarchy is used to allocate a block:
88 * 1) allocate the requested block.
89 * 2) allocate a rotationally optimal block in the same cylinder.
90 * 3) allocate a block in the same cylinder group.
91 * 4) quadradically rehash into other cylinder groups, until an
92 * available block is located.
93 * If no block preference is given the following hierarchy is used
94 * to allocate a block:
95 * 1) allocate a block in the cylinder group that contains the
97 * 2) quadradically rehash into other cylinder groups, until an
98 * available block is located.
101 ffs_alloc(struct inode
*ip
, daddr_t lbn __unused
, daddr_t bpref
, int size
,
104 struct fs
*fs
= ip
->i_fs
;
109 if (size
> fs
->fs_bsize
|| ffs_fragoff(fs
, size
) != 0) {
110 errx(1, "ffs_alloc: bad size: bsize %d size %d",
113 if (size
== fs
->fs_bsize
&& fs
->fs_cstotal
.cs_nbfree
== 0)
115 if (bpref
>= fs
->fs_size
)
118 cg
= ino_to_cg(fs
, ip
->i_number
);
120 cg
= dtog(fs
, bpref
);
121 bno
= ffs_hashalloc(ip
, cg
, bpref
, size
, ffs_alloccg
);
123 DIP_ADD(ip
, blocks
, size
/ DEV_BSIZE
);
132 * Select the desired position for the next block in a file. The file is
133 * logically divided into sections. The first section is composed of the
134 * direct blocks. Each additional section contains fs_maxbpg blocks.
136 * If no blocks have been allocated in the first section, the policy is to
137 * request a block in the same cylinder group as the inode that describes
138 * the file. If no blocks have been allocated in any other section, the
139 * policy is to place the section in a cylinder group with a greater than
140 * average number of free blocks. An appropriate cylinder group is found
141 * by using a rotor that sweeps the cylinder groups. When a new group of
142 * blocks is needed, the sweep begins in the cylinder group following the
143 * cylinder group from which the previous allocation was made. The sweep
144 * continues until a cylinder group with greater than the average number
145 * of free blocks is found. If the allocation is for the first block in an
146 * indirect block, the information on the previous allocation is unavailable;
147 * here a best guess is made based upon the logical block number being
150 * If a section is already partially allocated, the policy is to
151 * contiguously allocate fs_maxcontig blocks. The end of one of these
152 * contiguous blocks and the beginning of the next is physically separated
153 * so that the disk head will be in transit between them for at least
154 * fs_rotdelay milliseconds. This is to allow time for the processor to
155 * schedule another I/O transfer.
159 ffs_blkpref_ufs1(struct inode
*ip
, daddr_t lbn
, int indx
, int32_t *bap
)
163 int avgbfree
, startcg
;
166 if (indx
% fs
->fs_maxbpg
== 0 || bap
[indx
- 1] == 0) {
167 if (lbn
< UFS_NDADDR
+ FFS_NINDIR(fs
)) {
168 cg
= ino_to_cg(fs
, ip
->i_number
);
169 return (fs
->fs_fpg
* cg
+ fs
->fs_frag
);
172 * Find a cylinder with greater than average number of
173 * unused data blocks.
175 if (indx
== 0 || bap
[indx
- 1] == 0)
177 ino_to_cg(fs
, ip
->i_number
) + lbn
/ fs
->fs_maxbpg
;
180 ufs_rw32(bap
[indx
- 1], UFS_FSNEEDSWAP(fs
)) + 1);
181 startcg
%= fs
->fs_ncg
;
182 avgbfree
= fs
->fs_cstotal
.cs_nbfree
/ fs
->fs_ncg
;
183 for (cg
= startcg
; cg
< fs
->fs_ncg
; cg
++)
184 if (fs
->fs_cs(fs
, cg
).cs_nbfree
>= avgbfree
)
185 return (fs
->fs_fpg
* cg
+ fs
->fs_frag
);
186 for (cg
= 0; cg
<= startcg
; cg
++)
187 if (fs
->fs_cs(fs
, cg
).cs_nbfree
>= avgbfree
)
188 return (fs
->fs_fpg
* cg
+ fs
->fs_frag
);
192 * We just always try to lay things out contiguously.
194 return ufs_rw32(bap
[indx
- 1], UFS_FSNEEDSWAP(fs
)) + fs
->fs_frag
;
198 ffs_blkpref_ufs2(struct inode
*ip
, daddr_t lbn
, int indx
, int64_t *bap
)
202 int avgbfree
, startcg
;
205 if (indx
% fs
->fs_maxbpg
== 0 || bap
[indx
- 1] == 0) {
206 if (lbn
< UFS_NDADDR
+ FFS_NINDIR(fs
)) {
207 cg
= ino_to_cg(fs
, ip
->i_number
);
208 return (fs
->fs_fpg
* cg
+ fs
->fs_frag
);
211 * Find a cylinder with greater than average number of
212 * unused data blocks.
214 if (indx
== 0 || bap
[indx
- 1] == 0)
216 ino_to_cg(fs
, ip
->i_number
) + lbn
/ fs
->fs_maxbpg
;
219 ufs_rw64(bap
[indx
- 1], UFS_FSNEEDSWAP(fs
)) + 1);
220 startcg
%= fs
->fs_ncg
;
221 avgbfree
= fs
->fs_cstotal
.cs_nbfree
/ fs
->fs_ncg
;
222 for (cg
= startcg
; cg
< fs
->fs_ncg
; cg
++)
223 if (fs
->fs_cs(fs
, cg
).cs_nbfree
>= avgbfree
) {
224 return (fs
->fs_fpg
* cg
+ fs
->fs_frag
);
226 for (cg
= 0; cg
< startcg
; cg
++)
227 if (fs
->fs_cs(fs
, cg
).cs_nbfree
>= avgbfree
) {
228 return (fs
->fs_fpg
* cg
+ fs
->fs_frag
);
233 * We just always try to lay things out contiguously.
235 return ufs_rw64(bap
[indx
- 1], UFS_FSNEEDSWAP(fs
)) + fs
->fs_frag
;
239 * Implement the cylinder overflow algorithm.
241 * The policy implemented by this algorithm is:
242 * 1) allocate the block in its requested cylinder group.
243 * 2) quadradically rehash on the cylinder group number.
244 * 3) brute force search for a free block.
246 * `size': size for data blocks, mode for inodes
250 ffs_hashalloc(struct inode
*ip
, int cg
, daddr_t pref
, int size
,
251 daddr_t (*allocator
)(struct inode
*, int, daddr_t
, int))
259 * 1: preferred cylinder group
261 result
= (*allocator
)(ip
, cg
, pref
, size
);
265 * 2: quadratic rehash
267 for (i
= 1; i
< fs
->fs_ncg
; i
*= 2) {
269 if (cg
>= fs
->fs_ncg
)
271 result
= (*allocator
)(ip
, cg
, 0, size
);
276 * 3: brute force search
277 * Note that we start at i == 2, since 0 was checked initially,
278 * and 1 is always checked in the quadratic rehash.
280 cg
= (icg
+ 2) % fs
->fs_ncg
;
281 for (i
= 2; i
< fs
->fs_ncg
; i
++) {
282 result
= (*allocator
)(ip
, cg
, 0, size
);
286 if (cg
== fs
->fs_ncg
)
293 * Determine whether a block can be allocated.
295 * Check to see if a block of the appropriate size is available,
296 * and if it is, allocate it.
299 ffs_alloccg(struct inode
*ip
, int cg
, daddr_t bpref
, int size
)
304 int error
, frags
, allocsiz
, i
;
305 struct fs
*fs
= ip
->i_fs
;
306 const int needswap
= UFS_FSNEEDSWAP(fs
);
308 if (fs
->fs_cs(fs
, cg
).cs_nbfree
== 0 && size
== fs
->fs_bsize
)
310 error
= bread(ip
->i_devvp
, FFS_FSBTODB(fs
, cgtod(fs
, cg
)),
311 (int)fs
->fs_cgsize
, 0, &bp
);
315 cgp
= (struct cg
*)bp
->b_data
;
316 if (!cg_chkmagic(cgp
, needswap
) ||
317 (cgp
->cg_cs
.cs_nbfree
== 0 && size
== fs
->fs_bsize
)) {
321 if (size
== fs
->fs_bsize
) {
322 bno
= ffs_alloccgblk(ip
, bp
, bpref
);
327 * check to see if any fragments are already available
328 * allocsiz is the size which will be allocated, hacking
329 * it down to a smaller size if necessary
331 frags
= ffs_numfrags(fs
, size
);
332 for (allocsiz
= frags
; allocsiz
< fs
->fs_frag
; allocsiz
++)
333 if (cgp
->cg_frsum
[allocsiz
] != 0)
335 if (allocsiz
== fs
->fs_frag
) {
337 * no fragments were available, so a block will be
338 * allocated, and hacked up
340 if (cgp
->cg_cs
.cs_nbfree
== 0) {
344 bno
= ffs_alloccgblk(ip
, bp
, bpref
);
345 bpref
= dtogd(fs
, bno
);
346 for (i
= frags
; i
< fs
->fs_frag
; i
++)
347 setbit(cg_blksfree(cgp
, needswap
), bpref
+ i
);
348 i
= fs
->fs_frag
- frags
;
349 ufs_add32(cgp
->cg_cs
.cs_nffree
, i
, needswap
);
350 fs
->fs_cstotal
.cs_nffree
+= i
;
351 fs
->fs_cs(fs
, cg
).cs_nffree
+= i
;
353 ufs_add32(cgp
->cg_frsum
[i
], 1, needswap
);
357 bno
= ffs_mapsearch(fs
, cgp
, bpref
, allocsiz
);
358 for (i
= 0; i
< frags
; i
++)
359 clrbit(cg_blksfree(cgp
, needswap
), bno
+ i
);
360 ufs_add32(cgp
->cg_cs
.cs_nffree
, -frags
, needswap
);
361 fs
->fs_cstotal
.cs_nffree
-= frags
;
362 fs
->fs_cs(fs
, cg
).cs_nffree
-= frags
;
364 ufs_add32(cgp
->cg_frsum
[allocsiz
], -1, needswap
);
365 if (frags
!= allocsiz
)
366 ufs_add32(cgp
->cg_frsum
[allocsiz
- frags
], 1, needswap
);
367 blkno
= cg
* fs
->fs_fpg
+ bno
;
373 * Allocate a block in a cylinder group.
375 * This algorithm implements the following policy:
376 * 1) allocate the requested block.
377 * 2) allocate a rotationally optimal block in the same cylinder.
378 * 3) allocate the next available block on the block rotor for the
379 * specified cylinder group.
380 * Note that this routine only allocates fs_bsize blocks; these
381 * blocks may be fragmented by the routine that allocates them.
384 ffs_alloccgblk(struct inode
*ip
, struct buf
*bp
, daddr_t bpref
)
389 struct fs
*fs
= ip
->i_fs
;
390 const int needswap
= UFS_FSNEEDSWAP(fs
);
393 cgp
= (struct cg
*)bp
->b_data
;
394 blksfree
= cg_blksfree(cgp
, needswap
);
395 if (bpref
== 0 || dtog(fs
, bpref
) != ufs_rw32(cgp
->cg_cgx
, needswap
)) {
396 bpref
= ufs_rw32(cgp
->cg_rotor
, needswap
);
398 bpref
= ffs_blknum(fs
, bpref
);
399 bno
= dtogd(fs
, bpref
);
401 * if the requested block is available, use it
403 if (ffs_isblock(fs
, blksfree
, ffs_fragstoblks(fs
, bno
)))
407 * Take the next available one in this cylinder group.
409 bno
= ffs_mapsearch(fs
, cgp
, bpref
, (int)fs
->fs_frag
);
412 cgp
->cg_rotor
= ufs_rw32(bno
, needswap
);
414 blkno
= ffs_fragstoblks(fs
, bno
);
415 ffs_clrblock(fs
, blksfree
, (long)blkno
);
416 ffs_clusteracct(fs
, cgp
, blkno
, -1);
417 ufs_add32(cgp
->cg_cs
.cs_nbfree
, -1, needswap
);
418 fs
->fs_cstotal
.cs_nbfree
--;
419 fs
->fs_cs(fs
, ufs_rw32(cgp
->cg_cgx
, needswap
)).cs_nbfree
--;
421 blkno
= ufs_rw32(cgp
->cg_cgx
, needswap
) * fs
->fs_fpg
+ bno
;
426 * Free a block or fragment.
428 * The specified block or fragment is placed back in the
429 * free map. If a fragment is deallocated, a possible
430 * block reassembly is checked.
433 ffs_blkfree(struct inode
*ip
, daddr_t bno
, long size
)
437 int32_t fragno
, cgbno
;
438 int i
, error
, cg
, blk
, frags
, bbase
;
439 struct fs
*fs
= ip
->i_fs
;
440 const int needswap
= UFS_FSNEEDSWAP(fs
);
442 if (size
> fs
->fs_bsize
|| ffs_fragoff(fs
, size
) != 0 ||
443 ffs_fragnum(fs
, bno
) + ffs_numfrags(fs
, size
) > fs
->fs_frag
) {
444 errx(1, "blkfree: bad size: bno %lld bsize %d size %ld",
445 (long long)bno
, fs
->fs_bsize
, size
);
448 if (bno
>= fs
->fs_size
) {
449 warnx("bad block %lld, ino %llu", (long long)bno
,
450 (unsigned long long)ip
->i_number
);
453 error
= bread(ip
->i_devvp
, FFS_FSBTODB(fs
, cgtod(fs
, cg
)),
454 (int)fs
->fs_cgsize
, 0, &bp
);
459 cgp
= (struct cg
*)bp
->b_data
;
460 if (!cg_chkmagic(cgp
, needswap
)) {
464 cgbno
= dtogd(fs
, bno
);
465 if (size
== fs
->fs_bsize
) {
466 fragno
= ffs_fragstoblks(fs
, cgbno
);
467 if (!ffs_isfreeblock(fs
, cg_blksfree(cgp
, needswap
), fragno
)) {
468 errx(1, "blkfree: freeing free block %lld",
471 ffs_setblock(fs
, cg_blksfree(cgp
, needswap
), fragno
);
472 ffs_clusteracct(fs
, cgp
, fragno
, 1);
473 ufs_add32(cgp
->cg_cs
.cs_nbfree
, 1, needswap
);
474 fs
->fs_cstotal
.cs_nbfree
++;
475 fs
->fs_cs(fs
, cg
).cs_nbfree
++;
477 bbase
= cgbno
- ffs_fragnum(fs
, cgbno
);
479 * decrement the counts associated with the old frags
481 blk
= blkmap(fs
, cg_blksfree(cgp
, needswap
), bbase
);
482 ffs_fragacct(fs
, blk
, cgp
->cg_frsum
, -1, needswap
);
484 * deallocate the fragment
486 frags
= ffs_numfrags(fs
, size
);
487 for (i
= 0; i
< frags
; i
++) {
488 if (isset(cg_blksfree(cgp
, needswap
), cgbno
+ i
)) {
489 errx(1, "blkfree: freeing free frag: block %lld",
490 (long long)(cgbno
+ i
));
492 setbit(cg_blksfree(cgp
, needswap
), cgbno
+ i
);
494 ufs_add32(cgp
->cg_cs
.cs_nffree
, i
, needswap
);
495 fs
->fs_cstotal
.cs_nffree
+= i
;
496 fs
->fs_cs(fs
, cg
).cs_nffree
+= i
;
498 * add back in counts associated with the new frags
500 blk
= blkmap(fs
, cg_blksfree(cgp
, needswap
), bbase
);
501 ffs_fragacct(fs
, blk
, cgp
->cg_frsum
, 1, needswap
);
503 * if a complete block has been reassembled, account for it
505 fragno
= ffs_fragstoblks(fs
, bbase
);
506 if (ffs_isblock(fs
, cg_blksfree(cgp
, needswap
), fragno
)) {
507 ufs_add32(cgp
->cg_cs
.cs_nffree
, -fs
->fs_frag
, needswap
);
508 fs
->fs_cstotal
.cs_nffree
-= fs
->fs_frag
;
509 fs
->fs_cs(fs
, cg
).cs_nffree
-= fs
->fs_frag
;
510 ffs_clusteracct(fs
, cgp
, fragno
, 1);
511 ufs_add32(cgp
->cg_cs
.cs_nbfree
, 1, needswap
);
512 fs
->fs_cstotal
.cs_nbfree
++;
513 fs
->fs_cs(fs
, cg
).cs_nbfree
++;
522 scanc(u_int size
, const u_char
*cp
, const u_char table
[], int mask
)
524 const u_char
*end
= &cp
[size
];
526 while (cp
< end
&& (table
[*cp
] & mask
) == 0)
532 * Find a block of the specified size in the specified cylinder group.
534 * It is a panic if a request is made to find a block if none are
538 ffs_mapsearch(struct fs
*fs
, struct cg
*cgp
, daddr_t bpref
, int allocsiz
)
541 int start
, len
, loc
, i
;
542 int blk
, field
, subfield
, pos
;
544 const int needswap
= UFS_FSNEEDSWAP(fs
);
547 * find the fragment by searching through the free block
548 * map for an appropriate bit pattern
551 start
= dtogd(fs
, bpref
) / NBBY
;
553 start
= ufs_rw32(cgp
->cg_frotor
, needswap
) / NBBY
;
554 len
= howmany(fs
->fs_fpg
, NBBY
) - start
;
557 loc
= scanc((u_int
)len
,
558 (const u_char
*)&cg_blksfree(cgp
, needswap
)[start
],
559 (const u_char
*)fragtbl
[fs
->fs_frag
],
560 (1 << (allocsiz
- 1 + (fs
->fs_frag
% NBBY
))));
564 loc
= scanc((u_int
)len
,
565 (const u_char
*)&cg_blksfree(cgp
, needswap
)[0],
566 (const u_char
*)fragtbl
[fs
->fs_frag
],
567 (1 << (allocsiz
- 1 + (fs
->fs_frag
% NBBY
))));
570 "ffs_alloccg: map corrupted: start %d len %d offset %d %ld",
572 ufs_rw32(cgp
->cg_freeoff
, needswap
),
573 (long)cg_blksfree(cgp
, needswap
) - (long)cgp
);
577 bno
= (start
+ len
- loc
) * NBBY
;
578 cgp
->cg_frotor
= ufs_rw32(bno
, needswap
);
580 * found the byte in the map
581 * sift through the bits to find the selected frag
583 for (i
= bno
+ NBBY
; bno
< i
; bno
+= fs
->fs_frag
) {
584 blk
= blkmap(fs
, cg_blksfree(cgp
, needswap
), bno
);
586 field
= around
[allocsiz
];
587 subfield
= inside
[allocsiz
];
588 for (pos
= 0; pos
<= fs
->fs_frag
- allocsiz
; pos
++) {
589 if ((blk
& field
) == subfield
)
595 errx(1, "ffs_alloccg: block not in map: bno %lld", (long long)bno
);