#include <dt_object.h>
#define OUT_UPDATE_INIT_BUFFER_SIZE 4096
-#define OUT_UPDATE_REPLY_SIZE 8192
+/* 16KB, the current biggest size is llog header(8KB) */
+#define OUT_UPDATE_REPLY_SIZE 16384
struct dt_key;
struct dt_rec;
return param;
}
+static inline void*
+update_params_get_param_buf(const struct update_params *params, __u16 index,
+ unsigned int param_count, __u16 *size)
+{
+ struct object_update_param *param;
+
+ param = update_params_get_param(params, (unsigned int)index,
+ param_count);
+ if (param == NULL)
+ return NULL;
+
+ if (size != NULL)
+ *size = param->oup_len;
+
+ return ¶m->oup_buf[0];
+}
+
struct update_op {
struct lu_fid uop_fid;
__u16 uop_type;
};
#define TOP_THANDLE_MAGIC 0x20140917
+struct top_multiple_thandle {
+ struct dt_device *tmt_master_sub_dt;
+ atomic_t tmt_refcount;
+ /* Other sub transactions will be listed here. */
+ struct list_head tmt_sub_thandle_list;
+
+ struct list_head tmt_commit_list;
+ /* All of update records will packed here */
+ struct thandle_update_records *tmt_update_records;
+
+ __u64 tmt_batchid;
+ int tmt_result;
+ __u32 tmt_magic;
+ __u32 tmt_committed:1;
+};
+
/* {top,sub}_thandle are used to manage distributed transactions which
* include updates on several nodes. A top_handle represents the
* whole operation, and sub_thandle represents updates on each node. */
struct top_thandle {
struct thandle tt_super;
- __u32 tt_magic;
- atomic_t tt_refcount;
/* The master sub transaction. */
struct thandle *tt_master_sub_thandle;
- /* Other sub thandle will be listed here. */
- struct list_head tt_sub_thandle_list;
-
- /* All of update records will packed here */
- struct thandle_update_records *tt_update_records;
+ struct top_multiple_thandle *tt_multiple_thandle;
};
+/* Sub thandle is used to track multiple sub thandles under one parent
+ * thandle */
struct sub_thandle {
- /* point to the osd/osp_thandle */
struct thandle *st_sub_th;
+ struct dt_device *st_dt;
+ struct list_head st_list;
+ struct llog_cookie st_cookie;
+ struct dt_txn_commit_cb st_commit_dcb;
+ int st_result;
/* linked to top_thandle */
struct list_head st_sub_list;
/* If this sub thandle is committed */
- bool st_committed:1,
- st_record_update:1;
+ bool st_committed:1;
};
+struct tx_arg;
+typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
+ struct tx_arg *ta);
+
+/* Structure for holding one update executation */
+struct tx_arg {
+ tx_exec_func_t exec_fn;
+ tx_exec_func_t undo_fn;
+ struct dt_object *object;
+ const char *file;
+ struct object_update_reply *reply;
+ int line;
+ int index;
+ union {
+ struct {
+ struct dt_insert_rec rec;
+ const struct dt_key *key;
+ } insert;
+ struct {
+ } ref;
+ struct {
+ struct lu_attr attr;
+ } attr_set;
+ struct {
+ struct lu_buf buf;
+ const char *name;
+ int flags;
+ __u32 csum;
+ } xattr_set;
+ struct {
+ struct lu_attr attr;
+ struct dt_allocation_hint hint;
+ struct dt_object_format dof;
+ struct lu_fid fid;
+ } create;
+ struct {
+ struct lu_buf buf;
+ loff_t pos;
+ } write;
+ struct {
+ struct ost_body *body;
+ } destroy;
+ } u;
+};
+
+/* Structure for holding all update executations of one transaction */
+struct thandle_exec_args {
+ struct thandle *ta_handle;
+ int ta_argno; /* used args */
+ int ta_alloc_args; /* allocated args count */
+ struct tx_arg **ta_args;
+};
/* target/out_lib.c */
int out_update_pack(const struct lu_env *env, struct object_update *update,
int out_xattr_get_pack(const struct lu_env *env,
struct object_update *update, size_t max_update_size,
const struct lu_fid *fid, const char *name);
+int out_read_pack(const struct lu_env *env, struct object_update *update,
+ size_t max_update_length, const struct lu_fid *fid,
+ size_t size, loff_t pos);
const char *update_op_str(__u16 opcode);
struct thandle *
top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
-
int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
struct thandle *th);
-
int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
struct thandle *th);
+void top_multiple_thandle_destroy(struct top_multiple_thandle *tmt);
-void top_thandle_destroy(struct top_thandle *top_th);
+static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
+{
+ atomic_inc(&tmt->tmt_refcount);
+}
+
+static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
+{
+ if (atomic_dec_and_test(&tmt->tmt_refcount))
+ top_multiple_thandle_destroy(tmt);
+}
+
+struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
+ struct dt_device *dt_dev);
+int sub_thandle_trans_create(const struct lu_env *env,
+ struct top_thandle *top_th,
+ struct sub_thandle *st);
/* update_records.c */
int update_records_create_pack(const struct lu_env *env,
const struct lu_fid *fid,
const struct lu_buf *buf,
__u64 pos);
+int update_records_punch_pack(const struct lu_env *env,
+ struct update_ops *ops,
+ unsigned int *op_count,
+ size_t *max_ops_size,
+ struct update_params *params,
+ unsigned int *param_count,
+ size_t *max_param_size,
+ const struct lu_fid *fid,
+ __u64 start, __u64 end);
int tur_update_records_extend(struct thandle_update_records *tur,
size_t new_size);
int tur_update_params_extend(struct thandle_update_records *tur,
size_t new_size);
-int check_and_prepare_update_record(const struct lu_env *env,
- struct thandle *th);
-int merge_params_updates_buf(const struct lu_env *env,
- struct thandle_update_records *tur);
int tur_update_extend(struct thandle_update_records *tur,
size_t new_op_size, size_t new_param_size);
#define update_record_pack(name, th, ...) \
({ \
struct top_thandle *top_th; \
+ struct top_multiple_thandle *tmt; \
struct thandle_update_records *tur; \
struct llog_update_record *lur; \
size_t avail_param_size; \
\
while (1) { \
top_th = container_of(th, struct top_thandle, tt_super);\
- tur = top_th->tt_update_records; \
+ tmt = top_th->tt_multiple_thandle; \
+ tur = tmt->tmt_update_records; \
lur = tur->tur_update_records; \
avail_param_size = tur->tur_update_params_buf_size - \
update_params_size(tur->tur_update_params, \