2 * linux/fs/ufs/balloc.c
5 * Daniel Pirkl <daniel.pirkl@email.cz>
6 * Charles University, Faculty of Mathematics and Physics
10 #include <linux/ufs_fs.h>
11 #include <linux/stat.h>
12 #include <linux/sched.h>
13 #include <linux/string.h>
14 #include <linux/locks.h>
15 #include <linux/quotaops.h>
16 #include <asm/bitops.h>
17 #include <asm/byteorder.h>
22 #undef UFS_BALLOC_DEBUG
24 #ifdef UFS_BALLOC_DEBUG
25 #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
30 unsigned ufs_add_fragments (struct inode
*, unsigned, unsigned, unsigned, int *);
31 unsigned ufs_alloc_fragments (struct inode
*, unsigned, unsigned, unsigned, int *);
32 unsigned ufs_alloccg_block (struct inode
*, struct ufs_cg_private_info
*, unsigned, int *);
33 unsigned ufs_bitmap_search (struct super_block
*, struct ufs_cg_private_info
*, unsigned, unsigned);
34 static unsigned char ufs_fragtable_8fpb
[], ufs_fragtable_other
[];
35 void ufs_clusteracct(struct super_block
*, struct ufs_cg_private_info
*, unsigned, int);
38 * Free 'count' fragments from fragment number 'fragment'
40 void ufs_free_fragments (struct inode
* inode
, unsigned fragment
, unsigned count
) {
41 struct super_block
* sb
;
42 struct ufs_sb_private_info
* uspi
;
43 struct ufs_super_block_first
* usb1
;
44 struct ufs_cg_private_info
* ucpi
;
45 struct ufs_cylinder_group
* ucg
;
46 unsigned cgno
, bit
, end_bit
, bbase
, blkmap
, i
, blkno
, cylno
;
50 uspi
= sb
->u
.ufs_sb
.s_uspi
;
51 swab
= sb
->u
.ufs_sb
.s_swab
;
52 usb1
= ubh_get_usb_first(USPI_UBH
);
54 UFSD(("ENTER, fragment %u, count %u\n", fragment
, count
))
56 if (ufs_fragnum(fragment
) + count
> uspi
->s_fpg
)
57 ufs_error (sb
, "ufs_free_fragments", "internal error");
61 cgno
= ufs_dtog(fragment
);
62 bit
= ufs_dtogd(fragment
);
63 if (cgno
>= uspi
->s_ncg
) {
64 ufs_panic (sb
, "ufs_free_fragments", "freeing blocks are outside device");
68 ucpi
= ufs_load_cylinder (sb
, cgno
);
71 ucg
= ubh_get_ucg (UCPI_UBH
);
72 if (!ufs_cg_chkmagic (ucg
)) {
73 ufs_panic (sb
, "ufs_free_fragments", "internal error, bad magic number on cg %u", cgno
);
77 end_bit
= bit
+ count
;
78 bbase
= ufs_blknum (bit
);
79 blkmap
= ubh_blkmap (UCPI_UBH
, ucpi
->c_freeoff
, bbase
);
80 ufs_fragacct (sb
, blkmap
, ucg
->cg_frsum
, -1);
81 for (i
= bit
; i
< end_bit
; i
++) {
82 if (ubh_isclr (UCPI_UBH
, ucpi
->c_freeoff
, i
))
83 ubh_setbit (UCPI_UBH
, ucpi
->c_freeoff
, i
);
84 else ufs_error (sb
, "ufs_free_fragments",
85 "bit already cleared for fragment %u", i
);
88 DQUOT_FREE_BLOCK (sb
, inode
, count
);
89 ADD_SWAB32(ucg
->cg_cs
.cs_nffree
, count
);
90 ADD_SWAB32(usb1
->fs_cstotal
.cs_nffree
, count
);
91 ADD_SWAB32(sb
->fs_cs(cgno
).cs_nffree
, count
);
92 blkmap
= ubh_blkmap (UCPI_UBH
, ucpi
->c_freeoff
, bbase
);
93 ufs_fragacct(sb
, blkmap
, ucg
->cg_frsum
, 1);
96 * Trying to reassemble free fragments into block
98 blkno
= ufs_fragstoblks (bbase
);
99 if (ubh_isblockset(UCPI_UBH
, ucpi
->c_freeoff
, blkno
)) {
100 SUB_SWAB32(ucg
->cg_cs
.cs_nffree
, uspi
->s_fpb
);
101 SUB_SWAB32(usb1
->fs_cstotal
.cs_nffree
, uspi
->s_fpb
);
102 SUB_SWAB32(sb
->fs_cs(cgno
).cs_nffree
, uspi
->s_fpb
);
103 if ((sb
->u
.ufs_sb
.s_flags
& UFS_CG_MASK
) == UFS_CG_44BSD
)
104 ufs_clusteracct (sb
, ucpi
, blkno
, 1);
105 INC_SWAB32(ucg
->cg_cs
.cs_nbfree
);
106 INC_SWAB32(usb1
->fs_cstotal
.cs_nbfree
);
107 INC_SWAB32(sb
->fs_cs(cgno
).cs_nbfree
);
108 cylno
= ufs_cbtocylno (bbase
);
109 INC_SWAB16(ubh_cg_blks (ucpi
, cylno
, ufs_cbtorpos(bbase
)));
110 INC_SWAB32(ubh_cg_blktot (ucpi
, cylno
));
113 ubh_mark_buffer_dirty (USPI_UBH
);
114 ubh_mark_buffer_dirty (UCPI_UBH
);
115 if (sb
->s_flags
& MS_SYNCHRONOUS
) {
116 ubh_ll_rw_block (WRITE
, 1, (struct ufs_buffer_head
**)&ucpi
);
117 ubh_wait_on_buffer (UCPI_UBH
);
127 UFSD(("EXIT (FAILED)\n"))
132 * Free 'count' fragments from fragment number 'fragment' (free whole blocks)
134 void ufs_free_blocks (struct inode
* inode
, unsigned fragment
, unsigned count
) {
135 struct super_block
* sb
;
136 struct ufs_sb_private_info
* uspi
;
137 struct ufs_super_block_first
* usb1
;
138 struct ufs_cg_private_info
* ucpi
;
139 struct ufs_cylinder_group
* ucg
;
140 unsigned overflow
, cgno
, bit
, end_bit
, blkno
, i
, cylno
;
144 uspi
= sb
->u
.ufs_sb
.s_uspi
;
145 swab
= sb
->u
.ufs_sb
.s_swab
;
146 usb1
= ubh_get_usb_first(USPI_UBH
);
148 UFSD(("ENTER, fragment %u, count %u\n", fragment
, count
))
150 if ((fragment
& uspi
->s_fpbmask
) || (count
& uspi
->s_fpbmask
)) {
151 ufs_error (sb
, "ufs_free_blocks", "internal error, "
152 "fragment %u, count %u\n", fragment
, count
);
160 cgno
= ufs_dtog (fragment
);
161 bit
= ufs_dtogd (fragment
);
162 if (cgno
>= uspi
->s_ncg
) {
163 ufs_panic (sb
, "ufs_free_blocks", "freeing blocks are outside device");
166 end_bit
= bit
+ count
;
167 if (end_bit
> uspi
->s_fpg
) {
168 overflow
= bit
+ count
- uspi
->s_fpg
;
173 ucpi
= ufs_load_cylinder (sb
, cgno
);
176 ucg
= ubh_get_ucg (UCPI_UBH
);
177 if (!ufs_cg_chkmagic (ucg
)) {
178 ufs_panic (sb
, "ufs_free_blocks", "internal error, bad magic number on cg %u", cgno
);
182 for (i
= bit
; i
< end_bit
; i
+= uspi
->s_fpb
) {
183 blkno
= ufs_fragstoblks(i
);
184 if (ubh_isblockset(UCPI_UBH
, ucpi
->c_freeoff
, blkno
)) {
185 ufs_error(sb
, "ufs_free_blocks", "freeing free fragment");
187 ubh_setblock(UCPI_UBH
, ucpi
->c_freeoff
, blkno
);
188 if ((sb
->u
.ufs_sb
.s_flags
& UFS_CG_MASK
) == UFS_CG_44BSD
)
189 ufs_clusteracct (sb
, ucpi
, blkno
, 1);
190 DQUOT_FREE_BLOCK(sb
, inode
, uspi
->s_fpb
);
191 INC_SWAB32(ucg
->cg_cs
.cs_nbfree
);
192 INC_SWAB32(usb1
->fs_cstotal
.cs_nbfree
);
193 INC_SWAB32(sb
->fs_cs(cgno
).cs_nbfree
);
194 cylno
= ufs_cbtocylno(i
);
195 INC_SWAB16(ubh_cg_blks(ucpi
, cylno
, ufs_cbtorpos(i
)));
196 INC_SWAB32(ubh_cg_blktot(ucpi
, cylno
));
199 ubh_mark_buffer_dirty (USPI_UBH
);
200 ubh_mark_buffer_dirty (UCPI_UBH
);
201 if (sb
->s_flags
& MS_SYNCHRONOUS
) {
202 ubh_ll_rw_block (WRITE
, 1, (struct ufs_buffer_head
**)&ucpi
);
203 ubh_wait_on_buffer (UCPI_UBH
);
219 UFSD(("EXIT (FAILED)\n"))
225 #define NULLIFY_FRAGMENTS \
226 for (i = oldcount; i < newcount; i++) { \
227 bh = getblk (sb->s_dev, result + i, sb->s_blocksize); \
228 memset (bh->b_data, 0, sb->s_blocksize); \
229 mark_buffer_uptodate(bh, 1); \
230 mark_buffer_dirty (bh); \
231 if (IS_SYNC(inode)) { \
232 ll_rw_block (WRITE, 1, &bh); \
233 wait_on_buffer (bh); \
238 unsigned ufs_new_fragments (struct inode
* inode
, u32
* p
, unsigned fragment
,
239 unsigned goal
, unsigned count
, int * err
)
241 struct super_block
* sb
;
242 struct ufs_sb_private_info
* uspi
;
243 struct ufs_super_block_first
* usb1
;
244 struct buffer_head
* bh
;
245 unsigned cgno
, oldcount
, newcount
, tmp
, request
, i
, result
;
248 UFSD(("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode
->i_ino
, fragment
, goal
, count
))
251 swab
= sb
->u
.ufs_sb
.s_swab
;
252 uspi
= sb
->u
.ufs_sb
.s_uspi
;
253 usb1
= ubh_get_usb_first(USPI_UBH
);
259 if (count
+ ufs_fragnum(fragment
) > uspi
->s_fpb
) {
260 ufs_warning (sb
, "ufs_new_fragments", "internal warning"
261 " fragment %u, count %u", fragment
, count
);
262 count
= uspi
->s_fpb
- ufs_fragnum(fragment
);
264 oldcount
= ufs_fragnum (fragment
);
265 newcount
= oldcount
+ count
;
268 * Somebody else has just allocated our fragments
272 ufs_error (sb
, "ufs_new_fragments", "internal error, "
273 "fragment %u, tmp %u\n", fragment
, tmp
);
276 if (fragment
< inode
->u
.ufs_i
.i_lastfrag
) {
277 UFSD(("EXIT (ALREADY ALLOCATED)\n"))
284 UFSD(("EXIT (ALREADY ALLOCATED)\n"))
291 * There is not enough space for user on the device
293 if (!fsuser() && ufs_freespace(usb1
, UFS_MINFREE
) <= 0) {
295 UFSD(("EXIT (FAILED)\n"))
299 if (goal
>= uspi
->s_size
)
302 cgno
= ufs_inotocg (inode
->i_ino
);
304 cgno
= ufs_dtog (goal
);
307 * allocate new fragment
310 result
= ufs_alloc_fragments (inode
, cgno
, goal
, count
, err
);
314 inode
->i_blocks
+= count
<< uspi
->s_nspfshift
;
315 inode
->u
.ufs_i
.i_lastfrag
= max (inode
->u
.ufs_i
.i_lastfrag
, fragment
+ count
);
319 UFSD(("EXIT, result %u\n", result
))
326 result
= ufs_add_fragments (inode
, tmp
, oldcount
, newcount
, err
);
329 inode
->i_blocks
+= count
<< uspi
->s_nspfshift
;
330 inode
->u
.ufs_i
.i_lastfrag
= max (inode
->u
.ufs_i
.i_lastfrag
, fragment
+ count
);
333 UFSD(("EXIT, result %u\n", result
))
338 * allocate new block and move data
340 switch (SWAB32(usb1
->fs_optim
)) {
343 if (uspi
->s_minfree
< 5 || SWAB32(usb1
->fs_cstotal
.cs_nffree
)
344 > uspi
->s_dsize
* uspi
->s_minfree
/ (2 * 100) )
346 usb1
->fs_optim
= SWAB32(UFS_OPTTIME
);
349 usb1
->fs_optim
= SWAB32(UFS_OPTTIME
);
352 request
= uspi
->s_fpb
;
353 if (SWAB32(usb1
->fs_cstotal
.cs_nffree
) < uspi
->s_dsize
*
354 (uspi
->s_minfree
- 2) / 100)
356 usb1
->fs_optim
= SWAB32(UFS_OPTSPACE
);
359 result
= ufs_alloc_fragments (inode
, cgno
, goal
, request
, err
);
361 for (i
= 0; i
< oldcount
; i
++) {
362 bh
= bread (sb
->s_dev
, tmp
+ i
, sb
->s_blocksize
);
365 mark_buffer_clean (bh
);
366 bh
->b_blocknr
= result
+ i
;
367 mark_buffer_dirty (bh
);
368 if (IS_SYNC(inode
)) {
369 ll_rw_block (WRITE
, 1, &bh
);
376 printk(KERN_ERR
"ufs_new_fragments: bread fail\n");
382 inode
->i_blocks
+= count
<< uspi
->s_nspfshift
;
383 inode
->u
.ufs_i
.i_lastfrag
= max (inode
->u
.ufs_i
.i_lastfrag
, fragment
+ count
);
386 if (newcount
< request
)
387 ufs_free_fragments (inode
, result
+ newcount
, request
- newcount
);
388 ufs_free_fragments (inode
, tmp
, oldcount
);
389 UFSD(("EXIT, result %u\n", result
))
394 UFSD(("EXIT (FAILED)\n"))
398 unsigned ufs_add_fragments (struct inode
* inode
, unsigned fragment
,
399 unsigned oldcount
, unsigned newcount
, int * err
)
401 struct super_block
* sb
;
402 struct ufs_sb_private_info
* uspi
;
403 struct ufs_super_block_first
* usb1
;
404 struct ufs_cg_private_info
* ucpi
;
405 struct ufs_cylinder_group
* ucg
;
406 unsigned cgno
, fragno
, fragoff
, count
, fragsize
, i
;
409 UFSD(("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment
, oldcount
, newcount
))
412 swab
= sb
->u
.ufs_sb
.s_swab
;
413 uspi
= sb
->u
.ufs_sb
.s_uspi
;
414 usb1
= ubh_get_usb_first (USPI_UBH
);
415 count
= newcount
- oldcount
;
417 cgno
= ufs_dtog(fragment
);
418 if (sb
->fs_cs(cgno
).cs_nffree
< count
)
420 if ((ufs_fragnum (fragment
) + newcount
) > uspi
->s_fpb
)
422 ucpi
= ufs_load_cylinder (sb
, cgno
);
425 ucg
= ubh_get_ucg (UCPI_UBH
);
426 if (!ufs_cg_chkmagic(ucg
)) {
427 ufs_panic (sb
, "ufs_add_fragments",
428 "internal error, bad magic number on cg %u", cgno
);
432 fragno
= ufs_dtogd (fragment
);
433 fragoff
= ufs_fragnum (fragno
);
434 for (i
= oldcount
; i
< newcount
; i
++)
435 if (ubh_isclr (UCPI_UBH
, ucpi
->c_freeoff
, fragno
+ i
))
438 * Block can be extended
440 ucg
->cg_time
= SWAB32(CURRENT_TIME
);
441 for (i
= newcount
; i
< (uspi
->s_fpb
- fragoff
); i
++)
442 if (ubh_isclr (UCPI_UBH
, ucpi
->c_freeoff
, fragno
+ i
))
444 fragsize
= i
- oldcount
;
445 if (!SWAB32(ucg
->cg_frsum
[fragsize
]))
446 ufs_panic (sb
, "ufs_add_fragments",
447 "internal error or corrupted bitmap on cg %u", cgno
);
448 DEC_SWAB32(ucg
->cg_frsum
[fragsize
]);
449 if (fragsize
!= count
)
450 INC_SWAB32(ucg
->cg_frsum
[fragsize
- count
]);
451 for (i
= oldcount
; i
< newcount
; i
++)
452 ubh_clrbit (UCPI_UBH
, ucpi
->c_freeoff
, fragno
+ i
);
453 if(DQUOT_ALLOC_BLOCK(sb
, inode
, count
)) {
457 SUB_SWAB32(ucg
->cg_cs
.cs_nffree
, count
);
458 SUB_SWAB32(sb
->fs_cs(cgno
).cs_nffree
, count
);
459 SUB_SWAB32(usb1
->fs_cstotal
.cs_nffree
, count
);
461 ubh_mark_buffer_dirty (USPI_UBH
);
462 ubh_mark_buffer_dirty (UCPI_UBH
);
463 if (sb
->s_flags
& MS_SYNCHRONOUS
) {
464 ubh_ll_rw_block (WRITE
, 1, (struct ufs_buffer_head
**)&ucpi
);
465 ubh_wait_on_buffer (UCPI_UBH
);
469 UFSD(("EXIT, fragment %u\n", fragment
))
474 #define UFS_TEST_FREE_SPACE_CG \
475 ucg = (struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[cgno]->b_data; \
476 if (SWAB32(ucg->cg_cs.cs_nbfree)) \
478 for (k = count; k < uspi->s_fpb; k++) \
479 if (SWAB32(ucg->cg_frsum[k])) \
482 unsigned ufs_alloc_fragments (struct inode
* inode
, unsigned cgno
,
483 unsigned goal
, unsigned count
, int * err
)
485 struct super_block
* sb
;
486 struct ufs_sb_private_info
* uspi
;
487 struct ufs_super_block_first
* usb1
;
488 struct ufs_cg_private_info
* ucpi
;
489 struct ufs_cylinder_group
* ucg
;
490 unsigned oldcg
, i
, j
, k
, result
, allocsize
;
493 UFSD(("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode
->i_ino
, cgno
, goal
, count
))
496 swab
= sb
->u
.ufs_sb
.s_swab
;
497 uspi
= sb
->u
.ufs_sb
.s_uspi
;
498 usb1
= ubh_get_usb_first(USPI_UBH
);
502 * 1. searching on preferred cylinder group
504 UFS_TEST_FREE_SPACE_CG
507 * 2. quadratic rehash
509 for (j
= 1; j
< uspi
->s_ncg
; j
*= 2) {
511 if (cgno
>= uspi
->s_ncg
)
513 UFS_TEST_FREE_SPACE_CG
517 * 3. brute force search
518 * We start at i = 2 ( 0 is checked at 1.step, 1 at 2.step )
520 cgno
= (oldcg
+ 1) % uspi
->s_ncg
;
521 for (j
= 2; j
< uspi
->s_ncg
; j
++) {
523 if (cgno
>= uspi
->s_ncg
)
525 UFS_TEST_FREE_SPACE_CG
528 UFSD(("EXIT (FAILED)\n"))
532 ucpi
= ufs_load_cylinder (sb
, cgno
);
535 ucg
= ubh_get_ucg (UCPI_UBH
);
536 if (!ufs_cg_chkmagic(ucg
))
537 ufs_panic (sb
, "ufs_alloc_fragments",
538 "internal error, bad magic number on cg %u", cgno
);
539 ucg
->cg_time
= SWAB32(CURRENT_TIME
);
541 if (count
== uspi
->s_fpb
) {
542 result
= ufs_alloccg_block (inode
, ucpi
, goal
, err
);
543 if (result
== (unsigned)-1)
548 for (allocsize
= count
; allocsize
< uspi
->s_fpb
; allocsize
++)
549 if (SWAB32(ucg
->cg_frsum
[allocsize
]) != 0)
552 if (allocsize
== uspi
->s_fpb
) {
553 result
= ufs_alloccg_block (inode
, ucpi
, goal
, err
);
554 if (result
== (unsigned)-1)
556 goal
= ufs_dtogd (result
);
557 for (i
= count
; i
< uspi
->s_fpb
; i
++)
558 ubh_setbit (UCPI_UBH
, ucpi
->c_freeoff
, goal
+ i
);
559 i
= uspi
->s_fpb
- count
;
560 DQUOT_FREE_BLOCK(sb
, inode
, i
);
561 ADD_SWAB32(ucg
->cg_cs
.cs_nffree
, i
);
562 ADD_SWAB32(usb1
->fs_cstotal
.cs_nffree
, i
);
563 ADD_SWAB32(sb
->fs_cs(cgno
).cs_nffree
, i
);
564 INC_SWAB32(ucg
->cg_frsum
[i
]);
568 result
= ufs_bitmap_search (sb
, ucpi
, goal
, allocsize
);
569 if (result
== (unsigned)-1)
571 if(DQUOT_ALLOC_BLOCK(sb
, inode
, count
)) {
575 for (i
= 0; i
< count
; i
++)
576 ubh_clrbit (UCPI_UBH
, ucpi
->c_freeoff
, result
+ i
);
577 SUB_SWAB32(ucg
->cg_cs
.cs_nffree
, count
);
578 SUB_SWAB32(usb1
->fs_cstotal
.cs_nffree
, count
);
579 SUB_SWAB32(sb
->fs_cs(cgno
).cs_nffree
, count
);
580 DEC_SWAB32(ucg
->cg_frsum
[allocsize
]);
581 if (count
!= allocsize
)
582 INC_SWAB32(ucg
->cg_frsum
[allocsize
- count
]);
585 ubh_mark_buffer_dirty (USPI_UBH
);
586 ubh_mark_buffer_dirty (UCPI_UBH
);
587 if (sb
->s_flags
& MS_SYNCHRONOUS
) {
588 ubh_ll_rw_block (WRITE
, 1, (struct ufs_buffer_head
**)&ucpi
);
589 ubh_wait_on_buffer (UCPI_UBH
);
593 result
+= cgno
* uspi
->s_fpg
;
594 UFSD(("EXIT3, result %u\n", result
))
598 unsigned ufs_alloccg_block (struct inode
* inode
,
599 struct ufs_cg_private_info
* ucpi
, unsigned goal
, int * err
)
601 struct super_block
* sb
;
602 struct ufs_sb_private_info
* uspi
;
603 struct ufs_super_block_first
* usb1
;
604 struct ufs_cylinder_group
* ucg
;
605 unsigned result
, cylno
, blkno
;
608 UFSD(("ENTER, goal %u\n", goal
))
611 swab
= sb
->u
.ufs_sb
.s_swab
;
612 uspi
= sb
->u
.ufs_sb
.s_uspi
;
613 usb1
= ubh_get_usb_first(USPI_UBH
);
614 ucg
= ubh_get_ucg(UCPI_UBH
);
617 goal
= ucpi
->c_rotor
;
620 goal
= ufs_blknum (goal
);
621 goal
= ufs_dtogd (goal
);
624 * If the requested block is available, use it.
626 if (ubh_isblockset(UCPI_UBH
, ucpi
->c_freeoff
, ufs_fragstoblks(goal
))) {
632 result
= ufs_bitmap_search (sb
, ucpi
, goal
, uspi
->s_fpb
);
633 if (result
== (unsigned)-1)
635 ucpi
->c_rotor
= result
;
637 blkno
= ufs_fragstoblks(result
);
638 ubh_clrblock (UCPI_UBH
, ucpi
->c_freeoff
, blkno
);
639 if ((sb
->u
.ufs_sb
.s_flags
& UFS_CG_MASK
) == UFS_CG_44BSD
)
640 ufs_clusteracct (sb
, ucpi
, blkno
, -1);
641 if(DQUOT_ALLOC_BLOCK(sb
, inode
, uspi
->s_fpb
)) {
645 DEC_SWAB32(ucg
->cg_cs
.cs_nbfree
);
646 DEC_SWAB32(usb1
->fs_cstotal
.cs_nbfree
);
647 DEC_SWAB32(sb
->fs_cs(ucpi
->c_cgx
).cs_nbfree
);
648 cylno
= ufs_cbtocylno(result
);
649 DEC_SWAB16(ubh_cg_blks(ucpi
, cylno
, ufs_cbtorpos(result
)));
650 DEC_SWAB32(ubh_cg_blktot(ucpi
, cylno
));
652 UFSD(("EXIT, result %u\n", result
))
657 unsigned ufs_bitmap_search (struct super_block
* sb
,
658 struct ufs_cg_private_info
* ucpi
, unsigned goal
, unsigned count
)
660 struct ufs_sb_private_info
* uspi
;
661 struct ufs_super_block_first
* usb1
;
662 struct ufs_cylinder_group
* ucg
;
663 unsigned start
, length
, location
, result
;
664 unsigned possition
, fragsize
, blockmap
, mask
;
667 UFSD(("ENTER, cg %u, goal %u, count %u\n", ucpi
->c_cgx
, goal
, count
))
669 swab
= sb
->u
.ufs_sb
.s_swab
;
670 uspi
= sb
->u
.ufs_sb
.s_uspi
;
671 usb1
= ubh_get_usb_first (USPI_UBH
);
672 ucg
= ubh_get_ucg(UCPI_UBH
);
675 start
= ufs_dtogd(goal
) >> 3;
677 start
= ucpi
->c_frotor
>> 3;
679 length
= ((uspi
->s_fpg
+ 7) >> 3) - start
;
680 location
= ubh_scanc(UCPI_UBH
, ucpi
->c_freeoff
+ start
, length
,
681 (uspi
->s_fpb
== 8) ? ufs_fragtable_8fpb
: ufs_fragtable_other
,
682 1 << (count
- 1 + (uspi
->s_fpb
& 7)));
685 location
= ubh_scanc(UCPI_UBH
, ucpi
->c_freeoff
, length
,
686 (uspi
->s_fpb
== 8) ? ufs_fragtable_8fpb
: ufs_fragtable_other
,
687 1 << (count
- 1 + (uspi
->s_fpb
& 7)));
689 ufs_error (sb
, "ufs_bitmap_search",
690 "bitmap corrupted on cg %u, start %u, length %u, count %u, freeoff %u\n",
691 ucpi
->c_cgx
, start
, length
, count
, ucpi
->c_freeoff
);
696 result
= (start
+ length
- location
) << 3;
697 ucpi
->c_frotor
= result
;
700 * found the byte in the map
702 blockmap
= ubh_blkmap(UCPI_UBH
, ucpi
->c_freeoff
, result
);
704 for (possition
= 0, mask
= 1; possition
< 8; possition
++, mask
<<= 1) {
705 if (blockmap
& mask
) {
706 if (!(possition
& uspi
->s_fpbmask
))
712 if (fragsize
== count
) {
713 result
+= possition
- count
;
714 UFSD(("EXIT, result %u\n", result
))
720 if (fragsize
== count
) {
721 result
+= possition
- count
;
722 UFSD(("EXIT, result %u\n", result
))
725 ufs_error (sb
, "ufs_bitmap_search", "block not in map on cg %u\n", ucpi
->c_cgx
);
726 UFSD(("EXIT (FAILED)\n"))
730 void ufs_clusteracct(struct super_block
* sb
,
731 struct ufs_cg_private_info
* ucpi
, unsigned blkno
, int cnt
)
733 struct ufs_sb_private_info
* uspi
;
734 int i
, start
, end
, forw
, back
;
738 uspi
= sb
->u
.ufs_sb
.s_uspi
;
739 swab
= sb
->u
.ufs_sb
.s_swab
;
741 if (uspi
->s_contigsumsize
<= 0)
745 ubh_setbit(UCPI_UBH
, ucpi
->c_clusteroff
, blkno
);
747 ubh_clrbit(UCPI_UBH
, ucpi
->c_clusteroff
, blkno
);
750 * Find the size of the cluster going forward.
753 end
= start
+ uspi
->s_contigsumsize
;
754 if ( end
>= ucpi
->c_nclusterblks
)
755 end
= ucpi
->c_nclusterblks
;
756 i
= ubh_find_next_zero_bit (UCPI_UBH
, ucpi
->c_clusteroff
, end
, start
);
762 * Find the size of the cluster going backward.
765 end
= start
- uspi
->s_contigsumsize
;
768 i
= ubh_find_last_zero_bit (UCPI_UBH
, ucpi
->c_clusteroff
, start
, end
);
774 * Account for old cluster and the possibly new forward and
778 if (i
> uspi
->s_contigsumsize
)
779 i
= uspi
->s_contigsumsize
;
780 ADD_SWAB32(*((u32
*)ubh_get_addr(UCPI_UBH
, ucpi
->c_clustersumoff
+ (i
<< 2))), cnt
);
782 SUB_SWAB32(*((u32
*)ubh_get_addr(UCPI_UBH
, ucpi
->c_clustersumoff
+ (back
<< 2))), cnt
);
784 SUB_SWAB32(*((u32
*)ubh_get_addr(UCPI_UBH
, ucpi
->c_clustersumoff
+ (forw
<< 2))), cnt
);
788 static unsigned char ufs_fragtable_8fpb
[] = {
789 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
790 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
791 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
792 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
793 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
794 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
795 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0A,
796 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x08, 0x09, 0x09, 0x0A, 0x10, 0x11, 0x20, 0x40,
797 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
798 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
799 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
800 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
801 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0A,
802 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0A, 0x12,
803 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0C,
804 0x08, 0x09, 0x09, 0x0A, 0x09, 0x09, 0x0A, 0x0C, 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
807 static unsigned char ufs_fragtable_other
[] = {
808 0x00, 0x16, 0x16, 0x2A, 0x16, 0x16, 0x26, 0x4E, 0x16, 0x16, 0x16, 0x3E, 0x2A, 0x3E, 0x4E, 0x8A,
809 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
810 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
811 0x2A, 0x3E, 0x3E, 0x2A, 0x3E, 0x3E, 0x2E, 0x6E, 0x3E, 0x3E, 0x3E, 0x3E, 0x2A, 0x3E, 0x6E, 0xAA,
812 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
813 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
814 0x26, 0x36, 0x36, 0x2E, 0x36, 0x36, 0x26, 0x6E, 0x36, 0x36, 0x36, 0x3E, 0x2E, 0x3E, 0x6E, 0xAE,
815 0x4E, 0x5E, 0x5E, 0x6E, 0x5E, 0x5E, 0x6E, 0x4E, 0x5E, 0x5E, 0x5E, 0x7E, 0x6E, 0x7E, 0x4E, 0xCE,
816 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
817 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
818 0x16, 0x16, 0x16, 0x3E, 0x16, 0x16, 0x36, 0x5E, 0x16, 0x16, 0x16, 0x3E, 0x3E, 0x3E, 0x5E, 0x9E,
819 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xBE,
820 0x2A, 0x3E, 0x3E, 0x2A, 0x3E, 0x3E, 0x2E, 0x6E, 0x3E, 0x3E, 0x3E, 0x3E, 0x2A, 0x3E, 0x6E, 0xAA,
821 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xBE,
822 0x4E, 0x5E, 0x5E, 0x6E, 0x5E, 0x5E, 0x6E, 0x4E, 0x5E, 0x5E, 0x5E, 0x7E, 0x6E, 0x7E, 0x4E, 0xCE,
823 0x8A, 0x9E, 0x9E, 0xAA, 0x9E, 0x9E, 0xAE, 0xCE, 0x9E, 0x9E, 0x9E, 0xBE, 0xAA, 0xBE, 0xCE, 0x8A,