提交 18f85aef 编写于 作者: Z Zheng Zengkai

Revert "bcache: Add a sample of userspace prefetch client"

euleros/rtos inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4LOJ6
CVE: NA

--------------------------------

This patch set introduce many conflicts while backporting mainline
bcache patches, revert it temporarily.

This reverts commit 87f258f0.
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
上级 e4c0fe5d
.PHONY: client clean
CC = $(CROSS_COMPILE)gcc
CFLAGS = -Wall -g
OBJ = main.o connect.o
client: ${OBJ}
$(CC) $(CFLAGS) $^ -o acache_client
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o acache_client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include "connect.h"
static int ACACHE_READWRITE_CAPACITY = 4096;
static struct connection readwrite_conn;
static struct readwrite_conn_metadata {
int initialized;
int fd;
} private;
void *initialize(struct connection *self)
{
long ret;
private.fd = open(acache_path, O_RDWR | O_SYNC);
if (private.fd == -1) {
fprintf(stderr, "error opening device: %s\n", strerror(errno));
exit(-1);
}
struct acache_metadata {
uint32_t magic;
uint32_t conntype;
uint32_t devsize;
} acache_metadata;
#define ACACHE_GET_METADATA _IOR('a', 1, struct acache_metadata)
ret = ioctl(private.fd, ACACHE_GET_METADATA, &acache_metadata);
if (ret) {
fprintf(stderr, "error getting device memory length: %s\n", strerror(errno));
exit(-1);
}
if (acache_metadata.magic != ACACHE_MAGIC) {
fprintf(stderr, "version not match; client: %u kernel: %u\n",
ACACHE_MAGIC, acache_metadata.magic);
exit(-1);
}
if (acache_metadata.conntype != ACACHE_READWRITE_CONN) {
fprintf(stderr, "connect type not match; client: %u kernel: %u\n",
ACACHE_READWRITE_CONN, acache_metadata.conntype);
exit(-1);
}
printf("got dev size %u\n", acache_metadata.devsize);
private.initialized = 1;
return (void *)&private;
}
struct readwrite_conn_metadata* get_metadata(struct connection *self)
{
struct readwrite_conn_metadata *metadata;
if (self == NULL) {
fprintf(stderr, "connenction uninitailized\n");
return NULL;
}
metadata = (struct readwrite_conn_metadata *)self->private;
if (metadata->initialized == 0) {
fprintf(stderr, "connenction uninitailized\n");
return NULL;
}
return metadata;
}
int send_items(struct connection *self, struct acache_info *infos,
size_t count)
{
long ret;
struct readwrite_conn_metadata *metadata = get_metadata(self);
if (!metadata) {
return 0;
}
ret = write(metadata->fd, (void*)infos, count * sizeof(struct acache_info));
if (ret < 0) {
fprintf(stderr, "error writing data: %ld\n", ret);
return 0;
}
if (ret % sizeof(struct acache_info)) {
fprintf(stderr, "error writing data: data length is not multiple of sizeof(struct acache_info): %ld %ld\n",
ret, sizeof(struct acache_info));
return 0;
}
return ret / sizeof(struct acache_info);
}
int fetch_items(struct connection *self, struct acache_info *infos,
size_t count)
{
long ret;
struct readwrite_conn_metadata *metadata = get_metadata(self);
if (!metadata) {
return 0;
}
ret = read(metadata->fd, (void*)infos, count * sizeof(struct acache_info));
if (ret < 0) {
fprintf(stderr, "error reading data: %ld\n", ret);
return 0;
}
if (ret % sizeof(struct acache_info)) {
fprintf(stderr, "error reading data: data length is not multiple of sizeof(struct acache_info): %ld %ld\n",
ret, sizeof(struct acache_info));
return 0;
}
return ret / sizeof(struct acache_info);
}
int get_capacity() {
return ACACHE_READWRITE_CAPACITY;
}
int close_conn(struct connection *self)
{
struct readwrite_conn_metadata *metadata = get_metadata(self);
if (!metadata) {
return 0;
}
close(metadata->fd);
return 0;
}
struct connection *initialize_conn_rw(void)
{
readwrite_conn.ops.close = close_conn;
readwrite_conn.ops.initialize = initialize;
readwrite_conn.ops.send_items = send_items;
readwrite_conn.ops.fetch_items = fetch_items;
readwrite_conn.ops.get_capacity = get_capacity;
readwrite_conn.private = initialize(&readwrite_conn);
return &readwrite_conn;
}
#ifndef ACACHE_CONNENECT_H
#define ACACHE_CONNENECT_H
#include <stdint.h>
#define ACACHE_MAGIC 2
enum acache_conn_types {
ACACHE_NO_CONN = 0,
ACACHE_RINGBUFFER_CONN,
ACACHE_READWRITE_CONN,
};
#define acache_path "/dev/acache"
struct acache_info {
uint64_t length;
uint64_t offset;
uint64_t start_time;
uint32_t dev;
int opcode;
};
struct connection;
struct connection_operations {
/*
* initialize connnection
* parameters: none
* return values:
* - void *: private data for connection
*/
void *(*initialize)(struct connection *self);
/*
* send_items send items to peer side
* parameters:
* - infos: data to send
* - count: data length
* return values:
* - number of sent items
*/
int (*send_items)(struct connection *self, struct acache_info *infos,
size_t count);
/*
* send_items recieve items from peer side
* paremeters:
* - infos: buffer to place recieved items
* - count: length of buffer
* return values:
* - number of recieved items
*/
int (*fetch_items)(struct connection *self, struct acache_info *infos,
size_t count);
/*
* close closes the connection
*/
int (*close)(struct connection *self);
/*
* get_capacity return the capacity of items that can send and revice at once
*/
int (*get_capacity)(struct connection *self);
};
struct connection {
/*
* private data for specific connnetion
*/
void *private;
struct connection_operations ops;
};
struct connection *initialize_conn_rw(void);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include "connect.h"
/*
* dev_t in userspace is 8-bytes long but 4-byte long in kernel
* work around this
*/
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
#define MKDEV(ma, mi) ((ma)<<MINORBITS | (mi))
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
struct acache_info *inbuf, *outbuf;
struct connection *conn;
void print_infos(const char *prefix, struct acache_info *infos, size_t length)
{
size_t i;
struct acache_info *info;
for (i = 0; i < length; i++) {
info = infos + i;
printf("%4s,%20lu,%8u,%8u,%15lu,%12lu\n",
prefix, info->start_time, MAJOR(info->dev),
MINOR(info->dev), info->offset, info->length);
}
}
int malloc_buffers(struct acache_info **inbuf, struct acache_info **outbuf,
size_t capacity)
{
/* prepare buffers to store incoming or outgoing items */
*inbuf = (struct acache_info *)malloc(sizeof(struct acache_info) * capacity);
*outbuf = (struct acache_info *)malloc(sizeof(struct acache_info) * capacity);
if (!*inbuf || !*outbuf) {
fprintf(stderr, "error malloc memory: %s\n, size: %lu, %lu\n",
strerror(errno),
sizeof(struct acache_info) * capacity,
sizeof(struct acache_info) * capacity);
return -errno;
}
return 0;
}
void free_buffer(struct acache_info **buf)
{
if (buf && *buf) {
free(*buf);
*buf = NULL;
}
}
void elegant_exit(int sig) {
printf("exiting...");
free_buffer(&inbuf);
free_buffer(&outbuf);
conn->ops.close(conn);
exit(0);
}
int main(int argc, char **argv)
{
int debug = 0;
int ret;
int outbuf_tail;
size_t capacity;
conn = initialize_conn_rw();
if (conn == NULL) {
fprintf(stderr, "error initialzied connnection\n");
return -1;
}
if (argc > 1 && strcmp("-d", argv[1]) == 0)
debug = 1;
/* prepare buffers to store incoming or outgoing items */
capacity = conn->ops.get_capacity(conn);
ret = malloc_buffers(&inbuf, &outbuf, capacity);
if (ret < 0)
return ret;
if (debug) {
printf("%4s,%20s,%8s,%8s,%15s,%12s\n",
"op","time(ns)","majorDev","minorDev","offset(B)","length(B)");
}
/* main loop */
if (signal(SIGINT, elegant_exit) == SIG_ERR) {
fprintf(stderr, "error handling SIGINT: %s\n", strerror(errno));
}
if (signal(SIGTERM, elegant_exit) == SIG_ERR) {
fprintf(stderr, "error handling SIGTERM: %s\n", strerror(errno));
}
while (1) {
unsigned int i, inlen;
inlen = conn->ops.fetch_items(conn, inbuf, capacity);
if (!inlen) {
usleep(100);
continue;
}
outbuf_tail = 0;
for (i = 0; i < inlen; i++) {
/* customize prefetch strategy here */
memcpy(outbuf + outbuf_tail, inbuf + i, sizeof(struct acache_info));
outbuf[outbuf_tail].offset += outbuf[outbuf_tail].length >> 9;
outbuf_tail++;
}
if (debug) {
print_infos("R", inbuf, inlen);
print_infos("P", outbuf, outbuf_tail);
}
if (outbuf_tail) {
conn->ops.send_items(conn, outbuf, outbuf_tail);
}
}
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册