- Linus: drop support for old-style Makefiles entirely. Big.
[davej-history.git] / fs / ufs / balloc.c
blobfa83ba5bee9a8649286c93a8a6a3632a0c2c09a9
1 /*
2 * linux/fs/ufs/balloc.c
4 * Copyright (C) 1998
5 * Daniel Pirkl <daniel.pirkl@email.cz>
6 * Charles University, Faculty of Mathematics and Physics
7 */
9 #include <linux/fs.h>
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>
19 #include "swab.h"
20 #include "util.h"
22 #undef UFS_BALLOC_DEBUG
24 #ifdef UFS_BALLOC_DEBUG
25 #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
26 #else
27 #define UFSD(x)
28 #endif
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;
47 unsigned swab;
49 sb = inode->i_sb;
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");
59 lock_super(sb);
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");
65 goto failed;
68 ucpi = ufs_load_cylinder (sb, cgno);
69 if (!ucpi)
70 goto failed;
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);
74 goto failed;
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);
119 sb->s_dirt = 1;
121 unlock_super (sb);
122 UFSD(("EXIT\n"))
123 return;
125 failed:
126 unlock_super (sb);
127 UFSD(("EXIT (FAILED)\n"))
128 return;
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;
141 unsigned swab;
143 sb = inode->i_sb;
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);
153 goto failed;
156 lock_super(sb);
158 do_more:
159 overflow = 0;
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");
164 goto failed;
166 end_bit = bit + count;
167 if (end_bit > uspi->s_fpg) {
168 overflow = bit + count - uspi->s_fpg;
169 count -= overflow;
170 end_bit -= overflow;
173 ucpi = ufs_load_cylinder (sb, cgno);
174 if (!ucpi)
175 goto failed;
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);
179 goto failed;
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);
206 if (overflow) {
207 fragment += count;
208 count = overflow;
209 goto do_more;
212 sb->s_dirt = 1;
213 unlock_super (sb);
214 UFSD(("EXIT\n"))
215 return;
217 failed:
218 unlock_super (sb);
219 UFSD(("EXIT (FAILED)\n"))
220 return;
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); \
235 brelse (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;
246 unsigned swab;
248 UFSD(("ENTER, ino %lu, fragment %u, goal %u, count %u\n", inode->i_ino, fragment, goal, count))
250 sb = inode->i_sb;
251 swab = sb->u.ufs_sb.s_swab;
252 uspi = sb->u.ufs_sb.s_uspi;
253 usb1 = ubh_get_usb_first(USPI_UBH);
254 *err = -ENOSPC;
256 lock_super (sb);
258 tmp = SWAB32(*p);
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
270 if (oldcount) {
271 if (!tmp) {
272 ufs_error (sb, "ufs_new_fragments", "internal error, "
273 "fragment %u, tmp %u\n", fragment, tmp);
274 return (unsigned)-1;
276 if (fragment < inode->u.ufs_i.i_lastfrag) {
277 UFSD(("EXIT (ALREADY ALLOCATED)\n"))
278 unlock_super (sb);
279 return 0;
282 else {
283 if (tmp) {
284 UFSD(("EXIT (ALREADY ALLOCATED)\n"))
285 unlock_super(sb);
286 return 0;
291 * There is not enough space for user on the device
293 if (!fsuser() && ufs_freespace(usb1, UFS_MINFREE) <= 0) {
294 unlock_super (sb);
295 UFSD(("EXIT (FAILED)\n"))
296 return 0;
299 if (goal >= uspi->s_size)
300 goal = 0;
301 if (goal == 0)
302 cgno = ufs_inotocg (inode->i_ino);
303 else
304 cgno = ufs_dtog (goal);
307 * allocate new fragment
309 if (oldcount == 0) {
310 result = ufs_alloc_fragments (inode, cgno, goal, count, err);
311 if (result) {
312 *p = SWAB32(result);
313 *err = 0;
314 inode->i_blocks += count << uspi->s_nspfshift;
315 inode->u.ufs_i.i_lastfrag = max (inode->u.ufs_i.i_lastfrag, fragment + count);
316 NULLIFY_FRAGMENTS
318 unlock_super(sb);
319 UFSD(("EXIT, result %u\n", result))
320 return result;
324 * resize block
326 result = ufs_add_fragments (inode, tmp, oldcount, newcount, err);
327 if (result) {
328 *err = 0;
329 inode->i_blocks += count << uspi->s_nspfshift;
330 inode->u.ufs_i.i_lastfrag = max (inode->u.ufs_i.i_lastfrag, fragment + count);
331 NULLIFY_FRAGMENTS
332 unlock_super(sb);
333 UFSD(("EXIT, result %u\n", result))
334 return result;
338 * allocate new block and move data
340 switch (SWAB32(usb1->fs_optim)) {
341 case UFS_OPTSPACE:
342 request = newcount;
343 if (uspi->s_minfree < 5 || SWAB32(usb1->fs_cstotal.cs_nffree)
344 > uspi->s_dsize * uspi->s_minfree / (2 * 100) )
345 break;
346 usb1->fs_optim = SWAB32(UFS_OPTTIME);
347 break;
348 default:
349 usb1->fs_optim = SWAB32(UFS_OPTTIME);
351 case UFS_OPTTIME:
352 request = uspi->s_fpb;
353 if (SWAB32(usb1->fs_cstotal.cs_nffree) < uspi->s_dsize *
354 (uspi->s_minfree - 2) / 100)
355 break;
356 usb1->fs_optim = SWAB32(UFS_OPTSPACE);
357 break;
359 result = ufs_alloc_fragments (inode, cgno, goal, request, err);
360 if (result) {
361 for (i = 0; i < oldcount; i++) {
362 bh = bread (sb->s_dev, tmp + i, sb->s_blocksize);
363 if(bh)
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);
370 wait_on_buffer (bh);
372 brelse (bh);
374 else
376 printk(KERN_ERR "ufs_new_fragments: bread fail\n");
377 return 0;
380 *p = SWAB32(result);
381 *err = 0;
382 inode->i_blocks += count << uspi->s_nspfshift;
383 inode->u.ufs_i.i_lastfrag = max (inode->u.ufs_i.i_lastfrag, fragment + count);
384 NULLIFY_FRAGMENTS
385 unlock_super(sb);
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))
390 return result;
393 unlock_super(sb);
394 UFSD(("EXIT (FAILED)\n"))
395 return 0;
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;
407 unsigned swab;
409 UFSD(("ENTER, fragment %u, oldcount %u, newcount %u\n", fragment, oldcount, newcount))
411 sb = inode->i_sb;
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)
419 return 0;
420 if ((ufs_fragnum (fragment) + newcount) > uspi->s_fpb)
421 return 0;
422 ucpi = ufs_load_cylinder (sb, cgno);
423 if (!ucpi)
424 return 0;
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);
429 return 0;
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))
436 return 0;
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))
443 break;
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)) {
454 *err = -EDQUOT;
455 return 0;
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);
467 sb->s_dirt = 1;
469 UFSD(("EXIT, fragment %u\n", fragment))
471 return 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)) \
477 goto cg_found; \
478 for (k = count; k < uspi->s_fpb; k++) \
479 if (SWAB32(ucg->cg_frsum[k])) \
480 goto cg_found;
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;
491 unsigned swab;
493 UFSD(("ENTER, ino %lu, cgno %u, goal %u, count %u\n", inode->i_ino, cgno, goal, count))
495 sb = inode->i_sb;
496 swab = sb->u.ufs_sb.s_swab;
497 uspi = sb->u.ufs_sb.s_uspi;
498 usb1 = ubh_get_usb_first(USPI_UBH);
499 oldcg = cgno;
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) {
510 cgno += j;
511 if (cgno >= uspi->s_ncg)
512 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++) {
522 cgno++;
523 if (cgno >= uspi->s_ncg)
524 cgno = 0;
525 UFS_TEST_FREE_SPACE_CG
528 UFSD(("EXIT (FAILED)\n"))
529 return 0;
531 cg_found:
532 ucpi = ufs_load_cylinder (sb, cgno);
533 if (!ucpi)
534 return 0;
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)
544 return 0;
545 goto succed;
548 for (allocsize = count; allocsize < uspi->s_fpb; allocsize++)
549 if (SWAB32(ucg->cg_frsum[allocsize]) != 0)
550 break;
552 if (allocsize == uspi->s_fpb) {
553 result = ufs_alloccg_block (inode, ucpi, goal, err);
554 if (result == (unsigned)-1)
555 return 0;
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]);
565 goto succed;
568 result = ufs_bitmap_search (sb, ucpi, goal, allocsize);
569 if (result == (unsigned)-1)
570 return 0;
571 if(DQUOT_ALLOC_BLOCK(sb, inode, count)) {
572 *err = -EDQUOT;
573 return 0;
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]);
584 succed:
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);
591 sb->s_dirt = 1;
593 result += cgno * uspi->s_fpg;
594 UFSD(("EXIT3, result %u\n", result))
595 return 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;
606 unsigned swab;
608 UFSD(("ENTER, goal %u\n", goal))
610 sb = inode->i_sb;
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);
616 if (goal == 0) {
617 goal = ucpi->c_rotor;
618 goto norot;
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))) {
627 result = goal;
628 goto gotit;
631 norot:
632 result = ufs_bitmap_search (sb, ucpi, goal, uspi->s_fpb);
633 if (result == (unsigned)-1)
634 return (unsigned)-1;
635 ucpi->c_rotor = result;
636 gotit:
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)) {
642 *err = -EDQUOT;
643 return (unsigned)-1;
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))
654 return 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;
665 unsigned swab;
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);
674 if (goal)
675 start = ufs_dtogd(goal) >> 3;
676 else
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)));
683 if (location == 0) {
684 length = start + 1;
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)));
688 if (location == 0) {
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);
692 return (unsigned)-1;
694 start = 0;
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);
703 fragsize = 0;
704 for (possition = 0, mask = 1; possition < 8; possition++, mask <<= 1) {
705 if (blockmap & mask) {
706 if (!(possition & uspi->s_fpbmask))
707 fragsize = 1;
708 else
709 fragsize++;
711 else {
712 if (fragsize == count) {
713 result += possition - count;
714 UFSD(("EXIT, result %u\n", result))
715 return result;
717 fragsize = 0;
720 if (fragsize == count) {
721 result += possition - count;
722 UFSD(("EXIT, result %u\n", result))
723 return result;
725 ufs_error (sb, "ufs_bitmap_search", "block not in map on cg %u\n", ucpi->c_cgx);
726 UFSD(("EXIT (FAILED)\n"))
727 return (unsigned)-1;
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;
735 unsigned swab;
738 uspi = sb->u.ufs_sb.s_uspi;
739 swab = sb->u.ufs_sb.s_swab;
741 if (uspi->s_contigsumsize <= 0)
742 return;
744 if (cnt > 0)
745 ubh_setbit(UCPI_UBH, ucpi->c_clusteroff, blkno);
746 else
747 ubh_clrbit(UCPI_UBH, ucpi->c_clusteroff, blkno);
750 * Find the size of the cluster going forward.
752 start = blkno + 1;
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);
757 if (i > end)
758 i = end;
759 forw = i - start;
762 * Find the size of the cluster going backward.
764 start = blkno - 1;
765 end = start - uspi->s_contigsumsize;
766 if (end < 0 )
767 end = -1;
768 i = ubh_find_last_zero_bit (UCPI_UBH, ucpi->c_clusteroff, start, end);
769 if ( i < end)
770 i = end;
771 back = start - i;
774 * Account for old cluster and the possibly new forward and
775 * back clusters.
777 i = back + forw + 1;
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);
781 if (back > 0)
782 SUB_SWAB32(*((u32*)ubh_get_addr(UCPI_UBH, ucpi->c_clustersumoff + (back << 2))), cnt);
783 if (forw > 0)
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,