static inline int blocknrs_and_prealloc_arrays_from_search_start (reiserfs_blocknr_hint_t *hint, b_blocknr_t *new_blocknrs, int amount_needed) { struct super_block *s = hint->th->t_super; b_blocknr_t start = hint->search_start; b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1; int second_pass = 0; int nr_allocated = 0; determine_prealloc_size(hint); while((nr_allocated += allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish, amount_needed - nr_allocated, hint->prealloc_size)) < amount_needed) { /* not all blocks were successfully allocated yet*/ if (second_pass) { /* it was a second pass; we must free all blocks */ while (nr_allocated --) reiserfs_free_block(hint->th, new_blocknrs[nr_allocated]); return NO_DISK_SPACE; } else { /* refine search parameters for next pass */ second_pass = 1; finish = start; start = 0; continue; } } return CARRY_ON; }
static inline int blocknrs_and_prealloc_arrays_from_search_start (reiserfs_blocknr_hint_t *hint, b_blocknr_t *new_blocknrs, int amount_needed) { struct super_block *s = hint->th->t_super; b_blocknr_t start = hint->search_start; b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1; int passno = 0; int nr_allocated = 0; int bigalloc = 0; determine_prealloc_size(hint); if (!hint->formatted_node) { int quota_ret; #ifdef REISERQUOTA_DEBUG reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: allocating %d blocks id=%u", amount_needed, hint->inode->i_uid); #endif quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed); if (quota_ret) /* Quota exceeded? */ return QUOTA_EXCEEDED; if (hint->preallocate && hint->prealloc_size ) { #ifdef REISERQUOTA_DEBUG reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: allocating (prealloc) %d blocks id=%u", hint->prealloc_size, hint->inode->i_uid); #endif quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, hint->prealloc_size); if (quota_ret) hint->preallocate=hint->prealloc_size=0; } /* for unformatted nodes, force large allocations */ bigalloc = amount_needed; } do { /* in bigalloc mode, nr_allocated should stay zero until * the entire allocation is filled */ if (unlikely(bigalloc && nr_allocated)) { reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n", bigalloc, nr_allocated); /* reset things to a sane value */ bigalloc = amount_needed - nr_allocated; } /* * try pass 0 and pass 1 looking for a nice big * contiguous allocation. Then reset and look * for anything you can find. */ if (passno == 2 && bigalloc) { passno = 0; bigalloc = 0; } switch (passno++) { case 0: /* Search from hint->search_start to end of disk */ start = hint->search_start; finish = SB_BLOCK_COUNT(s) - 1; break; case 1: /* Search from hint->beg to hint->search_start */ start = hint->beg; finish = hint->search_start; break; case 2: /* Last chance: Search from 0 to hint->beg */ start = 0; finish = hint->beg; break; default: /* We've tried searching everywhere, not enough space */ /* Free the blocks */ if (!hint->formatted_node) { #ifdef REISERQUOTA_DEBUG reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: freeing (nospace) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated, hint->inode->i_uid); #endif DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */ } while (nr_allocated --) reiserfs_free_block(hint->th, hint->inode, new_blocknrs[nr_allocated], !hint->formatted_node); return NO_DISK_SPACE; } } while ((nr_allocated += allocate_without_wrapping_disk (hint, new_blocknrs + nr_allocated, start, finish, bigalloc ? bigalloc : 1, amount_needed - nr_allocated, hint->prealloc_size)) < amount_needed); if ( !hint->formatted_node && amount_needed + hint->prealloc_size > nr_allocated + REISERFS_I(hint->inode)->i_prealloc_count) { /* Some of preallocation blocks were not allocated */ #ifdef REISERQUOTA_DEBUG reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: freeing (failed prealloc) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated - REISERFS_I(hint->inode)->i_prealloc_count, hint->inode->i_uid); #endif DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated - REISERFS_I(hint->inode)->i_prealloc_count); } return CARRY_ON; }