Exemple #1
0
static void sibling_extent(ffs_sort_t *entry, uint32_t size_sib_entry, block_info_t *block_info){

	f3s_extptr_t		next,
						dir_next;
	f3s_head_t			dir_extent;
	uint32_t			pos,
						nbytes;
	uint16_t			extent_flags;

	//
	// Setup 'next' pointer to new extent
	//
	
	dir_next.logi_unit = swap16(target_endian,block_info->block_index + 1);			
	dir_next.index =  swap16(target_endian,block_info->extent_index);

	//
	// now write the entry to the correct place 
	// 'next' entry is 
	//

	pos = entry->extent_pos; 

	lseek(flashimage, pos, SEEK_SET);

	if (read(flashimage,&dir_extent,sizeof(dir_extent)) != sizeof(dir_extent))
		mk_flash_exit("read failed: %s\n",strerror(errno));

	dir_extent.status &= swap16(target_endian,~F3S_EXT_NO_NEXT);
	dir_extent.next = dir_next;
	
	lseek(flashimage, pos, SEEK_SET);

	memcpy(blk_buffer_ptr,&dir_extent, sizeof(dir_extent));

	if ((nbytes = write(flashimage,blk_buffer_ptr,sizeof(dir_extent))) !=sizeof(dir_extent))
		mk_flash_exit("write failed: %s\n",strerror(errno));

	entry->status |=FFS_SORT_ENTRY_SET;

	//
	//	write extent for the new entry
	//

	extent_flags = ~F3S_EXT_TYPE & 0xff00;
	extent_flags |=	(F3S_EXT_DIR | F3S_EXT_NO_NEXT | F3S_EXT_NO_SUPER | F3S_EXT_ALLOC | F3S_EXT_LAST | F3S_EXT_NO_SPLIT);

	next.logi_unit = FNULL;
	next.index = FNULL;
	write_extent(block_info, next, extent_flags, size_sib_entry);
}
Exemple #2
0
/*
 * update_ext()
 *
 * Given a (struct hfs_fork) write an extent record back to disk.
 */
static void update_ext(struct hfs_fork *fork, struct hfs_extent *ext)
{
    struct hfs_ext_key target;
    struct hfs_brec brec;

    if (ext->start) {
        build_key(&target, fork, ext->start);

        if (!hfs_bfind(&brec, fork->entry->mdb->ext_tree,
                       HFS_BKEY(&target), HFS_BFIND_WRITE)) {
            write_extent(brec.data, ext);
            hfs_brec_relse(&brec, NULL);
        }
    }
}
Exemple #3
0
/*
 * new_extent()
 *
 * Description:
 *   Adds a new extent record to a fork, extending its physical length.
 * Input Variable(s):
 *   struct hfs_fork *fork: the fork to extend
 *   struct hfs_extent *ext: the current last extent for 'fork'
 *   hfs_u16 ablock: the number of allocation blocks in 'fork'.
 *   hfs_u16 start: first allocation block to add to 'fork'.
 *   hfs_u16 len: the number of allocation blocks to add to 'fork'.
 *   hfs_u32 ablksz: number of sectors in an allocation block.
 * Output Variable(s):
 *   NONE
 * Returns:
 *   (struct hfs_extent *) the new extent or NULL
 * Preconditions:
 *   'fork' points to a valid (struct hfs_fork)
 *   'ext' point to a valid (struct hfs_extent) which is the last in 'fork'
 *   'ablock', 'start', 'len' and 'ablksz' are what they claim to be.
 * Postconditions:
 *   If NULL is returned then no changes have been made to 'fork'.
 *   If the return value is non-NULL that it is the extent that has been
 *   added to 'fork' both in memory and on disk.  The 'psize' field of
 *   'fork' has been updated to reflect the new physical size.
 */
static struct hfs_extent *new_extent(struct hfs_fork *fork,
                                     struct hfs_extent *ext,
                                     hfs_u16 ablock, hfs_u16 start,
                                     hfs_u16 len, hfs_u16 ablksz)
{
    struct hfs_raw_extent raw;
    struct hfs_ext_key key;
    int error;

    if (fork->entry->cnid == htonl(HFS_EXT_CNID)) {
        /* Limit extents tree to the record in the MDB */
        return NULL;
    }

    if (!HFS_NEW(ext->next)) {
        return NULL;
    }
    ext->next->prev = ext;
    ext->next->next = NULL;
    ext = ext->next;
    relse_ext(ext->prev);

    ext->start = ablock;
    ext->block[0] = start;
    ext->length[0] = len;
    ext->block[1] = 0;
    ext->length[1] = 0;
    ext->block[2] = 0;
    ext->length[2] = 0;
    ext->end = ablock + len - 1;
    ext->count = 1;

    write_extent(&raw, ext);

    build_key(&key, fork, ablock);

    error = hfs_binsert(fork->entry->mdb->ext_tree,
                        HFS_BKEY(&key), &raw, sizeof(raw));
    if (error) {
        ext->prev->next = NULL;
        HFS_DELETE(ext);
        return NULL;
    }
    set_cache(fork, ext);
    return ext;
}
Exemple #4
0
static void child_extent(ffs_sort_t *entry, uint32_t size_child_entry, block_info_t *block_info){

	f3s_extptr_t		first,
						next;
	uint32_t			pos,
						nbytes;
	uint16_t			extent_flags;

	//
	// Setup 'first' pointer to new extent
	//
	
	first.logi_unit = swap16(target_endian,block_info->block_index + 1);	
	first.index =  swap16(target_endian,block_info->extent_index);

	//
	// now write the entry to the correct place 
    // 'first' entry is 4 bytes offset into the f3s_dirent_t structure
	//
	
	pos = entry->entry_pos + sizeof(int);


	memcpy(blk_buffer_ptr,&first, sizeof(first));

	lseek(flashimage,pos,SEEK_SET);

	if ((nbytes = write(flashimage,blk_buffer_ptr,sizeof(first))) !=sizeof(first))
		mk_flash_exit("write failed: %s\n",strerror(errno));

	entry->status |=FFS_SORT_ENTRY_SET;

	//
	//	write extent for the new entry
	//

	extent_flags = ~F3S_EXT_TYPE & 0xff00;
	extent_flags |=	(F3S_EXT_DIR | F3S_EXT_NO_NEXT | F3S_EXT_NO_SUPER | F3S_EXT_ALLOC | F3S_EXT_LAST | F3S_EXT_NO_SPLIT);

	next.logi_unit = FNULL;
	next.index = FNULL;

	write_extent(block_info, next, extent_flags, size_child_entry);
}
Exemple #5
0
static void first_file_extent(uint32_t position, uint32_t size_file_entry, block_info_t *block_info){

	f3s_extptr_t		next,
						first;
	uint32_t			nbytes;
	uint16_t			extent_flags;
	
	

	//
	// Setup extent pointer to new extent
	//
	
	first.logi_unit = swap16(target_endian,block_info->block_index + 1);			
	first.index = swap16(target_endian,block_info->extent_index);

	//
	// write the update to the correct place 
	//
	

	lseek(flashimage, position, SEEK_SET);

	memcpy(blk_buffer_ptr, &first, sizeof(first)); 

	if ((nbytes = write(flashimage,blk_buffer_ptr,sizeof(first))) !=sizeof(first))
		mk_flash_exit("write failed: %s\n",strerror(errno));

	//
	//	write extent for the new entry
	//

	extent_flags = ~F3S_EXT_TYPE & 0xff00;
	extent_flags |=	(F3S_EXT_FILE | F3S_EXT_NO_NEXT | F3S_EXT_NO_SUPER | F3S_EXT_ALLOC | F3S_EXT_LAST | F3S_EXT_NO_SPLIT);

	next.logi_unit = FNULL;
	next.index = FNULL;
	write_extent(block_info, next, extent_flags, size_file_entry);
}
Exemple #6
0
static block_info_t *init_block(int block_size, uint16_t unit_flags){
    
	f3s_extptr_t		extptr,
						next;
	f3s_unit_t			unit;
	block_info_t **		binfo;
	uint32_t			position;
	uint16_t			extent_flags;
	uint8_t				*init_blk_ptr;
    
	//
	//	setup the block allocation structure
	//

	binfo = realloc (block_info, (block_index + 1) * sizeof(block_info_t *));
	if (binfo == NULL) return (NULL);
	block_info = binfo;

	block_info[block_index] = (block_info_t *)malloc(sizeof(block_info_t));
	if (block_info[block_index] == NULL)
		mk_flash_exit("malloc failed: %s\n", strerror(errno));	

	block_info[block_index]->block_index = block_index;
	block_info[block_index]->available_space = block_size;
	block_info[block_index]->offset_top = 0;
	block_info[block_index]->block_size = block_size;
	block_info[block_index]->offset_bottom = block_size;
	block_info[block_index]->extent_index = 0;
	block_info[block_index]->next = NULL;

	// 
	//	every block will contain a unit header information  
	//	structure
	//

	unit.status = swap16(target_endian,unit_flags);
	unit.struct_size = swap16(target_endian,sizeof(unit));
	unit.endian = target_endian ? 'B' : 'L';
	unit.age = 0;					//	hard coded, does not apply here
        if (unit_flags&F3S_UNIT_NO_LOGI)
	 unit.logi = ~0;
        else
	 unit.logi = swap16(target_endian,block_index+1);
	unit.unit_pow2 = swap16(target_endian,calc_log2(block_size));
	unit.reserve = 0xffff;
	unit.erase_count = 0;			//	hard coded, does not apply here

	//
	//	setup the f3s_extptr_t to boot structure
	//	these values are hard coded since they should not change
	//

	extptr.logi_unit = swap16(target_endian,F3S_FIRST_LOGI);
	extptr.index = swap16(target_endian,F3S_BOOT_INDEX);

	unit.boot = extptr;

	//
	//	create a memory region to build our block
	//	

	if ((init_blk_ptr = (char *) malloc(block_size)) == NULL)
		mk_flash_exit("memory allocation failed: %s\n",strerror(errno));

	//
	//	initialize block
	//

	memset(init_blk_ptr,0xff,block_size);

	//
	// the unit header info is written at the start of each block
	//

	memcpy(init_blk_ptr,&unit,sizeof(unit));

	position = (block_info[block_index]->block_index) * block_info[block_index]->block_size;

	lseek(flashimage, position,SEEK_SET);

	if (write(flashimage,init_blk_ptr,block_size) != block_size)
		mk_flash_exit("write failed: %s\n",strerror(errno));
	

	//
	//	write extent information
	//
	
	next.logi_unit = FNULL;
	next.index = FNULL;
	
	extent_flags = ~F3S_EXT_TYPE & 0xff00;
	extent_flags |=	(F3S_EXT_SYS | F3S_EXT_NO_NEXT | F3S_EXT_NO_SUPER | F3S_EXT_NO_SPLIT | F3S_EXT_ALLOC |F3S_EXT_LAST);

	write_extent(block_info[block_index], next, extent_flags, sizeof(unit));
                                       
	//
	//	update block information structure
	//

	block_info[block_index]->available_space -= sizeof(unit);
	block_info[block_index]->offset_top = sizeof(unit);

	//
	//	free our malloc'd memory
	//

	block_index++;

	free(init_blk_ptr);

	return block_info[block_index-1];
}
Exemple #7
0
static void write_boot_record(block_info_t *block_info, uint16_t spare, ffs_sort_t *sort)
{ 
	f3s_boot_t			boot_record;
	f3s_extptr_t		root,
						next;
	uint32_t			nbytes, 
						namelen,
						size,
						position;
	uint16_t			boot_flags,
						extent_flags;

	//
	//	setup the boot record structure
	//

	boot_flags = ~F3S_BOOT_NO_INDEX;
	boot_record.status = swap16(target_endian,boot_flags);
	boot_record.struct_size = swap16(target_endian,sizeof(boot_record));
	memcpy(&boot_record.sig, F3S_SIG_STRING, F3S_SIG_SIZE);
	boot_record.rev_major = F3S_REV_MAJOR;
	boot_record.rev_minor = F3S_REV_MINOR;

	//	
	//	offset information needed by the filesystem manager
	//

	boot_record.unit_index = 0;

	//
	//	to be determined once the filesystem is completed
	//

	boot_record.unit_total = 0;

	boot_record.unit_spare = swap16(target_endian,spare);
  	
	//
	//	these two entries are hard coded for now
	//

	boot_record.align_pow2 = swap16(target_endian,2);
	boot_record.xip_pow2 = swap16(target_endian,12);

	//
	//	setup root extent pointer
	//

	root.logi_unit = swap16(target_endian,F3S_FIRST_LOGI);
	root.index = swap16(target_endian,F3S_ROOT_INDEX);	

	boot_record.root = root;

	
	memcpy(blk_buffer_ptr,&boot_record,sizeof(boot_record));

	position = block_info->offset_top;
	
	lseek(flashimage,position,SEEK_SET);
	
	if((nbytes=write(flashimage,blk_buffer_ptr,sizeof(boot_record))) != 
			sizeof(boot_record))
		mk_flash_exit("write failed: %s\n",strerror(errno));

	//
	//	call extent header routine for boot structure
	//
	
	next.logi_unit = FNULL;
	next.index = FNULL;

	extent_flags = ~F3S_EXT_TYPE & 0xff00;
	extent_flags |=	(F3S_EXT_SYS | F3S_EXT_NO_NEXT | F3S_EXT_NO_SUPER | F3S_EXT_NO_SPLIT | F3S_EXT_ALLOC | F3S_EXT_LAST);
	write_extent(block_info, next,  extent_flags, sizeof(boot_record));

	//
	//	update block_info structures
	//

	block_info->available_space -= sizeof(boot_record);
	block_info->offset_top +=  sizeof(boot_record);

	//
	//	call extent header routine for root structure (dirent)	
	//

	extent_flags = (extent_flags & ~F3S_EXT_SYS) | F3S_EXT_DIR; 
	
	//
	//	calculate the size of the root name (can't assume /)
	//

	namelen = strlen(sort->name) + 1;
	size = sizeof(f3s_dirent_t) + F3S_NAME_ALIGN(namelen) + sizeof(f3s_stat_t);
	write_extent(block_info, next, extent_flags, size);
}