int __send_faf_file_desc(struct rpc_desc *desc, struct file *file)
{
	int r, fdesc_size;
	void *fdesc;

	BUG_ON(!file->f_objid);
	BUG_ON(!(file->f_flags & (O_FAF_SRV|O_FAF_CLT)));

	r = get_faf_file_krg_desc(file, &fdesc, &fdesc_size);
	if (r)
		goto out;

	r = rpc_pack_type(desc, file->f_objid);
	if (r)
		goto out_free_fdesc;

	r = rpc_pack_type(desc, fdesc_size);
	if (r)
		goto out_free_fdesc;

	r = rpc_pack(desc, 0, fdesc, fdesc_size);
	if (r)
		goto out_free_fdesc;

out_free_fdesc:
	kfree(fdesc);

out:
	return r;
}
Example #2
0
static
void handle_faf_poll_wait(struct rpc_desc *desc, void *_msg, size_t size)
{
	struct faf_poll_wait_msg *msg = _msg;
	struct file *file;
	unsigned int revents;
	int err, res = 0;

	if (msg->wait) {
		res = faf_polled_fd_add(desc->client,
					msg->server_fd,
					msg->objid);
		err = rpc_pack_type(desc, res);
		if (err)
			goto err;
	}

	file = fget(msg->server_fd);
	BUG_ON(!file);
	revents = file->f_op->poll(file, NULL);
	fput(file);

	err = rpc_pack_type(desc, revents);
	if (err)
		goto err;

	return;

err:
	if (msg->wait && !res)
		faf_polled_fd_remove(desc->client, msg->server_fd, msg->objid);
	rpc_cancel(desc);
}
Example #3
0
static int do_nodes_remove(struct hotplug_context *ctx)
{
	struct rpc_desc *desc;
	krgnodemask_t nodes;
	kerrighed_node_t node;
	char *page;
	int ret;

	ret = hotplug_start_request(ctx);
	if (ret)
		return ret;

	ret = check_remove_req(ctx);
	if (ret)
		goto err_finish;

	ret = -ENOMEM;
	page = (char *)__get_free_page(GFP_KERNEL);
	if (!page)
		goto err_finish;

	ret = krgnodelist_scnprintf(page, PAGE_SIZE, ctx->node_set.v);
	BUG_ON(ret >= PAGE_SIZE);
	printk("kerrighed: Removing nodes %s ...\n", page);

	free_page((unsigned long)page);

	ret = -ENOMEM;
	krgnodes_copy(nodes, krgnode_online_map);
	desc = rpc_begin_m(NODE_REMOVE, ctx->ns->rpc_comm, &nodes);
	if (!desc)
		goto err_warning;

	ret = rpc_pack_type(desc, ctx->node_set);
	if (ret) {
		rpc_end(desc, 0);
		goto err_warning;
	}

	ret = 0;
	for_each_krgnode_mask(node, nodes)
		rpc_unpack_type_from(desc, node, ret);

	hotplug_finish_request(ctx);

	rpc_pack_type(desc, ret);

	rpc_end(desc, 0);

	printk("kerrighed: Removing nodes succeeded.\n");

out:
	return ret;

err_warning:
	printk(KERN_ERR "kerrighed: Removing nodes failed! err=%d\n", ret);
err_finish:
	hotplug_finish_request(ctx);
	goto out;
}
/** Export an MM struct
 *  @author Renaud Lottiaux
 *
 *  @param  buffer    Buffer to export object data in.
 *  @param  obj_entry  Object entry of the object to export.
 */
int mm_export_object (struct rpc_desc *desc,
		      struct kddm_set *set,
		      struct kddm_obj *obj_entry,
		      objid_t objid,
		      int flags)
{
	struct mm_struct *mm;
	krgsyms_val_t unmap_id, get_unmap_id;

	mm = obj_entry->object;

	krgnode_set (desc->client, mm->copyset);

	rpc_pack(desc, 0, &mm->mm_id, sizeof(unique_id_t));
	rpc_pack(desc, 0, &mm->anon_vma_kddm_id, sizeof(unique_id_t));
	rpc_pack(desc, 0, &mm->context.vdso, sizeof(void*));
	rpc_pack(desc, 0, &mm->copyset, sizeof(krgnodemask_t));

	get_unmap_id = krgsyms_export(mm->get_unmapped_area);
	BUG_ON(mm->get_unmapped_area && get_unmap_id == KRGSYMS_UNDEF);
	rpc_pack_type(desc, get_unmap_id);

	unmap_id = krgsyms_export(mm->unmap_area);
	BUG_ON(mm->unmap_area && unmap_id == KRGSYMS_UNDEF);
	rpc_pack_type(desc, unmap_id);

	return 0;
}
Example #5
0
/** Handler for doing an FSTAT in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_fstat (struct rpc_desc* desc,
		       void *msgIn, size_t size)
{
	struct kstat statbuf;
	struct faf_stat_msg *msg = msgIn;
	long r;

	r = vfs_fstat (msg->server_fd, &statbuf);

	rpc_pack_type(desc, r);
	rpc_pack_type(desc, statbuf);
}
Example #6
0
/** Handler for seeking in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_llseek (struct rpc_desc* desc,
			void *msgIn, size_t size)
{
	struct faf_llseek_msg *msg = msgIn;
	long r = -EINVAL;
	loff_t result;

	r = sys_llseek (msg->server_fd, msg->offset_high, msg->offset_low,
			&result, msg->origin);

	rpc_pack_type(desc, r);
	rpc_pack_type(desc, result);
}
Example #7
0
/** Handler for locking in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_flock(struct rpc_desc *desc,
                      void *msgIn, size_t size)
{
	struct faf_ctl_msg *msg = msgIn;
	const struct cred *old_cred;
	long r = -EINVAL;
	int err;

	old_cred = unpack_override_creds(desc);
	if (IS_ERR(old_cred))
		goto cancel;
	r = remote_sleep_prepare(desc);
	if (r) {
		revert_creds(old_cred);
		goto cancel;
	}

	r = sys_flock (msg->server_fd, msg->cmd);

	remote_sleep_finish();
	revert_creds(old_cred);

	err = rpc_pack_type(desc, r);
	if (err)
		goto cancel;

	return;

cancel:
	rpc_cancel(desc);
}
static int handle_get_pid_cap(struct rpc_desc *desc, void *_msg, size_t size)
{
	struct pid *pid;
	kernel_krg_cap_t cap;
	const struct cred *old_cred;
	int ret;

	pid = krg_handle_remote_syscall_begin(desc, _msg, size,
					      NULL, &old_cred);
	if (IS_ERR(pid)) {
		ret = PTR_ERR(pid);
		goto out;
	}

	ret = krg_get_cap(pid_task(pid, PIDTYPE_PID), &cap);
	if (ret)
		goto out_end;

	ret = rpc_pack_type(desc, cap);
	if (ret)
		goto err_cancel;

out_end:
	krg_handle_remote_syscall_end(pid, old_cred);

out:
	return ret;

err_cancel:
	rpc_cancel(desc);
	goto out_end;
}
Example #9
0
void handle_faf_sendmsg(struct rpc_desc *desc,
			void *msgIn, size_t size)
{
	struct faf_sendmsg_msg *msg = msgIn;
	ssize_t r;
	int err;
	struct msghdr msghdr;

	err = recv_msghdr(desc, &msghdr, msg->total_len, 0);
	if (err) {
		rpc_cancel(desc);
		return;
	}

	err = remote_sleep_prepare(desc);
	if (err)
		goto cancel;

	r = sys_sendmsg (msg->server_fd, &msghdr, msg->flags);

	remote_sleep_finish();

	err = rpc_pack_type(desc, r);
	if (err)
		goto cancel;

out_free:
	free_msghdr(&msghdr);

	return;

cancel:
	rpc_cancel(desc);
	goto out_free;
}
Example #10
0
static void do_local_node_remove(struct rpc_desc *desc,
				 struct hotplug_context *ctx)
{
	struct rpc_communicator *comm = ctx->ns->rpc_comm;
	krgnodemask_t prev_online, new_online;
	int ret;

	SET_KERRIGHED_NODE_FLAGS(KRGFLAGS_STOPPING);
	printk("do_local_node_remove\n");

	krgnodes_copy(prev_online, krgnode_online_map);

	krgnodes_andnot(new_online, krgnode_online_map, ctx->node_set.v);
	atomic_set(&nr_to_wait, krgnodes_weight(new_online));

	printk("...notify local\n");
	hotplug_remove_notify(ctx, HOTPLUG_NOTIFY_REMOVE_LOCAL);

	krgnodes_copy(new_online, krgnode_online_map);

	printk("...notify_distant\n");
	hotplug_remove_notify(ctx, HOTPLUG_NOTIFY_REMOVE_DISTANT);

	printk("...confirm\n");
	rpc_sync_m(NODE_REMOVE_CONFIRM, comm, &new_online,
		   &ctx->node_set, sizeof(ctx->node_set));

	printk("...wait ack\n");
	wait_event(all_removed_wqh, atomic_read(&nr_to_wait) == 0);

	rpc_disable_all();
	rpc_enable(HOTPLUG_FINISH_REQ);

	ret = 0;
	rpc_pack_type(desc, ret);
	rpc_unpack_type(desc, ret);

	rpc_disable(HOTPLUG_FINISH_REQ);

	CLEAR_KERRIGHED_NODE_FLAGS(KRGFLAGS_RUNNING);
	CLEAR_KERRIGHED_CLUSTER_FLAGS(KRGFLAGS_RUNNING);
	clusters_status[kerrighed_subsession_id] = CLUSTER_UNDEF;

	down_write(&kerrighed_init_sem);
	hooks_stop();
	up_write(&kerrighed_init_sem);

	rpc_close_mask(comm, &prev_online);
	rpc_communicator_put(comm);
	ctx->ns->rpc_comm = NULL;

	CLEAR_KERRIGHED_NODE_FLAGS(KRGFLAGS_STOPPING);

	kerrighed_subsession_id = -1;

	rpc_enable(CLUSTER_START);
}
Example #11
0
/*
 * @author Pascal Gallard
 */
static int pid_export_object(struct rpc_desc *desc,
			     struct kddm_set *set,
			     struct kddm_obj *obj_entry,
			     objid_t objid,
			     int flags)
{
	struct pid_kddm_object *obj = obj_entry->object;

	return rpc_pack_type(desc, obj->node_count);
}
Example #12
0
/** Handler for seeking in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_lseek (struct rpc_desc* desc,
		       void *msgIn, size_t size)
{
	struct faf_seek_msg *msg = msgIn;
	off_t r = -EINVAL;

	r = sys_lseek (msg->server_fd, msg->offset, msg->origin);

	rpc_pack_type(desc, r);
}
Example #13
0
/** Handler for doing an FCNTL64 in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_fcntl64 (struct rpc_desc* desc,
			 void *msgIn, size_t size)
{
	struct faf_ctl_msg *msg = msgIn;
	const struct cred *old_cred;
	unsigned long arg;
	long r;
	int err;

	if (msg->cmd == F_GETLK64 || msg->cmd == F_SETLK64 || msg->cmd == F_SETLKW64)
		arg = (unsigned long) &msg->flock64;
	else
		arg = msg->arg;

	old_cred = unpack_override_creds(desc);
	if (IS_ERR(old_cred))
		goto cancel;
	err = remote_sleep_prepare(desc);
	if (err) {
		revert_creds(old_cred);
		goto cancel;
	}

	r = sys_fcntl64 (msg->server_fd, msg->cmd, arg);

	remote_sleep_finish();
	revert_creds(old_cred);

	err = rpc_pack_type(desc, r);
	if (unlikely(err))
		goto cancel;

	if (!r && msg->cmd == F_GETLK64) {
		err = rpc_pack_type(desc, msg->flock64);
		if (unlikely(err))
			goto cancel;
	}

	return;
cancel:
	rpc_cancel(desc);
}
Example #14
0
int remote_sleep_prepare(struct rpc_desc *desc)
{
	int dummy, err;

	current->sighand->action[SIGINT - 1].sa.sa_handler = SIG_DFL;
	err = rpc_pack_type(desc, dummy);
	if (err)
		ignore_signals(current);

	return err;
}
Example #15
0
/** Handler for doing an FSTATFS in a FAF open file.
 *  @author Matthieu Fertré
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
static void handle_faf_fstatfs(struct rpc_desc* desc,
			       void *msgIn, size_t size)
{
	struct statfs statbuf;
	struct faf_statfs_msg *msg = msgIn;
	long r;
	int err_rpc;

	r = sys_fstatfs(msg->server_fd, &statbuf);

	err_rpc = rpc_pack_type(desc, r);
	if (err_rpc)
		goto err_rpc;

	if (!r)
		err_rpc = rpc_pack_type(desc, statbuf);
err_rpc:
	if (err_rpc)
		rpc_cancel(desc);
}
Example #16
0
/* cluster receive the confirmation about the remove operation */
static void handle_node_remove_confirm(struct rpc_desc *desc, void *data, size_t size)
{
	int dummy;

	BUG_ON(desc->client == kerrighed_node_id);
	hotplug_remove_notify((void*)&desc->client, HOTPLUG_NOTIFY_REMOVE_ACK);
	if (rpc_pack_type(desc, dummy))
		rpc_cancel(desc);

	if (atomic_dec_and_test(&nr_to_wait))
		wake_up(&all_removed_wqh);
	printk("Kerrighed: node %d removed\n", desc->client);
}
Example #17
0
long get_appid_from_pid(pid_t pid)
{
	struct rpc_desc *desc;
	kerrighed_node_t n = KERRIGHED_NODE_ID_NONE;
	struct getappid_request_msg msg;
	long app_id;
	int err = 0;

	/* lock the task to be sure it does not exit */
	n = krg_lock_pid_location(pid);
	if (n == KERRIGHED_NODE_ID_NONE)
		return -ESRCH;

	/* the task is local */
	if (n == kerrighed_node_id) {
		app_id =  __get_appid_from_local_pid(pid);
		if (app_id < 0)
			err = app_id;
		goto out_unlock;
	}

	err = -ENOMEM;
	msg.requester = kerrighed_node_id;
	msg.pid = pid;

	desc = rpc_begin(APP_REMOTE_CHKPT, n);
	if (!desc)
		goto out_unlock;
	err = rpc_pack_type(desc, msg);
	if (err)
		goto err;
	err = pack_creds(desc, current_cred());
	if (err)
		goto err;

	err = rpc_unpack_type(desc, app_id);
	if (err)
		goto err;
out_end:
	rpc_end(desc, 0);

out_unlock:
	krg_unlock_pid_location(pid);
	if (err)
		return err;
	return app_id;

err:
	rpc_cancel(desc);
	goto out_end;
}
Example #18
0
static void handle_faf_readv(struct rpc_desc *desc, void *__msg, size_t size)
{
	struct faf_rw_msg *msg = __msg;
	struct faf_rw_ret ret;
	struct file *file;
	struct iovec *iov;
	int iovcnt, err;

	err = alloc_iov(&iov, &iovcnt, msg->count);
	if (err) {
		ret.ret = err;
		iov = NULL;
	}

	err = remote_sleep_prepare(desc);
	if (err)
		goto cancel;

	ret.pos = msg->pos;
	if (iov) {
		file = fget(msg->server_fd);
		ret.ret = vfs_readv(file, iov, iovcnt, &ret.pos);
		fput(file);
	}

	remote_sleep_finish();

	err = rpc_pack_type(desc, ret);
	if (err)
		goto cancel;
	if (ret.ret <= 0)
		goto out_free;

	err = send_iov(desc, iov, iovcnt, ret.ret, 0);
	if (err)
		goto cancel;

out_free:
	if (iov)
		free_iov(iov, iovcnt);

	return;

cancel:
	rpc_cancel(desc);
	goto out_free;
}
Example #19
0
static void do_other_node_remove(struct rpc_desc *desc,
				 struct hotplug_context *ctx)
{
	int ret;

	printk("do_other_node_remove\n");
	atomic_set(&nr_to_wait, krgnodes_weight(ctx->node_set.v));
	hotplug_remove_notify(ctx, HOTPLUG_NOTIFY_REMOVE_ADVERT);
	rpc_async_m(NODE_REMOVE_ACK, ctx->ns->rpc_comm, &ctx->node_set.v, NULL, 0);
	wait_event(all_removed_wqh, atomic_read(&nr_to_wait) == 0);

	ret = 0;
	rpc_pack_type(desc, ret);
	rpc_unpack_type(desc, ret);

	rpc_close_mask(ctx->ns->rpc_comm, &ctx->node_set.v);
}
Example #20
0
/** Handler for doing an IOCTL in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_ioctl(struct rpc_desc *desc,
		      void *msgIn, size_t size)
{
	struct faf_ctl_msg *msg = msgIn;
	struct prev_root prev_root;
	const struct cred *old_cred;
	long r;
	int err;

	err = unpack_context(desc, &prev_root, &old_cred);
	if (err) {
		rpc_cancel(desc);
		return;
	}

	err = remote_sleep_prepare(desc);
	if (err)
		goto out_err;

	err = prepare_ruaccess(desc);
	if (err)
		goto out_sleep_finish;

	r = sys_ioctl(msg->server_fd, msg->cmd, msg->arg);

	err = cleanup_ruaccess(desc);
	if (err)
		goto out_sleep_finish;

	err = rpc_pack_type(desc, r);

out_sleep_finish:
	remote_sleep_finish();
	if (err)
		goto out_err;

out:
	restore_context(&prev_root, old_cred);

	return;

out_err:
	rpc_cancel(desc);
	goto out;
}
Example #21
0
int handle_faf_getpeername (struct rpc_desc* desc,
			    void *msgIn, size_t size)
{
	struct faf_bind_msg *msg = msgIn;
	struct prev_root prev_root;
	int r;

	unpack_root(desc, &prev_root);

	r = sys_getpeername(msg->server_fd,
			    (struct sockaddr *)&msg->sa, &msg->addrlen);

	rpc_pack_type(desc, msg->addrlen);
	rpc_pack(desc, 0, &msg->sa, msg->addrlen);

	chroot_to_prev_root(&prev_root);

	return r;
}
Example #22
0
/*
 * @author Pascal Gallard
 */
static int task_export_object(struct rpc_desc *desc,
			      struct kddm_set *set,
			      struct kddm_obj *obj_entry,
			      objid_t objid,
			      int flags)
{
	struct task_kddm_object *src = obj_entry->object;
	struct task_struct *tsk;

	read_lock(&tasklist_lock);
	tsk = src->task;
	if (likely(tsk)) {
		task_lock(tsk);
		task_update_object(src);
		task_unlock(tsk);
	}
	read_unlock(&tasklist_lock);

	return rpc_pack_type(desc, *src);
}
Example #23
0
void handle_faf_setsockopt (struct rpc_desc *desc,
			    void *msgIn, size_t size)
{
	struct faf_setsockopt_msg *msg = msgIn;
	struct prev_root prev_root;
	const struct cred *old_cred;
	int r, err;

	err = unpack_context(desc, &prev_root, &old_cred);
	if (err) {
		rpc_cancel(desc);
		return;
	}

	err = prepare_ruaccess(desc);
	if (err)
		goto out_err;
	r = sys_setsockopt(msg->server_fd, msg->level, msg->optname,
			   msg->optval, msg->optlen);
	err = cleanup_ruaccess(desc);
	if (err)
		goto out_err;
	err = rpc_pack_type(desc, r);
	if (err)
		goto out_err;

exit:
	restore_context(&prev_root, old_cred);

	return;

out_err:
	rpc_cancel(desc);
	if (err > 0)
		err = -ENOMEM;
	r = err;
	goto exit;
}
Example #24
0
static
void handle_get_appid_from_pid(struct rpc_desc *desc, void *_msg, size_t size)
{
	struct getappid_request_msg *msg = _msg;
	long app_id;
	const struct cred *old_cred;
	int err;

	old_cred = unpack_override_creds(desc);
	if (IS_ERR(old_cred)) {
		err = PTR_ERR(old_cred);
		goto out;
	}

	app_id = __get_appid_from_local_pid(msg->pid);

	revert_creds(old_cred);

	err = rpc_pack_type(desc, app_id);

out:
	if (err)
		rpc_cancel(desc);
}
Example #25
0
int cluster_barrier(struct cluster_barrier *barrier,
		    krgnodemask_t *nodes,
		    kerrighed_node_t master)
{
	struct cluster_barrier_core *core_bar;
	struct cluster_barrier_id id;
	struct rpc_desc *desc;
	int err = 0;

	BUG_ON (!__krgnode_isset(kerrighed_node_id, nodes));
	BUG_ON (!__krgnode_isset(master, nodes));

	spin_lock(&barrier->lock);
	barrier->id.toggle = (barrier->id.toggle + 1) % 2;
	id = barrier->id;
	core_bar = &barrier->core[id.toggle];
	if (core_bar->in_barrier)
		err = -EBUSY;
	core_bar->in_barrier = 1;
	spin_unlock(&barrier->lock);
	if (err)
		return err;

	desc = rpc_begin(RPC_ENTER_BARRIER, master);

	rpc_pack_type (desc, id);
	rpc_pack(desc, 0, nodes, sizeof(krgnodemask_t));

	rpc_end(desc, 0);

	/* Wait for the barrier to complete */

	wait_event (core_bar->waiting_tsk, (core_bar->in_barrier == 0));

	return 0;
}
Example #26
0
void handle_faf_connect(struct rpc_desc *desc,
			void *msgIn, size_t size)
{
	struct faf_bind_msg *msg = msgIn;
	struct prev_root prev_root;
	const struct cred *old_cred;
	int r, err;

	r = unpack_context(desc, &prev_root, &old_cred);
	if (r) {
		rpc_cancel(desc);
		return;
	}

	r = remote_sleep_prepare(desc);
	if (r)
		goto cancel;

	r = sys_connect(msg->server_fd,
			(struct sockaddr *)&msg->sa, msg->addrlen);

	remote_sleep_finish();

	err = rpc_pack_type(desc, r);
	if (err)
		goto cancel;

out:
	restore_context(&prev_root, old_cred);

	return;

cancel:
	rpc_cancel(desc);
	goto out;
}
Example #27
0
void handle_faf_accept (struct rpc_desc *desc,
		        void *msgIn, size_t size)
{
	struct faf_bind_msg *msg = msgIn;
	int err, r;
	struct file *file;

	r = remote_sleep_prepare(desc);
	if (r)
		goto err_cancel;

	r = sys_accept(msg->server_fd,
		       (struct sockaddr *)&msg->sa, &msg->addrlen);

	remote_sleep_finish();

	err = rpc_pack_type(desc, r);
	if (err)
		goto err_close_file;

	if (r < 0)
		return;

	file = fcheck_files(current->files, r);

	if (!file->f_objid) {
		err = create_kddm_file_object(file);
		if (err)
			goto err_close_file;
	}

	file->f_flags |= O_FAF_SRV;
	file->f_faf_srv_index = r;

	/* Increment the DVFS count for the client node */
	get_dvfs_file(r, file->f_objid);

	err = rpc_pack_type(desc, msg->addrlen);
	if (err)
		goto err_close_faf_file;

	err = rpc_pack(desc, 0, &msg->sa, msg->addrlen);
	if (err)
		goto err_close_faf_file;

	err = __send_faf_file_desc(desc, file);
	if (err)
		goto err_close_faf_file;

	err = rpc_unpack_type(desc, r);
	if (err)
		goto err_close_faf_file;

out:
	return;

err_cancel:
	rpc_cancel(desc);
	goto out;

err_close_faf_file:
	/* The client couldn't setup a FAF client file. */
	put_dvfs_file(file->f_faf_srv_index, file);
	check_close_faf_srv_file(file);
	goto err_cancel;

err_close_file:
	if (r >= 0)
		sys_close(r);
	goto err_cancel;
}
Example #28
0
/** Handler for d_path in a FAF open file.
 *  @author Renaud Lottiaux
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_d_path (struct rpc_desc* desc,
			void *msgIn, size_t size)
{
	struct faf_d_path_msg *msg = msgIn;
	char *buff, *file_name = NULL;
	struct file *file;
	struct prev_root prev_root;
	const struct cred *old_cred;
	bool deleted = false;
	int len;
	int err;

	old_cred = unpack_override_creds(desc);
	if (IS_ERR(old_cred)) {
		rpc_cancel(desc);
		return;
	}
	err = unpack_root(desc, &prev_root);
	if (err) {
		revert_creds(old_cred);
		rpc_cancel(desc);
		return;
	}

	buff = kmalloc (msg->count, GFP_KERNEL);

	file = fcheck_files (current->files, msg->server_fd);
	/* Remote caller holds a reference so it can't disappear. */
	BUG_ON(!file);
	if (msg->deleted)
		file_name = d_path_check(&file->f_path, buff, msg->count, &deleted);
	else
		file_name = d_path(&file->f_path, buff, msg->count);
	if (IS_ERR(file_name))
		len = PTR_ERR(file_name);
	else
		len = strlen(file_name) + 1;

	err = rpc_pack_type(desc, len);
	if (err)
		goto err_cancel;
	if (len >= 0) {
		err = rpc_pack(desc, 0, file_name, len);
		if (err)
			goto err_cancel;
		if (msg->deleted) {
			err = rpc_pack_type(desc, deleted);
			if (err)
				goto err_cancel;
		}
	}

out:
	kfree (buff);

	chroot_to_prev_root(&prev_root);
	revert_creds(old_cred);

	return;

err_cancel:
	rpc_cancel(desc);
	goto out;
}
Example #29
0
/** Handler for reading in a FAF open file.
 *  @author Renaud Lottiaux, Matthieu Fertré
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_read(struct rpc_desc* desc, void *msgIn, size_t size)
{
	struct faf_rw_msg *msg = msgIn;
	struct file *file = NULL;
	char *buf = NULL;
	long buf_size = PAGE_SIZE;
	ssize_t to_read, r;
	loff_t fpos;
	int err;

	err = remote_sleep_prepare(desc);
	if (err) {
		rpc_cancel(desc);
		return;
	}

	to_read = msg->count;
	fpos = msg->pos;

	r = -ENOMEM;
	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!buf)
		goto error;

	file = fget(msg->server_fd);

	while (to_read > 0) {
		if (to_read < PAGE_SIZE)
			buf_size = to_read;

		r = vfs_read(file, buf, buf_size, &fpos);

		if (r > 0) {
			err = rpc_pack_type(desc, r);
			if (err)
				goto cancel;
			err = rpc_pack(desc, 0, buf, r);
			if (err)
				goto cancel;
		}

		/*
		 * Check if we have reach the end of the file
		 * or if there is an error
		 */
		if (r < buf_size)
			break;

		to_read -= r;
	}

error:
	/*
	 * Pack the end of transmission mark (0)
	 * or the error returned by vfs_read()
	 */
	if (r > 0)
		r = 0;
	err = rpc_pack_type(desc, r);
	if (err)
		goto cancel;

	/* send the updated file position */
	err = rpc_pack_type(desc, fpos);
	if (err)
		goto cancel;

out:
	if (buf)
		kfree(buf);
	if (file)
		fput(file);

	remote_sleep_finish();
	return;

cancel:
	rpc_cancel(desc);
	goto out;
}
Example #30
0
/** Handler for writing in a FAF open file.
 *  @author Renaud Lottiaux, Matthieu Fertré
 *
 *  @param from    Node sending the request
 *  @param msgIn   Request message
 */
void handle_faf_write(struct rpc_desc* desc, void *msgIn, size_t size)
{
	struct faf_rw_msg *msg = msgIn;
	struct file *file = NULL;
	long to_recv;
	char *buf = NULL;
	ssize_t buf_size = PAGE_SIZE;
	ssize_t r, nr_received = -ENOMEM;
	loff_t fpos;
	int err;

	r = remote_sleep_prepare(desc);
	if (r) {
		rpc_cancel(desc);
		return;
	}

	to_recv = msg->count;
	fpos = msg->pos;

	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!buf)
		goto error;

	nr_received = 0;

	file = fget(msg->server_fd);

	while (to_recv > 0) {
		err = rpc_unpack_type(desc, buf_size);
		if (err)
			goto cancel;

		/* copy_from_user has failed on the other side */
		if (buf_size < 0) {
			nr_received = buf_size;
			break;
		}

		err = rpc_unpack(desc, 0, buf, buf_size);
		if (err)
			goto cancel;

		r = vfs_write(file, buf, buf_size, &fpos);

		/* The last write failed. Break the write sequence */
		if (r < 0) {
			nr_received = r;
			break;
		}
		nr_received += r;
		to_recv -= buf_size;
	}

error:
	err = rpc_pack_type(desc, nr_received);
	if (err)
		goto cancel;

	/* send the updated file position */
	err = rpc_pack_type(desc, fpos);
	if (err)
		goto cancel;

out:
	if (buf)
		kfree(buf);
	if (file)
		fput(file);

	remote_sleep_finish();
	return;

cancel:
	rpc_cancel(desc);
	goto out;
}