Beispiel #1
0
/**
 * Look up and return the inode for a path name.
 * If nameiparent is true, return the inode for the parent and copy the final
 * path element into name, which must have room for DIRSIZ bytes.
 * Returns 0 in the case of error.
 */
static struct inode*
namex(char *path, bool nameiparent, char *name)
{
  struct inode *ip;
  struct inode *next;
  // If path is a full path, get the pointer to the root inode. Otherwise get
  // the inode corresponding to the current working directory.
  if(*path == '/'){
    ip = inode_get(ROOTDEV, ROOTINO);
  }
  else {
    ip = inode_dup((struct inode*) tcb_get_cwd(get_curid()));
  }

  while((path = skipelem(path, name)) != 0){
	inode_lock(ip);
	if(ip -> type != T_DIR) {
		return 0;
	}
	if(nameiparent && *path == 0) {
		inode_unlock(ip);
		return ip;
	}
	next = dir_lookup(ip, name, 0);
	inode_unlockput(ip);
	ip = next;
  }
  if(nameiparent){
    inode_put(ip);
    return 0;
  }
  return ip;
}
Beispiel #2
0
/*
 * Initializes the file system manager.
 */
PUBLIC void fs_init(void)
{
	binit();
	inode_init();
	superblock_init();
	
	/* Sanity check. */
	CHKSIZE(sizeof(struct d_dirent), sizeof(struct dirent));

	rootdev = superblock_read(ROOT_DEV);
	
	/* Failed to read root super block. */
	if (rootdev == NULL)
		kpanic("failed to mount root file system");
		
	superblock_unlock(rootdev);
	
	root = inode_get(ROOT_DEV, 1);
	
	/* Failed to read root inode. */
	if (root == NULL)
		kpanic("failed to read root inode");
	
	kprintf("fs: root file system mounted");
	
	/* Hand craft idle process. */
	IDLE->pwd = root;
	IDLE->root = root;
	root->count += 2;
	
	inode_unlock(root);
}
Beispiel #3
0
/*
 * "The l in the name lseek() derives from the fact that the
 * offset argument and the return value were both originally
 * typed as long. Early UNIX implementations provided a seek()
 * system call, which typed these values as int" --M. Kerrisk
 */
int64_t sys_lseek(int fd, uint64_t offset, uint whence)
{
	struct file *file;
	struct inode *inode;
	uint64_t offset_base;
	int error = 0;

	file = unrolled_lookup(&current->fdtable, fd);
	if (file == NULL)
		return -EBADF;

	assert(file->inum > 0);
	if (is_fifo(file->inum) || is_socket(file->inum))
		return -ESPIPE;
	inode = inode_get(file->inum);

	spin_lock(&file->lock);

	switch (whence) {
	case SEEK_SET: offset_base = 0; break;
	case SEEK_CUR: offset_base = file->offset; break;
	case SEEK_END: offset_base = inode->size_low; break;
	default: error = -EINVAL; goto out;
	}

	if ((offset_base + offset) < offset_base) {
		error = -EOVERFLOW;
		goto out;
	}

	file->offset = offset_base + offset;
out:	spin_unlock(&file->lock);
	return error ? error : (int64_t)file->offset;
}
Beispiel #4
0
/*
 * -EBADF, -EISDIR, -EFBIG, -ENOSPC
 */
int64_t sys_write(int fd, void *buf, uint64_t count)
{
	struct file *file;
	struct inode *inode;
	int64_t write_len;

	file = unrolled_lookup(&current->fdtable, fd);
	if (file == NULL)
		return -EBADF;
	if ((file->flags & O_WRONLY) == 0)
		return -EBADF;

	assert(file->inum > 0);
	if (is_dir(file->inum))
		return -EISDIR;
	if (!is_regular_file(file->inum))
		return -EBADF;
	inode = inode_get(file->inum);

	spin_lock(&file->lock);
	write_len = file_write(inode, buf, file->offset, count);
	if (write_len < 0)
		goto out;
	assert(file->offset + write_len <= inode->size_low);
	file->offset += write_len;

out:	spin_unlock(&file->lock);
	return write_len;
}
Beispiel #5
0
/*
 * Removes an entry from a directory.
 */
PUBLIC int dir_remove(struct inode *dinode, const char *filename)
{
	struct buffer *buf; /* Block buffer.    */
	struct d_dirent *d; /* Directory entry. */
	struct inode *file; /* File inode.      */
	
	d = dirent_search(dinode, filename, &buf, 0);
	
	/* Not found. */
	if (d == NULL)
		return (-ENOENT);

	/* Cannot remove '.' */
	if (d->d_ino == dinode->num)
	{
		brelse(buf);
		return (-EBUSY);
	}
	
	file = inode_get(dinode->dev, d->d_ino);
	
	/* Failed to get file's inode. */
	if (file == NULL)
	{
		brelse(buf);
		return (-ENOENT);
	}
	
	/* Unlinking directory. */
	if (S_ISDIR(file->mode))
	{
		/* Not allowed. */
		if (!IS_SUPERUSER(curr_proc))
		{
			inode_put(file);
			brelse(buf);
			return (-EPERM);
		}
		
		/* Directory not empty. */
		if (dinode->size)
		{
			inode_put(file);
			brelse(buf);
			return (-EBUSY);			
		}
	}
	
	/* Remove directory entry. */
	d->d_ino = INODE_NULL;
	buf->flags |= BUFFER_DIRTY;
	inode_touch(dinode);
	file->nlinks--;
	inode_touch(file);
	inode_put(file);
	brelse(buf);
	
	return (0);
}
Beispiel #6
0
int sys_link(const char *oldpath, const char *newpath)
{
	int64_t inum, parent_inum;
	const char *child;
	struct inode *inode;

	parent_inum = path_parent_child(newpath, &child, OK_DIR);
	if (parent_inum < 0)
		return parent_inum;
	inum = name_i(oldpath);
	if (inum < 0)
		return inum;
	inode = inode_get(inum);

	return ext2_new_dir_entry(parent_inum, inum, child,
				  inode_mode_to_dir_entry_type(inode->mode));
}
Beispiel #7
0
static void fill_statbuf(uint64_t inum, struct stat *buf)
{
	struct inode *inode;

	assert(inum > 0);
	assert(buf != NULL);
	inode = inode_get(inum);

	memset(buf, 0, sizeof(*buf));
	buf->st_ino = inum;
	buf->st_mode = inode->mode;
	buf->st_nlink = inode->links_count;
	buf->st_uid = inode->uid;
	buf->st_gid = inode->gid_low;
	buf->st_size = inode->size_low;
	buf->st_atime = inode->atime;
	buf->st_mtime = inode->mtime;
	buf->st_ctime = inode->ctime;
}
Beispiel #8
0
int op_getattr(const char *path, struct stat *stbuf)
{
    struct ext4_inode raw_inode;
    struct inode *inode;
    int ret = 0;
    uint64_t size;

    DEBUG("getattr(%s)", path);

    memset(stbuf, 0, sizeof(struct stat));
    ret = inode_get_by_path(path, &raw_inode);

    if (ret < 0) {
        return ret;
    }

    inode = inode_get(0, &raw_inode);
    if (!inode)
        return -ENOMEM;

    size = inode_get_size(inode);
    inode_put(inode);


    DEBUG("getattr done");

    stbuf->st_mode = raw_inode.i_mode;
    stbuf->st_nlink = raw_inode.i_links_count;
    stbuf->st_size = size;
    stbuf->st_blocks = raw_inode.i_blocks_lo;
    stbuf->st_uid = raw_inode.i_uid;
    stbuf->st_gid = raw_inode.i_gid;
    stbuf->st_atime = raw_inode.i_atime;
    stbuf->st_mtime = raw_inode.i_mtime;
    stbuf->st_ctime = raw_inode.i_ctime;

    return 0;
}
int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		printf("Usage: ext2_mkdir <virtual_disk> <virtual_path>\n");
		exit(1);
	}

	int fd = open(argv[1], O_RDWR);

	disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if(disk == MAP_FAILED) {
	    perror("mmap");
	    exit(1);
	}

	struct ext2_inode *parent = inode_get(get_parent_path(argv[2]), disk);
	if(!parent)
	{
		printf("No such path exists\n");
		exit(ENOENT);
	}
	if(inode_get(argv[2], disk))
	{
		printf("Directory/File with that name already exists\n");
		exit(EEXIST);
	}

	//get and set inode
	unsigned int new_inode_num = first_free_inode(disk);
	add_inode_bitmap(new_inode_num, disk);

	struct ext2_group_desc *gd = (struct ext2_group_desc *)(disk + (2 * EXT2_BLOCK_SIZE));
	struct ext2_inode *inode_table = (struct ext2_inode *)(disk + (gd->bg_inode_table * EXT2_BLOCK_SIZE));
	struct ext2_inode *new_inode = &(inode_table[new_inode_num - 1]);

	new_inode->i_mode = EXT2_S_IFDIR;

	//give it a block
	new_inode->i_size = EXT2_BLOCK_SIZE;
	new_inode->i_links_count = 2;
	new_inode->i_blocks = 2;
	unsigned int new_block_num = first_free_block(disk);
	add_block_bitmap(new_block_num, disk);
	new_inode->i_block[0] = new_block_num;
	int i;
	for(i = 1; i < 15; i++)
	{
		new_inode->i_block[i] = 0;
	}

	//set first dir_entry to itself
	struct ext2_dir_entry_2 *new_dir_entry = (struct ext2_dir_entry_2 *)(disk + (new_block_num * EXT2_BLOCK_SIZE));
	new_dir_entry->inode = new_inode_num;
	new_dir_entry->rec_len = sizeof(struct ext2_dir_entry_2) + 4;
	new_dir_entry->name_len = 1;
	new_dir_entry->file_type = EXT2_FT_DIR;
	strncpy(new_dir_entry->name, ".", 1);

	//set another dir_entry to = parent
	new_dir_entry = (struct ext2_dir_entry_2 *)((char *)new_dir_entry + new_dir_entry->rec_len);
	new_dir_entry->inode = ((struct ext2_dir_entry_2 *)(disk + (parent->i_block[0] * EXT2_BLOCK_SIZE)))->inode;
	new_dir_entry->rec_len = EXT2_BLOCK_SIZE - (sizeof(struct ext2_dir_entry_2) + 4);
	new_dir_entry->name_len = 2;
	new_dir_entry->file_type = EXT2_FT_DIR;
	strncpy(new_dir_entry->name, "..", 2);
	parent->i_links_count++;

	//find empty dir_entry in parent and set
	unsigned int total_size;
	struct ext2_dir_entry_2 *prev_entry;
	char *sourceName = &(argv[2][strlen(get_parent_path(argv[2]))]);
	for(i = 0; i < 12 && parent->i_block[i]; i++)
	{
		prev_entry = (struct ext2_dir_entry_2 *)(disk + (parent->i_block[i] * EXT2_BLOCK_SIZE));
		total_size = EXT2_BLOCK_SIZE;
		while(total_size)
		{
			int rounding_error = 0;
			if(strlen(sourceName) % 4)
			{
				rounding_error += 4 - (strlen(sourceName) % 4);
			}
			if(prev_entry->name_len % 4)
			{
				rounding_error += 4 - (prev_entry->name_len % 4);
			}

			if(prev_entry->rec_len >= (2 * sizeof(struct ext2_dir_entry_2)) + strlen(sourceName) + prev_entry->name_len + rounding_error)
			{
				break;
			}
			total_size -= prev_entry->rec_len;
			prev_entry = (struct ext2_dir_entry_2 *)((char *)prev_entry + prev_entry->rec_len);
		}
		if(total_size)
		{
			break;
		}
	}

	if(parent->i_block[i])
	{
		unsigned int prev_size = sizeof(struct ext2_dir_entry_2) + prev_entry->name_len;
		if(prev_entry->name_len % 4)
		{
			prev_size += 4 - (prev_entry->name_len % 4);
		}

		new_dir_entry = (struct ext2_dir_entry_2 *)((char *)prev_entry + prev_size);
		new_dir_entry->inode = new_inode_num;
		new_dir_entry->rec_len = prev_entry->rec_len - prev_size;
		new_dir_entry->name_len = strlen(sourceName);
		new_dir_entry->file_type = EXT2_FT_DIR;
		strncpy(new_dir_entry->name, sourceName, new_dir_entry->name_len);

		prev_entry->rec_len = prev_size;
	}
	else
	{
		parent->i_block[i] = first_free_block(disk);
		add_block_bitmap(parent->i_block[i], disk);
		new_dir_entry = (struct ext2_dir_entry_2 *)(disk + (parent->i_block[i] * EXT2_BLOCK_SIZE));
		new_dir_entry->inode = new_inode_num;
		new_dir_entry->rec_len = EXT2_BLOCK_SIZE;
		new_dir_entry->name_len = strlen(sourceName);
		new_dir_entry->file_type = EXT2_FT_DIR;
		strncpy(new_dir_entry->name, sourceName, new_dir_entry->name_len);

		parent->i_size += EXT2_BLOCK_SIZE;
		parent->i_blocks += 2;
	}	

	return 0;
}
Beispiel #10
0
int splitUnicodeString(Splitter *self,PyObject *doc)
{
    PyObject *word ;
    Py_UNICODE *s;
    int i, inside_word=0, start=0, len;
    register int value, next_value;

    s = PyUnicode_AS_UNICODE(doc);       // start of unicode string
    len = PyUnicode_GET_SIZE(doc);


    for (i=0; i<len; i++,s++) {
        register Py_UNICODE c;

        c = *s;

        if (self->casefolding)
            *s = Py_UNICODE_TOLOWER(c);

        value = inode_get(self, c);

        if (value == MISS ) {
            // cache miss

            value = Py_UNICODE_ISALNUM(c) ? IS_ALNUM : IS_TRASH;
            inode_set(self, c, value);
        }

        if (!inside_word) {
            if (value != IS_TRASH ) {
                start = i;
                inside_word = 1;
            }
        } else {

            if (value == IS_SEPARATOR) {
                register Py_UNICODE next_c = *(s+1);

                next_value = inode_get(self, next_c);

                if (next_value == MISS ) {
                    // cache miss

                    next_value = Py_UNICODE_ISALNUM(next_c) ? IS_ALNUM : IS_TRASH;
                    inode_set(self, next_c, next_value);
                }

                if (next_value == IS_TRASH) {
                    if (! (i-start<2 && ! self->single_chars)) {
                        word = Py_BuildValue("u#", s-(i-start), min(i-start, self->max_len));
                        PyList_Append(self->list, word);
                        Py_XDECREF(word);
                    }
                    start = i;
                    inside_word = 0;
                }

            }

            else if (value==IS_TRASH) {
                if (! (i-start<2 && ! self->single_chars)) {
                    word = Py_BuildValue("u#", s-(i-start), min(i-start, self->max_len));
                    PyList_Append(self->list, word);
                    Py_XDECREF(word);
                }
                start = i;
                inside_word = 0;
            }
        }
    }

    if (inside_word) {
        if (! (i-start<2 && ! self->single_chars)) {
            word = Py_BuildValue("u#", s-(i-start), min(i-start, self->max_len));
            PyList_Append(self->list, word);
            Py_XDECREF(word);
        }
    }

    return 1;
}
Beispiel #11
0
int splitString(Splitter *self,PyObject *doc)
{
    PyObject *word ;
    char *s,*str;
    int i, inside_word=0, start=0;
    Py_ssize_t len;
    register int value, next_value;

    PyBytes_AsStringAndSize(doc, &str, &len);
    s = str;

    for (i=0; i<len; i++,s++) {
        char c = *s;

        if (self->casefolding)
            *s = tolower(c);

        value = inode_get(self, c);


        if (value == MISS ) {
            // cache miss

            value = isalnum(c) ? IS_ALNUM : IS_TRASH;
            inode_set(self, c, value);
        }

        if (!inside_word) {
            if (value != IS_TRASH && value != IS_SEPARATOR) {
                start = i;
                inside_word = 1;
            }
        } else {

            if (value == IS_SEPARATOR) {
                char next_c = *(s+1);

                next_value = inode_get(self, next_c);

                if (next_value == MISS ) {
                    // cache miss

                    next_value = isalnum(next_c) ? IS_ALNUM : IS_TRASH;
                    inode_set(self, next_c, next_value);
                }

                if (next_value == IS_TRASH) {
                    if (! (i-start<2 && ! self->single_chars)) {
                        word = Py_BuildValue("s#", s-(i-start), min(i-start, self->max_len));
                        PyList_Append(self->list, word);
                        Py_XDECREF(word);
                    }
                    start = i;
                    inside_word = 0;
                }

            }
            else if (value == IS_TRASH) {
                if (! (i-start<2 && ! self->single_chars)) {
                    word = Py_BuildValue("s#", s-(i-start), min(i-start, self->max_len));
                    PyList_Append(self->list, word);
                    Py_XDECREF(word);
                }
                start = i;
                inside_word = 0;
            }
        }
    }

    if (inside_word) {
        if (! (i-start<2 && ! self->single_chars)) {
            word = Py_BuildValue("s#", s-(i-start), min(i-start, self->max_len));
            PyList_Append(self->list, word);
            Py_XDECREF(word);
        }
    }

    return 1;
}