2010-12-15 11:58:22 +00:00
|
|
|
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
|
2011-02-23 20:48:06 +00:00
|
|
|
|
|
|
|
/* Definitions for logfile format.
|
|
|
|
*
|
|
|
|
* This is meant for sharing between different transaction logger variants,
|
|
|
|
* and/or for sharing with userspace tools (e.g. logfile analyzers).
|
2011-04-18 09:23:04 +00:00
|
|
|
* TODO: factor out some remaining kernelspace issues.
|
2011-02-23 20:48:06 +00:00
|
|
|
*/
|
|
|
|
|
2011-04-18 09:23:04 +00:00
|
|
|
#ifndef LIB_LOG_H
|
|
|
|
#define LIB_LOG_H
|
2010-12-15 11:58:22 +00:00
|
|
|
|
|
|
|
#include "mars.h"
|
|
|
|
|
|
|
|
/* The following structure is memory-only.
|
|
|
|
* Transfers to disk are indirectly via the
|
|
|
|
* format conversion functions below.
|
|
|
|
* The advantage is that even newer disk formats can be parsed
|
|
|
|
* by old code (of course, not all information / features will be
|
|
|
|
* available then).
|
|
|
|
*/
|
2011-03-10 11:40:06 +00:00
|
|
|
#define log_header log_header_v1
|
|
|
|
|
|
|
|
struct log_header_v1 {
|
2010-12-15 11:58:22 +00:00
|
|
|
struct timespec l_stamp;
|
2011-03-27 15:18:38 +00:00
|
|
|
struct timespec l_written;
|
2010-12-15 11:58:22 +00:00
|
|
|
loff_t l_pos;
|
|
|
|
int l_len;
|
2011-03-27 15:18:38 +00:00
|
|
|
int l_extra_len;
|
|
|
|
short l_code;
|
|
|
|
short l_extra;
|
|
|
|
int l_crc; // NYI
|
2010-12-15 11:58:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define FORMAT_VERSION 1 // version of disk format, currently there is no other one
|
|
|
|
|
|
|
|
#define CODE_UNKNOWN 0
|
|
|
|
#define CODE_WRITE_NEW 1
|
|
|
|
#define CODE_WRITE_OLD 2
|
|
|
|
|
|
|
|
#define START_MAGIC 0xa8f7e908d9177957ll
|
|
|
|
#define END_MAGIC 0x74941fb74ab5726dll
|
|
|
|
|
2011-03-27 15:18:38 +00:00
|
|
|
#define START_OVERHEAD \
|
2010-12-15 11:58:22 +00:00
|
|
|
( \
|
|
|
|
sizeof(START_MAGIC) + \
|
2011-03-27 15:18:38 +00:00
|
|
|
sizeof(char) + \
|
|
|
|
sizeof(char) + \
|
2010-12-15 11:58:22 +00:00
|
|
|
sizeof(short) + \
|
2011-03-27 15:18:38 +00:00
|
|
|
sizeof(struct timespec) + \
|
|
|
|
sizeof(loff_t) + \
|
|
|
|
sizeof(int) + \
|
2010-12-15 11:58:22 +00:00
|
|
|
sizeof(int) + \
|
|
|
|
sizeof(short) + \
|
2011-03-27 15:18:38 +00:00
|
|
|
sizeof(short) + \
|
|
|
|
0 \
|
|
|
|
)
|
|
|
|
|
|
|
|
#define END_OVERHEAD \
|
|
|
|
( \
|
|
|
|
sizeof(END_MAGIC) + \
|
2010-12-15 11:58:22 +00:00
|
|
|
sizeof(int) + \
|
2011-03-27 15:18:38 +00:00
|
|
|
sizeof(char) + \
|
|
|
|
3 + 4 /*spare*/ + \
|
2010-12-15 11:58:22 +00:00
|
|
|
sizeof(struct timespec) + \
|
|
|
|
0 \
|
|
|
|
)
|
|
|
|
|
2011-03-27 15:18:38 +00:00
|
|
|
#define OVERHEAD (START_OVERHEAD + END_OVERHEAD)
|
|
|
|
|
2010-12-15 11:58:22 +00:00
|
|
|
// TODO: make this bytesex-aware.
|
|
|
|
#define DATA_PUT(data,offset,val) \
|
|
|
|
do { \
|
2011-03-27 15:18:38 +00:00
|
|
|
*((typeof(val)*)((data)+offset)) = val; \
|
2010-12-15 11:58:22 +00:00
|
|
|
offset += sizeof(val); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define DATA_GET(data,offset,val) \
|
|
|
|
do { \
|
2011-03-27 15:18:38 +00:00
|
|
|
val = *((typeof(val)*)((data)+offset)); \
|
2010-12-15 11:58:22 +00:00
|
|
|
offset += sizeof(val); \
|
|
|
|
} while (0)
|
|
|
|
|
2011-03-10 11:40:06 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
|
|
|
|
/* Bookkeeping status between calls
|
|
|
|
*/
|
|
|
|
struct log_status {
|
2011-03-11 13:57:54 +00:00
|
|
|
// tunables
|
|
|
|
int align_size; // alignment between requests
|
|
|
|
int chunk_size; // must be at least 8K (better 64k)
|
2011-11-03 11:17:59 +00:00
|
|
|
int max_flying; // limit allocation of buffers
|
2011-03-29 14:40:40 +00:00
|
|
|
int io_prio;
|
2011-03-18 13:15:40 +00:00
|
|
|
// informational
|
2011-11-03 11:17:59 +00:00
|
|
|
atomic_t mref_flying;
|
2011-05-13 11:19:28 +00:00
|
|
|
int count;
|
2011-03-18 13:15:40 +00:00
|
|
|
loff_t log_pos;
|
2011-03-11 13:57:54 +00:00
|
|
|
// internal
|
2011-03-10 11:40:06 +00:00
|
|
|
struct mars_input *input;
|
2011-10-03 17:31:02 +00:00
|
|
|
struct mars_brick *brick;
|
2011-03-10 11:40:06 +00:00
|
|
|
struct generic_object_layout ref_object_layout;
|
|
|
|
struct mars_info info;
|
2011-03-11 13:57:54 +00:00
|
|
|
int offset;
|
2011-03-10 11:40:06 +00:00
|
|
|
int validflag_offset;
|
|
|
|
int reallen_offset;
|
|
|
|
int payload_offset;
|
|
|
|
int payload_len;
|
|
|
|
struct mref_object *log_mref;
|
2011-03-22 14:36:26 +00:00
|
|
|
struct mref_object *read_mref;
|
|
|
|
wait_queue_head_t event;
|
|
|
|
int error_code;
|
|
|
|
bool got;
|
2011-04-08 09:52:46 +00:00
|
|
|
bool do_free;
|
2011-03-11 13:57:54 +00:00
|
|
|
void *private;
|
2011-03-10 11:40:06 +00:00
|
|
|
};
|
2010-12-15 11:58:22 +00:00
|
|
|
|
2011-10-03 17:31:02 +00:00
|
|
|
void init_logst(struct log_status *logst, struct mars_input *input, loff_t start_pos);
|
2011-10-05 13:04:43 +00:00
|
|
|
void exit_logst(struct log_status *logst);
|
2010-12-15 11:58:22 +00:00
|
|
|
|
2011-11-03 11:17:59 +00:00
|
|
|
bool is_log_ready(struct log_status *logst);
|
|
|
|
|
2011-03-22 14:36:26 +00:00
|
|
|
void log_flush(struct log_status *logst);
|
2011-03-10 11:40:06 +00:00
|
|
|
|
|
|
|
void *log_reserve(struct log_status *logst, struct log_header *lh);
|
|
|
|
|
2011-05-26 14:32:32 +00:00
|
|
|
bool log_finalize(struct log_status *logst, int len, void (*preio)(void *private), void (*endio)(void *private, int error), void *private);
|
2011-03-10 11:40:06 +00:00
|
|
|
|
2011-03-27 15:18:38 +00:00
|
|
|
int log_read(struct log_status *logst, struct log_header *lh, void **payload, int *payload_len);
|
2011-03-18 13:15:40 +00:00
|
|
|
|
2011-08-25 10:16:32 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// init
|
|
|
|
|
|
|
|
extern int init_log_format(void);
|
|
|
|
extern void exit_log_format(void);
|
|
|
|
|
2011-03-10 11:40:06 +00:00
|
|
|
#endif
|
2010-12-15 11:58:22 +00:00
|
|
|
#endif
|