Пример #1
0
static int
dup2_fd(int oldfd, int newfd, bool kernel)
{
	struct file_descriptor *evicted = NULL;
	struct io_context *context;

	TRACE(("dup2_fd: ofd = %d, nfd = %d\n", oldfd, newfd));

	// quick check
	if (oldfd < 0 || newfd < 0)
		return FSSH_B_FILE_ERROR;

	// Get current I/O context and lock it
	context = get_current_io_context(kernel);
	fssh_mutex_lock(&context->io_mutex);

	// Check if the fds are valid (mutex must be locked because
	// the table size could be changed)
	if ((uint32_t)oldfd >= context->table_size
		|| (uint32_t)newfd >= context->table_size
		|| context->fds[oldfd] == NULL) {
		fssh_mutex_unlock(&context->io_mutex);
		return FSSH_B_FILE_ERROR;
	}

	// Check for identity, note that it cannot be made above
	// because we always want to return an error on invalid
	// handles
	if (oldfd != newfd) {
		// Now do the work
		evicted = context->fds[newfd];
		fssh_atomic_add(&context->fds[oldfd]->ref_count, 1);
		fssh_atomic_add(&context->fds[oldfd]->open_count, 1);
		context->fds[newfd] = context->fds[oldfd];

		if (evicted == NULL)
			context->num_used_fds++;
	}

	fd_set_close_on_exec(context, newfd, false);

	fssh_mutex_unlock(&context->io_mutex);

	// Say bye bye to the evicted fd
	if (evicted) {
		close_fd(evicted);
		put_fd(evicted);
	}

	return newfd;
}
Пример #2
0
int
new_fd_etc(struct io_context *context, struct file_descriptor *descriptor,
	int firstIndex)
{
	int fd = -1;
	uint32_t i;

	fssh_mutex_lock(&context->io_mutex);

	for (i = firstIndex; i < context->table_size; i++) {
		if (!context->fds[i]) {
			fd = i;
			break;
		}
	}
	if (fd < 0) {
		fd = FSSH_B_NO_MORE_FDS;
		goto err;
	}

	context->fds[fd] = descriptor;
	context->num_used_fds++;
	fssh_atomic_add(&descriptor->open_count, 1);

err:
	fssh_mutex_unlock(&context->io_mutex);

	return fd;
}
Пример #3
0
static int
dup_fd(int fd, bool kernel)
{
	struct io_context *context = get_current_io_context(kernel);
	struct file_descriptor *descriptor;
	int status;

	TRACE(("dup_fd: fd = %d\n", fd));

	// Try to get the fd structure
	descriptor = get_fd(context, fd);
	if (descriptor == NULL)
		return FSSH_B_FILE_ERROR;

	// now put the fd in place
	status = new_fd(context, descriptor);
	if (status < 0)
		put_fd(descriptor);
	else {
		fssh_mutex_lock(&context->io_mutex);
		fd_set_close_on_exec(context, status, false);
		fssh_mutex_unlock(&context->io_mutex);
	}

	return status;
}
Пример #4
0
static struct file_descriptor *
remove_fd(struct io_context *context, int fd)
{
	struct file_descriptor *descriptor = NULL;

	if (fd < 0)
		return NULL;

	fssh_mutex_lock(&context->io_mutex);

	if ((uint32_t)fd < context->table_size)
		descriptor = context->fds[fd];

	if (descriptor)	{
		// fd is valid
		context->fds[fd] = NULL;
		fd_set_close_on_exec(context, fd, false);
		context->num_used_fds--;

		if (descriptor->open_mode & FSSH_O_DISCONNECTED)
			descriptor = NULL;
	}

	fssh_mutex_unlock(&context->io_mutex);

	return descriptor;
}
Пример #5
0
struct file_descriptor *
get_fd(struct io_context *context, int fd)
{
	struct file_descriptor *descriptor = NULL;

	if (fd < 0)
		return NULL;

	fssh_mutex_lock(&context->io_mutex);

	if ((uint32_t)fd < context->table_size)
		descriptor = context->fds[fd];

	if (descriptor != NULL) {
		// Disconnected descriptors cannot be accessed anymore
		if (descriptor->open_mode & FSSH_O_DISCONNECTED)
			descriptor = NULL;
		else
			inc_fd_ref_count(descriptor);
	}

	fssh_mutex_unlock(&context->io_mutex);

	return descriptor;
}
Пример #6
0
static fssh_status_t
read_from_file(file_cache_ref *ref, void *cookie, fssh_off_t offset,
               int32_t pageOffset, fssh_addr_t buffer, fssh_size_t bufferSize)
{
    fssh_iovec vec;
    vec.iov_base = (void *)buffer;
    vec.iov_len = bufferSize;

    fssh_mutex_unlock(&ref->lock);

    fssh_status_t status = vfs_read_pages(ref->node, cookie,
                                          offset + pageOffset, &vec, 1, &bufferSize);

    fssh_mutex_lock(&ref->lock);

    return status;
}