コード例 #1
0
ファイル: smack_backend.c プロジェクト: Inkvi/elliptics
static int smack_backend_read(struct smack_backend *s, void *state, struct dnet_cmd *cmd, void *iodata)
{
	struct dnet_io_attr *io = iodata;
	char *data;
	struct index idx;
	int err;

	dnet_convert_io_attr(io);

	smack_setup_idx(&idx, io->id);
	idx.data_size = io->size;

	err = smack_read(s->smack, &idx, &data);
	if (err < 0)
		goto err_out_exit;

	io->size = idx.data_size;
	err = dnet_send_read_data(state, cmd, io, data, -1, io->offset, 0);
	if (err)
		goto err_out_free;

err_out_free:
	free(data);
err_out_exit:
	return err;
}
コード例 #2
0
ファイル: dnet.c プロジェクト: SaveTheRbtz/elliptics
int dnet_remove_local(struct dnet_node *n, struct dnet_id *id)
{
	const size_t cmd_size = sizeof(struct dnet_cmd) + sizeof(struct dnet_io_attr);
	int err;
	char buffer[cmd_size];
	struct dnet_cmd *cmd = (struct dnet_cmd *)buffer;
	struct dnet_io_attr *io = (struct dnet_io_attr *)(cmd + 1);

	memset(buffer, 0, cmd_size);

	cmd->id = *id;
	cmd->size = cmd_size - sizeof(struct dnet_cmd);
	cmd->flags = DNET_FLAGS_NOLOCK;
	cmd->cmd = DNET_CMD_DEL;

	io->flags = DNET_IO_FLAGS_SKIP_SENDING;

	memcpy(io->parent, id->id, DNET_ID_SIZE);
	memcpy(io->id, id->id, DNET_ID_SIZE);

	dnet_convert_io_attr(io);

	err = n->cb->command_handler(n->st, n->cb->command_private, cmd, io);
	dnet_log(n, DNET_LOG_NOTICE, "%s: local remove: err: %d.\n", dnet_dump_id(&cmd->id), err);

	return err;

}
コード例 #3
0
ファイル: leveldb_backend.c プロジェクト: gorodok11/elliptics
static int leveldb_backend_read(struct leveldb_backend *s, void *state, struct dnet_cmd *cmd, void *iodata, int last)
{
	struct dnet_io_attr *io = iodata;
	struct dnet_ext_list elist;
	char *data;
	size_t data_size;
	int err = -EINVAL;
	char *error_string = NULL;

	dnet_ext_list_init(&elist);

	dnet_convert_io_attr(io);
	if (io->size || io->offset) {
		err = -ERANGE;
		goto err_out_exit;
	}

	data = leveldb_get(s->db, s->roptions, (const char *)io->id, DNET_ID_SIZE, &data_size, &error_string);
	if (error_string || !data) {
		if (!data)
			err = -ENOENT;
		goto err_out_exit;
	}

	/* Extract original data and extension list from &data */
	err = dnet_ext_list_extract((void *)&data, (uint64_t *)&data_size,
			&elist, DNET_EXT_FREE_ON_DESTROY);
	if (err != 0)
		goto err_out_exit;
	dnet_ext_list_to_io(&elist, io);

	io->size = data_size;
	if (data_size && data && last)
		cmd->flags &= ~DNET_FLAGS_NEED_ACK;
	err = dnet_send_read_data(state, cmd, io, data, -1, io->offset, 0);
	if (err < 0)
		goto err_out_exit;

	dnet_backend_log(DNET_LOG_NOTICE, "%s: leveldb: : READ: Ok: size: %llu.\n",
			dnet_dump_id(&cmd->id), (unsigned long long)io->size);

err_out_exit:
	dnet_ext_list_destroy(&elist);
	if (err < 0)
		dnet_backend_log(DNET_LOG_ERROR, "%s: leveldb: READ: error: %s: %d\n",
			dnet_dump_id(&cmd->id), error_string, err);

	free(error_string);
	return err;
}
コード例 #4
0
ファイル: dnet.c プロジェクト: miz-take/elliptics
int dnet_stat_local(struct dnet_net_state *st, struct dnet_id *id)
{
	struct dnet_node *n = st->n;
	int size, cmd_size;
	struct dnet_cmd *cmd;
	struct dnet_io_attr *io;
	int err;

	size = 1;
	cmd_size = size + sizeof(struct dnet_cmd) + sizeof(struct dnet_io_attr);

	cmd = malloc(cmd_size);
	if (!cmd) {
		dnet_log(n, DNET_LOG_ERROR, "%s: failed to allocate %d bytes for local stat.\n",
				dnet_dump_id(id), cmd_size);
		err = -ENOMEM;
		goto err_out_exit;
	}

	memset(cmd, 0, cmd_size);

	io = (struct dnet_io_attr *)(cmd + 1);

	memcpy(&cmd->id, id, sizeof(struct dnet_id));
	cmd->size = cmd_size - sizeof(struct dnet_cmd);
	cmd->flags = DNET_FLAGS_NOLOCK;
	cmd->cmd = DNET_CMD_READ;

	io->size = cmd->size - sizeof(struct dnet_io_attr);
	io->offset = 0;
	io->flags = DNET_IO_FLAGS_SKIP_SENDING;

	memcpy(io->parent, id->id, DNET_ID_SIZE);
	memcpy(io->id, id->id, DNET_ID_SIZE);

	dnet_convert_io_attr(io);

	err = n->cb->command_handler(st, n->cb->command_private, cmd, io);
	dnet_log(n, DNET_LOG_INFO, "%s: local stat: io_size: %llu, err: %d.\n", dnet_dump_id(&cmd->id), (unsigned long long)io->size, err);

	free(cmd);

err_out_exit:
	return err;
}
コード例 #5
0
ファイル: smack_backend.c プロジェクト: Inkvi/elliptics
static int smack_backend_write(struct smack_backend *s, void *state, struct dnet_cmd *cmd, void *data)
{
	struct dnet_node *n = dnet_get_node_from_state(state);
	int err;
	struct index idx;
	struct dnet_io_attr *io = data;
	struct dnet_file_info *info;
	struct dnet_addr_attr *a;

	dnet_convert_io_attr(io);
	
	data += sizeof(struct dnet_io_attr);

	smack_setup_idx(&idx, io->id);
	idx.data_size = io->size;

	err = smack_write(s->smack, &idx, data);
	if (err < 0)
		goto err_out_exit;
#if 0
	err = smack_backend_lookup_raw(s, &idx, state, cmd);
	if (err)
		goto err_out_exit;
#else
	a = malloc(sizeof(struct dnet_addr_attr) + sizeof(struct dnet_file_info));
	if (!a) {
		err = -ENOMEM;
		goto err_out_exit;
	}
	info = (struct dnet_file_info *)(a + 1);

	dnet_fill_addr_attr(n, a);
	dnet_convert_addr_attr(a);

	memset(info, 0, sizeof(struct dnet_file_info));
	dnet_convert_file_info(info);

	err = dnet_send_reply(state, cmd, a, sizeof(struct dnet_addr_attr) + sizeof(struct dnet_file_info), 0);
#endif
	dnet_backend_log(DNET_LOG_INFO, "%s: SMACK: : WRITE: Ok: offset: %llu, size: %llu.\n",
			dnet_dump_id(&cmd->id), (unsigned long long)io->offset, (unsigned long long)io->size);

err_out_exit:
	return err;
}
コード例 #6
0
ファイル: dnet.c プロジェクト: miz-take/elliptics
int dnet_remove_local(struct dnet_node *n, struct dnet_id *id)
{
	int cmd_size;
	struct dnet_cmd *cmd;
	struct dnet_io_attr *io;
	int err;

	cmd_size = sizeof(struct dnet_cmd) + sizeof(struct dnet_io_attr);

	cmd = malloc(cmd_size);
	if (!cmd) {
		dnet_log(n, DNET_LOG_ERROR, "%s: failed to allocate %d bytes for local remove.\n",
				dnet_dump_id(id), cmd_size);
		err = -ENOMEM;
		goto err_out_exit;
	}

	memset(cmd, 0, cmd_size);

	io = (struct dnet_io_attr *)(cmd + 1);

	cmd->id = *id;
	cmd->size = cmd_size - sizeof(struct dnet_cmd);
	cmd->flags = DNET_FLAGS_NOLOCK;
	cmd->cmd = DNET_CMD_DEL;

	io->flags = DNET_IO_FLAGS_SKIP_SENDING;

	memcpy(io->parent, id->id, DNET_ID_SIZE);
	memcpy(io->id, id->id, DNET_ID_SIZE);

	dnet_convert_io_attr(io);

	err = n->cb->command_handler(n->st, n->cb->command_private, cmd, io);
	dnet_log(n, DNET_LOG_NOTICE, "%s: local remove: err: %d.\n", dnet_dump_id(&cmd->id), err);

	free(cmd);

err_out_exit:
	return err;

}
コード例 #7
0
ファイル: leveldb_backend.c プロジェクト: gorodok11/elliptics
static int leveldb_backend_write(struct leveldb_backend *s, void *state, struct dnet_cmd *cmd, void *data)
{
	struct dnet_ext_list elist;
	int err = -EINVAL;
	char *error_string = NULL;
	struct dnet_io_attr *io = data;
	void *read_data = NULL;

	dnet_ext_list_init(&elist);

	dnet_convert_io_attr(io);

	data += sizeof(struct dnet_io_attr);

	/* Combine data with empty extension list header */
	err = dnet_ext_list_combine(&data, &io->size, &elist);
	if (err != 0)
		goto err_out_exit;

	/*
	 * key should be locked by elliptics here, so it is safe to run read-modify-write cycle
	 * if one performs write without lock we do not really care that one write may overwrite another one
	 */

	if (io->offset || (io->flags & DNET_IO_FLAGS_APPEND)) {
		size_t data_size;
		size_t offset = io->offset;

		read_data = leveldb_get(s->db, s->roptions, (const char *)io->id, DNET_ID_SIZE, &data_size, &error_string);
		if (error_string || !read_data) {
			free(error_string);
			error_string = NULL;
			goto plain_write;
		}

		if (io->flags & DNET_IO_FLAGS_APPEND) {
			io->offset = 0;
			offset = data_size;
		}

		/*
		 * XXX: Account for extended header
		 */

		if (io->offset > data_size) {
			err = -ERANGE;
			goto err_out_exit;
		}

		if (offset + io->size > data_size) {
			read_data = realloc(read_data, data_size + io->size);
			if (!read_data) {
				err = -ENOMEM;
				goto err_out_exit;
			}
		}

		memcpy(read_data + offset, data, io->size);

		data = read_data;
		if (offset + io->size > data_size)
			io->size = offset + io->size;
		else
			io->size = data_size;
	}

plain_write:
	leveldb_put(s->db, s->woptions, (const char *)cmd->id.id, DNET_ID_SIZE, data, io->size, &error_string);
	if (error_string)
		goto err_out_free;

	if (io->flags & DNET_IO_FLAGS_WRITE_NO_FILE_INFO) {
		cmd->flags |= DNET_FLAGS_NEED_ACK;
		err = 0;
		goto err_out_exit;
	}

	err = dnet_send_file_info_ts_without_fd(state, cmd, 0, io->size, &elist.timestamp);
	if (err < 0)
		goto err_out_free;

	dnet_backend_log(DNET_LOG_NOTICE, "%s: leveldb: : WRITE: Ok: offset: %llu, size: %llu, ioflags: %x.\n",
			dnet_dump_id(&cmd->id), (unsigned long long)io->offset, (unsigned long long)io->size, io->flags);

err_out_free:
	free(data);
err_out_exit:
	dnet_ext_list_destroy(&elist);

	if (err < 0)
		dnet_backend_log(DNET_LOG_ERROR, "%s: leveldb: : WRITE: error: %s: %d.\n",
			dnet_dump_id(&cmd->id), error_string, err);
	free(read_data);
	free(error_string);
	return err;
}