2 * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
5 /* Reiserfs block (de)allocator, bitmap-based. */
7 #include <linux/config.h>
8 #include <linux/sched.h>
9 #include <linux/vmalloc.h>
10 #include <linux/errno.h>
11 #include <linux/locks.h>
12 #include <linux/kernel.h>
14 #include <linux/reiserfs_fs.h>
15 #include <linux/reiserfs_fs_sb.h>
16 #include <linux/reiserfs_fs_i.h>
18 #define PREALLOCATION_SIZE 9
20 #define INODE_INFO(inode) (&(inode)->u.reiserfs_i)
22 /* different reiserfs block allocator options */
24 #define SB_ALLOC_OPTS(s) ((s)->u.reiserfs_sb.s_alloc_options.bits)
26 #define _ALLOC_concentrating_formatted_nodes 0
27 #define _ALLOC_displacing_large_files 1
28 #define _ALLOC_displacing_new_packing_localities 2
29 #define _ALLOC_old_hashed_relocation 3
30 #define _ALLOC_new_hashed_relocation 4
31 #define _ALLOC_skip_busy 5
32 #define _ALLOC_displace_based_on_dirid 6
33 #define _ALLOC_hashed_formatted_nodes 7
34 #define _ALLOC_old_way 8
35 #define _ALLOC_hundredth_slices 9
37 #define concentrating_formatted_nodes(s) test_bit(_ALLOC_concentrating_formatted_nodes, &SB_ALLOC_OPTS(s))
38 #define displacing_large_files(s) test_bit(_ALLOC_displacing_large_files, &SB_ALLOC_OPTS(s))
39 #define displacing_new_packing_localities(s) test_bit(_ALLOC_displacing_new_packing_localities, &SB_ALLOC_OPTS(s))
41 #define SET_OPTION(optname) \
43 reiserfs_warning("reiserfs: option \"%s\" is set\n", #optname); \
44 set_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s)); \
46 #define TEST_OPTION(optname, s) \
47 test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s))
50 /* #define LIMIT(a,b) do { if ((a) > (b)) (a) = (b); } while(0) */
52 static inline void get_bit_address (struct super_block * s,
53 unsigned long block, int * bmap_nr, int * offset)
55 /* It is in the bitmap block number equal to the block
56 * number divided by the number of bits in a block. */
57 *bmap_nr = block / (s->s_blocksize << 3);
58 /* Within that bitmap block it is located at bit offset *offset. */
59 *offset = block & ((s->s_blocksize << 3) - 1 );
63 #ifdef CONFIG_REISERFS_CHECK
64 int is_reusable (struct super_block * s, unsigned long block, int bit_value)
68 if (block == 0 || block >= SB_BLOCK_COUNT (s)) {
69 reiserfs_warning ("vs-4010: is_reusable: block number is out of range %lu (%u)\n",
70 block, SB_BLOCK_COUNT (s));
74 /* it can't be one of the bitmap blocks */
75 for (i = 0; i < SB_BMAP_NR (s); i ++)
76 if (block == SB_AP_BITMAP (s)[i].bh->b_blocknr) {
77 reiserfs_warning ("vs: 4020: is_reusable: "
78 "bitmap block %lu(%u) can't be freed or reused\n",
79 block, SB_BMAP_NR (s));
83 get_bit_address (s, block, &i, &j);
85 if (i >= SB_BMAP_NR (s)) {
86 reiserfs_warning ("vs-4030: is_reusable: there is no so many bitmap blocks: "
87 "block=%lu, bitmap_nr=%d\n", block, i);
91 if ((bit_value == 0 &&
92 reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
94 reiserfs_test_le_bit(j, SB_AP_BITMAP (s)[i].bh->b_data) == 0)) {
95 reiserfs_warning ("vs-4040: is_reusable: corresponding bit of block %lu does not "
96 "match required value (i==%d, j==%d) test_bit==%d\n",
97 block, i, j, reiserfs_test_le_bit (j, SB_AP_BITMAP (s)[i].bh->b_data));
102 if (bit_value == 0 && block == SB_ROOT_BLOCK (s)) {
103 reiserfs_warning ("vs-4050: is_reusable: this is root block (%u), "
104 "it must be busy\n", SB_ROOT_BLOCK (s));
110 #endif /* CONFIG_REISERFS_CHECK */
112 /* searches in journal structures for a given block number (bmap, off). If block
113 is found in reiserfs journal it suggests next free block candidate to test. */
114 static inline int is_block_in_journal (struct super_block * s, int bmap, int off, int *next)
118 if (reiserfs_in_journal (s, s->s_dev, bmap, off, s->s_blocksize, 1, &tmp)) {
119 if (tmp) { /* hint supplied */
121 PROC_INFO_INC( s, scan_bitmap.in_journal_hint );
123 (*next) = off + 1; /* inc offset to avoid looping. */
124 PROC_INFO_INC( s, scan_bitmap.in_journal_nohint );
126 PROC_INFO_INC( s, scan_bitmap.retry );
132 /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap
134 static int scan_bitmap_block (struct reiserfs_transaction_handle *th,
135 int bmap_n, int *beg, int boundary, int min, int max, int unfm)
137 struct super_block *s = th->t_super;
138 struct reiserfs_bitmap_info *bi=&SB_AP_BITMAP(s)[bmap_n];
142 RFALSE(bmap_n >= SB_BMAP_NR (s), "Bitmap %d is out of range (0..%d)\n",bmap_n, SB_BMAP_NR (s) - 1);
143 PROC_INFO_INC( s, scan_bitmap.bmap );
144 /* this is unclear and lacks comments, explain how journal bitmaps
145 work here for the reader. Convey a sense of the design here. What
147 /* - I mean `a window of zero bits' as in description of this function - Zam. */
150 printk("Hey, bitmap info pointer is zero for bitmap %d!\n",bmap_n);
153 if (buffer_locked (bi->bh)) {
154 PROC_INFO_INC( s, scan_bitmap.wait );
155 __wait_on_buffer (bi->bh);
158 /* If we know that first zero bit is only one or first zero bit is
159 closer to the end of bitmap than our start pointer */
160 if (bi->first_zero_hint > *beg || bi->free_count == 1)
161 *beg = bi->first_zero_hint;
165 if (bi->free_count < min)
166 return 0; // No free blocks in this bitmap
168 /* search for a first zero bit -- beggining of a window */
169 *beg = reiserfs_find_next_zero_le_bit
170 ((unsigned long*)(bi->bh->b_data), boundary, *beg);
172 if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block
173 * cannot contain a zero window of minimum size */
177 if (unfm && is_block_in_journal(s,bmap_n, *beg, beg))
179 /* first zero bit found; we check next bits */
180 for (end = *beg + 1;; end ++) {
181 if (end >= *beg + max || end >= boundary || reiserfs_test_le_bit (end, bi->bh->b_data)) {
185 /* finding the other end of zero bit window requires looking into journal structures (in
186 * case of searching for free blocks for unformatted nodes) */
187 if (unfm && is_block_in_journal(s, bmap_n, end, &next))
191 /* now (*beg) points to beginning of zero bits window,
192 * (end) points to one bit after the window end */
193 if (end - *beg >= min) { /* it seems we have found window of proper size */
195 reiserfs_prepare_for_journal (s, bi->bh, 1);
196 /* try to set all blocks used checking are they still free */
197 for (i = *beg; i < end; i++) {
198 /* It seems that we should not check in journal again. */
199 if (reiserfs_test_and_set_le_bit (i, bi->bh->b_data)) {
200 /* bit was set by another process
201 * while we slept in prepare_for_journal() */
202 PROC_INFO_INC( s, scan_bitmap.stolen );
203 if (i >= *beg + min) { /* we can continue with smaller set of allocated blocks,
204 * if length of this set is more or equal to `min' */
208 /* otherwise we clear all bit were set ... */
210 reiserfs_test_and_clear_le_bit (i, bi->bh->b_data);
211 reiserfs_restore_prepared_buffer (s, bi->bh);
212 *beg = max(org, (int)bi->first_zero_hint);
213 /* ... and search again in current block from beginning */
217 bi->free_count -= (end - *beg);
219 /* if search started from zero_hint bit, and zero hint have not
220 changed since, then we need to update first_zero_hint */
221 if ( bi->first_zero_hint >= *beg)
222 /* no point in looking for free bit if there is not any */
223 bi->first_zero_hint = (bi->free_count > 0 ) ?
224 reiserfs_find_next_zero_le_bit
225 ((unsigned long*)(bi->bh->b_data), s->s_blocksize << 3, end) : (s->s_blocksize << 3);
227 journal_mark_dirty (th, s, bi->bh);
229 /* free block count calculation */
230 reiserfs_prepare_for_journal (s, SB_BUFFER_WITH_SB(s), 1);
231 PUT_SB_FREE_BLOCKS(s, SB_FREE_BLOCKS(s) - (end - *beg));
232 journal_mark_dirty (th, s, SB_BUFFER_WITH_SB(s));
241 /* Tries to find contiguous zero bit window (given size) in given region of
242 * bitmap and place new blocks there. Returns number of allocated blocks. */
243 static int scan_bitmap (struct reiserfs_transaction_handle *th,
244 unsigned long *start, unsigned long finish,
245 int min, int max, int unfm, unsigned long file_block)
248 struct super_block * s = th->t_super;
249 /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
250 * - Hans, it is not a block number - Zam. */
254 int off_max = s->s_blocksize << 3;
256 PROC_INFO_INC( s, scan_bitmap.call );
257 if ( SB_FREE_BLOCKS(s) <= 0)
258 return 0; // No point in looking for more free blocks
260 get_bit_address (s, *start, &bm, &off);
261 get_bit_address (s, finish, &end_bm, &end_off);
263 // With this option set first we try to find a bitmap that is at least 10%
264 // free, and if that fails, then we fall back to old whole bitmap scanning
265 if ( TEST_OPTION(skip_busy, s) && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s)/20 ) {
266 for (;bm < end_bm; bm++, off = 0) {
267 if ( ( off && (!unfm || (file_block != 0))) || SB_AP_BITMAP(s)[bm].free_count > (s->s_blocksize << 3) / 10 )
268 nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm);
272 get_bit_address (s, *start, &bm, &off);
275 for (;bm < end_bm; bm++, off = 0) {
276 nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm);
281 nr_allocated = scan_bitmap_block(th, bm, &off, end_off + 1, min, max, unfm);
284 *start = bm * off_max + off;
289 static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
292 struct super_block * s = th->t_super;
293 struct reiserfs_super_block * rs;
294 struct buffer_head * sbh;
295 struct reiserfs_bitmap_info *apbi;
298 PROC_INFO_INC( s, free_block );
300 rs = SB_DISK_SUPER_BLOCK (s);
301 sbh = SB_BUFFER_WITH_SB (s);
302 apbi = SB_AP_BITMAP(s);
304 get_bit_address (s, block, &nr, &offset);
306 if (nr >= sb_bmap_nr (rs)) {
307 reiserfs_warning ("vs-4075: reiserfs_free_block: "
308 "block %lu is out of range on %s\n",
309 block, bdevname(s->s_dev));
313 reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ;
315 /* clear bit for the given block in bit map */
316 if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) {
317 reiserfs_warning ("vs-4080: reiserfs_free_block: "
318 "free_block (%04x:%lu)[dev:blocknr]: bit already cleared\n",
321 if (offset < apbi[nr].first_zero_hint) {
322 apbi[nr].first_zero_hint = offset;
324 apbi[nr].free_count ++;
325 journal_mark_dirty (th, s, apbi[nr].bh);
327 reiserfs_prepare_for_journal(s, sbh, 1) ;
328 /* update super block */
329 set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );
331 journal_mark_dirty (th, s, sbh);
334 void reiserfs_free_block (struct reiserfs_transaction_handle *th,
335 unsigned long block) {
336 struct super_block * s = th->t_super;
338 RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
339 RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
340 /* mark it before we clear it, just in case */
341 journal_mark_freed(th, s, block) ;
342 _reiserfs_free_block(th, block) ;
345 /* preallocated blocks don't need to be run through journal_mark_freed */
346 void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th,
347 unsigned long block) {
348 RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
349 RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
350 _reiserfs_free_block(th, block) ;
353 static void __discard_prealloc (struct reiserfs_transaction_handle * th,
354 struct inode * inode)
356 unsigned long save = inode->u.reiserfs_i.i_prealloc_block ;
357 #ifdef CONFIG_REISERFS_CHECK
358 if (inode->u.reiserfs_i.i_prealloc_count < 0)
359 reiserfs_warning("zam-4001:%s: inode has negative prealloc blocks count.\n", __FUNCTION__ );
361 while (inode->u.reiserfs_i.i_prealloc_count > 0) {
362 reiserfs_free_prealloc_block(th,inode->u.reiserfs_i.i_prealloc_block);
363 inode->u.reiserfs_i.i_prealloc_block++;
364 inode->u.reiserfs_i.i_prealloc_count --;
366 inode->u.reiserfs_i.i_prealloc_block = save ;
367 list_del (&(inode->u.reiserfs_i.i_prealloc_list));
370 /* FIXME: It should be inline function */
371 void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th,
372 struct inode * inode)
374 if (inode->u.reiserfs_i.i_prealloc_count) {
375 __discard_prealloc(th, inode);
379 void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
381 struct list_head * plist = &SB_JOURNAL(th->t_super)->j_prealloc_list;
382 struct inode * inode;
384 while (!list_empty(plist)) {
385 inode = list_entry(plist->next, struct inode, u.reiserfs_i.i_prealloc_list);
386 #ifdef CONFIG_REISERFS_CHECK
387 if (!inode->u.reiserfs_i.i_prealloc_count) {
388 reiserfs_warning("zam-4001:%s: inode is in prealloc list but has no preallocated blocks.\n", __FUNCTION__ );
391 __discard_prealloc(th, inode);
395 /* block allocator related options are parsed here */
396 int reiserfs_parse_alloc_options(struct super_block * s, char * options)
398 char * this_char, * value;
400 s->u.reiserfs_sb.s_alloc_options.bits = 0; /* clear default settings */
402 for (this_char = strtok (options, ":"); this_char != NULL; this_char = strtok (NULL, ":")) {
403 if ((value = strchr (this_char, '=')) != NULL)
406 if (!strcmp(this_char, "concentrating_formatted_nodes")) {
408 SET_OPTION(concentrating_formatted_nodes);
409 temp = (value && *value) ? simple_strtoul (value, &value, 0) : 10;
410 if (temp <= 0 || temp > 100) {
411 s->u.reiserfs_sb.s_alloc_options.border = 10;
413 s->u.reiserfs_sb.s_alloc_options.border = 100 / temp;
417 if (!strcmp(this_char, "displacing_large_files")) {
418 SET_OPTION(displacing_large_files);
419 s->u.reiserfs_sb.s_alloc_options.large_file_size =
420 (value && *value) ? simple_strtoul (value, &value, 0) : 16;
423 if (!strcmp(this_char, "displacing_new_packing_localities")) {
424 SET_OPTION(displacing_new_packing_localities);
428 if (!strcmp(this_char, "old_hashed_relocation")) {
429 SET_OPTION(old_hashed_relocation);
433 if (!strcmp(this_char, "new_hashed_relocation")) {
434 SET_OPTION(new_hashed_relocation);
438 if (!strcmp(this_char, "hashed_formatted_nodes")) {
439 SET_OPTION(hashed_formatted_nodes);
443 if (!strcmp(this_char, "skip_busy")) {
444 SET_OPTION(skip_busy);
448 if (!strcmp(this_char, "hundredth_slices")) {
449 SET_OPTION(hundredth_slices);
453 if (!strcmp(this_char, "old_way")) {
458 if (!strcmp(this_char, "displace_based_on_dirid")) {
459 SET_OPTION(displace_based_on_dirid);
463 if (!strcmp(this_char, "preallocmin")) {
464 s->u.reiserfs_sb.s_alloc_options.preallocmin =
465 (value && *value) ? simple_strtoul (value, &value, 0) : 4;
469 if (!strcmp(this_char, "preallocsize")) {
470 s->u.reiserfs_sb.s_alloc_options.preallocsize =
471 (value && *value) ? simple_strtoul (value, &value, 0) : PREALLOCATION_SIZE;
475 reiserfs_warning("zam-4001: %s : unknown option - %s\n", __FUNCTION__ , this_char);
482 static void inline new_hashed_relocation (reiserfs_blocknr_hint_t * hint)
485 if (hint->formatted_node) {
486 hash_in = (char*)&hint->key.k_dir_id;
489 //hint->search_start = hint->beg;
490 hash_in = (char*)&hint->key.k_dir_id;
492 if ( TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
493 hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);
495 hash_in = (char *)(&INODE_PKEY(hint->inode)->k_objectid);
498 hint->search_start = hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
501 static void inline get_left_neighbor(reiserfs_blocknr_hint_t *hint)
504 struct buffer_head * bh;
505 struct item_head * ih;
509 if (!hint->path) /* reiserfs code can call this function w/o pointer to path
510 * structure supplied; then we rely on supplied search_start */
514 bh = get_last_bh(path);
515 RFALSE( !bh, "green-4002: Illegal path specified to get_left_neighbor\n");
517 pos_in_item = path->pos_in_item;
518 item = get_item (path);
520 hint->search_start = bh->b_blocknr;
522 if (!hint->formatted_node && is_indirect_le_ih (ih)) {
523 /* for indirect item: go to left and look for the first non-hole entry
524 in the indirect item */
525 if (pos_in_item == I_UNFM_NUM (ih))
527 // pos_in_item = I_UNFM_NUM (ih) - 1;
528 while (pos_in_item >= 0) {
529 int t=get_block_num(item,pos_in_item);
531 hint->search_start = t;
539 /* does result value fit into specified region? */
543 /* should be, if formatted node, then try to put on first part of the device
544 specified as number of percent with mount option device, else try to put
545 on last of device. This is not to say it is good code to do so,
546 but the effect should be measured. */
547 static void inline set_border_in_hint(struct super_block *s, reiserfs_blocknr_hint_t *hint)
549 b_blocknr_t border = SB_BLOCK_COUNT(hint->th->t_super) / s->u.reiserfs_sb.s_alloc_options.border;
551 if (hint->formatted_node)
552 hint->end = border - 1;
557 static void inline displace_large_file(reiserfs_blocknr_hint_t *hint)
559 if ( TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
560 hint->search_start = hint->beg + keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_dir_id), 4) % (hint->end - hint->beg);
562 hint->search_start = hint->beg + keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_objectid), 4) % (hint->end - hint->beg);
565 static void inline hash_formatted_node(reiserfs_blocknr_hint_t *hint)
570 hash_in = (char*)&hint->key.k_dir_id;
571 else if ( TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
572 hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);
574 hash_in = (char *)(&INODE_PKEY(hint->inode)->k_objectid);
576 hint->search_start = hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
579 static int inline this_blocknr_allocation_would_make_it_a_large_file(reiserfs_blocknr_hint_t *hint)
581 return hint->block == hint->th->t_super->u.reiserfs_sb.s_alloc_options.large_file_size;
584 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
585 static void inline displace_new_packing_locality (reiserfs_blocknr_hint_t *hint)
587 struct key * key = &hint->key;
589 hint->th->displace_new_blocks = 0;
590 hint->search_start = hint->beg + keyed_hash((char*)(&key->k_objectid),4) % (hint->end - hint->beg);
594 static int inline old_hashed_relocation (reiserfs_blocknr_hint_t * hint)
596 unsigned long border;
597 unsigned long hash_in;
599 if (hint->formatted_node || hint->inode == NULL) {
603 hash_in = le32_to_cpu((INODE_PKEY(hint->inode))->k_dir_id);
604 border = hint->beg + (unsigned long) keyed_hash(((char *) (&hash_in)), 4) % (hint->end - hint->beg - 1);
605 if (border > hint->search_start)
606 hint->search_start = border;
611 static int inline old_way (reiserfs_blocknr_hint_t * hint)
613 unsigned long border;
615 if (hint->formatted_node || hint->inode == NULL) {
619 border = hint->beg + le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id) % (hint->end - hint->beg);
620 if (border > hint->search_start)
621 hint->search_start = border;
626 static void inline hundredth_slices (reiserfs_blocknr_hint_t * hint)
628 struct key * key = &hint->key;
629 unsigned long slice_start;
631 slice_start = (keyed_hash((char*)(&key->k_dir_id),4) % 100) * (hint->end / 100);
632 if ( slice_start > hint->search_start || slice_start + (hint->end / 100) <= hint->search_start) {
633 hint->search_start = slice_start;
637 static void inline determine_search_start(reiserfs_blocknr_hint_t *hint,
640 struct super_block *s = hint->th->t_super;
642 hint->end = SB_BLOCK_COUNT(s) - 1;
644 /* This is former border algorithm. Now with tunable border offset */
645 if (concentrating_formatted_nodes(s))
646 set_border_in_hint(s, hint);
648 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
649 /* whenever we create a new directory, we displace it. At first we will
650 hash for location, later we might look for a moderately empty place for
652 if (displacing_new_packing_localities(s)
653 && hint->th->displace_new_blocks) {
654 displace_new_packing_locality(hint);
656 /* we do not continue determine_search_start,
657 * if new packing locality is being displaced */
662 /* all persons should feel encouraged to add more special cases here and
665 if (displacing_large_files(s) && !hint->formatted_node
666 && this_blocknr_allocation_would_make_it_a_large_file(hint)) {
667 displace_large_file(hint);
671 /* attempt to copy a feature from old block allocator code */
672 if (TEST_OPTION(old_hashed_relocation, s) && !hint->formatted_node) {
673 old_hashed_relocation(hint);
676 /* if none of our special cases is relevant, use the left neighbor in the
677 tree order of the new node we are allocating for */
678 if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes,s)) {
679 hash_formatted_node(hint);
683 get_left_neighbor(hint);
685 /* Mimic old block allocator behaviour, that is if VFS allowed for preallocation,
686 new blocks are displaced based on directory ID. Also, if suggested search_start
687 is less than last preallocated block, we start searching from it, assuming that
688 HDD dataflow is faster in forward direction */
689 if ( TEST_OPTION(old_way, s)) {
690 if (!hint->formatted_node) {
691 if ( !reiserfs_hashed_relocation(s))
693 else if (!reiserfs_no_unhashed_relocation(s))
694 old_hashed_relocation(hint);
696 if ( hint->inode && hint->search_start < hint->inode->u.reiserfs_i.i_prealloc_block)
697 hint->search_start = hint->inode->u.reiserfs_i.i_prealloc_block;
702 /* This is an approach proposed by Hans */
703 if ( TEST_OPTION(hundredth_slices, s) && ! (displacing_large_files(s) && !hint->formatted_node)) {
704 hundredth_slices(hint);
708 if (TEST_OPTION(old_hashed_relocation, s))
709 old_hashed_relocation(hint);
710 if (TEST_OPTION(new_hashed_relocation, s))
711 new_hashed_relocation(hint);
715 static int determine_prealloc_size(reiserfs_blocknr_hint_t * hint)
717 /* make minimum size a mount option and benchmark both ways */
718 /* we preallocate blocks only for regular files, specific size */
719 /* benchmark preallocating always and see what happens */
721 hint->prealloc_size = 0;
723 if (!hint->formatted_node && hint->preallocate) {
724 if (S_ISREG(hint->inode->i_mode)
725 && hint->inode->i_size >= hint->th->t_super->u.reiserfs_sb.s_alloc_options.preallocmin * hint->inode->i_sb->s_blocksize)
726 hint->prealloc_size = hint->th->t_super->u.reiserfs_sb.s_alloc_options.preallocsize - 1;
731 /* XXX I know it could be merged with upper-level function;
732 but may be result function would be too complex. */
733 static inline int allocate_without_wrapping_disk (reiserfs_blocknr_hint_t * hint,
734 b_blocknr_t * new_blocknrs,
735 b_blocknr_t start, b_blocknr_t finish,
736 int amount_needed, int prealloc_size)
738 int rest = amount_needed;
742 nr_allocated = scan_bitmap (hint->th, &start, finish, 1,
743 rest + prealloc_size, !hint->formatted_node,
746 if (nr_allocated == 0) /* no new blocks allocated, return */
749 /* fill free_blocknrs array first */
750 while (rest > 0 && nr_allocated > 0) {
751 * new_blocknrs ++ = start ++;
752 rest --; nr_allocated --;
755 /* do we have something to fill prealloc. array also ? */
756 if (nr_allocated > 0) {
757 /* it means prealloc_size was greater that 0 and we do preallocation */
758 list_add(&INODE_INFO(hint->inode)->i_prealloc_list,
759 &SB_JOURNAL(hint->th->t_super)->j_prealloc_list);
760 INODE_INFO(hint->inode)->i_prealloc_block = start;
761 INODE_INFO(hint->inode)->i_prealloc_count = nr_allocated;
766 return (amount_needed - rest);
769 static inline int blocknrs_and_prealloc_arrays_from_search_start
770 (reiserfs_blocknr_hint_t *hint, b_blocknr_t *new_blocknrs, int amount_needed)
772 struct super_block *s = hint->th->t_super;
773 b_blocknr_t start = hint->search_start;
774 b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
776 int nr_allocated = 0;
778 determine_prealloc_size(hint);
780 += allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish,
781 amount_needed - nr_allocated, hint->prealloc_size))
784 /* not all blocks were successfully allocated yet*/
785 if (second_pass) { /* it was a second pass; we must free all blocks */
786 while (nr_allocated --)
787 reiserfs_free_block(hint->th, new_blocknrs[nr_allocated]);
789 return NO_DISK_SPACE;
790 } else { /* refine search parameters for next pass */
800 /* grab new blocknrs from preallocated list */
801 /* return amount still needed after using them */
802 static int use_preallocated_list_if_available (reiserfs_blocknr_hint_t *hint,
803 b_blocknr_t *new_blocknrs, int amount_needed)
805 struct inode * inode = hint->inode;
807 if (INODE_INFO(inode)->i_prealloc_count > 0) {
808 while (amount_needed) {
810 *new_blocknrs ++ = INODE_INFO(inode)->i_prealloc_block ++;
811 INODE_INFO(inode)->i_prealloc_count --;
815 if (INODE_INFO(inode)->i_prealloc_count <= 0) {
816 list_del(&inode->u.reiserfs_i.i_prealloc_list);
821 /* return amount still needed after using preallocated blocks */
822 return amount_needed;
825 int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint,
826 b_blocknr_t * new_blocknrs, int amount_needed,
827 int reserved_by_us /* Amount of blocks we have
830 int initial_amount_needed = amount_needed;
833 /* Check if there is enough space, taking into account reserved space */
834 if ( SB_FREE_BLOCKS(hint->th->t_super) - hint->th->t_super->u.reiserfs_sb.reserved_blocks <
835 amount_needed - reserved_by_us)
836 return NO_DISK_SPACE;
837 /* should this be if !hint->inode && hint->preallocate? */
838 /* do you mean hint->formatted_node can be removed ? - Zam */
839 /* hint->formatted_node cannot be removed because we try to access
840 inode information here, and there is often no inode assotiated with
841 metadata allocations - green */
843 if (!hint->formatted_node && hint->preallocate) {
844 amount_needed = use_preallocated_list_if_available
845 (hint, new_blocknrs, amount_needed);
846 if (amount_needed == 0) /* all blocknrs we need we got from
849 new_blocknrs += (initial_amount_needed - amount_needed);
852 /* find search start and save it in hint structure */
853 determine_search_start(hint, amount_needed);
855 /* allocation itself; fill new_blocknrs and preallocation arrays */
856 ret = blocknrs_and_prealloc_arrays_from_search_start
857 (hint, new_blocknrs, amount_needed);
859 /* we used prealloc. list to fill (partially) new_blocknrs array. If final allocation fails we
860 * need to return blocks back to prealloc. list or just free them. -- Zam (I chose second
863 if (ret != CARRY_ON) {
864 while (amount_needed ++ < initial_amount_needed) {
865 reiserfs_free_block(hint->th, *(--new_blocknrs));
871 /* These 2 functions are here to provide blocks reservation to the rest of kernel */
872 /* Reserve @blocks amount of blocks in fs pointed by @sb. Caller must make sure
873 there are actually this much blocks on the FS available */
874 void reiserfs_claim_blocks_to_be_allocated(
875 struct super_block *sb, /* super block of
879 int blocks /* How much to reserve */
883 /* Fast case, if reservation is zero - exit immediately. */
887 sb->u.reiserfs_sb.reserved_blocks += blocks;
890 /* Unreserve @blocks amount of blocks in fs pointed by @sb */
891 void reiserfs_release_claimed_blocks(
892 struct super_block *sb, /* super block of
896 int blocks /* How much to unreserve */
900 /* Fast case, if unreservation is zero - exit immediately. */
904 sb->u.reiserfs_sb.reserved_blocks -= blocks;
905 RFALSE( sb->u.reiserfs_sb.reserved_blocks < 0, "amount of blocks reserved became zero?");