Example #1
0
//*****************umount****************
int8_t cnumount(void)
{
	cnclosedir(cwd);
	fs.superblk->state = VALID_FS;
	blk_write(BLOCKID_SUPER, &superblk_cache);
	blk_write(BLOCKID_BLOCK_BITMAP, &block_bm_cache);
	blk_write(BLOCKID_INODE_BITMAP, &inode_bm_cache);
	return 0;
}
Example #2
0
static int addlink(struct filesys *fs, struct inode *target, struct inode *node, const char *name)
{
	struct dir_entry ent, *data;
	int i, boffs, bidx, len;

	if(!(target->mode & S_IFDIR)) {
		return -ENOTDIR;
	}
	if(node->mode & S_IFDIR) {
		return -EPERM;
	}
	/* TODO check that the link does not already exist (EEXIST) */

	if((len = strlen(name)) > NAME_MAX) {
		return -ENAMETOOLONG;
	}
	ent.ino = node->ino;
	memcpy(ent.name, name, len + 1);

	/* find a place to put it */
	if(!(data = malloc(BLKSZ))) {
		return -ENOMEM;
	}

	boffs = 0;
	while((bidx = get_file_block(fs, target, boffs)) > 0) {
		/* read the block, and search for an empty entry */
		blk_read(fs->bdev, bidx, 1, data);

		/* for all directory entries in this block... */
		for(i=0; i<BLK_DIRENT; i++) {
			if(data[i].ino == 0) {
				/* found empty */
				memcpy(data + i, &ent, sizeof ent);
				goto success;
			}
		}
		boffs++;
	}

	/* didn't find any free entries amongst our blocks, allocate a new one */
	if(!(bidx = alloc_file_block(fs, target, boffs))) {
		free(data);
		return -ENOSPC;
	}
	/* zero-fill the new block and add the first entry */
	memset(data, 0, BLKSZ);
	*data = ent;

success:
	/* write to disk */
	blk_write(fs->bdev, bidx, 1, data);
	node->nlink++;	/* increase reference count */

	free(data);
	return 0;
}
Example #3
0
void inode_bitmap_init(void)
{
	block *inode_btm = calloc(1,sizeof(block));

	//Mark first inode as used
	set_bitmap(inode_btm, 0);

	blk_write(BLOCKID_INODE_BITMAP, inode_btm);
	free(inode_btm);
}
Example #4
0
//******** llwrite ******************
//Writes a file completely and updates inode data
int8_t llwrite(inode* inode_ptr, block* buf)
{
	uint32_t* s_ind = calloc(1, sizeof(block));
	for(uint8_t i = 0; i < MIN(inode_ptr->blocks,8); i++)
	{
		blk_write(inode_ptr->data0[i], buf);
		buf++;
	}

	if(inode_ptr->blocks > 8)
	{
		blk_read(inode_ptr->data1, (block*)s_ind);
		for(uint32_t j = 0; j < inode_ptr->blocks - 8; j++)
		{
			blk_write(s_ind[j], buf);
			buf++;
		}
	}
	free(s_ind);
	return 0;
}
Example #5
0
static int check_diskformat(void)
{
  int ret;

#ifdef CONFIG_FS_EVFAT
  struct evfat_format_s fmt = EVFAT_FORMAT_INITIALIZER;

  /* load MBR */

  ret = blk_read(copybuf, sizeof(copybuf), "/dev/mtdblock0p2", 0);

  if (ret < 0)
    {
      return 0;
    }

  /* If part2 has MBR signature, this eMMC was formated by PC.
   * This means the set is just after writing IPL2.
   */

  if (copybuf[510] != 0x55 || copybuf[511] != 0xaa)
    {
      return 0;
    }

  ret = mkevfatfs(CONFIG_MTD_CP_DEVPATH, &fmt);
#endif

  _info("FORMAT content partition : %d\n", ret);

  memset(copybuf, 0, sizeof(copybuf));
  ret = blk_write(copybuf, 512, CONFIG_MTD_ETC_DEVPATH, 0);
  _info("clear /etc : %d\n", ret);
  ret = blk_write(copybuf, 512, CONFIG_MTD_SYSTEM_DEVPATH, 0);
  _info("clear /system : %d\n", ret);
  ret = blk_write(copybuf, 512, CONFIG_MTD_CACHE_DEVPATH, 0);
  _info("clear /cache : %d\n", ret);

  return 1;
}
Example #6
0
//*****************mkfs****************
void superblock_init(void)
{
	superblock *sb = calloc(1,sizeof(block));
	memset(sb, 0, sizeof(block));
	sb->inode_count = INODE_COUNT;
	sb->block_count = BD_SIZE_BLOCKS;
	sb->free_inode_count = INODE_COUNT-1;
	sb->free_block_count = BD_SIZE_BLOCKS-4-INODE_TABLE_BLOCKS;  // 4 = super + bitmaps + rootdir
	sb->magic = FS_MAGIC;
	sb->state = FS_VALID;
	blk_write(BLOCKID_SUPER, (block*)sb);
	free(sb);
}
Example #7
0
static int write_superblock(struct filesys *fs)
{
	struct superblock *sb = fs->sb;

	/* write back any changes in the root inode */
	if(put_inode(fs, sb->root) == -1) {
		return -1;
	}
	/* write back the block bitmap */
	if(blk_write(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) {
		return -1;
	}
	/* write back the inode bitmap */
	if(blk_write(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) {
		return -1;
	}
	/* write the superblock itself */
	if(blk_write(fs->bdev, 1, 1, sb) == -1) {
		return -1;
	}
	return 0;
}
Example #8
0
/* write the inode to the disk */
static int put_inode(struct filesys *fs, struct inode *inode)
{
	struct inode *buf = malloc(BLKSZ);
	assert(buf);

	if(blk_read(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) {
		free(buf);
		return -1;
	}
	memcpy(buf + inode->ino % BLK_INODES, inode, sizeof *inode);

	if(blk_write(fs->bdev, fs->sb->itbl_start + inode->ino / BLK_INODES, 1, buf) == -1) {
		free(buf);
		return -1;
	}
	free(buf);
	return 0;
}
Example #9
0
void block_bitmap_init(void)
{
	block *block_btm = calloc(1,sizeof(block));

	//Mark all reserved blocks as used
	set_bitmap(block_btm, BLOCKID_SUPER);
	set_bitmap(block_btm, BLOCKID_BLOCK_BITMAP);
	set_bitmap(block_btm, BLOCKID_INODE_BITMAP);

	//Mark all inode table blocks as used
	for (uint16_t i = BLOCKID_INODE_TABLE; i < INODE_TABLE_BLOCKS + BLOCKID_INODE_TABLE; i++) {
		set_bitmap(block_btm, i);
	}

	//Mark root directory block as used
	set_bitmap(block_btm, INODE_TABLE_BLOCKS + BLOCKID_INODE_TABLE);

	blk_write(BLOCKID_BLOCK_BITMAP, block_btm);
	free(block_btm);
}
Example #10
0
TEST(blockdev, BlockdevCanReadWrite)
{
	TEST_ASSERT_TRUE(blockdev_attach() == 0);
	block* test_write_blk = (block*)malloc(BLOCK_SIZE);
	uint32_t* wblk_32 = (uint32_t*)test_write_blk;
	wblk_32[0] = 0xDEADBEEF;
	wblk_32[45] = 0xFEEDBEEF;
	TEST_ASSERT_TRUE(blk_write(1234, test_write_blk) == 0);
	free(test_write_blk);
	TEST_ASSERT_TRUE(blockdev_detach() == 0);

	TEST_ASSERT_TRUE(blockdev_attach() == 0);
	block* test_read_blk = (block*)malloc(BLOCK_SIZE);
	TEST_ASSERT_TRUE(blk_read(1234, test_read_blk) == 0);
	uint32_t* rblk_32 = (uint32_t*)test_read_blk;
	TEST_ASSERT_TRUE(rblk_32[0] == 0xDEADBEEF);
	TEST_ASSERT_TRUE(rblk_32[45] == 0xFEEDBEEF);
	free(test_read_blk);
	TEST_ASSERT_TRUE(blockdev_detach() == 0);
}
static int _usb_drv_send(int endpoint, void *ptr, int length, bool block)
{
    struct endpoint_t *ep;
    int ep_num = EP_NUM(endpoint);
    
    if (ep_num == 0)
        ep = &ctrlep[DIR_IN];
    else
        ep = &endpoints[ep_num];

    ep->buf = ptr;
    ep->len = ep->cnt = length;
    
    if (block)
        ep->block = true;
    else
        ep->block = false;
    
    switch (ep->type)
    {
        case USB_ENDPOINT_XFER_CONTROL:                     
            ctr_write();
            break;
        
        case USB_ENDPOINT_XFER_BULK:
            blk_write(ep_num);
            break;
        
        case USB_ENDPOINT_XFER_INT:
            int_write(ep_num);
            break;
    }
    
    if (block)
        /* wait for transfer to end */
        semaphore_wait(&ep->complete, TIMEOUT_BLOCK);

    return 0;
}
Example #12
0
//******** creat ********************
int8_t cncreat(dir_ptr* dir, const char* name)
{
	stat_st stat_buf;
	dir_entry* entry;

	check(cnstat(dir,name,&stat_buf) != 0, "File exists");  //If this file exists

	//Create parent directory entry
	entry = (dir_entry*)(((uint8_t*)dir->data)+dir->index);
	entry->file_type = ITYPE_FILE;
	entry->inode = reserve_inode();
	memcpy(entry->name, name, strlen(name));
	entry->name_len = strlen(name);
	entry->entry_len = entry->name_len + 8;
	entry->entry_len += (4 - entry->entry_len % 4);  //padding out to 32 bits
	dir->inode_st.size += entry->entry_len;
	//TODO: handle creat dir block overflow

	//Write parent dir and inode
	dir->inode_st.modified = time(NULL);
	inode_write(dir->inode_id, &dir->inode_st);
	blk_write(dir->inode_st.data0[0], dir->data);

	//Write new file inode
	inode new_file_i;
	memset(&new_file_i, 0, sizeof(inode));
	uint32_t now = time(NULL);
	new_file_i.modified = now;
	new_file_i.type = ITYPE_FILE;
	new_file_i.size = 0;
	new_file_i.blocks = 0;
	inode_write(entry->inode, &new_file_i);

	return 0;

error:
	return -1;
}
Example #13
0
void write_root_dir(void)
{
	//Prepare inode
	inode root_i;
	memset(&root_i, 0, sizeof(inode));
	uint32_t now = time(NULL);
	root_i.modified = now;
	root_i.type = ITYPE_DIR;
	root_i.size = 0;
	root_i.blocks = 1;
	root_i.data0[0] = BLOCKID_ROOT_DIR;

	block* root_dir_block = calloc(1,sizeof(block));

	// . (self entry)
	dir_entry* root_dir_entry = (dir_entry*)root_dir_block;
	root_dir_entry->inode = 0;
	root_dir_entry->file_type = ITYPE_DIR;
	root_dir_entry->name_len = 1;
	root_dir_entry->entry_len = 12;
	memcpy(root_dir_entry->name, ".", 1);
	root_i.size += 12;

	// .. (parent entry, also itself)
	root_dir_entry = (dir_entry*)(((char*)root_dir_block) + 12);
	root_dir_entry->inode = 0;
	root_dir_entry->file_type = ITYPE_DIR;
	root_dir_entry->name_len = 2;
	root_dir_entry->entry_len = 12;
	memcpy(root_dir_entry->name, "..", 2);
	root_i.size += 12;

	inode_write(0, &root_i);
	blk_write(BLOCKID_ROOT_DIR, root_dir_block);

	free(root_dir_block);
}
Example #14
0
//****** realloc_fs_blocks*****************
//Allocates at least "blocks_needed" blocks for this file
int8_t realloc_fs_blocks(inode* inode, uint32_t blocks_needed)
{
	uint32_t* s_ind = calloc(1, sizeof(block));
	if(blocks_needed > inode->blocks)
	{
		if(inode->blocks <= 8)
		{
			for(; inode->blocks < MIN(8,blocks_needed); inode->blocks++)
			{
				inode->data0[inode->blocks] = reserve_block();
			}
		}

		if(inode->blocks < blocks_needed) //still not enough after allocating direct
		{
			//Determine if a single indirect block has been allocated
			if(inode->data1 == 0)
			{
				inode->data1 = reserve_block();
			}
			else
			{
				blk_read(inode->data1,(block*)s_ind);
			}
			//Allocate the blocks and save in the indirect block
			for(;inode->blocks < blocks_needed; inode->blocks++)
			{
				s_ind[inode->blocks-8] = reserve_block();
			}
			blk_write(inode->data1,(block*)s_ind);
		}

	}
	free(s_ind);
	return 0;
}
/* UDC ISR function */
void INT_UDC(void)
{
    uint32_t txstat, rxstat;
    int tmp, ep_num;
    
    /* read what caused UDC irq */
    uint32_t intsrc = INT2FLAG & 0x7fffff;
    
    if (intsrc & (1<<1)) /* setup interrupt */
    {
        setup_received();
    }
    else if (intsrc & (1<<2)) /* ep0 in interrupt */
    {
        txstat = TX0STAT; /* read clears flags */
        
        /* TODO handle errors */
        if (txstat & (1<<18)) /* check TxACK flag */
        {
            if (ctrlep[DIR_IN].cnt >= 0)
            {
                /* we still have data to send (or ZLP) */
                ctr_write();
            }
            else
            {
                /* final ack received */
                usb_core_transfer_complete(0,                   /* ep */
                                           USB_DIR_IN,          /* dir */
                                           0,                   /* status */
                                           ctrlep[DIR_IN].len); /* length */
                
                /* release semaphore for blocking transfer */
                if (ctrlep[DIR_IN].block)
                    semaphore_release(&ctrlep[DIR_IN].complete);
            }
        }
    }
    else if (intsrc & (1<<3)) /* ep0 out interrupt */
    {
        rxstat = RX0STAT;

        /* TODO handle errors */
        if (rxstat & (1<<18)) /* RxACK */
        {
            if (ctrlep[DIR_OUT].cnt > 0)
                ctr_read();
            else
                usb_core_transfer_complete(0,                    /* ep */
                                           USB_DIR_OUT,          /* dir */
                                           0,                    /* status */
                                           ctrlep[DIR_OUT].len); /* length */                
        }
    }
    else if (intsrc & (1<<4)) /* usb reset */
    {
        usb_drv_init();
    }
    else if (intsrc & (1<<5)) /* usb resume */
    {
        TX0CON |= (1<<0); /* TxClr */
        TX0CON &= ~(1<<0);
        RX0CON |= (1<<1); /* RxClr */
        RX0CON &= (1<<1);
    }
    else if (intsrc & (1<<6)) /* usb suspend */
    {
    }
    else if (intsrc & (1<<7)) /* usb connect */
    {
    }
    else
    {
        /* lets figure out which ep generated irq */
        tmp = intsrc >> 7;
        for (ep_num=1; ep_num < 15; ep_num++)
        {
            tmp >>= ep_num;
            if (tmp & 0x01)
                break;
        }
        
        if (intsrc & ((1<<8)|(1<<11)|(1<<14)|(1<<17)|(1<<20)))
        {
            /* bulk out */
            rxstat = BOUT_RXSTAT(ep_num);
            
            /* TODO handle errors */
            if (rxstat & (1<<18)) /* RxACK */
            {
                if (endpoints[ep_num].cnt > 0)
                    blk_read(ep_num);
                else
                    usb_core_transfer_complete(ep_num,               /* ep */
                                               USB_DIR_OUT,          /* dir */
                                               0,                    /* status */
                                               endpoints[ep_num].len); /* length */                
            }
        }
        else if (intsrc & ((1<<9)|(1<<12)|(1<<15)|(1<<18)|(1<<21)))
        {
            /* bulk in */
            txstat = BIN_TXSTAT(ep_num);
            
            /* TODO handle errors */
            if (txstat & (1<<18)) /* check TxACK flag */
            {
                if (endpoints[ep_num].cnt >= 0)
                {
                    /* we still have data to send (or ZLP) */
                    blk_write(ep_num);
                }
                else
                {
                    /* final ack received */
                    usb_core_transfer_complete(ep_num,                   /* ep */
                                               USB_DIR_IN,          /* dir */
                                               0,                   /* status */
                                               endpoints[ep_num].len); /* length */
                
                    /* release semaphore for blocking transfer */
                    if (endpoints[ep_num].block)
                        semaphore_release(&endpoints[ep_num].complete);
                }
            }
        }
        else if (intsrc & ((1<<10)|(1<13)|(1<<16)|(1<<19)|(1<<22)))
        {
            /* int in */
            txstat = IIN_TXSTAT(ep_num);

            /* TODO handle errors */
            if (txstat & (1<<18)) /* check TxACK flag */
            {
                if (endpoints[ep_num].cnt >= 0)
                {
                    /* we still have data to send (or ZLP) */
                    int_write(ep_num);
                }
                else
                {
                    /* final ack received */
                    usb_core_transfer_complete(ep_num,                   /* ep */
                                               USB_DIR_IN,          /* dir */
                                               0,                   /* status */
                                               endpoints[ep_num].len); /* length */
                
                    /* release semaphore for blocking transfer */
                    if (endpoints[ep_num].block)
                        semaphore_release(&endpoints[ep_num].complete);
                }
            }
        }
    }
}
Example #16
0
static int set_config(int num, char *buf)
{
  int ret;
  ret = blk_write(buf, 512, CONFIG_MTD_CONFIG_DEVPATH, num * 512);
  return ret;
}
Example #17
0
static int file_block(struct filesys *fs, struct inode *node, int boffs, int allocate)
{
	int res, idx, node_dirty = 0;
	blkid *barr;

	/* out of bounds */
	if(boffs < 0 || boffs >= MAX_DIND) {
		return 0;
	}

	/* is it a direct block ? */
	if(boffs < NDIRBLK) {
		if(!(res = node->blk[boffs]) && allocate) {
			res = node->blk[boffs] = alloc_block(fs);
			if(res) {
				zero_block(fs, res);
				/* also write back the modified inode */
				put_inode(fs, node);
			}
		}
		return res;
	}

	barr = malloc(fs->sb->blksize);
	assert(barr);

	/* is it an indirect block ? */
	if(boffs < MAX_IND) {
		int ind_dirty = 0;

		if(node->ind) {
			/* read the indirect block */
			blk_read(fs->bdev, node->ind, 1, barr);
		} else {
			/* does not exist... try to allocate if requested */
			if(!allocate || !(node->ind = alloc_block(fs))) {
				res = 0;
				goto end;
			}

			/* allocated a block clear the buffer, and invalidate everything */
			memset(barr, 0, sizeof fs->sb->blksize);
			node_dirty = 1;
			ind_dirty = 1;
		}

		idx = boffs - NDIRBLK;

		if(!(res = barr[idx])) {
			if(allocate && (res = barr[idx] = alloc_block(fs))) {
				ind_dirty = 1;
			}
		}

		/* write back the indirect block if needed */
		if(ind_dirty) {
			blk_write(fs->bdev, node->ind, 1, barr);
		}
		goto end;
	}

	/* TODO check/rewrite this */
#if 0
	/* is it a double-indirect block ? */
	if(boffs < MAX_DIND) {
		/* first read the dind block and find the index of the ind block */
		if(!node->dind) {
			if(allocate) {
				/* allocate and zero-out the double indirect block */
				res = node->dind = alloc_block(fs);
				if(res) {
					zero_block(fs, res);
				}
			} else {
				res = 0;
				goto end;
			}
		}
		blk_read(fd->bdev, node->dind, 1, barr);
		idx = (boffs - MAX_IND) / BLK_BLKID;

		/* then read the ind block and find the index of the block */
		if(!barr[idx]) {
			res = 0;
			goto end;
		}
		blk_read(fd->bdev, barr[idx], 1, barr);
		res = barr[(boffs - MAX_IND) % BLK_BLKID];
	}
#endif

end:
	if(node_dirty) {
		put_inode(fs, node);
	}
	free(barr);
	return res;
}
Example #18
0
//************flush_metadata************
void flush_metadata(void)
{
	blk_write(BLOCKID_SUPER, &superblk_cache);
	blk_write(BLOCKID_BLOCK_BITMAP, &block_bm_cache);
	blk_write(BLOCKID_INODE_BITMAP, &inode_bm_cache);
}
Example #19
0
//******** mkdir ********************
int8_t cnmkdir(const char* name)
{
	char* name_copy = strdup(name);
	char name_tok[256];
	char entry_name[256];
	char* next_name_tok;
	dir_entry* entry;
	dir_ptr *dir = calloc(1,sizeof(dir_ptr));		//Directory file in memory (e.g. DIR object from filedef.h)
	bool last_dir = false;

	inode_read(cwd->inode_id, &dir->inode_st);		//Start at cwd
	dir->inode_id = cwd->inode_id;

	next_name_tok = strtok(name_copy, "/");
	do
	{
		//name_tok is the dir we are searching for or going to create
		strcpy(name_tok, next_name_tok);

		//Read the directory file for this inode
		dir->data = calloc(dir->inode_st.blocks,sizeof(block));  	//Memory for all directory file blocks
		llread(&dir->inode_st, dir->data);	//Read the directory file
		dir->index = 0;

		next_name_tok = strtok(NULL, "/");		//Read the next token
		if(next_name_tok == NULL)   //This is the last directory in the path
		{
			last_dir = true;
		}

		//Find the token in this dir
		while((entry = cnreaddir(dir)))
		{
			memcpy(entry_name, entry->name, entry->name_len);
			entry_name[entry->name_len] = 0;
			if(strcmp(entry_name, name_tok) == 0)  //If this directory already exists
			{
				if(last_dir)
				{
					return -1;   //Directory already exists
				}
				else   //Read the directory inode
				{
					dir->inode_id = entry->inode;
					inode_read(entry->inode,&dir->inode_st);   //Read the next directory's inode
					free(dir->data);  //Forget the directory we just read
					break;
				}
			}
		}

		if(last_dir)  //Create the directory at the end of the list
		{
			//Create parent directory entry
			entry = (dir_entry*)(((uint8_t*)dir->data)+dir->index);
			entry->file_type = ITYPE_DIR;
			entry->inode = reserve_inode();
			memcpy(entry->name,name_tok,strlen(name_tok));
			entry->name_len = strlen(name_tok);
			entry->entry_len = entry->name_len + 8;
			entry->entry_len += (4 - entry->entry_len % 4);  //padding out to 32 bits
			dir->inode_st.size += entry->entry_len;
			//TODO: handle mkdir block overflow

			//Write parent dir and inode
			dir->inode_st.modified = time(NULL);
			inode_write(dir->inode_id, &dir->inode_st);
			blk_write(dir->inode_st.data0[0], dir->data);

			//Write new directory inode
			inode new_dir_i;
			memset(&new_dir_i, 0, sizeof(inode));
			uint32_t now = time(NULL);
			new_dir_i.modified = now;
			new_dir_i.type = ITYPE_DIR;
			new_dir_i.size = 0;
			new_dir_i.blocks = 1;
			new_dir_i.data0[0] = reserve_block();

			//Write new directory file
			block* new_dir_block = calloc(1,sizeof(block));

			// . (self entry)
			dir_entry* new_dir_self_entry = (dir_entry*)new_dir_block;
			new_dir_self_entry->inode = entry->inode;
			new_dir_self_entry->file_type = ITYPE_DIR;
			new_dir_self_entry->name_len = 1;
			new_dir_self_entry->entry_len = 12;
			memcpy(new_dir_self_entry->name, ".", 1);
			new_dir_i.size += 12;

			// .. (parent entry)
			dir_entry* new_dir_parent_entry = (dir_entry*)(((uint8_t*)new_dir_block) + 12);
			new_dir_parent_entry->inode = dir->inode_id;
			new_dir_parent_entry->file_type = ITYPE_DIR;
			new_dir_parent_entry->name_len = 2;
			new_dir_parent_entry->entry_len = 12;
			memcpy(new_dir_parent_entry->name, "..", 2);
			new_dir_i.size += 12;

			//Write new dir and inode
			inode_write(entry->inode, &new_dir_i);
			blk_write(new_dir_i.data0[0], new_dir_block);

			free(new_dir_block);
			break;
		}

	} while(1);
	free(dir);
	free(name_copy);
	return 0;
}