bitmap.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:27k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  3.  */
  4. #include <linux/config.h>
  5. #include <linux/sched.h>
  6. #include <linux/reiserfs_fs.h>
  7. #include <linux/locks.h>
  8. #include <asm/bitops.h>
  9. #include <linux/list.h>
  10. #ifdef CONFIG_REISERFS_CHECK
  11. /* this is a safety check to make sure
  12. ** blocks are reused properly.  used for debugging only.
  13. **
  14. ** this checks, that block can be reused, and it has correct state
  15. **   (free or busy) 
  16. */
  17. int is_reusable (struct super_block * s, unsigned long block, int bit_value)
  18. {
  19.     int i, j;
  20.   
  21.     if (block == 0 || block >= SB_BLOCK_COUNT (s)) {
  22. reiserfs_warning ("vs-4010: is_reusable: block number is out of range %lu (%u)n",
  23.   block, SB_BLOCK_COUNT (s));
  24. return 0;
  25.     }
  26.     /* it can't be one of the bitmap blocks */
  27.     for (i = 0; i < SB_BMAP_NR (s); i ++)
  28. if (block == SB_AP_BITMAP (s)[i]->b_blocknr) {
  29.     reiserfs_warning ("vs: 4020: is_reusable: "
  30.       "bitmap block %lu(%u) can't be freed or reusedn",
  31.       block, SB_BMAP_NR (s));
  32.     return 0;
  33. }
  34.   
  35.     i = block / (s->s_blocksize << 3);
  36.     if (i >= SB_BMAP_NR (s)) {
  37. reiserfs_warning ("vs-4030: is_reusable: there is no so many bitmap blocks: "
  38.   "block=%lu, bitmap_nr=%dn", block, i);
  39. return 0;
  40.     }
  41.     j = block % (s->s_blocksize << 3);
  42.     if ((bit_value == 0 && 
  43.          reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i]->b_data)) ||
  44. (bit_value == 1 && 
  45.  reiserfs_test_le_bit(j, SB_AP_BITMAP (s)[i]->b_data) == 0)) {
  46. reiserfs_warning ("vs-4040: is_reusable: corresponding bit of block %lu does not "
  47.   "match required value (i==%d, j==%d) test_bit==%dn",
  48. block, i, j, reiserfs_test_le_bit (j, SB_AP_BITMAP (s)[i]->b_data));
  49. return 0;
  50.     }
  51.     if (bit_value == 0 && block == SB_ROOT_BLOCK (s)) {
  52. reiserfs_warning ("vs-4050: is_reusable: this is root block (%u), "
  53.   "it must be busy", SB_ROOT_BLOCK (s));
  54. return 0;
  55.     }
  56.     return 1;
  57. }
  58. #endif /* CONFIG_REISERFS_CHECK */
  59. /* get address of corresponding bit (bitmap block number and offset in it) */
  60. static inline void get_bit_address (struct super_block * s, unsigned long block, int * bmap_nr, int * offset)
  61. {
  62.                                 /* It is in the bitmap block number equal to the block number divided by the number of
  63.                                    bits in a block. */
  64.     *bmap_nr = block / (s->s_blocksize << 3);
  65.                                 /* Within that bitmap block it is located at bit offset *offset. */
  66.     *offset = block % (s->s_blocksize << 3);
  67.     return;
  68. }
  69. /* There would be a modest performance benefit if we write a version
  70.    to free a list of blocks at once. -Hans */
  71. /* I wonder if it would be less modest
  72.                                    now that we use journaling. -Hans */
  73. static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block)
  74. {
  75.     struct super_block * s = th->t_super;
  76.     struct reiserfs_super_block * rs;
  77.     struct buffer_head * sbh;
  78.     struct buffer_head ** apbh;
  79.     int nr, offset;
  80.   PROC_INFO_INC( s, free_block );
  81.   rs = SB_DISK_SUPER_BLOCK (s);
  82.   sbh = SB_BUFFER_WITH_SB (s);
  83.   apbh = SB_AP_BITMAP (s);
  84.   get_bit_address (s, block, &nr, &offset);
  85.   if (nr >= sb_bmap_nr (rs)) {
  86.   reiserfs_warning ("vs-4075: reiserfs_free_block: "
  87.     "block %lu is out of range on %sn", 
  88.     block, bdevname(s->s_dev));
  89.   return;
  90.   }
  91.   reiserfs_prepare_for_journal(s, apbh[nr], 1 ) ;
  92.   /* clear bit for the given block in bit map */
  93.   if (!reiserfs_test_and_clear_le_bit (offset, apbh[nr]->b_data)) {
  94.       reiserfs_warning ("vs-4080: reiserfs_free_block: "
  95. "free_block (%04x:%lu)[dev:blocknr]: bit already clearedn", 
  96.     s->s_dev, block);
  97.   }
  98.   journal_mark_dirty (th, s, apbh[nr]);
  99.   reiserfs_prepare_for_journal(s, sbh, 1) ;
  100.   /* update super block */
  101.   set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );
  102.   journal_mark_dirty (th, s, sbh);
  103.   s->s_dirt = 1;
  104. }
  105. void reiserfs_free_block (struct reiserfs_transaction_handle *th, 
  106.                           unsigned long block) {
  107.     struct super_block * s = th->t_super;
  108.     RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
  109.     RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
  110.     /* mark it before we clear it, just in case */
  111.     journal_mark_freed(th, s, block) ;
  112.     _reiserfs_free_block(th, block) ;
  113. }
  114. /* preallocated blocks don't need to be run through journal_mark_freed */
  115. void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, 
  116.                           unsigned long block) {
  117.     struct super_block * s = th->t_super;
  118.     RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
  119.     RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
  120.     _reiserfs_free_block(th, block) ;
  121. }
  122. /* beginning from offset-th bit in bmap_nr-th bitmap block,
  123.    find_forward finds the closest zero bit. It returns 1 and zero
  124.    bit address (bitmap, offset) if zero bit found or 0 if there is no
  125.    zero bit in the forward direction */
  126. /* The function is NOT SCHEDULE-SAFE! */
  127. static int find_forward (struct super_block * s, int * bmap_nr, int * offset, int for_unformatted)
  128. {
  129.   int i, j;
  130.   struct buffer_head * bh;
  131.   unsigned long block_to_try = 0;
  132.   unsigned long next_block_to_try = 0 ;
  133.   PROC_INFO_INC( s, find_forward.call );
  134.   for (i = *bmap_nr; i < SB_BMAP_NR (s); i ++, *offset = 0, 
  135.        PROC_INFO_INC( s, find_forward.bmap )) {
  136.     /* get corresponding bitmap block */
  137.     bh = SB_AP_BITMAP (s)[i];
  138.     if (buffer_locked (bh)) {
  139. PROC_INFO_INC( s, find_forward.wait );
  140.         __wait_on_buffer (bh);
  141.     }
  142. retry:
  143.     j = reiserfs_find_next_zero_le_bit ((unsigned long *)bh->b_data, 
  144.                                          s->s_blocksize << 3, *offset);
  145.     /* wow, this really needs to be redone.  We can't allocate a block if
  146.     ** it is in the journal somehow.  reiserfs_in_journal makes a suggestion
  147.     ** for a good block if the one you ask for is in the journal.  Note,
  148.     ** reiserfs_in_journal might reject the block it suggests.  The big
  149.     ** gain from the suggestion is when a big file has been deleted, and
  150.     ** many blocks show free in the real bitmap, but are all not free
  151.     ** in the journal list bitmaps.
  152.     **
  153.     ** this whole system sucks.  The bitmaps should reflect exactly what
  154.     ** can and can't be allocated, and the journal should update them as
  155.     ** it goes.  TODO.
  156.     */
  157.     if (j < (s->s_blocksize << 3)) {
  158.       block_to_try = (i * (s->s_blocksize << 3)) + j; 
  159.       /* the block is not in the journal, we can proceed */
  160.       if (!(reiserfs_in_journal(s, s->s_dev, block_to_try, s->s_blocksize, for_unformatted, &next_block_to_try))) {
  161. *bmap_nr = i;
  162. *offset = j;
  163. return 1;
  164.       } 
  165.       /* the block is in the journal */
  166.       else if ((j+1) < (s->s_blocksize << 3)) { /* try again */
  167. /* reiserfs_in_journal suggested a new block to try */
  168. if (next_block_to_try > 0) {
  169.   int new_i ;
  170.   get_bit_address (s, next_block_to_try, &new_i, offset);
  171.   PROC_INFO_INC( s, find_forward.in_journal_hint );
  172.   /* block is not in this bitmap. reset i and continue
  173.   ** we only reset i if new_i is in a later bitmap.
  174.   */
  175.   if (new_i > i) {
  176.     i = (new_i - 1 ); /* i gets incremented by the for loop */
  177.     PROC_INFO_INC( s, find_forward.in_journal_out );
  178.     continue ;
  179.   }
  180. } else {
  181.   /* no suggestion was made, just try the next block */
  182.   *offset = j+1 ;
  183. }
  184. PROC_INFO_INC( s, find_forward.retry );
  185. goto retry ;
  186.       }
  187.     }
  188.   }
  189.     /* zero bit not found */
  190.     return 0;
  191. }
  192. /* return 0 if no free blocks, else return 1 */
  193. /* The function is NOT SCHEDULE-SAFE!  
  194. ** because the bitmap block we want to change could be locked, and on its
  195. ** way to the disk when we want to read it, and because of the 
  196. ** flush_async_commits.  Per bitmap block locks won't help much, and 
  197. ** really aren't needed, as we retry later on if we try to set the bit
  198. ** and it is already set.
  199. */
  200. static int find_zero_bit_in_bitmap (struct super_block * s, 
  201.                                     unsigned long search_start, 
  202.     int * bmap_nr, int * offset, 
  203.     int for_unformatted)
  204. {
  205.   int retry_count = 0 ;
  206.   /* get bit location (bitmap number and bit offset) of search_start block */
  207.   get_bit_address (s, search_start, bmap_nr, offset);
  208.     /* note that we search forward in the bitmap, benchmarks have shown that it is better to allocate in increasing
  209.        sequence, which is probably due to the disk spinning in the forward direction.. */
  210.     if (find_forward (s, bmap_nr, offset, for_unformatted) == 0) {
  211.       /* there wasn't a free block with number greater than our
  212.          starting point, so we are going to go to the beginning of the disk */
  213. retry:
  214.       search_start = 0; /* caller will reset search_start for itself also. */
  215.       get_bit_address (s, search_start, bmap_nr, offset);
  216.       if (find_forward (s, bmap_nr,offset,for_unformatted) == 0) {
  217. if (for_unformatted) { /* why only unformatted nodes? -Hans */
  218.   if (retry_count == 0) {
  219.     /* we've got a chance that flushing async commits will free up
  220.     ** some space.  Sync then retry
  221.     */
  222.     flush_async_commits(s) ;
  223.     retry_count++ ;
  224.     goto retry ;
  225.   } else if (retry_count > 0) {
  226.     /* nothing more we can do.  Make the others wait, flush
  227.     ** all log blocks to disk, and flush to their home locations.
  228.     ** this will free up any blocks held by the journal
  229.     */
  230.     SB_JOURNAL(s)->j_must_wait = 1 ;
  231.   }
  232. }
  233.         return 0;
  234.       }
  235.     }
  236.   return 1;
  237. }
  238. /* get amount_needed free block numbers from scanning the bitmap of
  239.    free/used blocks.
  240.    
  241.    Optimize layout by trying to find them starting from search_start
  242.    and moving in increasing blocknr direction.  (This was found to be
  243.    faster than using a bi-directional elevator_direction, in part
  244.    because of disk spin direction, in part because by the time one
  245.    reaches the end of the disk the beginning of the disk is the least
  246.    congested).
  247.    search_start is the block number of the left
  248.    semantic neighbor of the node we create.
  249.    return CARRY_ON if everything is ok
  250.    return NO_DISK_SPACE if out of disk space
  251.    return NO_MORE_UNUSED_CONTIGUOUS_BLOCKS if the block we found is not contiguous to the last one
  252.    
  253.    return block numbers found, in the array free_blocknrs.  assumes
  254.    that any non-zero entries already present in the array are valid.
  255.    This feature is perhaps convenient coding when one might not have
  256.    used all blocknrs from the last time one called this function, or
  257.    perhaps it is an archaism from the days of schedule tracking, one
  258.    of us ought to reread the code that calls this, and analyze whether
  259.    it is still the right way to code it.
  260.    spare space is used only when priority is set to 1. reiserfsck has
  261.    its own reiserfs_new_blocknrs, which can use reserved space
  262.    exactly what reserved space?  the SPARE_SPACE?  if so, please comment reiserfs.h.
  263.    Give example of who uses spare space, and say that it is a deadlock
  264.    avoidance mechanism.  -Hans */
  265. /* This function is NOT SCHEDULE-SAFE! */
  266. static int do_reiserfs_new_blocknrs (struct reiserfs_transaction_handle *th,
  267.                                      unsigned long * free_blocknrs, 
  268.      unsigned long search_start, 
  269.      int amount_needed, int priority, 
  270.      int for_unformatted,
  271.      int for_prealloc)
  272. {
  273.   struct super_block * s = th->t_super;
  274.   int i, j;
  275.   unsigned long * block_list_start = free_blocknrs;
  276.   int init_amount_needed = amount_needed;
  277.   unsigned long new_block = 0 ; 
  278.     if (SB_FREE_BLOCKS (s) < SPARE_SPACE && !priority)
  279. /* we can answer NO_DISK_SPACE being asked for new block with
  280.    priority 0 */
  281. return NO_DISK_SPACE;
  282.   RFALSE( !s, "vs-4090: trying to get new block from nonexistent device");
  283.   RFALSE( search_start == MAX_B_NUM,
  284.   "vs-4100: we are optimizing location based on "
  285.   "the bogus location of a temp buffer (%lu).", search_start);
  286.   RFALSE( amount_needed < 1 || amount_needed > 2,
  287.   "vs-4110: amount_needed parameter incorrect (%d)", amount_needed);
  288.   /* We continue the while loop if another process snatches our found
  289.    * free block from us after we find it but before we successfully
  290.    * mark it as in use */
  291.   while (amount_needed--) {
  292.     /* skip over any blocknrs already gotten last time. */
  293.     if (*(free_blocknrs) != 0) {
  294.       RFALSE( is_reusable (s, *free_blocknrs, 1) == 0, 
  295.       "vs-4120: bad blocknr on free_blocknrs list");
  296.       free_blocknrs++;
  297.       continue;
  298.     }
  299.     /* look for zero bits in bitmap */
  300.     if (find_zero_bit_in_bitmap(s,search_start, &i, &j,for_unformatted) == 0) {
  301.       if (find_zero_bit_in_bitmap(s,search_start,&i,&j, for_unformatted) == 0) {
  302. /* recode without the goto and without
  303.    the if.  It will require a
  304.    duplicate for.  This is worth the
  305.    code clarity.  Your way was
  306.    admirable, and just a bit too
  307.    clever in saving instructions.:-)
  308.    I'd say create a new function, but
  309.    that would slow things also, yes?
  310.    -Hans */
  311. free_and_return:
  312. for ( ; block_list_start != free_blocknrs; block_list_start++) {
  313.   reiserfs_free_block (th, *block_list_start);
  314.   *block_list_start = 0;
  315. }
  316. if (for_prealloc) 
  317.     return NO_MORE_UNUSED_CONTIGUOUS_BLOCKS;
  318. else
  319.     return NO_DISK_SPACE;
  320.       }
  321.     }
  322.     
  323.     /* i and j now contain the results of the search. i = bitmap block
  324.        number containing free block, j = offset in this block.  we
  325.        compute the blocknr which is our result, store it in
  326.        free_blocknrs, and increment the pointer so that on the next
  327.        loop we will insert into the next location in the array.  Also
  328.        in preparation for the next loop, search_start is changed so
  329.        that the next search will not rescan the same range but will
  330.        start where this search finished.  Note that while it is
  331.        possible that schedule has occurred and blocks have been freed
  332.        in that range, it is perhaps more important that the blocks
  333.        returned be near each other than that they be near their other
  334.        neighbors, and it also simplifies and speeds the code this way.  */
  335.     /* journal: we need to make sure the block we are giving out is not
  336.     ** a log block, horrible things would happen there.
  337.     */
  338.     new_block = (i * (s->s_blocksize << 3)) + j; 
  339.     if (for_prealloc && (new_block - 1) != search_start) {
  340.       /* preallocated blocks must be contiguous, bail if we didnt find one.
  341.       ** this is not a bug.  We want to do the check here, before the
  342.       ** bitmap block is prepared, and before we set the bit and log the
  343.       ** bitmap. 
  344.       **
  345.       ** If we do the check after this function returns, we have to 
  346.       ** call reiserfs_free_block for new_block, which would be pure
  347.       ** overhead.
  348.       **
  349.       ** for_prealloc should only be set if the caller can deal with the
  350.       ** NO_MORE_UNUSED_CONTIGUOUS_BLOCKS return value.  This can be
  351.       ** returned before the disk is actually full
  352.       */
  353.       goto free_and_return ;
  354.     }
  355.     search_start = new_block ;
  356.     if (search_start >= reiserfs_get_journal_block(s) &&
  357.         search_start < (reiserfs_get_journal_block(s) + JOURNAL_BLOCK_COUNT)) {
  358. reiserfs_warning("vs-4130: reiserfs_new_blocknrs: trying to allocate log block %lun",
  359.  search_start) ;
  360. search_start++ ;
  361. amount_needed++ ;
  362. continue ;
  363.     }
  364.        
  365.     reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[i], 1) ;
  366.     RFALSE( buffer_locked (SB_AP_BITMAP (s)[i]) || 
  367.     is_reusable (s, search_start, 0) == 0,
  368.     "vs-4140: bitmap block is locked or bad block number found");
  369.     /* if this bit was already set, we've scheduled, and someone else
  370.     ** has allocated it.  loop around and try again
  371.     */
  372.     if (reiserfs_test_and_set_le_bit (j, SB_AP_BITMAP (s)[i]->b_data)) {
  373. reiserfs_restore_prepared_buffer(s, SB_AP_BITMAP(s)[i]) ;
  374. amount_needed++ ;
  375. continue ;
  376.     }    
  377.     journal_mark_dirty (th, s, SB_AP_BITMAP (s)[i]); 
  378.     *free_blocknrs = search_start ;
  379.     free_blocknrs ++;
  380.   }
  381.   reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
  382.   /* update free block count in super block */
  383.   PUT_SB_FREE_BLOCKS( s, SB_FREE_BLOCKS(s) - init_amount_needed );
  384.   journal_mark_dirty (th, s, SB_BUFFER_WITH_SB (s));
  385.   s->s_dirt = 1;
  386.   return CARRY_ON;
  387. }
  388. // this is called only by get_empty_nodes
  389. int reiserfs_new_blocknrs (struct reiserfs_transaction_handle *th, unsigned long * free_blocknrs,
  390.     unsigned long search_start, int amount_needed) {
  391.   return do_reiserfs_new_blocknrs(th, free_blocknrs, search_start, amount_needed, 0/*priority*/, 0/*for_formatted*/, 0/*for_prealloc */) ;
  392. }
  393. // called by get_new_buffer and by reiserfs_get_block with amount_needed == 1
  394. int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle *th, unsigned long * free_blocknrs,
  395.       unsigned long search_start) {
  396.   return do_reiserfs_new_blocknrs(th, free_blocknrs, search_start, 
  397.                                   1/*amount_needed*/,
  398.   0/*priority*/, 
  399.   1/*for formatted*/,
  400.   0/*for prealloc */) ;
  401. }
  402. #ifdef REISERFS_PREALLOCATE
  403. /* 
  404. ** We pre-allocate 8 blocks.  Pre-allocation is used for files > 16 KB only.
  405. ** This lowers fragmentation on large files by grabbing a contiguous set of
  406. ** blocks at once.  It also limits the number of times the bitmap block is
  407. ** logged by making X number of allocation changes in a single transaction.
  408. **
  409. ** We are using a border to divide the disk into two parts.  The first part
  410. ** is used for tree blocks, which have a very high turnover rate (they
  411. ** are constantly allocated then freed)
  412. **
  413. ** The second part of the disk is for the unformatted nodes of larger files.
  414. ** Putting them away from the tree blocks lowers fragmentation, and makes
  415. ** it easier to group files together.  There are a number of different
  416. ** allocation schemes being tried right now, each is documented below.
  417. **
  418. ** A great deal of the allocator's speed comes because reiserfs_get_block
  419. ** sends us the block number of the last unformatted node in the file.  Once
  420. ** a given block is allocated past the border, we don't collide with the
  421. ** blocks near the search_start again.
  422. ** 
  423. */
  424. int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th, 
  425. struct inode       * p_s_inode,
  426. unsigned long      * free_blocknrs,
  427. unsigned long        search_start)
  428. {
  429.   int ret=0, blks_gotten=0;
  430.   unsigned long border = 0;
  431.   unsigned long bstart = 0;
  432.   unsigned long hash_in, hash_out;
  433.   unsigned long saved_search_start=search_start;
  434.   int allocated[PREALLOCATION_SIZE];
  435.   int blks;
  436.   if (!reiserfs_no_border(th->t_super)) {
  437.     /* we default to having the border at the 10% mark of the disk.  This
  438.     ** is an arbitrary decision and it needs tuning.  It also needs a limit
  439.     ** to prevent it from taking too much space on huge drives.
  440.     */
  441.     bstart = (SB_BLOCK_COUNT(th->t_super) / 10); 
  442.   }
  443.   if (!reiserfs_no_unhashed_relocation(th->t_super)) {
  444.     /* this is a very simple first attempt at preventing too much grouping
  445.     ** around the border value.  Since k_dir_id is never larger than the
  446.     ** highest allocated oid, it is far from perfect, and files will tend
  447.     ** to be grouped towards the start of the border
  448.     */
  449.     border = le32_to_cpu(INODE_PKEY(p_s_inode)->k_dir_id) % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ;
  450.   } else if (!reiserfs_hashed_relocation(th->t_super)) {
  451.       hash_in = le32_to_cpu((INODE_PKEY(p_s_inode))->k_dir_id);
  452. /* I wonder if the CPU cost of the
  453.                                    hash will obscure the layout
  454.                                    effect? Of course, whether that
  455.                                    effect is good or bad we don't
  456.                                    know.... :-) */
  457.       
  458.       hash_out = keyed_hash(((char *) (&hash_in)), 4);
  459.       border = hash_out % (SB_BLOCK_COUNT(th->t_super) - bstart - 1) ;
  460.   }
  461.   border += bstart ;
  462.   allocated[0] = 0 ; /* important.  Allows a check later on to see if at
  463.                       * least one block was allocated.  This prevents false
  464.       * no disk space returns
  465.       */
  466.   if ( (p_s_inode->i_size < 4 * 4096) || 
  467.        !(S_ISREG(p_s_inode->i_mode)) )
  468.     {
  469.       if ( search_start < border 
  470.    || (
  471. /* allow us to test whether it is a
  472.                                    good idea to prevent files from
  473.                                    getting too far away from their
  474.                                    packing locality by some unexpected
  475.                                    means.  This might be poor code for
  476.                                    directories whose files total
  477.                                    larger than 1/10th of the disk, and
  478.                                    it might be good code for
  479.                                    suffering from old insertions when the disk
  480.                                    was almost full. */
  481.                /* changed from !reiserfs_test3(th->t_super), which doesn't
  482.                ** seem like a good idea.  Think about adding blocks to
  483.                ** a large file.  If you've allocated 10% of the disk
  484.                ** in contiguous blocks, you start over at the border value
  485.                ** for every new allocation.  This throws away all the
  486.                ** information sent in about the last block that was allocated
  487.                ** in the file.  Not a good general case at all.
  488.                ** -chris
  489.                */
  490.        reiserfs_test4(th->t_super) && 
  491.        (search_start > border + (SB_BLOCK_COUNT(th->t_super) / 10))
  492.        )
  493.    )
  494. search_start=border;
  495.   
  496.       ret = do_reiserfs_new_blocknrs(th, free_blocknrs, search_start, 
  497.      1/*amount_needed*/, 
  498.      0/*use reserved blocks for root */,
  499.      1/*for_formatted*/,
  500.      0/*for prealloc */) ;  
  501.       return ret;
  502.     }
  503.   /* take a block off the prealloc list and return it -Hans */
  504.   if (p_s_inode->u.reiserfs_i.i_prealloc_count > 0) {
  505.     p_s_inode->u.reiserfs_i.i_prealloc_count--;
  506.     *free_blocknrs = p_s_inode->u.reiserfs_i.i_prealloc_block++;
  507.     /* if no more preallocated blocks, remove inode from list */
  508.     if (! p_s_inode->u.reiserfs_i.i_prealloc_count) {
  509.       list_del(&p_s_inode->u.reiserfs_i.i_prealloc_list);
  510.     }
  511.     
  512.     return ret;
  513.   }
  514. /* else get a new preallocation for the file */
  515.   reiserfs_discard_prealloc (th, p_s_inode);
  516.   /* this uses the last preallocated block as the search_start.  discard
  517.   ** prealloc does not zero out this number.
  518.   */
  519.   if (search_start <= p_s_inode->u.reiserfs_i.i_prealloc_block) {
  520.     search_start = p_s_inode->u.reiserfs_i.i_prealloc_block;
  521.   }
  522.   
  523.   /* doing the compare again forces search_start to be >= the border,
  524.   ** even if the file already had prealloction done.  This seems extra,
  525.   ** and should probably be removed
  526.   */
  527.   if ( search_start < border ) search_start=border; 
  528.   /* If the disk free space is already below 10% we should 
  529.   ** start looking for the free blocks from the beginning 
  530.   ** of the partition, before the border line.
  531.   */
  532.   if ( SB_FREE_BLOCKS(th->t_super) <= (SB_BLOCK_COUNT(th->t_super) / 10) ) {
  533.     search_start=saved_search_start;
  534.   }
  535.   *free_blocknrs = 0;
  536.   blks = PREALLOCATION_SIZE-1;
  537.   for (blks_gotten=0; blks_gotten<PREALLOCATION_SIZE; blks_gotten++) {
  538.     ret = do_reiserfs_new_blocknrs(th, free_blocknrs, search_start, 
  539.    1/*amount_needed*/, 
  540.    0/*for root reserved*/,
  541.    1/*for_formatted*/,
  542.    (blks_gotten > 0)/*must_be_contiguous*/) ;
  543.     /* if we didn't find a block this time, adjust blks to reflect
  544.     ** the actual number of blocks allocated
  545.     */ 
  546.     if (ret != CARRY_ON) {
  547.       blks = blks_gotten > 0 ? (blks_gotten - 1) : 0 ;
  548.       break ;
  549.     }
  550.     allocated[blks_gotten]= *free_blocknrs;
  551. #ifdef CONFIG_REISERFS_CHECK
  552.     if ( (blks_gotten>0) && (allocated[blks_gotten] - allocated[blks_gotten-1]) != 1 ) {
  553.       /* this should be caught by new_blocknrs now, checking code */
  554.       reiserfs_warning("yura-1, reiserfs_new_unf_blocknrs2: pre-allocated not contiguous set of blocks!n") ;
  555.       reiserfs_free_block(th, allocated[blks_gotten]);
  556.       blks = blks_gotten-1; 
  557.       break;
  558.     }
  559. #endif
  560.     if (blks_gotten==0) {
  561.       p_s_inode->u.reiserfs_i.i_prealloc_block = *free_blocknrs;
  562.     }
  563.     search_start = *free_blocknrs; 
  564.     *free_blocknrs = 0;
  565.   }
  566.   p_s_inode->u.reiserfs_i.i_prealloc_count = blks;
  567.   *free_blocknrs = p_s_inode->u.reiserfs_i.i_prealloc_block;
  568.   p_s_inode->u.reiserfs_i.i_prealloc_block++;
  569.   /* if inode has preallocated blocks, link him to list */
  570.   if (p_s_inode->u.reiserfs_i.i_prealloc_count) {
  571.     list_add(&p_s_inode->u.reiserfs_i.i_prealloc_list,
  572.      &SB_JOURNAL(th->t_super)->j_prealloc_list);
  573.   } 
  574.   /* we did actually manage to get 1 block */
  575.   if (ret != CARRY_ON && allocated[0] > 0) {
  576.     return CARRY_ON ;
  577.   }
  578.   /* NO_MORE_UNUSED_CONTIGUOUS_BLOCKS should only mean something to
  579.   ** the preallocation code.  The rest of the filesystem asks for a block
  580.   ** and should either get it, or know the disk is full.  The code
  581.   ** above should never allow ret == NO_MORE_UNUSED_CONTIGUOUS_BLOCK,
  582.   ** as it doesn't send for_prealloc = 1 to do_reiserfs_new_blocknrs
  583.   ** unless it has already successfully allocated at least one block.
  584.   ** Just in case, we translate into a return value the rest of the
  585.   ** filesystem can understand.
  586.   **
  587.   ** It is an error to change this without making the
  588.   ** rest of the filesystem understand NO_MORE_UNUSED_CONTIGUOUS_BLOCKS
  589.   ** If you consider it a bug to return NO_DISK_SPACE here, fix the rest
  590.   ** of the fs first.
  591.   */
  592.   if (ret == NO_MORE_UNUSED_CONTIGUOUS_BLOCKS) {
  593. #ifdef CONFIG_REISERFS_CHECK
  594.     reiserfs_warning("reiser-2015: this shouldn't happen, may cause false out of disk space error");
  595. #endif
  596.      return NO_DISK_SPACE; 
  597.   }
  598.   return ret;
  599. }
  600. //
  601. // a portion of this function, was derived from minix or ext2's
  602. // analog. You should be able to tell which portion by looking at the
  603. // ext2 code and comparing. 
  604. static void __discard_prealloc (struct reiserfs_transaction_handle * th,
  605. struct inode * inode)
  606. {
  607.   unsigned long save = inode->u.reiserfs_i.i_prealloc_block ;
  608.   while (inode->u.reiserfs_i.i_prealloc_count > 0) {
  609.     reiserfs_free_prealloc_block(th,inode->u.reiserfs_i.i_prealloc_block);
  610.     inode->u.reiserfs_i.i_prealloc_block++;
  611.     inode->u.reiserfs_i.i_prealloc_count --;
  612.   }
  613.   inode->u.reiserfs_i.i_prealloc_block = save ; 
  614.   list_del (&(inode->u.reiserfs_i.i_prealloc_list));
  615. }
  616. void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th, 
  617. struct inode * inode)
  618. {
  619. #ifdef CONFIG_REISERFS_CHECK
  620.   if (inode->u.reiserfs_i.i_prealloc_count < 0)
  621.      reiserfs_warning("zam-4001:" __FUNCTION__ ": inode has negative prealloc blocks count.n");
  622. #endif  
  623.     if (inode->u.reiserfs_i.i_prealloc_count > 0) {
  624.     __discard_prealloc(th, inode);
  625.   }
  626.       }
  627. void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
  628. {
  629.   struct list_head * plist = &SB_JOURNAL(th->t_super)->j_prealloc_list;
  630.   struct inode * inode;
  631.   
  632.   while (!list_empty(plist)) {
  633.     inode = list_entry(plist->next, struct inode, u.reiserfs_i.i_prealloc_list);
  634. #ifdef CONFIG_REISERFS_CHECK
  635.     if (!inode->u.reiserfs_i.i_prealloc_count) {
  636.       reiserfs_warning("zam-4001:" __FUNCTION__ ": inode is in prealloc list but has no preallocated blocks.n");
  637.     }
  638. #endif    
  639.     __discard_prealloc(th, inode);
  640.     }
  641. }
  642. #endif