-
-
Save yyyyyyuanfei/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