Susumu Yata
null+****@clear*****
Thu Dec 17 11:40:30 JST 2015
Susumu Yata 2015-12-17 11:40:30 +0900 (Thu, 17 Dec 2015) New Revision: b038bbb771f2e676b5f6333c0dff8ceccfc8522f https://github.com/groonga/groonga/commit/b038bbb771f2e676b5f6333c0dff8ceccfc8522f Message: grn_pat: return an error when `truncate` is detected GitHub: #447 Modified files: lib/pat.c Modified: lib/pat.c (+66 -157) =================================================================== --- lib/pat.c 2015-12-17 10:52:10 +0900 (9a5d02c) +++ lib/pat.c 2015-12-17 11:40:30 +0900 (595c4fe) @@ -625,53 +625,21 @@ grn_pat_open(grn_ctx *ctx, const char *path) return pat; } -/* grn_pat_reopen() reopens a grn_io for a truncated grn_pat. */ +/* + * grn_pat_error_if_truncated() logs an error and returns its error code if + * a pat is truncated by another process. + * Otherwise, this function returns GRN_SUCCESS. + * Note that `ctx` and `pat` must be valid. + * + * FIXME: A pat should be reopened if possible. + */ static grn_rc -grn_pat_reopen(grn_ctx *ctx, grn_pat *pat) +grn_pat_error_if_truncated(grn_ctx *ctx, grn_pat *pat) { - grn_io *new_io; - const char *path; - struct grn_pat_header *new_header; - if (!ctx) { - return GRN_INVALID_ARGUMENT; - } - if (!pat || !pat->io) { - ERR(GRN_INVALID_ARGUMENT, "invalid argument"); - return ctx->rc; - } - path = grn_io_path(pat->io); - if (!path || !*path) { - ERR(GRN_INVALID_ARGUMENT, "path not available"); - return ctx->rc; - } - new_io = grn_io_open(ctx, path, grn_io_auto); - if (!new_io) { - if (ctx->rc == GRN_SUCCESS) { - ERR(GRN_UNKNOWN_ERROR, "grn_io_open failed"); - } - return ctx->rc; - } - if (grn_io_get_type(new_io) != GRN_TABLE_PAT_KEY) { - grn_io_close(ctx, new_io); - ERR(GRN_INVALID_FORMAT, "file type unmatch"); - return ctx->rc; - } - new_header = grn_io_header(new_io); - - pat->io = new_io; - pat->header = new_header; - pat->key_size = new_header->key_size; - pat->value_size = new_header->value_size; - pat->encoding = new_header->encoding; - pat->tokenizer = grn_ctx_at(ctx, new_header->tokenizer); - pat->normalizer = grn_ctx_at(ctx, new_header->normalizer); - GRN_OBJ_FIN(ctx, &(pat->token_filters)); - GRN_PTR_INIT(&(pat->token_filters), GRN_OBJ_VECTOR, GRN_ID_NIL); - pat->obj.header.flags = new_header->flags; - if (pat->cache) { - grn_pat_cache_disable(ctx, pat); - pat->cache = NULL; - pat->cache_size = 0; + if (pat->header->truncated) { + ERR(GRN_FILE_CORRUPT, + "pat is truncated, please unmap or reopen the database"); + return GRN_FILE_CORRUPT; } return GRN_SUCCESS; } @@ -708,11 +676,9 @@ grn_pat_truncate(grn_ctx *ctx, grn_pat *pat) char *path; uint32_t key_size, value_size, flags; - if (pat->header->truncated) { - rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + rc = grn_pat_error_if_truncated(ctx, pat); + if (rc != GRN_SUCCESS) { + return rc; } if ((io_path = grn_io_path(pat->io)) && *io_path != '\0') { if (!(path = GRN_STRDUP(io_path))) { @@ -976,11 +942,8 @@ grn_pat_add(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size, uint32_t new, lkey = 0; grn_id r0; uint8_t keybuf[MAX_FIXED_KEY_SIZE]; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return GRN_ID_NIL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return GRN_ID_NIL; } if (!key || !key_size) { return GRN_ID_NIL; } if (key_size > GRN_TABLE_MAX_KEY_SIZE) { @@ -1072,11 +1035,8 @@ grn_id grn_pat_get(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size, void **value) { uint8_t keybuf[MAX_FIXED_KEY_SIZE]; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return GRN_ID_NIL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return GRN_ID_NIL; } KEY_ENCODE(pat, keybuf, key, key_size); return _grn_pat_get(ctx, pat, key, key_size, value); @@ -1087,11 +1047,8 @@ grn_pat_nextid(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size) { grn_id r = GRN_ID_NIL; if (pat && key) { - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return GRN_ID_NIL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return GRN_ID_NIL; } if (!(r = pat->header->garbages[key_size > sizeof(uint32_t) ? key_size : 0])) { r = pat->header->curr_rec + 1; @@ -1139,11 +1096,9 @@ grn_pat_prefix_search(grn_ctx *ctx, grn_pat *pat, grn_id r; pat_node *rn; uint8_t keybuf[MAX_FIXED_KEY_SIZE]; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + grn_rc rc = grn_pat_error_if_truncated(ctx, pat); + if (rc != GRN_SUCCESS) { + return rc; } KEY_ENCODE(pat, keybuf, key, key_size); PAT_AT(pat, 0, rn); @@ -1230,11 +1185,8 @@ grn_pat_lcp_search(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_siz if (!pat || !key) { return GRN_ID_NIL; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return GRN_ID_NIL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return GRN_ID_NIL; } if (!(pat->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE)) { return GRN_ID_NIL; } PAT_AT(pat, 0, rn); @@ -1489,13 +1441,12 @@ grn_rc grn_pat_delete(grn_ctx *ctx, grn_pat *pat, const void *key, uint32_t key_size, grn_table_delete_optarg *optarg) { + grn_rc rc; uint8_t keybuf[MAX_FIXED_KEY_SIZE]; if (!pat || !key || !key_size) { return GRN_INVALID_ARGUMENT; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + rc = grn_pat_error_if_truncated(ctx, pat); + if (rc != GRN_SUCCESS) { + return rc; } KEY_ENCODE(pat, keybuf, key, key_size); return _grn_pat_delete(ctx, pat, key, key_size, optarg); @@ -1505,11 +1456,8 @@ uint32_t grn_pat_size(grn_ctx *ctx, grn_pat *pat) { if (!pat) { return GRN_INVALID_ARGUMENT; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return 0; } return pat->header->n_entries; } @@ -1519,11 +1467,8 @@ _grn_pat_key(grn_ctx *ctx, grn_pat *pat, grn_id id, uint32_t *key_size) { pat_node *node; uint8_t *key; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return NULL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return NULL; } PAT_AT(pat, id, node); if (!node) { @@ -1543,12 +1488,11 @@ grn_rc grn_pat_delete_by_id(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_table_delete_optarg *optarg) { + grn_rc rc; if (!pat || !id) { return GRN_INVALID_ARGUMENT; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + rc = grn_pat_error_if_truncated(ctx, pat); + if (rc != GRN_SUCCESS) { + return rc; } { uint32_t key_size; @@ -1564,11 +1508,8 @@ grn_pat_get_key(grn_ctx *ctx, grn_pat *pat, grn_id id, void *keybuf, int bufsize uint8_t *key; pat_node *node; if (!pat) { return GRN_INVALID_ARGUMENT; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return 0; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return 0; } if (!id) { return 0; } PAT_AT(pat, id, node); @@ -1592,11 +1533,8 @@ grn_pat_get_key2(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_obj *bulk) uint8_t *key; pat_node *node; if (!pat) { return GRN_INVALID_ARGUMENT; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return 0; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return 0; } if (!id) { return 0; } PAT_AT(pat, id, node); @@ -1627,11 +1565,8 @@ int grn_pat_get_value(grn_ctx *ctx, grn_pat *pat, grn_id id, void *valuebuf) { int value_size; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return 0; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return 0; } value_size = (int)pat->value_size; if (value_size) { @@ -1654,11 +1589,8 @@ const char * grn_pat_get_value_(grn_ctx *ctx, grn_pat *pat, grn_id id, uint32_t *size) { const char *value = NULL; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return NULL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return NULL; } if ((*size = pat->value_size)) { if ((value = (const char *)sis_at(ctx, pat, id)) @@ -1673,11 +1605,9 @@ grn_rc grn_pat_set_value(grn_ctx *ctx, grn_pat *pat, grn_id id, const void *value, int flags) { - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + grn_rc rc = grn_pat_error_if_truncated(ctx, pat); + if (rc != GRN_SUCCESS) { + return rc; } if (value) { uint32_t value_size = pat->value_size; @@ -1729,20 +1659,18 @@ grn_rc grn_pat_info(grn_ctx *ctx, grn_pat *pat, int *key_size, unsigned int *flags, grn_encoding *encoding, unsigned int *n_entries, unsigned int *file_size) { + grn_rc rc; ERRCLR(NULL); if (!pat) { return GRN_INVALID_ARGUMENT; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return rc; - } + rc = grn_pat_error_if_truncated(ctx, pat); + if (rc != GRN_SUCCESS) { + return rc; } if (key_size) { *key_size = pat->key_size; } if (flags) { *flags = pat->obj.header.flags; } if (encoding) { *encoding = pat->encoding; } if (n_entries) { *n_entries = pat->header->n_entries; } if (file_size) { - grn_rc rc; uint64_t tmp = 0; if ((rc = grn_io_size(ctx, pat->io, &tmp))) { return rc; @@ -1759,11 +1687,8 @@ grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id, int level = 0, shared; const char *key = NULL, *_key; sis_node *sp, *ss = NULL, *si; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return 0; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return 0; } si = sis_at(ctx, pat, id); while (id) { @@ -1839,11 +1764,8 @@ grn_pat_delete_with_sis(grn_ctx *ctx, grn_pat *pat, grn_id id, grn_id grn_pat_next(grn_ctx *ctx, grn_pat *pat, grn_id id) { - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return GRN_ID_NIL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return GRN_ID_NIL; } while (++id <= pat->header->curr_rec) { uint32_t key_size; @@ -1867,11 +1789,8 @@ grn_pat_at(grn_ctx *ctx, grn_pat *pat, grn_id id) grn_id grn_pat_curr_id(grn_ctx *ctx, grn_pat *pat) { - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return GRN_ID_NIL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return GRN_ID_NIL; } return pat->header->curr_rec; } @@ -1882,11 +1801,8 @@ grn_pat_scan(grn_ctx *ctx, grn_pat *pat, const char *str, unsigned int str_len, { int n = 0; grn_id tid; - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return 0; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return 0; } if (pat->normalizer) { grn_obj *nstr = grn_string_open(ctx, str, str_len, @@ -2474,11 +2390,8 @@ grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat, pat_node *node; grn_pat_cursor *c; if (!pat || !ctx) { return NULL; } - if (pat->header->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return NULL; - } + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return NULL; } if ((flags & GRN_CURSOR_BY_ID)) { return grn_pat_cursor_open_by_id(ctx, pat, min, min_size, max, max_size, @@ -2643,12 +2556,8 @@ grn_pat_check(grn_ctx *ctx, grn_pat *pat) { char buf[8]; struct grn_pat_header *h = pat->header; - if (h->truncated) { - grn_rc rc = grn_pat_reopen(ctx, pat); - if (rc != GRN_SUCCESS) { - return; - } - h = pat->header; + if (grn_pat_error_if_truncated(ctx, pat) != GRN_SUCCESS) { + return; } GRN_OUTPUT_ARRAY_OPEN("RESULT", 1); GRN_OUTPUT_MAP_OPEN("SUMMARY", 23); -------------- next part -------------- HTML����������������������������... Download