import mars-08.tgz

This commit is contained in:
Thomas Schoebel-Theuer 2010-06-20 19:55:34 +01:00
parent d4d6d80fb5
commit 9419d047b9
8 changed files with 161 additions and 68 deletions

94
mars.h
View File

@ -23,48 +23,65 @@
/////////////////////////////////////////////////////////////////////////
// definitions for generic objects
// definitions for generic objects with aspects
#define MAX_DEFAULT_ASPECTS 8
struct generic_aspect;
#define GENERIC_OBJECT_TYPE(PREFIX) \
char *object_type_name; \
int default_size; \
struct generic_object_type {
GENERIC_OBJECT_TYPE(generic);
};
#define GENERIC_OBJECT_LAYOUT(PREFIX) \
const struct generic_object_type *type; \
int max_size; \
int rest_size; \
int max_aspects; \
int nr_aspects; \
int *aspect_sizes; \
int *aspect_offsets; \
int (**init_fns)(struct PREFIX##_aspect *ini, void *data); \
void **init_datas; \
void *alloc_ptr; \
struct generic_object_layout {
GENERIC_OBJECT_LAYOUT(generic);
};
#ifdef _STRATEGY
#define GENERIC_OBJECT_LAYOUT_FUNCTIONS(PREFIX) \
extern inline struct PREFIX##_object_layout *PREFIX##_init_object_layout(void *data, int size, int max_aspects) \
extern inline struct PREFIX##_object_layout *PREFIX##_init_object_layout(void *data, int size, int max_aspects, const struct generic_object_type *type) \
{ \
struct PREFIX##_object_layout *object_layout = data; \
data += sizeof(struct PREFIX##_object_layout); \
size -= sizeof(struct PREFIX##_object_layout); \
if (size < 0) \
return NULL; \
object_layout->type = type; \
object_layout->max_size = type->default_size; \
object_layout->max_aspects = max_aspects; \
object_layout->nr_aspects = 0; \
object_layout->max_size = sizeof(struct PREFIX##_object_layout); \
data += sizeof(struct PREFIX##_object_layout); \
size -= max_aspects * sizeof(void*) * 2; \
size -= max_aspects * sizeof(void*) * 4; \
if (size < 0) \
return NULL; \
object_layout->rest_size = size; \
object_layout->aspect_sizes = data; \
data += max_aspects * sizeof(void*); \
object_layout->aspect_offsets = data; \
data += max_aspects * sizeof(void*); \
object_layout->init_fns = data; \
data += max_aspects * sizeof(void*); \
object_layout->init_datas = data; \
data += max_aspects * sizeof(void*); \
object_layout->alloc_ptr = data; \
object_layout->rest_size = size; \
return object_layout; \
} \
\
extern int PREFIX##_add_aspect(struct PREFIX##_object_layout *object_layout, int aspect_size) \
extern int PREFIX##_add_aspect(struct PREFIX##_object_layout *object_layout, int aspect_size, int (*init_fn)(struct PREFIX##_aspect *ini, void *init_data), void *init_data) \
{ \
int slot = object_layout->nr_aspects; \
int max_aspects = object_layout->max_aspects; \
@ -72,31 +89,40 @@ extern int PREFIX##_add_aspect(struct PREFIX##_object_layout *object_layout, int
void *data = object_layout->alloc_ptr; \
void *old; \
int size = object_layout->rest_size; \
int old_aspects = max_aspects; \
max_aspects <<= 1; \
size -= max_aspects * sizeof(void*) * 2; \
size -= max_aspects * sizeof(void*) * 4; \
if (size < 0) \
return -ENOMEM; \
object_layout->rest_size = size; \
old = object_layout->aspect_sizes; \
object_layout->aspect_sizes = data; \
memcpy(data, old, max_aspects * sizeof(void*)); \
memcpy(data, old, old_aspects * sizeof(void*)); \
data += max_aspects * sizeof(void*); \
old = object_layout->aspect_offsets; \
object_layout->aspect_offsets = data; \
memcpy(data, old, max_aspects * sizeof(void*)); \
memcpy(data, old, old_aspects * sizeof(void*)); \
data += max_aspects * sizeof(void*); \
old = object_layout->init_fns; \
object_layout->init_fns = data; \
memcpy(data, old, old_aspects * sizeof(void*)); \
data += max_aspects * sizeof(void*); \
old = object_layout->init_datas; \
object_layout->init_datas = data; \
memcpy(data, old, old_aspects * sizeof(void*)); \
data += max_aspects * sizeof(void*); \
object_layout->alloc_ptr = data; \
object_layout->max_aspects = max_aspects; \
} \
object_layout->aspect_sizes[slot] = aspect_size; \
object_layout->aspect_offsets[slot] = object_layout->max_size; \
object_layout->init_fns[slot] = init_fn; \
object_layout->init_datas[slot] = init_data; \
object_layout->max_size += aspect_size; \
object_layout->nr_aspects++; \
return slot; \
} \
#endif
#define GENERIC_OBJECT(PREFIX) \
struct PREFIX##_object_layout *object_layout; \
int object_size; \
@ -121,6 +147,13 @@ extern inline struct PREFIX##_object *PREFIX##_construct(void *data, struct PREF
for (i = 0; i < object_layout->nr_aspects; i++) { \
struct PREFIX##_aspect *aspect = data + object_layout->aspect_offsets[i]; \
aspect->object = obj; \
if (object_layout->init_fns[i]) { \
void *init_data = object_layout->init_datas[i]; \
int status = object_layout->init_fns[i](aspect, init_data); \
if (status) { \
return NULL; \
} \
} \
} \
return obj; \
} \
@ -199,6 +232,7 @@ struct generic_brick_ops {
#define GENERIC_OUTPUT_OPS(PREFIX) \
int (*output_start)(struct PREFIX##_output *output); \
int (*output_stop)(struct PREFIX##_output *output); \
int (*get_size)(struct PREFIX##_output *output, const struct generic_object_type *object_type); \
struct generic_output_ops {
GENERIC_OUTPUT_OPS(generic)
@ -426,7 +460,8 @@ extern inline int PREFIX##_brick_exit_full( \
* For type safety, use this for all possible combinations.
* Yes, this may become quadratic in large type systems, but
* (a) thou shalt not define many types,
* (b) these macros generate only definitions, no code by itself
* (b) these macros generate only definitions, but no additional
* code at runtime.
*/
#define GENERIC_MAKE_CONNECT(INPUT_PREFIX,OUTPUT_PREFIX) \
\
@ -450,19 +485,37 @@ extern inline int INPUT_PREFIX##_##OUTPUT_PREFIX####_disconnect( \
// MARS-specific definitions
// object stuff
#define HT_SHIFT 6 //????
#define MARS_MAX_SEGMENT_SIZE (1U << (9+HT_SHIFT))
#define MARS_IO(PREFIX) \
extern const struct generic_object_type mars_io_type;
struct mars_io_aspect {
GENERIC_ASPECT(mars_io);
};
struct mars_io_object_layout {
GENERIC_OBJECT_LAYOUT(mars_io);
};
#define MARS_IO_OBJECT(PREFIX) \
GENERIC_OBJECT(PREFIX); \
struct bio *orig_bio; \
int (*mars_endio)(struct mars_io *mio); \
int (*mars_endio)(struct mars_io_object *mio); \
struct mars_io {
MARS_IO(mars);
struct list_head io_head; //TODO: move to aspect
struct mars_io_object {
MARS_IO_OBJECT(mars_io);
struct list_head io_head; //TODO: move to aspect (device_sio)
};
GENERIC_OBJECT_LAYOUT_FUNCTIONS(mars_io);
GENERIC_OBJECT_FUNCTIONS(mars_io);
// brick stuff
#define MARS_BRICK(PREFIX) \
GENERIC_BRICK(PREFIX); \
@ -490,7 +543,7 @@ struct mars_output {
#define MARS_OUTPUT_OPS(PREFIX) \
GENERIC_OUTPUT_OPS(PREFIX); \
int (*mars_io)(struct PREFIX##_output *output, struct mars_io *mio); \
int (*mars_io)(struct PREFIX##_output *output, struct mars_io_object *mio); \
// all non-extendable types
#define _MARS_TYPES(PREFIX) \
@ -522,7 +575,6 @@ _MARS_TYPES(PREFIX) \
GENERIC_MAKE_CONNECT(generic,PREFIX); \
GENERIC_MAKE_CONNECT(mars,PREFIX); \
/////////////////////////////////////////////////////////////////////////
// MARS-specific helper functions

View File

@ -20,6 +20,14 @@
////////////////// own brick / input / output operations //////////////////
static int device_sio_get_size(struct device_sio_output *output, const struct generic_object_type *object_type)
{
int res = sizeof(struct device_sio_mars_io_aspect);
if (object_type != &mars_io_type)
return 0;
return res;
}
// some code borrowed from the loopback driver
static int transfer_none(int cmd,
@ -41,7 +49,7 @@ static int transfer_none(int cmd,
return 0;
}
static int write_aops(struct device_sio_output *output, struct mars_io *mio)
static int write_aops(struct device_sio_output *output, struct mars_io_object *mio)
{
struct bio *bio = mio->orig_bio;
loff_t pos = ((loff_t)bio->bi_sector << 9);
@ -122,7 +130,7 @@ static int write_aops(struct device_sio_output *output, struct mars_io *mio)
struct cookie_data {
struct device_sio_output *output;
struct mars_io *mio;
struct mars_io_object *mio;
struct bio_vec *bvec;
unsigned int offset;
};
@ -134,7 +142,7 @@ device_sio_splice_actor(struct pipe_inode_info *pipe,
{
struct cookie_data *p = sd->u.data;
//struct device_sio_output *output = p->output;
//struct mars_io *mio = p->mio;
//struct mars_io_object *mio = p->mio;
struct page *page = buf->page;
sector_t IV;
int size, ret;
@ -170,7 +178,7 @@ device_sio_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc
return __splice_from_pipe(pipe, sd, device_sio_splice_actor);
}
static int read_aops(struct device_sio_output *output, struct mars_io *mio)
static int read_aops(struct device_sio_output *output, struct mars_io_object *mio)
{
struct bio *bio = mio->orig_bio;
loff_t pos = ((loff_t)bio->bi_sector << 9);
@ -222,7 +230,7 @@ static void sync_file(struct device_sio_output *output)
#endif
}
static int device_sio_mars_io(struct device_sio_output *output, struct mars_io *mio)
static int device_sio_mars_io(struct device_sio_output *output, struct mars_io_object *mio)
{
struct bio *bio = mio->orig_bio;
int direction = bio->bi_rw & 1;
@ -300,7 +308,7 @@ done:
}
#ifdef WITH_THREAD
static int device_sio_mars_queue(struct device_sio_output *output, struct mars_io *mio)
static int device_sio_mars_queue(struct device_sio_output *output, struct mars_io_object *mio)
{
int index = 0;
struct sio_threadinfo *tinfo;
@ -332,7 +340,7 @@ static int device_sio_thread(void *data)
while (!kthread_should_stop()) {
struct list_head *tmp;
struct mars_io *mio;
struct mars_io_object *mio;
wait_event_interruptible(tinfo->event,
!list_empty(&tinfo->mio_list) ||
@ -346,7 +354,7 @@ static int device_sio_thread(void *data)
list_del_init(tmp);
spin_unlock_irq(&tinfo->lock);
mio = container_of(tmp, struct mars_io, io_head);
mio = container_of(tmp, struct mars_io_object, io_head);
MARS_DBG("got %p\n", mio);
device_sio_mars_io(output, mio);
}
@ -437,6 +445,7 @@ static struct device_sio_brick_ops device_sio_brick_ops = {
};
static struct device_sio_output_ops device_sio_output_ops = {
.get_size = device_sio_get_size,
#ifdef WITH_THREAD
.mars_io = device_sio_mars_queue,
#else

View File

@ -1,6 +1,14 @@
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
#ifndef MARS_DEVICE_SIO_H
#define MARS_DEVICE_SIO_H
#define WITH_THREAD 16
struct device_sio_mars_io_aspect {
GENERIC_ASPECT(mars_io);
struct list_head io_head; //TODO: move to aspect (device_sio)
};
struct device_sio_brick {
MARS_BRICK(device_sio);
};
@ -31,3 +39,5 @@ struct device_sio_output {
};
MARS_TYPES(device_sio);
#endif

View File

@ -10,25 +10,27 @@
///////////////////////// own type definitions ////////////////////////
struct dummy_brick {
MARS_BRICK(dummy);
int my_own;
};
struct dummy_input {
MARS_INPUT(dummy);
};
struct dummy_output {
MARS_OUTPUT(dummy);
int my_own;
};
MARS_TYPES(dummy);
#include "mars_dummy.h"
////////////////// own brick / input / output operations //////////////////
///////////////////////// contructors / destructors ////////////////////////
static int dummy_get_size(struct dummy_output *output, const struct generic_object_type *object_type)
{
int res = sizeof(struct dummy_mars_io_aspect);
struct dummy_brick *brick = output->brick;
int i;
if (object_type != &mars_io_type)
return 0;
for (i = 0; i < brick->type->max_inputs; i++) {
struct dummy_input *input = brick->inputs[i];
if (input && input->connect) {
res += input->connect->ops->get_size(input->connect, &mars_io_type);
}
}
return res;
}
///////////////////////// constructors / destructors ////////////////////////
static int dummy_brick_construct(struct dummy_brick *brick)
{
@ -48,6 +50,7 @@ static struct dummy_brick_ops dummy_brick_ops = {
};
static struct dummy_output_ops dummy_output_ops = {
.get_size = dummy_get_size,
};
static struct dummy_input_type dummy_input_type = {

26
mars_dummy.h Normal file
View File

@ -0,0 +1,26 @@
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
#ifndef MARS_DUMMY_H
#define MARS_DUMMY_H
struct dummy_mars_io_aspect {
GENERIC_ASPECT(mars_io);
int my_own;
};
struct dummy_brick {
MARS_BRICK(dummy);
int my_own;
};
struct dummy_input {
MARS_INPUT(dummy);
};
struct dummy_output {
MARS_OUTPUT(dummy);
int my_own;
};
MARS_TYPES(dummy);
#endif

View File

@ -9,30 +9,18 @@
//////////////////////////////////////////////////////////////
// testing.....
// object stuff
#if 1
#include <linux/slab.h>
GENERIC_OBJECT_LAYOUT_FUNCTIONS(generic);
GENERIC_OBJECT_FUNCTIONS(generic);
void test(void)
{
char data[1024];
struct generic_object *obj;
struct generic_object_layout *t = generic_init_object_layout(data, sizeof(data), 4);
int slot = generic_add_aspect(t, 17);
char *my_aspect;
obj = kmalloc(t->max_size, GFP_KERNEL);
obj = generic_construct(obj, t);
my_aspect = (void*)obj + obj->object_layout->aspect_offsets[slot];
my_aspect = generic_get_aspect(obj, slot);
}
#endif
const struct generic_object_type mars_io_type = {
.object_type_name = "mars_io",
.default_size = sizeof(struct mars_io_object),
};
EXPORT_SYMBOL_GPL(mars_io_type);
//////////////////////////////////////////////////////////////
// brick stuff
#define MAX_BRICK_TYPES 64
static int nr_brick_types = 0;

View File

@ -26,7 +26,7 @@ static int device_minor = 0;
/* callback
*/
static int if_device_endio(struct mars_io *mio)
static int if_device_endio(struct mars_io_object *mio)
{
struct bio *bio = mio->orig_bio;
if (bio) {
@ -43,13 +43,13 @@ static int if_device_endio(struct mars_io *mio)
return 0;
}
/* accept a linux bio, wrap it into struct mars_io and call mars_io() on it.
/* accept a linux bio, wrap it into struct mars_io_object and call mars_io() on it.
*/
static int if_device_make_request(struct request_queue *q, struct bio *bio)
{
struct if_device_input *input = q->queuedata;
struct if_device_output *output;
struct mars_io *mio = NULL;
struct mars_io_object *mio = NULL;
int error = -ENOSYS;
MARS_DBG("make_request(%d)\n", bio->bi_size);

View File

@ -1,4 +1,7 @@
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
#ifndef MARS_IF_DEVICE_H
#define MARS_IF_DEVICE_H
struct if_device_brick {
MARS_BRICK(if_device);
};
@ -17,3 +20,5 @@ struct if_device_output {
};
MARS_TYPES(if_device);
#endif