Esempio n. 1
0
File: alloc.c Progetto: Jimx-/lyos
PUBLIC block_t ext2_alloc_block(ext2_inode_t * pin)
{
    ext2_superblock_t * psb = pin->i_sb;
    block_t block = 0;
    
    if (psb->sb_readonly) {
        printl("ext2fs: alloc_block: try to allocate block on readonly filesystem!");
        err_code = EROFS;
        return 0;
    }

    int group = (pin->i_num - 1) / psb->sb_inodes_per_group;
	block_t goal = psb->sb_blocks_per_group*group + psb->sb_first_data_block;
    off_t startp= ((goal - psb->sb_first_data_block) % psb->sb_blocks_per_group)
			/ (sizeof(bitchunk_t) * CHAR_BIT);

    int i;
    for (i = 0; i <= psb->sb_groups_count; i++, group++) {
	    ext2_buffer_t * pb;
	    ext2_bgdescriptor_t * gd;

	    if (group >= psb->sb_groups_count)
		    group = 0;

	    gd = get_ext2_group_desc(psb, group);
	    if (gd == NULL)
		    panic("ext2fs: alloc_block: can't get block group descriptor to alloc block");

	    if (gd->free_blocks_count == 0) {
		    startp = 0;
		    continue;
	    }

	    pb = ext2_get_buffer(psb->sb_dev, gd->block_bitmap);

        int bit = ext2_setbit((bitchunk_t*)pb->b_data, psb->sb_blocks_per_group, startp);

        if (bit == -1) {
            if (startp == 0) {
                panic("ext2fs: alloc_block: failed to allocate bit in bitmap with free bits");
            } else {
                startp = 0;
                continue;
            }
        }

	    block = psb->sb_first_data_block + group * psb->sb_blocks_per_group + bit;

        pb->b_dirt = 1;
	    ext2_put_buffer(pb);

	    gd->free_blocks_count--;
	    psb->sb_free_blocks_count--;
	    ext2_update_group_desc(psb, group);

	    return block;
    }

    return block;
}
Esempio n. 2
0
File: alloc.c Progetto: Jimx-/lyos
/**
 * Allocate a bit in the inode bitmap.
 * @param  psb    Ptr to the superblock.
 * @param  parent The parent directory.
 * @param  mode   Inode mode.
 * @return        Inode number.
 */
PRIVATE int ext2_alloc_inode_bit(ext2_superblock_t * psb, ext2_inode_t * parent, mode_t mode)
{
    /* Can't allocate inode on readonly filesystem */
    if (psb->sb_readonly) {
        panic("ext2fs: ext2_alloc_inode_bit: can't allocate inode on readonly filesystem.");
    }

    ext2_bgdescriptor_t * group = NULL;
    ext2_bgdescriptor_t * bgdesc = psb->sb_bgdescs;
    int i;
    for (i = 0; i < psb->sb_groups_count; i++, bgdesc++) {
        if (bgdesc->free_inodes_count > 0) {
            group = bgdesc;
            break;
        }
    }

    /* No space */
    if (group == NULL) return 0;
    ext2_buffer_t * pb = ext2_get_buffer(psb->sb_dev, group->inode_bitmap);
    int bit = ext2_setbit((bitchunk_t*)(pb->b_data), psb->sb_inodes_per_group, 0);

    ino_t num = (group - psb->sb_bgdescs) * psb->sb_inodes_per_group + bit + 1;

    if (num > psb->sb_inodes_count) {
        panic("ext2fs: ext2_alloc_inode_bit: num > total number of inodes.");
    }
    if (num < psb->sb_first_ino) {
        panic("ext2fs: ext2_alloc_inode_bit: try to allocate reserved inode.");
    }

    pb->b_dirt = 1;
    ext2_put_buffer(pb);

    psb->sb_free_inodes_count--;
    group->free_inodes_count--;
    
    /* write back the changes */
    write_ext2_super_block(psb->sb_dev);
    ext2_update_group_desc(psb, group - psb->sb_bgdescs);

    return num;
}
Esempio n. 3
0
static uint32_t ext2_alloc_block_bit(struct nas *nas, uint32_t goal) { /* try to allocate near this block */
	uint32_t block;	/* allocated block */
	int word;			/* word in block bitmap */
	uint32_t bit;
	int group;
	char update_bsearch = 0;
	int i;
	struct ext2_gd *gd;

	struct ext2_file_info *fi;
	struct ext2_fs_info *fsi;

	fi = nas->fi->privdata;
	fsi = nas->fs->fsi;

	block = NO_BLOCK;
	bit = -1;

	if (goal >= fsi->e2sb.s_blocks_count ||
		(goal < fsi->e2sb.s_first_data_block && goal != 0)) {
		goal = fsi->s_bsearch;
	}

	if (goal <= fsi->s_bsearch) {
		/* No reason to search in a place with no free blocks */
		goal = fsi->s_bsearch;
		update_bsearch = DIRTY;
	}

	/* Figure out where to start the bit search. */
	word = ((goal - fsi->e2sb.s_first_data_block) %
			fsi->e2sb.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 - fsi->e2sb.s_first_data_block) / fsi->e2sb.s_blocks_per_group;
	for (i = 0; i <= fsi->s_groups_count; i++, group++) {

		if (group >= fsi->s_groups_count) {
			group = 0;
		}
		gd = ext2_get_group_desc(group, fsi);
		if (gd->free_blocks_count == 0) {
			word = 0;
			continue;
		}

		ext2_read_sector(nas, fi->f_buf, 1, gd->block_bitmap);

		bit = ext2_setbit(b_bitmap(fi->f_buf), fsi->e2sb.s_blocks_per_group, word);
		if (-1 == bit) {
			if (0 == word) {
				/* allocator failed to allocate a bit in bitmap	with free bits.*/
				return 0;
			} else {
				word = 0;
				continue;
			}
		}

		block = fsi->e2sb.s_first_data_block + group * fsi->e2sb.s_blocks_per_group + bit;
		if (ext2_check_block_number(block, fsi, gd)) {
			return 0;
		}

		ext2_write_sector(nas, fi->f_buf, 1, gd->block_bitmap);

		fsi->e2sb.s_free_blocks_count--;
		ext2_write_sblock(nas);
		gd->free_blocks_count--;
		ext2_write_gdblock(nas);

		if (update_bsearch && block != -1 && block != NO_BLOCK) {
			/* We searched from the beginning, update bsearch. */
			fsi->s_bsearch = block;
		}

		return block;
	}

	return block;
}