Esempio n. 1
0
int ext2_read_directory(struct filesystem *fs, int dino, char *f)
{
    /* read the directory inode in */
    struct ext2_inode *inode = kmalloc(sizeof(*inode));
    ext2_read_inode(fs, inode, dino);

    if (inode->type & 0x4000 == 0)
        return -ENOTDIR;

    /* the block pointers contain some 'struct ext2_dir's, so parse */
    void *bbuf = kmalloc(EXT2_PRIV(fs)->blocksize);
    for (int i = 0; i < 12; i++) {
        ext2_read_block(fs, bbuf, inode->dbp[i]);
        struct ext2_dir *d = (void *)bbuf;
        if (d->size == 0 || d->namelength == 0)
            break;
        int r = 0;
        while (r < EXT2_PRIV(fs)->blocksize) {
            if (strncmp(&d->reserved + 1, f, d->namelength) == 0) {
                int k = d->inode;
                new_free(bbuf);
                return k;
            }
            r += d->size;
            if (d->size == 0 || d->namelength == 0) {
                goto c1;
            }
            d = (struct ext2_dir *)((uintptr_t)d + d->size);
        }
        c1:;
    }
    new_free(bbuf);
    return -ENOENT;
}
Esempio n. 2
0
struct fs_Inode* fs_inode_open(size_t inode) {

    for (size_t i = 0; i < MAX_OPEN_INODES; i++) {
        if (inodeTable[i]) {
            if (inodeTable[i]->refCount <= 0) {
                kprintf("Inode %u in entry %u is broken.\n", inodeTable[i]->number, i);
                while (1);
            }
        }
    }
    for (size_t i = 0; i < MAX_OPEN_INODES; i++) {
        if (inodeTable[i] != NULL && inodeTable[i]->number == inode) {
            inodeTable[i]->refCount++;
            return inodeTable[i];
        }
    }

    struct fs_Inode* node = ext2_read_inode(fs, inode);
    node->extra = NULL;
    if (node == NULL) {
        return NULL;
    }

    node->refCount = 1;
    for (size_t i = 0; i < MAX_OPEN_INODES; i++) {
        if (inodeTable[i] == NULL) {
            inodeTable[i] = node;
            return node;
        }
    }

    free_inode(node);

    return NULL;
}
Esempio n. 3
0
int sys_open(char* path)
{
	u32 fd;
	struct file* fp;
	struct open_file* of;

	if (!(fp = path_to_file(path)))
	{
		// printk("DEBUG: sys_open(): can't open %s\n", path);
		return -1;
	}

	// printk("DEBUG: sys_open(): process[%d] opening file %s\n", current->pid, fp->name);

	fp->opened++;

	if (!fp->inode)
		fp->inode = ext2_read_inode(fp->disk, fp->inum);

	/* Lecture du fichier */
	fp->mmap = ext2_read_file(fp->disk, fp->inode);

	/*
	 * Recherche d'un descripteur libre.
	 */
	fd = 0;
	if (current->fd == 0)
	{
		current->fd = (struct open_file *) malloc(sizeof(struct open_file));
		current->fd->file = fp;
		current->fd->ptr = 0;
		current->fd->next = 0;
	}
	else
	{
		of = current->fd;
		while (of->file && of->next)
		{
			of = of->next;
			fd++;
		}

		if (of->file == 0) 	/* Reuse old descriptor */
		{
			of->file = fp;
			of->ptr = 0;
		}
		else				/* Use new one */
		{
			of->next = (struct open_file *) malloc(sizeof(struct open_file));
			of->next->file = fp;
			of->next->ptr = 0;
			of->next->next = 0;
			fd++;
		}
	}

	return fd;
}
Esempio n. 4
0
void ext2fs_dump_info( char *path ){
	ext2_device_t *e2 = ext2_create_device( path );

	printf( "ext version: %d.%d\n", e2->sprblk->maj_version, e2->sprblk->min_version );
	printf( "n_inodes: %d, n_blocks: %d, reserved blocks: %d\n",
		e2->sprblk->n_inodes, e2->sprblk->n_blocks, e2->sprblk->su_reserved );

	printf( "free_blocks: %d, free_inodes: %d, superblock: %d\n",
		e2->sprblk->free_blocks, e2->sprblk->free_inodes, e2->sprblk->sprblk_block );

	printf( "block size: %d, fragment size: %d, blocks per group: %d\n", 
		1024 << e2->sprblk->block_size, 1024 << e2->sprblk->frag_size, 
		e2->sprblk->n_block_block_grp );

	printf( "First free inode: %d, sizeof inode: %d\n", e2->esprblk->first_free_inode,
		e2->esprblk->inode_size );

	printf( "last path: \"%s\"\n", e2->esprblk->last_path );

	printf( "first block group descript, inode table: %d\n", e2->blkdesc->inode_table_addr );

	ext2_inode_t *inode = knew( char[ e2->esprblk->inode_size ]);
	ext2_get_inode( e2, 2, inode );

	printf( "Got inode, links: %d, 1st block: %d\n", inode->hard_links, inode->d_ptr[0] );

	char *data = knew( char[ e2->block_size * 5 ] );
	ext2_read_inode( e2, inode, data, e2->block_size );

	printf( "root listing:\n" );
	ext2_dirent_t *dirent = (ext2_dirent_t *)data;
	while( *(char *)dirent ){
		printf( "name: \"%s\", inode: %d\n", &dirent->name, dirent->inode );
		dirent = (ext2_dirent_t *)(((unsigned long)dirent) + dirent->size );
	}

	//ext2_get_inode( e2, 2049, inode );
	//ext2_read_inode( e2, inode, data, e2->block_size * 3, 0 );
	//ext2_read_inode( e2, inode, data, 4279 );

	//printf( "size: %d\n", inode->low_size );
	//printf( "%s\n", data );

	//printf( "listing asdf:\n" );
	/*
	dirent = (ext2_dirent_t *)data;
	while( *(char *)dirent ){
		printf( "name: \"%s\", inode: %d\n", &dirent->name, dirent->inode );
		dirent = (ext2_dirent_t *)(((unsigned long)dirent) + dirent->size );
	}
	*/

	kfree( data );
	kfree( e2->sprblk );
	kfree( e2->blkdesc );
	kfree( e2 );
	return;
}
Esempio n. 5
0
/* read in the dir, look for the entry */
static int ext2_dir_lookup(ext2_t *ext2, struct ext2_inode *dir_inode, const char *name, inodenum_t *inum)
{
	uint file_blocknum;
	int err;
	uint8_t *buf;
	size_t namelen = strlen(name);
	
	if (!S_ISDIR(dir_inode->i_mode))
		return ERR_NOT_DIR;

	buf = malloc(EXT2_BLOCK_SIZE(ext2->sb));

	file_blocknum = 0;
	for (;;) {
		/* read in the offset */
		err = ext2_read_inode(ext2, dir_inode, buf, file_blocknum * EXT2_BLOCK_SIZE(ext2->sb), EXT2_BLOCK_SIZE(ext2->sb));
		if (err <= 0) {
			free(buf);
			return -1;
		}

		/* walk through the directory entries, looking for the one that matches */
		struct ext2_dir_entry_2 *ent;
		uint pos = 0;
		while (pos < EXT2_BLOCK_SIZE(ext2->sb)) {
			ent = (struct ext2_dir_entry_2 *)&buf[pos];

			LTRACEF("ent %d:%d: inode 0x%x, reclen %d, namelen %d\n",
					file_blocknum, pos, LE32(ent->inode), LE16(ent->rec_len), ent->name_len/* , ent->name*/);

			/* sanity check the record length */
			if (LE16(ent->rec_len) == 0)
				break;

			if (ent->name_len == namelen && memcmp(name, ent->name, ent->name_len) == 0) {
				// match
				*inum = LE32(ent->inode);
				LTRACEF("match: inode %d\n", *inum);
				free(buf);
				return 1;
			}

			pos += ROUNDUP(LE16(ent->rec_len), 4);
		}

		file_blocknum++;

		/* sanity check the directory. 4MB should be enough */
		if (file_blocknum > 1024) {
			free(buf);
			return -1;
		}
	}
}
Esempio n. 6
0
/* read in the dir, look for the entry */
int ext2_dirent_lookup(ext2_t *ext2, struct ext2_inode *dir_inode, const char **name, unsigned index)
{
	uint file_blocknum;
	int err;
	uint8_t *buf;
	unsigned curpos = 0;
	
	if (!S_ISDIR(dir_inode->i_mode))
		return ERR_NOT_DIR;

	buf = malloc(EXT2_BLOCK_SIZE(ext2->sb));

	file_blocknum = 0;
	for (;;) {
		/* read in the offset */
		err = ext2_read_inode(ext2, dir_inode, buf, file_blocknum * EXT2_BLOCK_SIZE(ext2->sb), EXT2_BLOCK_SIZE(ext2->sb));
		if (err <= 0) {
			free(buf);
			if (err == 0)
				return 0;
			else
				return -1;
		}

		/* walk through the directory entries, looking for the one that matches */
		struct ext2_dir_entry_2 *ent;
		uint pos = 0;
		while (pos < EXT2_BLOCK_SIZE(ext2->sb)) {
			ent = (struct ext2_dir_entry_2 *)&buf[pos];

			LTRACEF("ent %d:%d: inode 0x%x, reclen %d, namelen %d\n",
					file_blocknum, pos, LE32(ent->inode), LE16(ent->rec_len), ent->name_len/* , ent->name*/);

			/* sanity check the record length */
			if (LE16(ent->rec_len) == 0)
				break;

			if (strncmp(ent->name, ".", ent->name_len) != 0 &&
					strncmp(ent->name, "..", ent->name_len) != 0) {
				if (curpos == index) {
					*name = malloc(ent->name_len + 1);
					memcpy(*name, ent->name, ent->name_len);
					*((char *)(*name) + ent->name_len) = 0;
					return 1;
				} else {
					curpos++;
				}
			}
				
			pos += ROUNDUP(LE16(ent->rec_len), 4);
		}

		file_blocknum++;

		/* sanity check the directory. 4MB should be enough */
		if (file_blocknum > 1024) {
			free(buf);
			return -1;
		}
	}
	return -1;
}
Esempio n. 7
0
int ext2_find_file(struct ext2_desc *desc, const char *pathname, struct ext2_inode *inode)
{
	struct ext2_directory_entry entry;
	char path_temp[1024], *filename, *p;

	text_copy(path_temp, pathname);
	filename = p = path_temp;

	entry.inode = 2;
	entry.file_type = EXT_FILE_TYPE_DIRECTORY;

	while (1)
	{
		int ret;
		ssize_t rdlen;

		rdlen = ext2_read_inode(desc, entry.inode, inode);
		if (rdlen < 0)
		{
			print_error("ext2_read_inode");
			return rdlen;
		}

#if CAVAN_EXT2_DEBUG
		show_ext2_inode(inode);
#endif

		while (*filename == '/')
		{
			filename++;
		}

		if (*filename == 0)
		{
			break;
		}

		if (entry.file_type != EXT_FILE_TYPE_DIRECTORY)
		{
			ERROR_RETURN(ENOENT);
		}

		for (p = filename; *p && *p != '/'; p++);

		*p = 0;

		if (inode->flags & EXT2_INODE_FLAG_EXTENTS)
		{
			ret = ext4_find_file_base(desc, filename, (struct ext4_extent_header *) inode->block, &entry);
		}
		else
		{
			ret = ext2_find_file_base(desc, filename, inode->block, inode->blocks, &entry);
		}

		if (ret < 0)
		{
			ERROR_RETURN(ENOENT);
		}

		filename = p + 1;
	}

	return 0;
}
Esempio n. 8
0
bool
ext2_add_entry( PEXT2_FILESYS Ext2Sys,
                ULONG parent, ULONG inode,
                int filetype, char *name )
{
    PEXT2_DIR_ENTRY2  dir = NULL, newdir = NULL;
    EXT2_INODE      parent_inode;
    ULONG       dwRet;
    char        *buf;
    int         rec_len;
    bool        bRet = false;

    rec_len = EXT2_DIR_REC_LEN(strlen(name));

    if (!ext2_load_inode(Ext2Sys, parent, &parent_inode))
    {
        return false;
    }

    buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, parent_inode.i_size);

    if (!ext2_read_inode(Ext2Sys, parent, 0, buf, parent_inode.i_size, &dwRet))
    {
        return false;
    }

    dir = (PEXT2_DIR_ENTRY2) buf;

    while ((char *)dir < buf + parent_inode.i_size)
    {
        if ((dir->inode == 0 && dir->rec_len >= rec_len) || 
               (dir->rec_len >= dir->name_len + rec_len) )
        {
            if (dir->inode)
            {
                newdir = (PEXT2_DIR_ENTRY2) ((PUCHAR)dir + EXT2_DIR_REC_LEN(dir->name_len));
                newdir->rec_len = dir->rec_len - EXT2_DIR_REC_LEN(dir->name_len);

                dir->rec_len = EXT2_DIR_REC_LEN(dir->name_len);

                dir = newdir;
            }

            dir->file_type = filetype;
            dir->inode = inode;
            dir->name_len = strlen(name);
            memcpy(dir->name, name, strlen(name));
    
            bRet = true;
            break;
        }

        dir = (PEXT2_DIR_ENTRY2) (dir->rec_len + (PUCHAR) dir);
    }


    if (bRet)
        return ext2_write_inode(Ext2Sys, parent, 0, buf, parent_inode.i_size, &dwRet);

    return bRet;
}