A ref change was pushed to the repository containing the project "Grayskull Repository". The branch, master has been updated via 0fd9f3de3dfa793453f556f5951762a3348e1026 (commit) via ec3fffe6805803edc2c39c1e52b413b2944bded8 (commit) from cb8be4c05c5cc874e93f6c4d8daf50c3d6b2eb81 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0fd9f3de3dfa793453f556f5951762a3348e1026 Author: Phil Carns <[email protected]> Date: Tue Dec 15 11:47:38 2009 -0500 whitespace cleanups commit ec3fffe6805803edc2c39c1e52b413b2944bded8 Author: Phil Carns <[email protected]> Date: Tue Dec 15 11:44:30 2009 -0500 cosd api function to retrieve current version ----------------------------------------------------------------------- Summary of changes: .../gsl/resources/cosd-prototype/cosd-prototype.c | 146 ++++++++++++++++---- .../resources/cosd-prototype/cosd-prototype.gsh | 9 ++ .../src/gsl/resources/cosd-prototype/test/cosd1.gs | 20 ++- 3 files changed, 145 insertions(+), 30 deletions(-) Diff of changes: diff --git a/code/src/gsl/resources/cosd-prototype/cosd-prototype.c b/code/src/gsl/resources/cosd-prototype/cosd-prototype.c index 8e9b9cd..b501646 100644 --- a/code/src/gsl/resources/cosd-prototype/cosd-prototype.c +++ b/code/src/gsl/resources/cosd-prototype/cosd-prototype.c @@ -22,14 +22,14 @@ * - use txn_checkpoint to flush when coalescing * - consider rmw locks where appropriate * - long term: consider fallocate hint for logs to keep them linear - * - try computing cksum along the way, store in db + * - try computing cksum along the way, store in db * - either in log map itself or db that matches its keys */ /**************************************************************/ /* TODO: this needs to be in a header somewhere */ #ifndef llu -#if SIZEOF_LONG_INT == 4 +#if SIZEOF_LONG_INT == 4 # define llu(x) (x) # define lld(x) (x) # define SCANF_lld "%lld" @@ -97,7 +97,7 @@ static int gs_cosd_resource_id; static enum progress_mode gs_cosd_progress_mode = GS_PROG_NONE; static int merge_logical_map(struct gs_list_link* list1_in, int - list1_count, struct gs_list_link* list2_in, int list2_count, + list1_count, struct gs_list_link* list2_in, int list2_count, struct gs_list_link* list_out, void** free_ptr); static int compare_log_map_key(DB * dbp, const DBT * a, const DBT * b); static int compare_missing_version(DB * dbp, const DBT * a, const DBT * b); @@ -170,7 +170,10 @@ struct cosd_op uint64_t oid; uint64_t txn_number; } txn_close; - + struct get_version_op{ + uint64_t oid; + uint64_t *version; + } get_version; #if 0 struct remove_op{ uint64_t oid; @@ -364,7 +367,7 @@ static int gs_cosd_poll(gs_context_t context, int millisecs) c_op = gs_op_entry(gop, struct cosd_op, op); - ret = gop->op_worker(gop); + ret = gop->op_worker(gop); if(ret == 1) { /* done */ @@ -391,7 +394,7 @@ static int gs_cosd_cancel(gs_context_t gs_ctx, gs_op_id_t op_id) gs_mutex_lock(&cosd_mutex); struct gs_op *op; struct cosd_op *c_op; - + cache_id = gs_id_lookup(op_id, &resource_id); assert(resource_id == gs_cosd_resource_id); @@ -401,7 +404,7 @@ static int gs_cosd_cancel(gs_context_t gs_ctx, gs_op_id_t op_id) gs_oplist_del(op, &cosd_oplist); gs_opcache_put(cosd_opcache, op); #endif - + gs_mutex_unlock(&cosd_mutex); return 0; @@ -600,7 +603,7 @@ int gs_cosd_init(enum progress_mode mode, const char* path) gs_cosd_resource_id = gs_resource_register(&gs_cosd_resource); if(gs_cosd_resource_id < 0) { - gs_opcache_destroy(cosd_opcache); + gs_opcache_destroy(cosd_opcache); return(gs_cosd_resource_id); } gs_cosd_progress_mode = mode; @@ -662,7 +665,7 @@ static int write_op_worker(struct gs_op* op) /* open log file */ sprintf(log_name, "%s/%llu.dat", cosd_log_path, llu(c_op->u.write.oid)); - ret = open(log_name, O_RDWR|O_DIRECT|O_EXCL|O_NOATIME, + ret = open(log_name, O_RDWR|O_DIRECT|O_EXCL|O_NOATIME, S_IRUSR|S_IWUSR); if(ret < 0) { @@ -720,7 +723,7 @@ static int write_op_worker(struct gs_op* op) /* calculate aligned buffer size */ if(tmp_update->size % DIRECT_ALIGN != 0) - aligned_size = + aligned_size = ((tmp_update->size / DIRECT_ALIGN)+1)*DIRECT_ALIGN; else aligned_size = tmp_update->size; @@ -799,7 +802,7 @@ static int write_op_worker(struct gs_op* op) c_op->error_code = -errno; return(1); } - + /* track this update in the txn accumulator */ gs_mutex_lock(&txn_mutex); hash_link = gs_hash_search(txn_table, &c_op->u.write.txn_number); @@ -810,7 +813,7 @@ static int write_op_worker(struct gs_op* op) gs_mutex_unlock(&txn_mutex); return(1); } - txn_acc = gs_hash_get_entry(hash_link, struct txn_accumulator, + txn_acc = gs_hash_get_entry(hash_link, struct txn_accumulator, hash_link); tmp_update->version = txn_acc->txn_number; gs_list_add(&tmp_update->list_link, &txn_acc->update_list); @@ -919,7 +922,7 @@ static int dump_op_worker(struct gs_op* op) { printf("logical_off: %lld, logical_end: %lld, size: %lld, log_off: %lld, ver: %llu\n", lld(lmv.logical_offset), lld(lmv.logical_offset_end), - lld(lmv.size), lld(lmv.log_offset), llu(lmv.version)); + lld(lmv.size), lld(lmv.log_offset), llu(lmv.version)); c_get_flag = DB_NEXT; } assert(ret == DB_NOTFOUND); /* TODO: err handling */ @@ -944,7 +947,7 @@ static int dump_op_worker(struct gs_op* op) return(1); } - + /* create_op_worker() * * creates an object @@ -968,7 +971,7 @@ static int create_op_worker(struct gs_op* op) /* create a log file */ sprintf(log_name, "%s/%llu.dat", cosd_log_path, llu(c_op->u.create.requested_oid)); - ret = open(log_name, O_RDWR|O_CREAT|O_DIRECT|O_EXCL|O_NOATIME, + ret = open(log_name, O_RDWR|O_CREAT|O_DIRECT|O_EXCL|O_NOATIME, S_IRUSR|S_IWUSR); if(ret < 0) { @@ -997,7 +1000,7 @@ static int create_op_worker(struct gs_op* op) /* TODO: error handling */ assert(0); } - + /* set initial log offset of 0 */ val = 0; ret = log_offset_dbp->put(log_offset_dbp, txn, &key, &value, 0); @@ -1006,7 +1009,7 @@ static int create_op_worker(struct gs_op* op) /* TODO: error handling */ assert(0); } - + ret = txn->commit(txn, 0); if(ret != 0) { @@ -1169,6 +1172,99 @@ int gs_cosd_txn_open(uint64_t oid, uint64_t txn_number) return(0); } + +/* get_version_op_worker() + * + * retrieves the current version number of an object + */ +static int get_version_op_worker(struct gs_op* op) +{ + struct cosd_op *c_op; + int ret; + DB_TXN *txn; + uint64_t version; + DBT key, value; + + c_op = gs_op_entry(op, struct cosd_op, op); + assert(c_op); + + /* only support one object for now */ + assert(c_op->u.get_version.oid == 1); + + /* do db stuff */ + ret = envp->txn_begin(envp, NULL, &txn, 0); + if(ret != 0) + { + /* TODO: error handling */ + c_op->error_code = -1; + return(1); + } + + /* read current version */ + COSD_INIT_DBT(key, c_op->u.get_version.oid); + COSD_INIT_DBT(value, version); + + ret = ver_dbp->get(ver_dbp, txn, &key, &value, 0); + if(ret != 0) + { + /* TODO: error handling */ + assert(0); + } + + *c_op->u.get_version.version = version; + + ret = txn->commit(txn, 0); + if(ret != 0) + { + /* TODO: error handling */ + assert(0); + } + + c_op->error_code = 0; + + return(1); +} + + +gs_ret_t gs_cosd_get_version_post( + uint64_t oid, + uint64_t* version, + void (*callback)(void *ptr, int ret), + void *user_ptr, + gs_hints_t hints, + gs_context_t ctx, + gs_op_id_t *op_id) +{ + struct gs_op *op; + struct cosd_op *c_op; + + op = gs_opcache_get(cosd_opcache); + gs_op_fill(op, callback, user_ptr, hints, ctx); + + c_op = gs_op_entry(op, struct cosd_op, op); + c_op->op_id = gs_id_gen(gs_cosd_resource_id, (uint64_t)(op->cache_id)); + c_op->u.get_version.oid = oid; + c_op->u.get_version.version = version; + + *op_id = c_op->op_id; + + /* TODO: put this in the fill function if we keep it? */ + op->op_worker = get_version_op_worker; + + gs_cosd_launch_op(op, gs_cosd_progress_mode); + + return 0; +} +gs_ret_t (* gs_cosd_get_version)( + uint64_t oid, + uint64_t* version, + void (*callback)(void *ptr, int ret), + void *user_ptr, + gs_hints_t hints, + gs_context_t ctx, + gs_op_id_t *op_id) = gs_cosd_get_version_post; + + /* txn_close_op_worker() * * closes a transaction @@ -1217,7 +1313,7 @@ static int txn_close_op_worker(struct gs_op* op) gs_mutex_unlock(&txn_mutex); return(1); } - txn_acc = gs_hash_get_entry(hash_link, struct txn_accumulator, + txn_acc = gs_hash_get_entry(hash_link, struct txn_accumulator, hash_link); gs_list_del(&txn_acc->hash_link); gs_mutex_unlock(&txn_mutex); @@ -1251,7 +1347,7 @@ static int txn_close_op_worker(struct gs_op* op) { tmp_update = gs_list_get_entry(iterator, struct logical_map_entry, list_link); - + lmk.logical_offset_end = tmp_update->logical_offset; done = 0; while(!done) @@ -1339,7 +1435,7 @@ static int txn_close_op_worker(struct gs_op* op) /* TODO: error handling */ assert(0); } - + if(txn_acc->txn_number > version) { /* this update is newer than the current version of the object */ @@ -1456,7 +1552,7 @@ gs_ret_t (* gs_cosd_txn_close)( /* merge_logical_map() - * + * * merges two logical maps into one map. The two input maps are destroyed * by this function. The output map is allocated from scratch and can be * freed via the free_ptr argument. @@ -1464,7 +1560,7 @@ gs_ret_t (* gs_cosd_txn_close)( * returns 0 on success, -errno on failure */ static int merge_logical_map(struct gs_list_link* list1_in, int - list1_count, struct gs_list_link* list2_in, int list2_count, + list1_count, struct gs_list_link* list2_in, int list2_count, struct gs_list_link* list_out, void** free_ptr) { struct gs_list_link* iterator; @@ -1541,17 +1637,17 @@ static int merge_logical_map(struct gs_list_link* list1_in, int { /* consume any elements that have been entirely passed over */ - if(i < list1_count && list1_array[i].logical_offset_end <= logical_offset) + if(i < list1_count && list1_array[i].logical_offset_end <= logical_offset) { i++; continue; } - if(j < list2_count && list2_array[j].logical_offset_end <= logical_offset) + if(j < list2_count && list2_array[j].logical_offset_end <= logical_offset) { j++; continue; } - + /* shave off the beginning of any extent that has been partially * passed over */ diff --git a/code/src/gsl/resources/cosd-prototype/cosd-prototype.gsh b/code/src/gsl/resources/cosd-prototype/cosd-prototype.gsh index 212780c..3943c3f 100644 --- a/code/src/gsl/resources/cosd-prototype/cosd-prototype.gsh +++ b/code/src/gsl/resources/cosd-prototype/cosd-prototype.gsh @@ -54,6 +54,15 @@ __blocking int gs_cosd_create( ); /** + * Retrieves current version number of object + * \return 0 on success, -errno on failure + */ +__blocking int gs_cosd_get_version( + uint64_t oid, /**< object to operate on */ + uint64_t* version /**< version number of object */ +); + +/** * Opens a txn * \return 0 on success, -errno on failure */ diff --git a/code/src/gsl/resources/cosd-prototype/test/cosd1.gs b/code/src/gsl/resources/cosd-prototype/test/cosd1.gs index f4e3153..288708a 100644 --- a/code/src/gsl/resources/cosd-prototype/test/cosd1.gs +++ b/code/src/gsl/resources/cosd-prototype/test/cosd1.gs @@ -29,8 +29,9 @@ static __blocking int do_cosd_test(void) int64_t obj_sz = 1024; int64_t obj_offset = 0; uint64_t out_oid1; + uint64_t version; - printf("Creating oid 1...\n"); + printf("Creating oid 1 (if it doesn't already exist)...\n"); ret = gs_cosd_create(1, &out_oid1); if(ret != 0 && ret != -EEXIST) { @@ -39,8 +40,17 @@ static __blocking int do_cosd_test(void) } printf("DONE\n"); - printf("opening txn 1...\n"); - ret = gs_cosd_txn_open(1, 1); + printf("Getting version number of oid 1...\n"); + ret = gs_cosd_get_version(1, &version); + if(ret != 0) + { + printf("Error getting version number for oid=1: %d\n", ret); + return(1); + } + printf("DONE: %llu\n", llu(version)); + + printf("opening txn...\n"); + ret = gs_cosd_txn_open(1, (version+1)); if(ret != 0) { printf("Error opening txn 1: %d\n", ret); @@ -49,7 +59,7 @@ static __blocking int do_cosd_test(void) printf("DONE\n"); printf("writing 0-1024...\n"); - ret = gs_cosd_write(1, 1, &buffer_offset, &buffer_sz, 1, &obj_offset, + ret = gs_cosd_write(1, (version+1), &buffer_offset, &buffer_sz, 1, &obj_offset, &obj_sz, 1); if(ret != 0) { @@ -59,7 +69,7 @@ static __blocking int do_cosd_test(void) printf("DONE\n"); printf("closing txn...\n"); - ret = gs_cosd_txn_close(1, 1); + ret = gs_cosd_txn_close(1, (version+1)); if(ret != 0) { printf("Error closing txn 1: %d\n", ret); hooks/post-receive -- Grayskull Repository