Пример #1
0
int fs_format(fs_t* fs)
{
   if (fs == NULL) {
      printf("[fs] argument is null.\n");
      return -1;
   }

   // erase all blocks
   char null_block[BLOCK_SIZE];
   memset(null_block,0,sizeof(null_block));
   for (int i = 0; i < block_num_blocks(fs->blocks); i++) {
      block_write(fs->blocks,i,null_block);
   }

   // reserve file system meta data blocks
   BMAP_SET(fs->blk_bmap,0);
   BMAP_SET(fs->blk_bmap,1);
   for (int i = 0; i < ITAB_NUM_BLKS; i++) {
      BMAP_SET(fs->blk_bmap,i+2);
   }

   // reserve inodes 0 (will never be used) and 1 (the root)
   BMAP_SET(fs->inode_bmap,0);
   BMAP_SET(fs->inode_bmap,1);
   fsi_inode_init(&fs->inode_tab[1],FS_DIR);

   // save the file system metadata
   fsi_store_fsdata(fs);
   return 0;
}
Пример #2
0
static int cbm_write(struct exfat_dev* dev)
{
	uint32_t allocated_clusters =
			DIV_ROUND_UP(cbm.get_size(), get_cluster_size()) +
			DIV_ROUND_UP(uct.get_size(), get_cluster_size()) +
			DIV_ROUND_UP(rootdir.get_size(), get_cluster_size());
	size_t bitmap_size = DIV_ROUND_UP(allocated_clusters, CHAR_BIT);
	bitmap_t* bitmap = malloc(BMAP_SIZE(bitmap_size));
	size_t i;

	if (bitmap == NULL)
	{
		exfat_error("failed to allocate bitmap of %zu bytes",
				BMAP_SIZE(bitmap_size));
		return 1;
	}
	memset(bitmap, 0, BMAP_SIZE(bitmap_size));

	for (i = 0; i < bitmap_size * CHAR_BIT; i++)
		if (i < allocated_clusters)
			BMAP_SET(bitmap, i);
	if (exfat_write(dev, bitmap, bitmap_size) < 0)
	{
		free(bitmap);
		exfat_error("failed to write bitmap of %zu bytes", bitmap_size);
		return 1;
	}
	free(bitmap);
	return 0;
}
Пример #3
0
/*
 * Identify memory proximity domains and hot-remove capabilities.
 * Fill node memory chunk list structure.
 */
static void __init parse_memory_affinity_structure (char *sratp)
{
	unsigned long long paddr, size;
	unsigned long start_pfn, end_pfn;
	u8 pxm;
	struct node_memory_chunk_s *p, *q, *pend;
	struct acpi_srat_mem_affinity *memory_affinity =
			(struct acpi_srat_mem_affinity *) sratp;

	if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0)
		return;		/* empty entry */

	pxm = memory_affinity->proximity_domain & 0xff;

	/* mark this node as "seen" in node bitmap */
	BMAP_SET(pxm_bitmap, pxm);

	/* calculate info for memory chunk structure */
	paddr = memory_affinity->base_address;
	size = memory_affinity->length;

	start_pfn = paddr >> PAGE_SHIFT;
	end_pfn = (paddr + size) >> PAGE_SHIFT;


	if (num_memory_chunks >= MAXCHUNKS) {
		printk("Too many mem chunks in SRAT. Ignoring %lld MBytes at %llx\n",
			size/(1024*1024), paddr);
		return;
	}

	/* Insertion sort based on base address */
	pend = &node_memory_chunk[num_memory_chunks];
	for (p = &node_memory_chunk[0]; p < pend; p++) {
		if (start_pfn < p->start_pfn)
			break;
	}
	if (p < pend) {
		for (q = pend; q >= p; q--)
			*(q + 1) = *q;
	}
	p->start_pfn = start_pfn;
	p->end_pfn = end_pfn;
	p->pxm = pxm;

	num_memory_chunks++;

	printk("Memory range 0x%lX to 0x%lX (type 0x%X) in proximity domain 0x%02X %s\n",
		start_pfn, end_pfn,
		memory_affinity->memory_type,
		pxm,
		((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
		 "enabled and removable" : "enabled" ) );
}
static cluster_t find_bit_and_set(uint8_t* bitmap, cluster_t start,
		cluster_t end)
{
	const cluster_t mid_start = (start + 7) / 8 * 8;
	const cluster_t mid_end = end / 8 * 8;
	cluster_t c;
	cluster_t byte;

	for (c = start; c < mid_start; c++)
		if (BMAP_GET(bitmap, c) == 0)
		{
			BMAP_SET(bitmap, c);
			return c + EXFAT_FIRST_DATA_CLUSTER;
		}

	for (byte = mid_start / 8; byte < mid_end / 8; byte++)
		if (bitmap[byte] != 0xff)
		{
			cluster_t bit;

			for (bit = 0; bit < 8; bit++)
				if (!(bitmap[byte] & (1u << bit)))
				{
					bitmap[byte] |= (1u << bit);
					return byte * 8 + bit + EXFAT_FIRST_DATA_CLUSTER;
				}
		}

	for (c = mid_end; c < end; c++)
		if (BMAP_GET(bitmap, c) == 0)
		{
			BMAP_SET(bitmap, c);
			return c + EXFAT_FIRST_DATA_CLUSTER;
		}

	return EXFAT_CLUSTER_END;
}
Пример #5
0
/* Identify CPU proximity domains */
static void __init parse_cpu_affinity_structure(char *p)
{
	struct acpi_srat_cpu_affinity *cpu_affinity =
				(struct acpi_srat_cpu_affinity *) p;

	if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0)
		return;		/* empty entry */

	/* mark this node as "seen" in node bitmap */
	BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo);

	apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo;

	printk("CPU 0x%02X in proximity domain 0x%02X\n",
		cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo);
}
Пример #6
0
static cluster_t find_bit_and_set(uint8_t* bitmap, size_t start, size_t end)
{
	const size_t start_index = start / 8;
	const size_t end_index = DIV_ROUND_UP(end, 8);
	size_t i;
	size_t c;

	for (i = start_index; i < end_index; i++)
	{
		if (bitmap[i] == 0xff)
			continue;
		for (c = MAX(i * 8, start); c < MIN((i + 1) * 8, end); c++)
			if (BMAP_GET(bitmap, c) == 0)
			{
				BMAP_SET(bitmap, c);
				return c + EXFAT_FIRST_DATA_CLUSTER;
			}
	}
	return EXFAT_CLUSTER_END;
}
Пример #7
0
/* Identify CPU proximity domains */
void __init
acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *cpu_affinity)
{
	if (srat_disabled())
		return;
	if (cpu_affinity->header.length !=
	     sizeof(struct acpi_srat_cpu_affinity)) {
		bad_srat();
		return;
	}

	if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0)
		return;		/* empty entry */

	/* mark this node as "seen" in node bitmap */
	BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo);

	apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo;

	printk(KERN_DEBUG "CPU %02x in proximity domain %02x\n",
		cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo);
}
Пример #8
0
static cluster_t find_bit_and_set(bitmap_t* bitmap, size_t start, size_t end)
{
	const size_t start_index = start / sizeof(bitmap_t) / 8;
	const size_t end_index = DIV_ROUND_UP(end, sizeof(bitmap_t) * 8);
	size_t i;
	size_t start_bitindex;
	size_t end_bitindex;
	size_t c;

	for (i = start_index; i < end_index; i++)
	{
		if (bitmap[i] == ~((bitmap_t) 0))
			continue;
		start_bitindex = MAX(i * sizeof(bitmap_t) * 8, start);
		end_bitindex = MIN((i + 1) * sizeof(bitmap_t) * 8, end);
		for (c = start_bitindex; c < end_bitindex; c++)
			if (BMAP_GET(bitmap, c) == 0)
			{
				BMAP_SET(bitmap, c);
				return c + EXFAT_FIRST_DATA_CLUSTER;
			}
	}
	return EXFAT_CLUSTER_END;
}
Пример #9
0
/*
 * Identify memory proximity domains and hot-remove capabilities.
 * Fill node memory chunk list structure.
 */
void __init
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity)
{
	unsigned long long paddr, size;
	unsigned long start_pfn, end_pfn;
	u8 pxm;
	struct node_memory_chunk_s *p, *q, *pend;

	if (srat_disabled())
		return;
	if (memory_affinity->header.length !=
	     sizeof(struct acpi_srat_mem_affinity)) {
		bad_srat();
		return;
	}

	if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0)
		return;		/* empty entry */

	pxm = memory_affinity->proximity_domain & 0xff;

	/* mark this node as "seen" in node bitmap */
	BMAP_SET(pxm_bitmap, pxm);

	/* calculate info for memory chunk structure */
	paddr = memory_affinity->base_address;
	size = memory_affinity->length;

	start_pfn = paddr >> PAGE_SHIFT;
	end_pfn = (paddr + size) >> PAGE_SHIFT;


	if (num_memory_chunks >= MAXCHUNKS) {
		printk(KERN_WARNING "Too many mem chunks in SRAT."
			" Ignoring %lld MBytes at %llx\n",
			size/(1024*1024), paddr);
		return;
	}

	/* Insertion sort based on base address */
	pend = &node_memory_chunk[num_memory_chunks];
	for (p = &node_memory_chunk[0]; p < pend; p++) {
		if (start_pfn < p->start_pfn)
			break;
	}
	if (p < pend) {
		for (q = pend; q >= p; q--)
			*(q + 1) = *q;
	}
	p->start_pfn = start_pfn;
	p->end_pfn = end_pfn;
	p->pxm = pxm;

	num_memory_chunks++;

	printk(KERN_DEBUG "Memory range %08lx to %08lx"
			  " in proximity domain %02x %s\n",
		start_pfn, end_pfn,
		pxm,
		((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
		 "enabled and removable" : "enabled" ) );
}
Пример #10
0
int fs_mkdir(fs_t* fs, inodeid_t dir, char* newdir, inodeid_t* newdirid)
{
	if (fs==NULL || dir>=ITAB_SIZE || newdir==NULL || newdirid==NULL) {
		printf("[fs_mkdir] malformed arguments.\n");
		return -1;
	}

	if (strlen(newdir) == 0 || strlen(newdir)+1 > FS_MAX_FNAME_SZ){
		dprintf("[fs_mkdir] directory size error.\n");
		return -1;
	}

	if (!BMAP_ISSET(fs->inode_bmap,dir)) {
		dprintf("[fs_mkdir] inode is not being used.\n");
		return -1;
	}

	fs_inode_t* idir = &fs->inode_tab[dir];
	if (idir->type != FS_DIR) {
		dprintf("[fs_mkdir] inode is not a directory.\n");
		return -1;
	}

	if (fsi_dir_search(fs,dir,newdir,newdirid) == 0) {
		dprintf("[fs_mkdir] directory already exists.\n");
		return -1;
	}
   
   	// check if there are free inodes
	unsigned finode;
	if (!fsi_bmap_find_free(fs->inode_bmap,ITAB_SIZE,&finode)) {
		dprintf("[fs_mkdir] there are no free inodes.\n");
		return -1;
	}

   	// add a new block to the directory if necessary
	if (idir->size % BLOCK_SIZE == 0) {
		unsigned fblock;
		if (!fsi_bmap_find_free(fs->blk_bmap,block_num_blocks(fs->blocks),&fblock)) {
			dprintf("[fs_mkdir] no free blocks to augment directory.\n");
			return -1;
		}
		BMAP_SET(fs->blk_bmap,fblock);
		idir->blocks[idir->size / BLOCK_SIZE] = fblock;
	}

   	// add the entry to the directory
	fs_dentry_t page[DIR_PAGE_ENTRIES];
	block_read(fs->blocks,idir->blocks[idir->size/BLOCK_SIZE],(char*)page);
	fs_dentry_t* entry = &page[idir->size % BLOCK_SIZE / sizeof(fs_dentry_t)];
	strcpy(entry->name,newdir);
	entry->inodeid = finode;
	block_write(fs->blocks,idir->blocks[idir->size/BLOCK_SIZE],(char*)page);
	idir->size += sizeof(fs_dentry_t);

   	// reserve and init the new file inode
	BMAP_SET(fs->inode_bmap,finode);
	fsi_inode_init(&fs->inode_tab[finode],FS_DIR);

   	// save the file system metadata
	fsi_store_fsdata(fs);

	*newdirid = finode;
	return 0;
}
Пример #11
0
int fs_write(fs_t* fs, inodeid_t file, unsigned offset, unsigned count,
   char* buffer)
{
	if (fs == NULL || file >= ITAB_SIZE || buffer == NULL) {
		dprintf("[fs_write] malformed arguments.\n");
		return -1;
	}

	if (!BMAP_ISSET(fs->inode_bmap,file)) {
		dprintf("[fs_write] inode is not being used.\n");
		return -1;
	}

	fs_inode_t* ifile = &fs->inode_tab[file];
	if (ifile->type != FS_FILE) {
		dprintf("[fs_write] inode is not a file.\n");
		return -1;
	}

	if (offset > ifile->size) {
		offset = ifile->size;
	}

	unsigned *blk;

	int blks_used = OFFSET_TO_BLOCKS(ifile->size);
	int blks_req = MAX(OFFSET_TO_BLOCKS(offset+count),blks_used)-blks_used;

	dprintf("[fs_write] count=%d, offset=%d, fsize=%d, bused=%d, breq=%d\n",
		count,offset,ifile->size,blks_used,blks_req);
	
	if (blks_req > 0) {
		if(blks_req > INODE_NUM_BLKS-blks_used) {
			dprintf("[fs_write] no free block entries in inode.\n");
			return -1;
		}

		dprintf("[fs_write] required %d blocks, used %d\n", blks_req, blks_used);

      		// check and reserve if there are free blocks
		for (int i = blks_used; i < blks_used + blks_req; i++) {

			if(i < INODE_NUM_BLKS)
				blk = &ifile->blocks[i];
	 
			if (!fsi_bmap_find_free(fs->blk_bmap,block_num_blocks(fs->blocks),blk)) { // ITAB_SIZE
				dprintf("[fs_write] there are no free blocks.\n");
				return -1;
			}
			BMAP_SET(fs->blk_bmap, *blk);
			dprintf("[fs_write] block %d allocated.\n", *blk);
		}
	}
   
	char block[BLOCK_SIZE];
	int num = 0, pos;
	int iblock = offset/BLOCK_SIZE;

   	// write within the existent blocks
	while (num < count && iblock < blks_used) {
		if(iblock < INODE_NUM_BLKS) {
			blk = ifile->blocks;
			pos = iblock;
		}
      
		block_read(fs->blocks, blk[pos], block);

		int start = ((num == 0)?(offset % BLOCK_SIZE):0);
		for (int i = start; i < BLOCK_SIZE && num < count; i++, num++) {
			block[i] = buffer[num];
		}
		block_write(fs->blocks, blk[pos], block);
		iblock++;
	}

	dprintf("[fs_write] written %d bytes within.\n", num);

  	// write within the allocated blocks
	while (num < count && iblock < blks_used + blks_req) {
		if(iblock < INODE_NUM_BLKS) {
			blk = ifile->blocks;
			pos = iblock;
		}
      
		for (int i = 0; i < BLOCK_SIZE && num < count; i++, num++) {
			block[i] = buffer[num];
		}

		block_write(fs->blocks, blk[pos], block);
		iblock++;
	}

	if (num != count) {
		printf("[fs_write] severe error: num=%d != count=%d!\n", num, count);
		exit(-1);
	}

	ifile->size = MAX(offset + count, ifile->size);

   	// update the inode in disk
	fsi_store_fsdata(fs);

	dprintf("[fs_write] written %d bytes, file size %d.\n", count, ifile->size);
	return 0;
}