-
-
Save yuanfeiz/8574221 to your computer and use it in GitHub Desktop.
<file path="/Volumes/HappyPecanDisk/repos/minix-src/servers/ext2/balloc.c"> | |
<content> | |
<text><![CDATA[/* This files manages blocks allocation and deallocation. | |
* | |
* The entry points into this file are: | |
* discard_preallocated_blocks: Discard preallocated blocks. | |
* alloc_block: somebody wants to allocate a block; find one. | |
* free_block: indicate that a block is available for new allocation. | |
* | |
* Created: | |
* June 2010 (Evgeniy Ivanov) | |
*/ | |
#include "fs.h" | |
#include <string.h> | |
#include <stdlib.h> | |
#include <minix/com.h> | |
#include <minix/u64.h> | |
#include "buf.h" | |
#include "inode.h" | |
#include "super.h" | |
#include "const.h" | |
static block_t alloc_block_bit(struct super_block *sp, block_t origin, | |
struct inode *rip); | |
/*===========================================================================* | |
* discard_preallocated_blocks * | |
*===========================================================================*/ | |
void discard_preallocated_blocks(struct inode *rip) | |
{ | |
/* When called for rip, discard (free) blocks preallocated for rip, | |
* otherwise discard all preallocated blocks. | |
* Normally it should be called in following situations: | |
* 1. File is closed. | |
* 2. File is truncated. | |
* 3. Non-sequential write. | |
* 4. inode is "unloaded" from the memory. | |
* 5. No free blocks left (discard all preallocated blocks). | |
*/ | |
int i; | |
if (rip) { | |
rip->i_prealloc_count = rip->i_prealloc_index = 0; | |
for (i = 0; i < EXT2_PREALLOC_BLOCKS; i++) { | |
if (rip->i_prealloc_blocks[i] != NO_BLOCK) { | |
free_block(rip->i_sp, rip->i_prealloc_blocks[i]); | |
rip->i_prealloc_blocks[i] = NO_BLOCK; | |
} | |
} | |
return; | |
} | |
/* Discard all allocated blocks. | |
* Probably there are just few blocks on the disc, so forbid preallocation.*/ | |
for(rip = &inode[0]; rip < &inode[NR_INODES]; rip++) { | |
rip->i_prealloc_count = rip->i_prealloc_index = 0; | |
rip->i_preallocation = 0; /* forbid preallocation */ | |
for (i = 0; i < EXT2_PREALLOC_BLOCKS; i++) { | |
if (rip->i_prealloc_blocks[i] != NO_BLOCK) { | |
free_block(rip->i_sp, rip->i_prealloc_blocks[i]); | |
rip->i_prealloc_blocks[i] = NO_BLOCK; | |
} | |
} | |
} | |
} | |
/*===========================================================================* | |
* alloc_block * | |
*===========================================================================*/ | |
block_t alloc_block(struct inode *rip, block_t block) | |
{ | |
/* Allocate a block for inode. If block is provided, then use it as a goal: | |
* try to allocate this block or his neghbors. | |
* If block is not provided then goal is group, where inode lives. | |
*/ | |
block_t goal; | |
block_t b; | |
struct super_block *sp = rip->i_sp; | |
if (sp->s_rd_only) | |
panic("can't alloc block on read-only filesys."); | |
/* Check for free blocks. First time discard preallocation, | |
* next time return NO_BLOCK | |
*/ | |
if (!opt.use_reserved_blocks && | |
sp->s_free_blocks_count <= sp->s_r_blocks_count) { | |
discard_preallocated_blocks(NULL); | |
} else if (sp->s_free_blocks_count <= EXT2_PREALLOC_BLOCKS) { | |
discard_preallocated_blocks(NULL); | |
} | |
if (!opt.use_reserved_blocks && | |
sp->s_free_blocks_count <= sp->s_r_blocks_count) { | |
return(NO_BLOCK); | |
} else if (sp->s_free_blocks_count == 0) { | |
return(NO_BLOCK); | |
} | |
if (block != NO_BLOCK) { | |
goal = block; | |
if (rip->i_preallocation && rip->i_prealloc_count > 0) { | |
/* check if goal is preallocated */ | |
b = rip->i_prealloc_blocks[rip->i_prealloc_index]; | |
if (block == b || (block + 1) == b) { | |
/* use preallocated block */ | |
rip->i_prealloc_blocks[rip->i_prealloc_index] = NO_BLOCK; | |
rip->i_prealloc_count--; | |
rip->i_prealloc_index++; | |
if (rip->i_prealloc_index >= EXT2_PREALLOC_BLOCKS) { | |
rip->i_prealloc_index = 0; | |
ASSERT(rip->i_prealloc_count == 0); | |
} | |
rip->i_bsearch = b; | |
return b; | |
} else { | |
/* probably non-sequential write operation, | |
* disable preallocation for this inode. | |
*/ | |
rip->i_preallocation = 0; | |
discard_preallocated_blocks(rip); | |
} | |
} | |
} else { | |
int group = (rip->i_num - 1) / sp->s_inodes_per_group; | |
goal = sp->s_blocks_per_group*group + sp->s_first_data_block; | |
} | |
if (rip->i_preallocation && rip->i_prealloc_count) { | |
ext2_debug("There're preallocated blocks, but they're\ | |
neither used or freed!"); | |
} | |
b = alloc_block_bit(sp, goal, rip); | |
if (b != NO_BLOCK) | |
rip->i_bsearch = b; | |
return b; | |
} | |
static void check_block_number(block_t block, struct super_block *sp, | |
struct group_desc *gd); | |
/*===========================================================================* | |
* alloc_block_bit * | |
*===========================================================================*/ | |
static block_t alloc_block_bit(sp, goal, rip) | |
struct super_block *sp; /* the filesystem to allocate from */ | |
block_t goal; /* try to allocate near this block */ | |
struct inode *rip; /* used for preallocation */ | |
{ | |
block_t block = NO_BLOCK; /* allocated block */ | |
int word; /* word in block bitmap */ | |
bit_t bit = -1; | |
int group; | |
char update_bsearch = FALSE; | |
int i; | |
if (goal >= sp->s_blocks_count || | |
(goal < sp->s_first_data_block && goal != 0)) { | |
goal = sp->s_bsearch; | |
} | |
if (goal <= sp->s_bsearch) { | |
/* No reason to search in a place with no free blocks */ | |
goal = sp->s_bsearch; | |
update_bsearch = TRUE; | |
} | |
/* Figure out where to start the bit search. */ | |
word = ((goal - sp->s_first_data_block) % sp->s_blocks_per_group) | |
/ FS_BITCHUNK_BITS; | |
/* Try to allocate block at any group starting from the goal's group. | |
* First time goal's group is checked from the word=goal, after all | |
* groups checked, it's checked again from word=0, that's why "i <=". | |
*/ | |
group = (goal - sp->s_first_data_block) / sp->s_blocks_per_group; | |
for (i = 0; i <= sp->s_groups_count; i++, group++) { | |
struct buf *bp; | |
struct group_desc *gd; | |
if (group >= sp->s_groups_count) | |
group = 0; | |
gd = get_group_desc(group); | |
if (gd == NULL) | |
panic("can't get group_desc to alloc block"); | |
if (gd->free_blocks_count == 0) { | |
word = 0; | |
continue; | |
} | |
bp = get_block(sp->s_dev, gd->block_bitmap, NORMAL); | |
if (rip->i_preallocation && | |
gd->free_blocks_count >= (EXT2_PREALLOC_BLOCKS * 4) ) { | |
/* Try to preallocate blocks */ | |
if (rip->i_prealloc_count != 0) { | |
/* kind of glitch... */ | |
discard_preallocated_blocks(rip); | |
ext2_debug("warning, discarding previously preallocated\ | |
blocks! It had to be done by another code."); | |
} | |
ASSERT(rip->i_prealloc_count == 0); | |
/* we preallocate bytes only */ | |
ASSERT(EXT2_PREALLOC_BLOCKS == sizeof(char)*CHAR_BIT); | |
bit = setbyte(b_bitmap(bp), sp->s_blocks_per_group); | |
if (bit != -1) { | |
block = bit + sp->s_first_data_block + | |
group * sp->s_blocks_per_group; | |
check_block_number(block, sp, gd); | |
/* We preallocate a byte starting from block. | |
* First preallocated block will be returned as | |
* normally allocated block. | |
*/ | |
for (i = 1; i < EXT2_PREALLOC_BLOCKS; i++) { | |
check_block_number(block + i, sp, gd); | |
rip->i_prealloc_blocks[i-1] = block + i; | |
} | |
rip->i_prealloc_index = 0; | |
rip->i_prealloc_count = EXT2_PREALLOC_BLOCKS - 1; | |
lmfs_markdirty(bp); | |
put_block(bp, MAP_BLOCK); | |
gd->free_blocks_count -= EXT2_PREALLOC_BLOCKS; | |
sp->s_free_blocks_count -= EXT2_PREALLOC_BLOCKS; | |
lmfs_blockschange(sp->s_dev, -EXT2_PREALLOC_BLOCKS); | |
group_descriptors_dirty = 1; | |
return block; | |
} | |
} | |
bit = setbit(b_bitmap(bp), sp->s_blocks_per_group, word); | |
if (bit == -1) { | |
if (word == 0) { | |
panic("ext2: allocator failed to allocate a bit in bitmap\ | |
with free bits."); | |
} else { | |
word = 0; | |
continue; | |
} | |
} | |
block = sp->s_first_data_block + group * sp->s_blocks_per_group + bit; | |
check_block_number(block, sp, gd); | |
lmfs_markdirty(bp); | |
put_block(bp, MAP_BLOCK); | |
gd->free_blocks_count--; | |
sp->s_free_blocks_count--; | |
lmfs_blockschange(sp->s_dev, -1); | |
group_descriptors_dirty = 1; | |
if (update_bsearch && block != -1 && block != NO_BLOCK) { | |
/* We searched from the beginning, update bsearch. */ | |
sp->s_bsearch = block; | |
} | |
return block; | |
} | |
return block; | |
} | |
/*===========================================================================* | |
* free_block * | |
*===========================================================================*/ | |
void free_block(struct super_block *sp, bit_t bit_returned) | |
{ | |
/* Return a block by turning off its bitmap bit. */ | |
int group; /* group number of bit_returned */ | |
int bit; /* bit_returned number within its group */ | |
struct buf *bp; | |
struct group_desc *gd; | |
if (sp->s_rd_only) | |
panic("can't free bit on read-only filesys."); | |
if (bit_returned >= sp->s_blocks_count || | |
bit_returned < sp->s_first_data_block) | |
panic("trying to free block %d beyond blocks scope.", | |
bit_returned); | |
/* At first search group, to which bit_returned belongs to | |
* and figure out in what word bit is stored. | |
*/ | |
group = (bit_returned - sp->s_first_data_block) / sp->s_blocks_per_group; | |
bit = (bit_returned - sp->s_first_data_block) % sp->s_blocks_per_group; | |
gd = get_group_desc(group); | |
if (gd == NULL) | |
panic("can't get group_desc to alloc block"); | |
/* We might be buggy (No way! :P), so check if we deallocate | |
* data block, but not control (system) block. | |
* This should never happen. | |
*/ | |
if (bit_returned == gd->inode_bitmap || bit_returned == gd->block_bitmap | |
|| (bit_returned >= gd->inode_table | |
&& bit_returned < (gd->inode_table + sp->s_itb_per_group))) { | |
ext2_debug("ext2: freeing non-data block %d\n", bit_returned); | |
panic("trying to deallocate \ | |
system/control block, hardly poke author."); | |
} | |
bp = get_block(sp->s_dev, gd->block_bitmap, NORMAL); | |
if (unsetbit(b_bitmap(bp), bit)) | |
panic("Tried to free unused block", bit_returned); | |
lmfs_markdirty(bp); | |
put_block(bp, MAP_BLOCK); | |
gd->free_blocks_count++; | |
sp->s_free_blocks_count++; | |
lmfs_blockschange(sp->s_dev, 1); | |
group_descriptors_dirty = 1; | |
if (bit_returned < sp->s_bsearch) | |
sp->s_bsearch = bit_returned; | |
} | |
static void check_block_number(block_t block, struct super_block *sp, | |
struct group_desc *gd) | |
{ | |
/* Check if we allocated a data block, but not control (system) block. | |
* Only major bug can cause us to allocate wrong block. If it happens, | |
* we panic (and don't bloat filesystem's bitmap). | |
*/ | |
if (block == gd->inode_bitmap || block == gd->block_bitmap || | |
(block >= gd->inode_table | |
&& block < (gd->inode_table + sp->s_itb_per_group))) { | |
ext2_debug("ext2: allocating non-data block %d\n", block); | |
panic("ext2: block allocator tryed to return \ | |
system/control block, poke author.\n"); | |
} | |
if (block >= sp->s_blocks_count) { | |
panic("ext2: allocator returned blocknum greater, than \ | |
total number of blocks.\n"); | |
} | |
}]]></text> | |
<tokens> | |
</tokens> | |
<concepts> | |
<concept id="1991219" weight="0.35588833689689636">JFFS2</concept> | |
<concept id="437471" weight="0.41070467233657837">Block Island</concept> | |
<concept id="1103580" weight="0.3325919806957245">Cinder block</concept> | |
<concept id="572854" weight="0.39552876353263855">H&R Block</concept> | |
<concept id="512614" weight="0.3742939829826355">USS Block Island (CVE-106)</concept> | |
<concept id="631107" weight="0.34605568647384644">City Block</concept> | |
<concept id="1716537" weight="0.3287249803543091">Gauge blocks</concept> | |
<concept id="981057" weight="0.34063366055488586">Minix file system</concept> | |
<concept id="55347" weight="0.3387579321861267">Hierarchical File System</concept> | |
<concept id="1251844" weight="0.37822970747947693">The Block (Sydney)</concept> | |
</concepts> | |
</content> | |
<comment> | |
<text><![CDATA[/*===========================================================================* | |
* discard_preallocated_blocks * | |
/* When called for rip, discard (free) blocks preallocated for rip, | |
* otherwise discard all preallocated blocks. | |
* Normally it should be called in following situations: | |
* 1. File is closed. | |
* 2. File is truncated. | |
* 3. Non-sequential write. | |
* 4. inode is "unloaded" from the memory. | |
* 5. No free blocks left (discard all preallocated blocks). | |
*/ | |
/* Discard all allocated blocks. | |
* Probably there are just few blocks on the disc, so forbid preallocation.*/ | |
/*===========================================================================* | |
* alloc_block * | |
/* Allocate a block for inode. If block is provided, then use it as a goal: | |
* try to allocate this block or his neghbors. | |
* If block is not provided then goal is group, where inode lives. | |
*/ | |
/* Check for free blocks. First time discard preallocation, | |
* next time return NO_BLOCK | |
*/ | |
/* check if goal is preallocated */ | |
/* use preallocated block */ | |
/* probably non-sequential write operation, | |
* disable preallocation for this inode. | |
*/ | |
/*===========================================================================* | |
* alloc_block_bit * | |
/* No reason to search in a place with no free blocks */ | |
/* Figure out where to start the bit search. */ | |
/* Try to allocate block at any group starting from the goal's group. | |
* First time goal's group is checked from the word=goal, after all | |
* groups checked, it's checked again from word=0, that's why "i <=". | |
*/ | |
/* Try to preallocate blocks */ | |
/* kind of glitch... */ | |
/* we preallocate bytes only */ | |
/* We preallocate a byte starting from block. | |
* First preallocated block will be returned as | |
* normally allocated block. | |
*/ | |
/* We searched from the beginning, update bsearch. */ | |
/*===========================================================================* | |
* free_block * | |
/* Return a block by turning off its bitmap bit. */ | |
/* At first search group, to which bit_returned belongs to | |
* and figure out in what word bit is stored. | |
*/ | |
/* We might be buggy (No way! :P), so check if we deallocate | |
* data block, but not control (system) block. | |
* This should never happen. | |
*/ | |
/* Check if we allocated a data block, but not control (system) block. | |
* Only major bug can cause us to allocate wrong block. If it happens, | |
* we panic (and don't bloat filesystem's bitmap). | |
*/]]></text> | |
<tokens> | |
</tokens> | |
<concepts> | |
<concept id="1991219" weight="0.11820138990879059">JFFS2</concept> | |
<concept id="311193" weight="0.1060536727309227">Paging</concept> | |
<concept id="437471" weight="0.12390121817588806">Block Island</concept> | |
<concept id="572854" weight="0.11681419610977173">H&R Block</concept> | |
<concept id="512614" weight="0.11059369146823883">USS Block Island (CVE-106)</concept> | |
<concept id="927752" weight="0.11466237902641296">HFS Plus</concept> | |
<concept id="981057" weight="0.11578171700239182">Minix file system</concept> | |
<concept id="55347" weight="0.12457172572612762">Hierarchical File System</concept> | |
<concept id="329777" weight="0.12344598770141602">Fragmentation</concept> | |
<concept id="1251844" weight="0.11170514672994614">The Block (Sydney)</concept> | |
</concepts> | |
</comment> | |
<sourceCode> | |
<text><![CDATA[#include "fs.h" | |
#include <string.h> | |
#include <stdlib.h> | |
#include <minix/com.h> | |
#include <minix/u64.h> | |
#include "buf.h" | |
#include "inode.h" | |
#include "super.h" | |
#include "const.h" | |
static block_t alloc_block_bit(struct super_block *sp, block_t origin, | |
struct inode *rip); | |
void discard_preallocated_blocks(struct inode *rip) | |
{ | |
int i; | |
if (rip) { | |
rip->i_prealloc_count = rip->i_prealloc_index = 0; | |
for (i = 0; i < EXT2_PREALLOC_BLOCKS; i++) { | |
if (rip->i_prealloc_blocks[i] != NO_BLOCK) { | |
free_block(rip->i_sp, rip->i_prealloc_blocks[i]); | |
rip->i_prealloc_blocks[i] = NO_BLOCK; | |
} | |
} | |
return; | |
} | |
for(rip = &inode[0]; rip < &inode[NR_INODES]; rip++) { | |
rip->i_prealloc_count = rip->i_prealloc_index = 0; | |
rip->i_preallocation = 0; /* forbid preallocation */ | |
for (i = 0; i < EXT2_PREALLOC_BLOCKS; i++) { | |
if (rip->i_prealloc_blocks[i] != NO_BLOCK) { | |
free_block(rip->i_sp, rip->i_prealloc_blocks[i]); | |
rip->i_prealloc_blocks[i] = NO_BLOCK; | |
} | |
} | |
} | |
} | |
block_t alloc_block(struct inode *rip, block_t block) | |
{ | |
block_t goal; | |
block_t b; | |
struct super_block *sp = rip->i_sp; | |
if (sp->s_rd_only) | |
panic("can't alloc block on read-only filesys."); | |
if (!opt.use_reserved_blocks && | |
sp->s_free_blocks_count <= sp->s_r_blocks_count) { | |
discard_preallocated_blocks(NULL); | |
} else if (sp->s_free_blocks_count <= EXT2_PREALLOC_BLOCKS) { | |
discard_preallocated_blocks(NULL); | |
} | |
if (!opt.use_reserved_blocks && | |
sp->s_free_blocks_count <= sp->s_r_blocks_count) { | |
return(NO_BLOCK); | |
} else if (sp->s_free_blocks_count == 0) { | |
return(NO_BLOCK); | |
} | |
if (block != NO_BLOCK) { | |
goal = block; | |
if (rip->i_preallocation && rip->i_prealloc_count > 0) { | |
b = rip->i_prealloc_blocks[rip->i_prealloc_index]; | |
if (block == b || (block + 1) == b) { | |
rip->i_prealloc_blocks[rip->i_prealloc_index] = NO_BLOCK; | |
rip->i_prealloc_count--; | |
rip->i_prealloc_index++; | |
if (rip->i_prealloc_index >= EXT2_PREALLOC_BLOCKS) { | |
rip->i_prealloc_index = 0; | |
ASSERT(rip->i_prealloc_count == 0); | |
} | |
rip->i_bsearch = b; | |
return b; | |
} else { | |
rip->i_preallocation = 0; | |
discard_preallocated_blocks(rip); | |
} | |
} | |
} else { | |
int group = (rip->i_num - 1) / sp->s_inodes_per_group; | |
goal = sp->s_blocks_per_group*group + sp->s_first_data_block; | |
} | |
if (rip->i_preallocation && rip->i_prealloc_count) { | |
ext2_debug("There're preallocated blocks, but they're\ | |
neither used or freed!"); | |
} | |
b = alloc_block_bit(sp, goal, rip); | |
if (b != NO_BLOCK) | |
rip->i_bsearch = b; | |
return b; | |
} | |
static void check_block_number(block_t block, struct super_block *sp, | |
struct group_desc *gd); | |
static block_t alloc_block_bit(sp, goal, rip) | |
struct super_block *sp; /* the filesystem to allocate from */ | |
block_t goal; /* try to allocate near this block */ | |
struct inode *rip; /* used for preallocation */ | |
{ | |
block_t block = NO_BLOCK; /* allocated block */ | |
int word; /* word in block bitmap */ | |
bit_t bit = -1; | |
int group; | |
char update_bsearch = FALSE; | |
int i; | |
if (goal >= sp->s_blocks_count || | |
(goal < sp->s_first_data_block && goal != 0)) { | |
goal = sp->s_bsearch; | |
} | |
if (goal <= sp->s_bsearch) { | |
goal = sp->s_bsearch; | |
update_bsearch = TRUE; | |
} | |
word = ((goal - sp->s_first_data_block) % sp->s_blocks_per_group) | |
/ FS_BITCHUNK_BITS; | |
group = (goal - sp->s_first_data_block) / sp->s_blocks_per_group; | |
for (i = 0; i <= sp->s_groups_count; i++, group++) { | |
struct buf *bp; | |
struct group_desc *gd; | |
if (group >= sp->s_groups_count) | |
group = 0; | |
gd = get_group_desc(group); | |
if (gd == NULL) | |
panic("can't get group_desc to alloc block"); | |
if (gd->free_blocks_count == 0) { | |
word = 0; | |
continue; | |
} | |
bp = get_block(sp->s_dev, gd->block_bitmap, NORMAL); | |
if (rip->i_preallocation && | |
gd->free_blocks_count >= (EXT2_PREALLOC_BLOCKS * 4) ) { | |
if (rip->i_prealloc_count != 0) { | |
discard_preallocated_blocks(rip); | |
ext2_debug("warning, discarding previously preallocated\ | |
blocks! It had to be done by another code."); | |
} | |
ASSERT(rip->i_prealloc_count == 0); | |
ASSERT(EXT2_PREALLOC_BLOCKS == sizeof(char)*CHAR_BIT); | |
bit = setbyte(b_bitmap(bp), sp->s_blocks_per_group); | |
if (bit != -1) { | |
block = bit + sp->s_first_data_block + | |
group * sp->s_blocks_per_group; | |
check_block_number(block, sp, gd); | |
for (i = 1; i < EXT2_PREALLOC_BLOCKS; i++) { | |
check_block_number(block + i, sp, gd); | |
rip->i_prealloc_blocks[i-1] = block + i; | |
} | |
rip->i_prealloc_index = 0; | |
rip->i_prealloc_count = EXT2_PREALLOC_BLOCKS - 1; | |
lmfs_markdirty(bp); | |
put_block(bp, MAP_BLOCK); | |
gd->free_blocks_count -= EXT2_PREALLOC_BLOCKS; | |
sp->s_free_blocks_count -= EXT2_PREALLOC_BLOCKS; | |
lmfs_blockschange(sp->s_dev, -EXT2_PREALLOC_BLOCKS); | |
group_descriptors_dirty = 1; | |
return block; | |
} | |
} | |
bit = setbit(b_bitmap(bp), sp->s_blocks_per_group, word); | |
if (bit == -1) { | |
if (word == 0) { | |
panic("ext2: allocator failed to allocate a bit in bitmap\ | |
with free bits."); | |
} else { | |
word = 0; | |
continue; | |
} | |
} | |
block = sp->s_first_data_block + group * sp->s_blocks_per_group + bit; | |
check_block_number(block, sp, gd); | |
lmfs_markdirty(bp); | |
put_block(bp, MAP_BLOCK); | |
gd->free_blocks_count--; | |
sp->s_free_blocks_count--; | |
lmfs_blockschange(sp->s_dev, -1); | |
group_descriptors_dirty = 1; | |
if (update_bsearch && block != -1 && block != NO_BLOCK) { | |
sp->s_bsearch = block; | |
} | |
return block; | |
} | |
return block; | |
} | |
void free_block(struct super_block *sp, bit_t bit_returned) | |
{ | |
int group; /* group number of bit_returned */ | |
int bit; /* bit_returned number within its group */ | |
struct buf *bp; | |
struct group_desc *gd; | |
if (sp->s_rd_only) | |
panic("can't free bit on read-only filesys."); | |
if (bit_returned >= sp->s_blocks_count || | |
bit_returned < sp->s_first_data_block) | |
panic("trying to free block %d beyond blocks scope.", | |
bit_returned); | |
group = (bit_returned - sp->s_first_data_block) / sp->s_blocks_per_group; | |
bit = (bit_returned - sp->s_first_data_block) % sp->s_blocks_per_group; | |
gd = get_group_desc(group); | |
if (gd == NULL) | |
panic("can't get group_desc to alloc block"); | |
if (bit_returned == gd->inode_bitmap || bit_returned == gd->block_bitmap | |
|| (bit_returned >= gd->inode_table | |
&& bit_returned < (gd->inode_table + sp->s_itb_per_group))) { | |
ext2_debug("ext2: freeing non-data block %d\n", bit_returned); | |
panic("trying to deallocate \ | |
system/control block, hardly poke author."); | |
} | |
bp = get_block(sp->s_dev, gd->block_bitmap, NORMAL); | |
if (unsetbit(b_bitmap(bp), bit)) | |
panic("Tried to free unused block", bit_returned); | |
lmfs_markdirty(bp); | |
put_block(bp, MAP_BLOCK); | |
gd->free_blocks_count++; | |
sp->s_free_blocks_count++; | |
lmfs_blockschange(sp->s_dev, 1); | |
group_descriptors_dirty = 1; | |
if (bit_returned < sp->s_bsearch) | |
sp->s_bsearch = bit_returned; | |
} | |
static void check_block_number(block_t block, struct super_block *sp, | |
struct group_desc *gd) | |
{ | |
if (block == gd->inode_bitmap || block == gd->block_bitmap || | |
(block >= gd->inode_table | |
&& block < (gd->inode_table + sp->s_itb_per_group))) { | |
ext2_debug("ext2: allocating non-data block %d\n", block); | |
panic("ext2: block allocator tryed to return \ | |
system/control block, poke author.\n"); | |
} | |
if (block >= sp->s_blocks_count) { | |
panic("ext2: allocator returned blocknum greater, than \ | |
total number of blocks.\n"); | |
} | |
}]]></text> | |
<tokens> | |
</tokens> | |
<concepts> | |
<concept id="1991219" weight="0.46036943793296814">JFFS2</concept> | |
<concept id="437471" weight="0.5421051979064941">Block Island</concept> | |
<concept id="1103580" weight="0.4406166672706604">Cinder block</concept> | |
<concept id="572854" weight="0.5239951014518738">H&R Block</concept> | |
<concept id="512614" weight="0.49463191628456116">USS Block Island (CVE-106)</concept> | |
<concept id="631107" weight="0.45932334661483765">City Block</concept> | |
<concept id="1716537" weight="0.4348750114440918">Gauge blocks</concept> | |
<concept id="981057" weight="0.44125351309776306">Minix file system</concept> | |
<concept id="55347" weight="0.4211011826992035">Hierarchical File System</concept> | |
<concept id="1251844" weight="0.5010773539543152">The Block (Sydney)</concept> | |
</concepts> | |
</sourceCode> | |
</file> |
In computers:
Delayed allocation
Block allocation map
File allocation table
IP address allocation
Memory allocation, see memory management
C++ allocators
No-write allocation (cache)
Register allocation
- http://en.wikipedia.org/wiki/Blocks
Technology[edit]
Block (data storage), the practice of storing electronic data in equally-sized units
Block (Internet), technical measures to restrict users' access to certain internet resources
Block (programming), a group of declarations and statements treated as a unit
Block (telecommunications), a unit of data transmission
Block-level element in the HTML markup language
Block Number (aircraft), a method of differentiating between groups of aircraft of the same type that have minor modifications
Blocks (C language extension), an extension to the C programming language designed to support parallel programming
Boom Blox, a 2008 video game for the Wii console from EA, previously known as Blocks
Block elements, a class of Box-drawing characters
Unicode block, a named range of codepoints in Unicode
TFIDF result of heading description