Last active
January 4, 2016 05:19
-
-
Save yyyyyyuanfei/8574221 to your computer and use it in GitHub Desktop.
ESA result on minix file system balloc.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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> |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
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
no result.