コード例 #1
0
ファイル: path.c プロジェクト: Dennisbonke/DB-OS
/* This is the main workhorse for the virtual filesystem. Given a start point and
 * a path string, it resolves the path into a directory entry. This is simply a
 * matter of looping through the path (seperated at '/', of course), and reading
 * the successive directory entries and inodes (see vfs_dirent_lookup and
 * vfs_dirent_readinode). The one thing it needs to pay attention to is the case
 * of traversing backwards up through a mount point. */
struct dirent *fs_do_path_resolve(struct inode *start, const char *path, int sym_start_level, int *result)
{
	vfs_inode_get(start);
	ASSERT(start);
	if(!*path)
		path = ".";
	if(result) *result = 0;
	
	struct inode *node = start;
	struct dirent *dir = 0;
	struct inode *nextnode = 0;
	while(node && *path) {
		if(dir) {
			vfs_dirent_release(dir);
			dir = 0;
		}
		char *delim = strchr(path, '/');
		if(delim != path) {
			nextnode = 0;
			const char *name = path;
			size_t namelen = delim ? (size_t)(delim - name) : strlen(name);
			dir = fs_dirent_lookup(node, name, namelen);
			if(!dir) {
				if(result) *result = -ENOENT;
				vfs_icache_put(node);
				return 0;
			}
			if(delim) {
				nextnode = fs_dirent_readinode(dir, true);
				if(namelen == 2 && !strncmp("..", name, 2)
						&& node->id == node->filesystem->root_inode_id) {
					// Traverse back up through a mount.
					vfs_inode_get(nextnode->filesystem->point);
					struct inode *tmp = nextnode;
					nextnode = nextnode->filesystem->point;
					vfs_icache_put(tmp);
				} else if(nextnode) {
					if((*result = fs_resolve_iter_symlink(&dir, &nextnode, sym_start_level))) {
						vfs_icache_put(node);
						return 0;
					}
					nextnode = fs_resolve_mount(nextnode);
					if(!nextnode) {
						vfs_icache_put(node);
						return 0;
					}
				}
			}
			vfs_icache_put(node);
			node = nextnode;
		}
		path = delim + 1;
	}
	if(nextnode)
		vfs_icache_put(nextnode);
	return dir;
}
コード例 #2
0
ファイル: pty.c プロジェクト: AshishKumar4/seakernel
int sys_openpty(int *master, int *slave, char *slavename, const struct termios *term,
		const struct winsize *win)
{
	int num = atomic_fetch_add(&__pty_next_num, 1);
	char mname[32];
	char sname[32];
	snprintf(mname, 32, "/dev/ptym%d", num);
	snprintf(sname, 32, "/dev/ptys%d", num);

	sys_mknod(mname, S_IFCHR | 0666, GETDEV(pty_major, num));
	sys_mknod(sname, S_IFCHR | 0666, GETDEV(pty_major, num));

	int mfd = sys_open(mname, O_RDWR, 0);
	int sfd = sys_open(sname, O_RDWR, 0);
	if(mfd < 0 || sfd < 0) {
		sys_unlink(mname);
		sys_unlink(sname);
		return -ENOENT;
	}

	struct file *mf = file_get(mfd);
	struct file *sf = file_get(sfd);
	vfs_inode_get(mf->inode);
	vfs_inode_get(sf->inode);
	
	pty_create(mf->inode);
	sf->inode->devdata = mf->inode->devdata;
	struct pty *pty = mf->inode->devdata;
	assert(pty);
	
	pty->master = mf->inode;
	pty->slave = sf->inode;
	pty->num = num;
	if(term)
		memcpy(&pty->term, term, sizeof(*term));
	if(win)
		memcpy(&pty->size, win, sizeof(*win));
	file_put(mf);
	file_put(sf);

	if(slavename)
		strncpy(slavename, sname, 32);
	if(master)
		*master = mfd;
	if(slave)
		*slave = sfd;
	return 0;
}
コード例 #3
0
ファイル: inode.c プロジェクト: AshishKumar4/seakernel
void vfs_inode_mount(struct inode *node, struct filesystem *fs)
{
	assert(!node->mount);
	node->mount = fs;
	vfs_inode_get(node);
	fs->point = node;
}
コード例 #4
0
ファイル: inode.c プロジェクト: AshishKumar4/seakernel
int vfs_inode_chdir(struct inode *node)
{
	if(!S_ISDIR(node->mode))
		return -ENOTDIR;
	struct inode *old = current_process->cwd;
	current_process->cwd = node;
	vfs_inode_get(node);
	vfs_icache_put(old);
	return 0;
}
コード例 #5
0
ファイル: inode.c プロジェクト: AshishKumar4/seakernel
int vfs_inode_chroot(struct inode *node)
{
	if(!S_ISDIR(node->mode))
		return -ENOTDIR;
	if(current_process->effective_uid)
		return -EPERM;
	struct inode *old = current_process->root;
	current_process->root = node;
	vfs_inode_get(node);
	vfs_icache_put(old);
	return 0;
}
コード例 #6
0
ファイル: dirent.c プロジェクト: AshishKumar4/seakernel
/* This function returns the directory entry associated with the name 'name' under
 * the inode 'node'. It must be careful to lookup the entry in the cache first. */
struct dirent *fs_dirent_lookup(struct inode *node, const char *name, size_t namelen)
{
	if(!vfs_inode_check_permissions(node, MAY_READ, 0))
		return 0;
	if(!S_ISDIR(node->mode))
		return 0;
	if(node == current_process->root && !strncmp(name, "..", 2) && namelen == 2)
		return fs_dirent_lookup(node, ".", 1);
	mutex_acquire(dirent_cache_lock);
	rwlock_acquire(&node->lock, RWL_WRITER);
	struct dirent *dir = vfs_inode_get_dirent(node, name, namelen);
	if(!dir) {
		dir = vfs_dirent_create(node);
		dir->count = 1;
		strncpy(dir->name, name, namelen);
		dir->namelen = namelen;
		int r = fs_callback_inode_lookup(node, name, namelen, dir);
		if(r) {
			dir->count = 0;
			vfs_dirent_destroy(dir);
			rwlock_release(&node->lock, RWL_WRITER);
			mutex_release(dirent_cache_lock);
			return 0;
		}
		vfs_inode_get(node);
		vfs_inode_add_dirent(node, dir);
	} else {
		if(atomic_fetch_add(&dir->count, 1) == 0) {
			fs_dirent_remove_lru(dir);
			vfs_inode_get(node);
		}
	}
	rwlock_release(&node->lock, RWL_WRITER);
	mutex_release(dirent_cache_lock);
	return dir;
}