Commit 018da258 authored by Yoni Fogel's avatar Yoni Fogel

closes[t:2463] Merge #2463 changes (r18552,18555) to main to fix race condition

with CACHEFILE->fd

git-svn-id: file:///svn/toku/tokudb@18612 c7de825b-a66e-492c-adef-691d508d4ae1
parent 4baa5cd0
......@@ -91,20 +91,22 @@ brtheader_set_dirty(struct brt_header *h, BOOL for_checkpoint){
}
}
//fd is protected (must be holding fdlock)
static void
maybe_truncate_cachefile(BLOCK_TABLE bt, struct brt_header *h, u_int64_t size_needed_before) {
maybe_truncate_cachefile(BLOCK_TABLE bt, int fd, struct brt_header *h, u_int64_t size_needed_before) {
assert(bt->is_locked);
u_int64_t new_size_needed = block_allocator_allocated_limit(bt->block_allocator);
//Save a call to toku_os_get_file_size (kernel call) if unlikely to be useful.
if (new_size_needed < size_needed_before)
toku_maybe_truncate_cachefile(h->cf, new_size_needed);
toku_maybe_truncate_cachefile(h->cf, fd, new_size_needed);
}
//fd is protected (must be holding fdlock)
void
toku_maybe_truncate_cachefile_on_open(BLOCK_TABLE bt, struct brt_header *h) {
toku_maybe_truncate_cachefile_on_open(BLOCK_TABLE bt, int fd, struct brt_header *h) {
lock_for_blocktable(bt);
u_int64_t size_needed = block_allocator_allocated_limit(bt->block_allocator);
toku_maybe_truncate_cachefile(h->cf, size_needed);
toku_maybe_truncate_cachefile(h->cf, fd, size_needed);
unlock_for_blocktable(bt);
}
......@@ -189,8 +191,9 @@ PRNTF("free", i, pair->size, pair->u.diskoff, bt);
// free (offset,len) from checkpoint
// move inprogress to checkpoint (resetting type)
// inprogress = NULL
//fd is protected (must be holding fdlock)
void
toku_block_translation_note_end_checkpoint (BLOCK_TABLE bt, struct brt_header *h) {
toku_block_translation_note_end_checkpoint (BLOCK_TABLE bt, int fd, struct brt_header *h) {
// Free unused blocks
lock_for_blocktable(bt);
u_int64_t allocated_limit_at_start = block_allocator_allocated_limit(bt->block_allocator);
......@@ -219,7 +222,7 @@ PRNTF("free", i, pair->size, pair->u.diskoff, bt);
bt->checkpointed = bt->inprogress;
bt->checkpointed.type = TRANSLATION_CHECKPOINTED;
memset(&bt->inprogress, 0, sizeof(bt->inprogress));
maybe_truncate_cachefile(bt, h, allocated_limit_at_start);
maybe_truncate_cachefile(bt, fd, h, allocated_limit_at_start);
end:
unlock_for_blocktable(bt);
}
......@@ -528,8 +531,9 @@ toku_free_blocknum(BLOCK_TABLE bt, BLOCKNUM *bp, struct brt_header * h) {
unlock_for_blocktable(bt);
}
//fd is protected (must be holding fdlock)
void
toku_block_translation_truncate_unlocked(BLOCK_TABLE bt, struct brt_header *h) {
toku_block_translation_truncate_unlocked(BLOCK_TABLE bt, int fd, struct brt_header *h) {
assert(bt->is_locked);
u_int64_t allocated_limit_at_start = block_allocator_allocated_limit(bt->block_allocator);
brtheader_set_dirty(h, FALSE);
......@@ -541,7 +545,7 @@ toku_block_translation_truncate_unlocked(BLOCK_TABLE bt, struct brt_header *h) {
BLOCKNUM b = make_blocknum(i);
if (t->block_translation[i].size >= 0) free_blocknum_unlocked(bt, &b, h);
}
maybe_truncate_cachefile(bt, h, allocated_limit_at_start);
maybe_truncate_cachefile(bt, fd, h, allocated_limit_at_start);
}
//Verify there are no free blocks.
......
......@@ -24,11 +24,11 @@ void toku_brtheader_lock(struct brt_header *h);
void toku_brtheader_unlock(struct brt_header *h);
void toku_block_translation_note_start_checkpoint_unlocked(BLOCK_TABLE bt);
void toku_block_translation_note_end_checkpoint(BLOCK_TABLE bt, struct brt_header *h);
void toku_block_translation_note_end_checkpoint(BLOCK_TABLE bt, int fd, struct brt_header *h);
void toku_block_translation_note_failed_checkpoint(BLOCK_TABLE bt);
void toku_block_translation_note_skipped_checkpoint(BLOCK_TABLE bt);
void toku_block_translation_truncate_unlocked(BLOCK_TABLE bt, struct brt_header *h);
void toku_maybe_truncate_cachefile_on_open(BLOCK_TABLE bt, struct brt_header *h);
void toku_block_translation_truncate_unlocked(BLOCK_TABLE bt, int fd, struct brt_header *h);
void toku_maybe_truncate_cachefile_on_open(BLOCK_TABLE bt, int fd, struct brt_header *h);
//Blocknums
void toku_allocate_blocknum(BLOCK_TABLE bt, BLOCKNUM *res, struct brt_header * h);
......
......@@ -244,8 +244,8 @@ struct brtenv {
long long checksum_number;
};
extern void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *brtnode_v, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL for_checkpoint);
extern int toku_brtnode_fetch_callback (CACHEFILE cachefile, BLOCKNUM nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*extraargs);
extern void toku_brtnode_flush_callback (CACHEFILE cachefile, int fd, BLOCKNUM nodename, void *brtnode_v, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL for_checkpoint);
extern int toku_brtnode_fetch_callback (CACHEFILE cachefile, int fd, BLOCKNUM nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*extraargs);
extern int toku_brt_alloc_init_header(BRT t);
extern int toku_read_brt_header_and_store_in_cachefile (CACHEFILE cf, struct brt_header **header, BOOL* was_open);
extern CACHEKEY* toku_calculate_root_offset_pointer (BRT brt, u_int32_t *root_hash);
......@@ -342,10 +342,10 @@ enum brt_layout_version_e {
};
void toku_brtheader_free (struct brt_header *h);
int toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **error_string, BOOL oplsn_valid, LSN oplsn);
int toku_brtheader_begin_checkpoint (CACHEFILE cachefile, LSN checkpoint_lsn, void *header_v);
int toku_brtheader_checkpoint (CACHEFILE cachefile, void *header_v);
int toku_brtheader_end_checkpoint (CACHEFILE cachefile, void *header_v);
int toku_brtheader_close (CACHEFILE cachefile, int fd, void *header_v, char **error_string, BOOL oplsn_valid, LSN oplsn);
int toku_brtheader_begin_checkpoint (CACHEFILE cachefile, int fd, LSN checkpoint_lsn, void *header_v);
int toku_brtheader_checkpoint (CACHEFILE cachefile, int fd, void *header_v);
int toku_brtheader_end_checkpoint (CACHEFILE cachefile, int fd, void *header_v);
int toku_maybe_upgrade_brt(BRT t);
int toku_db_badformat(void);
......
......@@ -94,19 +94,20 @@ enum {FILE_CHANGE_INCREMENT = (16<<20)};
//Race condition if ydb lock is split.
//Ydb lock is held when this function is called.
//Not going to truncate and delete (redirect to devnull) at same time.
//Must be holding a read or write lock on fdlock (fd is protected)
void
toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used)
toku_maybe_truncate_cachefile (CACHEFILE cf, int fd, u_int64_t size_used)
// Effect: If file size >= SIZE+32MiB, reduce file size.
// (32 instead of 16.. hysteresis).
// Return 0 on success, otherwise an error number.
{
//Check file size before taking pwrite lock to reduce likelihood of taking
//the lock needlessly.
//the pwrite lock needlessly.
//Check file size after taking lock to avoid race conditions.
int64_t file_size;
if (toku_cachefile_is_dev_null_unlocked(cf)) goto done;
{
int r = toku_os_get_file_size(toku_cachefile_fd(cf), &file_size);
if (r!=0 && toku_cachefile_is_dev_null(cf)) goto done;
int r = toku_os_get_file_size(fd, &file_size);
assert(r==0);
assert(file_size >= 0);
}
......@@ -114,8 +115,7 @@ toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used)
if ((u_int64_t)file_size >= size_used + (2*FILE_CHANGE_INCREMENT)) {
lock_for_pwrite();
{
int r = toku_os_get_file_size(toku_cachefile_fd(cf), &file_size);
if (r!=0 && toku_cachefile_is_dev_null(cf)) goto cleanup;
int r = toku_os_get_file_size(fd, &file_size);
assert(r==0);
assert(file_size >= 0);
}
......@@ -125,7 +125,6 @@ toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used)
int r = toku_cachefile_truncate(cf, new_size);
assert(r==0);
}
cleanup:
unlock_for_pwrite();
}
done:
......@@ -140,6 +139,10 @@ maybe_preallocate_in_file (int fd, u_int64_t size)
int64_t file_size;
{
int r = toku_os_get_file_size(fd, &file_size);
if (r != 0) { // debug #2463
int the_errno = errno;
fprintf(stderr, "%s:%d fd=%d size=%"PRIu64"r=%d errno=%d\n", __FUNCTION__, __LINE__, fd, size, r, the_errno); fflush(stderr);
}
assert(r==0);
}
assert(file_size >= 0);
......
......@@ -433,7 +433,8 @@ int toku_unpin_brtnode (BRT brt, BRTNODE node) {
return toku_cachetable_unpin(brt->cf, node->thisnodename, node->fullhash, (enum cachetable_dirty) node->dirty, brtnode_memory_size(node));
}
void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *brtnode_v, void *extraargs, long size __attribute__((unused)), BOOL write_me, BOOL keep_me, BOOL for_checkpoint) {
//fd is protected (must be holding fdlock)
void toku_brtnode_flush_callback (CACHEFILE cachefile, int fd, BLOCKNUM nodename, void *brtnode_v, void *extraargs, long size __attribute__((unused)), BOOL write_me, BOOL keep_me, BOOL for_checkpoint) {
struct brt_header *h = extraargs;
BRTNODE brtnode = brtnode_v;
// if ((write_me || keep_me) && (brtnode->height==0)) {
......@@ -451,7 +452,7 @@ void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *
if (!h->panic) { // if the brt panicked, stop writing, otherwise try to write it.
int n_workitems, n_threads;
toku_cachefile_get_workqueue_load(cachefile, &n_workitems, &n_threads);
int r = toku_serialize_brtnode_to(toku_cachefile_fd(cachefile), brtnode->thisnodename, brtnode, h, n_workitems, n_threads, for_checkpoint);
int r = toku_serialize_brtnode_to(fd, brtnode->thisnodename, brtnode, h, n_workitems, n_threads, for_checkpoint);
if (r) {
if (h->panic==0) {
char *e = strerror(r);
......@@ -471,11 +472,12 @@ void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *
//printf("%s:%d n_items_malloced=%lld\n", __FILE__, __LINE__, n_items_malloced);
}
int toku_brtnode_fetch_callback (CACHEFILE cachefile, BLOCKNUM nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*extraargs) {
//fd is protected (must be holding fdlock)
int toku_brtnode_fetch_callback (CACHEFILE UU(cachefile), int fd, BLOCKNUM nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*extraargs) {
assert(extraargs);
struct brt_header *h = extraargs;
BRTNODE *result=(BRTNODE*)brtnode_pv;
int r = toku_deserialize_brtnode_from(toku_cachefile_fd(cachefile), nodename, fullhash, result, h);
int r = toku_deserialize_brtnode_from(fd, nodename, fullhash, result, h);
if (r == 0)
*sizep = brtnode_memory_size(*result);
//(*result)->parent_brtnode = 0; /* Don't know it right now. */
......@@ -3028,7 +3030,12 @@ int toku_read_brt_header_and_store_in_cachefile (CACHEFILE cf, struct brt_header
}
*was_open = FALSE;
struct brt_header *h;
int r = toku_deserialize_brtheader_from(toku_cachefile_fd(cf), &h);
int r;
{
int fd = toku_cachefile_get_and_pin_fd (cf);
r = toku_deserialize_brtheader_from(fd, &h);
toku_cachefile_unpin_fd(cf);
}
if (r!=0) return r;
h->cf = cf;
h->root_put_counter = global_root_put_counter++;
......@@ -3230,7 +3237,11 @@ brt_open(BRT t, const char *fname_in_env, const char *fname_in_cwd, int is_creat
DISKOFF offset;
//4 for checksum
toku_realloc_descriptor_on_disk(t->h->blocktable, toku_serialize_descriptor_size(&t->temp_descriptor)+4, &offset, t->h);
r = toku_serialize_descriptor_contents_to_fd(toku_cachefile_fd(t->cf), &t->temp_descriptor, offset);
{
int fd = toku_cachefile_get_and_pin_fd (t->cf);
r = toku_serialize_descriptor_contents_to_fd(fd, &t->temp_descriptor, offset);
toku_cachefile_unpin_fd(t->cf);
}
if (r!=0) goto died_after_read_and_pin;
if (t->h->descriptor.dbt.data) toku_free(t->h->descriptor.dbt.data);
t->h->descriptor = t->temp_descriptor;
......@@ -3256,7 +3267,11 @@ brt_open(BRT t, const char *fname_in_env, const char *fname_in_cwd, int is_creat
}
//Opening a brt may restore to previous checkpoint. Truncate if necessary.
toku_maybe_truncate_cachefile_on_open(t->h->blocktable, t->h);
{
int fd = toku_cachefile_get_and_pin_fd (t->h->cf);
toku_maybe_truncate_cachefile_on_open(t->h->blocktable, fd, t->h);
toku_cachefile_unpin_fd(t->h->cf);
}
WHEN_BRTTRACE(fprintf(stderr, "BRTTRACE -> %p\n", t));
return 0;
}
......@@ -3618,8 +3633,9 @@ int toku_brt_create_cachetable(CACHETABLE *ct, long cachesize, LSN initial_lsn,
}
// Create checkpoint-in-progress versions of header and translation (btt) (and fifo for now...).
//Has access to fd (it is protected).
int
toku_brtheader_begin_checkpoint (CACHEFILE UU(cachefile), LSN checkpoint_lsn, void *header_v) {
toku_brtheader_begin_checkpoint (CACHEFILE UU(cachefile), int UU(fd), LSN checkpoint_lsn, void *header_v) {
struct brt_header *h = header_v;
int r = h->panic;
if (r==0) {
......@@ -3718,8 +3734,9 @@ brtheader_note_unpin_by_checkpoint (CACHEFILE UU(cachefile), void *header_v)
}
// Write checkpoint-in-progress versions of header and translation to disk (really to OS internal buffer).
// Must have access to fd (protected)
int
toku_brtheader_checkpoint (CACHEFILE cachefile, void *header_v)
toku_brtheader_checkpoint (CACHEFILE UU(cachefile), int fd, void *header_v)
{
struct brt_header *h = header_v;
struct brt_header *ch = h->checkpoint_header;
......@@ -3734,7 +3751,7 @@ toku_brtheader_checkpoint (CACHEFILE cachefile, void *header_v)
{
ch->checkpoint_count++;
// write translation and header to disk (or at least to OS internal buffer)
r = toku_serialize_brt_header_to(toku_cachefile_fd(cachefile), ch);
r = toku_serialize_brt_header_to(fd, ch);
if (r!=0) goto handle_error;
}
ch->dirty = 0; // this is only place this bit is cleared (in checkpoint_header)
......@@ -3757,8 +3774,9 @@ toku_brtheader_checkpoint (CACHEFILE cachefile, void *header_v)
// Really write everything to disk (fsync dictionary), then free unused disk space
// (i.e. tell BlockAllocator to liberate blocks used by previous checkpoint).
// Must have access to fd (protected)
int
toku_brtheader_end_checkpoint (CACHEFILE cachefile, void *header_v) {
toku_brtheader_end_checkpoint (CACHEFILE cachefile, int fd, void *header_v) {
struct brt_header *h = header_v;
int r = h->panic;
if (r==0) {
......@@ -3774,7 +3792,7 @@ toku_brtheader_end_checkpoint (CACHEFILE cachefile, void *header_v) {
h->checkpoint_lsn = ch->checkpoint_lsn; //Header updated.
}
}
toku_block_translation_note_end_checkpoint(h->blocktable, h);
toku_block_translation_note_end_checkpoint(h->blocktable, fd, h);
}
if (h->checkpoint_header) { // could be NULL only if panic was true at begin_checkpoint
brtheader_free(h->checkpoint_header);
......@@ -3783,8 +3801,9 @@ toku_brtheader_end_checkpoint (CACHEFILE cachefile, void *header_v) {
return r;
}
//Has access to fd (it is protected).
int
toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **malloced_error_string, BOOL oplsn_valid, LSN oplsn) {
toku_brtheader_close (CACHEFILE cachefile, int fd, void *header_v, char **malloced_error_string, BOOL oplsn_valid, LSN oplsn) {
struct brt_header *h = header_v;
assert(h->type == BRTHEADER_CURRENT);
toku_brtheader_lock(h);
......@@ -3820,11 +3839,11 @@ toku_brtheader_close (CACHEFILE cachefile, void *header_v, char **malloced_error
if (h->dirty) { // this is the only place this bit is tested (in currentheader)
int r2;
//assert(lsn.lsn!=0);
r2 = toku_brtheader_begin_checkpoint(cachefile, lsn, header_v);
r2 = toku_brtheader_begin_checkpoint(cachefile, fd, lsn, header_v);
if (r==0) r = r2;
r2 = toku_brtheader_checkpoint(cachefile, h);
r2 = toku_brtheader_checkpoint(cachefile, fd, h);
if (r==0) r = r2;
r2 = toku_brtheader_end_checkpoint(cachefile, header_v);
r2 = toku_brtheader_end_checkpoint(cachefile, fd, header_v);
if (r==0) r = r2;
if (!h->panic) assert(!h->dirty); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
}
......@@ -5302,7 +5321,9 @@ int toku_brt_keyrange (BRT brt, DBT *key, u_int64_t *less, u_int64_t *equal, u
int toku_brt_stat64 (BRT brt, TOKUTXN UU(txn), struct brtstat64_s *s) {
{
int64_t file_size;
int r = toku_os_get_file_size(toku_cachefile_fd(brt->cf), &file_size);
int fd = toku_cachefile_get_and_pin_fd(brt->cf);
int r = toku_os_get_file_size(fd, &file_size);
toku_cachefile_unpin_fd(brt->cf);
assert(r==0);
s->fsize = file_size + toku_cachefile_size_in_memory(brt->cf);
}
......@@ -5439,10 +5460,11 @@ int toku_brt_truncate (BRT brt) {
// TODO log the truncate?
int fd = toku_cachefile_get_and_pin_fd(brt->cf);
toku_brtheader_lock(brt->h);
if (r==0) {
//Free all data blocknums and associated disk space (if not held on to by checkpoint)
toku_block_translation_truncate_unlocked(brt->h->blocktable, brt->h);
toku_block_translation_truncate_unlocked(brt->h->blocktable, fd, brt->h);
//Assign blocknum for root block, also dirty the header
toku_allocate_blocknum_unlocked(brt->h->blocktable, &brt->h->root, brt->h);
// reinit the header
......@@ -5450,6 +5472,7 @@ int toku_brt_truncate (BRT brt) {
}
toku_brtheader_unlock(brt->h);
toku_cachefile_unpin_fd(brt->cf);
return r;
}
......@@ -5650,17 +5673,20 @@ int
toku_brt_get_fragmentation(BRT brt, TOKU_DB_FRAGMENTATION report) {
int r;
int fd = toku_cachefile_get_and_pin_fd(brt->cf);
toku_brtheader_lock(brt->h);
int64_t file_size;
if (toku_cachefile_is_dev_null(brt->cf))
if (toku_cachefile_is_dev_null_unlocked(brt->cf))
r = EINVAL;
else
r = toku_os_get_file_size(toku_cachefile_fd(brt->cf), &file_size);
r = toku_os_get_file_size(fd, &file_size);
if (r==0) {
report->file_size_bytes = file_size;
toku_block_table_get_fragmentation_unlocked(brt->h->blocktable, report);
}
toku_brtheader_unlock(brt->h);
toku_cachefile_unpin_fd(brt->cf);
return r;
}
......@@ -198,7 +198,7 @@ int toku_pwrite_lock_destroy(void);
int toku_brt_serialize_init(void);
int toku_brt_serialize_destroy(void);
void toku_maybe_truncate_cachefile (CACHEFILE cf, u_int64_t size_used);
void toku_maybe_truncate_cachefile (CACHEFILE cf, int fd, u_int64_t size_used);
// Effect: truncate file if overallocated by at least 32MiB
int maybe_preallocate_in_file (int fd, u_int64_t size);
......
This diff is collapsed.
......@@ -51,6 +51,10 @@ int toku_cachefile_of_filenum (CACHETABLE t, FILENUM filenum, CACHEFILE *cf);
// During a transaction, we cannot reuse an iname.
int toku_cachefile_of_iname_in_env (CACHETABLE ct, const char *iname_in_env, CACHEFILE *cf);
// Get the iname (within the cwd) associated with the cachefile
// Return the filename
char * toku_cachefile_fname_in_cwd (CACHEFILE cf);
// TODO: #1510 Add comments on how these behave
int toku_cachetable_begin_checkpoint (CACHETABLE ct, TOKULOGGER);
int toku_cachetable_end_checkpoint(CACHETABLE ct, TOKULOGGER logger,
......@@ -104,20 +108,22 @@ int toku_cachefile_fsync(CACHEFILE cf);
// When keep_me is false, the value should be freed.
// When for_checkpoint is true, this was a 'pending' write
// Returns: 0 if success, otherwise an error number.
typedef void (*CACHETABLE_FLUSH_CALLBACK)(CACHEFILE, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL for_checkpoint);
// Can access fd (fd is protected by a readlock during call)
typedef void (*CACHETABLE_FLUSH_CALLBACK)(CACHEFILE, int fd, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL for_checkpoint);
// The fetch callback is called when a thread is attempting to get and pin a memory
// object and it is not in the cachetable.
// Returns: 0 if success, otherwise an error number. The address and size of the object
// associated with the key are returned.
typedef int (*CACHETABLE_FETCH_CALLBACK)(CACHEFILE, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs);
// Can access fd (fd is protected by a readlock during call)
typedef int (*CACHETABLE_FETCH_CALLBACK)(CACHEFILE, int fd, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs);
void toku_cachefile_set_userdata(CACHEFILE cf, void *userdata,
int (*log_fassociate_during_checkpoint)(CACHEFILE, void*),
int (*close_userdata)(CACHEFILE, void*, char **/*error_string*/, BOOL, LSN),
int (*checkpoint_userdata)(CACHEFILE, void*),
int (*begin_checkpoint_userdata)(CACHEFILE, LSN, void*),
int (*end_checkpoint_userdata)(CACHEFILE, void*),
int (*close_userdata)(CACHEFILE, int, void*, char **/*error_string*/, BOOL, LSN),
int (*checkpoint_userdata)(CACHEFILE, int, void*),
int (*begin_checkpoint_userdata)(CACHEFILE, int, LSN, void*),
int (*end_checkpoint_userdata)(CACHEFILE, int, void*),
int (*note_pin_by_checkpoint)(CACHEFILE, void*),
int (*note_unpin_by_checkpoint)(CACHEFILE, void*));
// Effect: Store some cachefile-specific user data. When the last reference to a cachefile is closed, we call close_userdata().
......@@ -215,15 +221,15 @@ int toku_cachefile_flush (CACHEFILE);
// Get the file descriptor associated with the cachefile
// Return the file descriptor
int toku_cachefile_fd (CACHEFILE);
// Grabs a read lock protecting the fd
int toku_cachefile_get_and_pin_fd (CACHEFILE);
// Get the iname (within the environment) associated with the cachefile
// Return the filename
char * toku_cachefile_fname_in_env (CACHEFILE cf);
// Get the iname (within the cwd) associated with the cachefile
// Return the filename
char * toku_cachefile_fname_in_cwd (CACHEFILE cf);
// Releases the read lock (taken by toku_cachefile_get_and_pin_fd) protecting the fd
void toku_cachefile_unpin_fd (CACHEFILE);
// For test programs only.
// Set the cachefile's fd and fname.
......@@ -239,7 +245,8 @@ int toku_cachefile_redirect_nullfd (CACHEFILE cf);
int toku_cachefile_truncate (CACHEFILE cf, toku_off_t new_size);
//has it been redirected to dev null?
BOOL toku_cachefile_is_dev_null (CACHEFILE cf);
//Must have called toku_cachefile_get_and_pin_fd to hold a lock around this function
BOOL toku_cachefile_is_dev_null_unlocked (CACHEFILE cf);
// Return the logger associated with the cachefile
TOKULOGGER toku_cachefile_logger (CACHEFILE);
......
......@@ -29,10 +29,12 @@ toku_commit_fdelete (u_int8_t file_was_open,
r = toku_cachefile_of_filenum(txn->logger->ct, filenum, &cf);
assert(r == 0); // must still be open (toku_brt_remove_on_commit() incremented refcount)
{
assert(!toku_cachefile_is_dev_null(cf));
(void)toku_cachefile_get_and_pin_fd(cf);
assert(!toku_cachefile_is_dev_null_unlocked(cf));
struct brt_header *h = toku_cachefile_get_userdata(cf);
DICTIONARY_ID dict_id = h->dict_id;
toku_logger_call_remove_finalize_callback(txn->logger, dict_id);
toku_cachefile_unpin_fd(cf);
}
r = toku_cachefile_redirect_nullfd(cf);
assert(r==0);
......@@ -83,10 +85,12 @@ toku_rollback_fcreate (FILENUM filenum,
int r = toku_cachefile_of_filenum(txn->logger->ct, filenum, &cf);
assert(r == 0);
{
assert(!toku_cachefile_is_dev_null(cf));
(void)toku_cachefile_get_and_pin_fd(cf);
assert(!toku_cachefile_is_dev_null_unlocked(cf));
struct brt_header *h = toku_cachefile_get_userdata(cf);
DICTIONARY_ID dict_id = h->dict_id;
toku_logger_call_remove_finalize_callback(txn->logger, dict_id);
toku_cachefile_unpin_fd(cf);
}
r = toku_cachefile_redirect_nullfd(cf);
assert(r==0);
......@@ -111,15 +115,18 @@ static int do_insertion (enum brt_msg_type type, FILENUM filenum, BYTESTRING key
int r = toku_cachefile_of_filenum(txn->logger->ct, filenum, &cf);
assert(r==0);
if (!toku_cachefile_is_dev_null(cf)) {
(void)toku_cachefile_get_and_pin_fd(cf);
if (!toku_cachefile_is_dev_null_unlocked(cf)) {
OMTVALUE brtv=NULL;
r = toku_omt_find_zero(txn->open_brts, find_brt_from_filenum, &filenum, &brtv, NULL, NULL);
assert(r==0);
BRT brt = brtv;
LSN treelsn = toku_brt_checkpoint_lsn(brt);
if (oplsn.lsn != 0 && oplsn.lsn <= treelsn.lsn)
return 0;
if (oplsn.lsn != 0 && oplsn.lsn <= treelsn.lsn) {
r = 0;
goto cleanup;
}
DBT key_dbt,data_dbt;
XIDS xids = toku_txn_get_xids(txn);
......@@ -131,6 +138,8 @@ static int do_insertion (enum brt_msg_type type, FILENUM filenum, BYTESTRING key
r = toku_brt_root_put_cmd(brt, &brtcmd);
}
cleanup:
toku_cachefile_unpin_fd(cf);
return r;
}
......
......@@ -32,7 +32,7 @@ sleep_random (void)
int expect_value = 42; // initially 42, later 43
static void
flush (CACHEFILE UU(thiscf), CACHEKEY UU(key), void *value, void *UU(extraargs), long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint))
flush (CACHEFILE UU(thiscf), int UU(fd), CACHEKEY UU(key), void *value, void *UU(extraargs), long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint))
{
// printf("f");
assert(size == item_size);
......@@ -46,7 +46,7 @@ flush (CACHEFILE UU(thiscf), CACHEKEY UU(key), void *value, void *UU(extraargs),
}
static int
fetch (CACHEFILE UU(thiscf), CACHEKEY UU(key), u_int32_t UU(fullhash), void **UU(value), long *UU(sizep), void *UU(extraargs))
fetch (CACHEFILE UU(thiscf), int UU(fd), CACHEKEY UU(key), u_int32_t UU(fullhash), void **UU(value), long *UU(sizep), void *UU(extraargs))
{
assert(0); // should not be called
return 0;
......
......@@ -10,7 +10,7 @@ static const int item_size = 1;
static int n_flush, n_write_me, n_keep_me, n_fetch;
static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) {
static void flush(CACHEFILE cf, int UU(fd), CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) {
cf = cf; key = key; value = value; extraargs = extraargs;
// assert(key == make_blocknum((long)value));
assert(size == item_size);
......@@ -19,7 +19,7 @@ static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long
if (keep_me) n_keep_me++;
}
static int fetch(CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs) {
static int fetch(CACHEFILE cf, int UU(fd), CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs) {
cf = cf; key = key; fullhash = fullhash; value = value; sizep = sizep; extraargs = extraargs;
assert(0); // should not be called
n_fetch++;
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -16,6 +17,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -16,6 +17,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -13,20 +13,23 @@ cachetable_fd_test (void) {
CACHEFILE cf;
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int fd1 = toku_cachefile_fd(cf); assert(fd1 >= 0);
int fd1 = toku_cachefile_get_and_pin_fd(cf); assert(fd1 >= 0);
toku_cachefile_unpin_fd(cf);
// test set to good fd succeeds
char fname2[] = __FILE__ "test2.data";
unlink(fname2);
int fd2 = open(fname2, O_RDWR | O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(fd2 >= 0 && fd1 != fd2);
r = toku_cachefile_set_fd(cf, fd2, fname2); assert(r == 0);
assert(toku_cachefile_fd(cf) == fd2);
assert(toku_cachefile_get_and_pin_fd(cf) == fd2);
toku_cachefile_unpin_fd(cf);
// test set to bogus fd fails
int fd3 = open(DEV_NULL_FILE, O_RDWR); assert(fd3 >= 0);
r = close(fd3); assert(r == 0);
r = toku_cachefile_set_fd(cf, fd3, DEV_NULL_FILE); assert(r != 0);
assert(toku_cachefile_fd(cf) == fd2);
assert(toku_cachefile_get_and_pin_fd(cf) == fd2);
toku_cachefile_unpin_fd(cf);
// test the filenum functions
FILENUM fn = toku_cachefile_filenum(cf);
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -16,6 +17,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE cf __attribute__((__unused__)),
int UU(fd),
CACHEKEY key __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *extraargs __attribute__((__unused__)),
......@@ -16,7 +17,7 @@ flush (CACHEFILE cf __attribute__((__unused__)),
}
static int
fetch (CACHEFILE cf, CACHEKEY key, u_int32_t hash, void **vptr, long *sizep, void *extra) {
fetch (CACHEFILE cf, int UU(fd), CACHEKEY key, u_int32_t hash, void **vptr, long *sizep, void *extra) {
cf = cf; hash = hash; extra = extra;
*sizep = (long) key.b;
*vptr = toku_malloc(*sizep);
......@@ -25,6 +26,7 @@ fetch (CACHEFILE cf, CACHEKEY key, u_int32_t hash, void **vptr, long *sizep, voi
static int
fetch_error (CACHEFILE cf __attribute__((__unused__)),
int UU(fd),
CACHEKEY key __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -13,7 +13,7 @@ const int item_size = 1;
int n_flush, n_write_me, n_keep_me, n_fetch;
static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) {
static void flush(CACHEFILE cf, int UU(fd), CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, BOOL UU(for_checkpoint)) {
cf = cf; key = key; value = value; extraargs = extraargs;
// assert(key == make_blocknum((long)value));
assert(size == item_size);
......@@ -22,7 +22,7 @@ static void flush(CACHEFILE cf, CACHEKEY key, void *value, void *extraargs, long
if (keep_me) n_keep_me++;
}
static int fetch(CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs) {
static int fetch(CACHEFILE cf, int UU(fd), CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs) {
cf = cf; key = key; fullhash = fullhash; value = value; sizep = sizep; extraargs = extraargs;
n_fetch++;
sleep(10);
......
......@@ -6,6 +6,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -21,6 +22,7 @@ static int fetch_calls = 0;
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -6,6 +6,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -22,6 +23,7 @@ static int fetch_calls = 0;
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -6,6 +6,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -21,6 +22,7 @@ static int fetch_calls = 0;
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -12,6 +12,7 @@ static int evicted_keys = 0;
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k,
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -33,6 +34,7 @@ static int fetch_calls = 0;
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k,
u_int32_t fullhash __attribute__((__unused__)),
void **value,
......
......@@ -6,6 +6,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -19,6 +20,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -6,6 +6,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -19,6 +20,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -6,6 +6,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -19,6 +20,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -7,6 +7,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -22,6 +23,7 @@ static int fetch_calls = 0;
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -16,6 +17,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -38,6 +38,7 @@ static void* vals[KEYLIMIT];
static int n_keys=0;
static void r_flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k,
void *value,
void *extra __attribute__((__unused__)),
......@@ -69,6 +70,7 @@ static void r_flush (CACHEFILE f __attribute__((__unused__)),
}
static int r_fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY key __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void**value __attribute__((__unused__)),
......
......@@ -20,20 +20,23 @@ cachetable_reserve_filenum_test (void) {
CACHEFILE cf;
r = toku_cachetable_openf(&cf, ct, fname1, fname1, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
int fd1 = toku_cachefile_fd(cf); assert(fd1 >= 0);
int fd1 = toku_cachefile_get_and_pin_fd(cf); assert(fd1 >= 0);
toku_cachefile_unpin_fd(cf);
// test set to good fd succeeds
char fname2[] = __FILE__ "test2.data";
unlink(fname2);
int fd2 = open(fname2, O_RDWR | O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); assert(fd2 >= 0 && fd1 != fd2);
r = toku_cachefile_set_fd(cf, fd2, fname2); assert(r == 0);
assert(toku_cachefile_fd(cf) == fd2);
assert(toku_cachefile_get_and_pin_fd(cf) == fd2);
toku_cachefile_unpin_fd(cf);
// test set to bogus fd fails
int fd3 = open(DEV_NULL_FILE, O_RDWR); assert(fd3 >= 0);
r = close(fd3); assert(r == 0);
r = toku_cachefile_set_fd(cf, fd3, DEV_NULL_FILE); assert(r != 0);
assert(toku_cachefile_fd(cf) == fd2);
assert(toku_cachefile_get_and_pin_fd(cf) == fd2);
toku_cachefile_unpin_fd(cf);
// test the filenum functions
FILENUM fn = toku_cachefile_filenum(cf);
......
......@@ -9,6 +9,7 @@
enum { KEYLIMIT = 4, BLOCKSIZE=1<<20, N=2048};
static void f_flush (CACHEFILE f,
int UU(fd),
CACHEKEY key,
void *value,
void *extra __attribute__((__unused__)),
......@@ -18,7 +19,8 @@ static void f_flush (CACHEFILE f,
BOOL for_checkpoint __attribute__((__unused__))) {
assert(size==BLOCKSIZE);
if (write_me) {
toku_os_full_pwrite(toku_cachefile_fd(f), value, BLOCKSIZE, key.b);
toku_os_full_pwrite(toku_cachefile_get_and_pin_fd(f), value, BLOCKSIZE, key.b);
toku_cachefile_unpin_fd(f);
}
if (!keep_me) {
toku_free(value);
......@@ -26,13 +28,15 @@ static void f_flush (CACHEFILE f,
}
static int f_fetch (CACHEFILE f,
int UU(fd),
CACHEKEY key,
u_int32_t fullhash __attribute__((__unused__)),
void**value,
long *sizep,
void*extraargs __attribute__((__unused__))) {
void *buf = toku_malloc(BLOCKSIZE);
int r = pread(toku_cachefile_fd(f), buf, BLOCKSIZE, key.b);
int r = pread(toku_cachefile_get_and_pin_fd(f), buf, BLOCKSIZE, key.b);
toku_cachefile_unpin_fd(f);
assert(r==BLOCKSIZE);
*value = buf;
*sizep = BLOCKSIZE;
......
......@@ -101,6 +101,7 @@ static void expectN(int64_t blocknum_n) {
static CACHEFILE expect_f;
static void flush (CACHEFILE f,
int UU(fd),
CACHEKEY key,
void*value,
void *extra __attribute__((__unused__)),
......@@ -143,7 +144,7 @@ static struct item *make_item (u_int64_t key) {
}
static CACHEKEY did_fetch={-1};
static int fetch (CACHEFILE f, CACHEKEY key, u_int32_t fullhash __attribute__((__unused__)), void**value, long *sizep __attribute__((__unused__)), void*extraargs) {
static int fetch (CACHEFILE f, int UU(fd), CACHEKEY key, u_int32_t fullhash __attribute__((__unused__)), void**value, long *sizep __attribute__((__unused__)), void*extraargs) {
if (verbose) printf("Fetch %" PRId64 "\n", key.b);
assert (expect_f==f);
assert((long)extraargs==23);
......@@ -296,7 +297,7 @@ static void test0 (void) {
toku_memory_check_all_free();
}
static void flush_n (CACHEFILE f __attribute__((__unused__)), CACHEKEY key __attribute__((__unused__)),
static void flush_n (CACHEFILE f __attribute__((__unused__)), int UU(fd), CACHEKEY key __attribute__((__unused__)),
void *value,
void *extra __attribute__((__unused__)),
long size __attribute__((__unused__)),
......@@ -305,7 +306,7 @@ static void flush_n (CACHEFILE f __attribute__((__unused__)), CACHEKEY key __att
int *v = value;
assert(*v==0);
}
static int fetch_n (CACHEFILE f __attribute__((__unused__)), CACHEKEY key __attribute__((__unused__)),
static int fetch_n (CACHEFILE f __attribute__((__unused__)), int UU(fd), CACHEKEY key __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void**value, long *sizep __attribute__((__unused__)), void*extraargs) {
assert((long)extraargs==42);
......@@ -358,6 +359,7 @@ static void test_nested_pin (void) {
static void null_flush (CACHEFILE cf __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *extra __attribute__((__unused__)),
......@@ -367,14 +369,14 @@ static void null_flush (CACHEFILE cf __attribute__((__unused__)),
BOOL for_checkpoint __attribute__((__unused__))) {
}
static int add123_fetch (CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep __attribute__((__unused__)), void*extraargs) {
static int add123_fetch (CACHEFILE cf, int UU(fd), CACHEKEY key, u_int32_t fullhash, void **value, long *sizep __attribute__((__unused__)), void*extraargs) {
assert(fullhash==toku_cachetable_hash(cf,key));
assert((long)extraargs==123);
*value = (void*)((unsigned long)key.b+123L);
return 0;
}
static int add222_fetch (CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep __attribute__((__unused__)), void*extraargs) {
static int add222_fetch (CACHEFILE cf, int UU(fd), CACHEKEY key, u_int32_t fullhash, void **value, long *sizep __attribute__((__unused__)), void*extraargs) {
assert(fullhash==toku_cachetable_hash(cf,key));
assert((long)extraargs==222);
*value = (void*)((unsigned long)key.b+222L);
......@@ -430,6 +432,7 @@ static void test_multi_filehandles (void) {
#endif
static void test_dirty_flush(CACHEFILE f,
int UU(fd),
CACHEKEY key,
void *value,
void *extra __attribute__((__unused__)),
......@@ -440,7 +443,7 @@ static void test_dirty_flush(CACHEFILE f,
if (verbose) printf("test_dirty_flush %p %" PRId64 " %p %ld %u %u\n", f, key.b, value, size, (unsigned)do_write, (unsigned)keep);
}
static int test_dirty_fetch(CACHEFILE f, CACHEKEY key, u_int32_t fullhash, void **value_ptr, long *size_ptr, void *arg) {
static int test_dirty_fetch(CACHEFILE f, int UU(fd), CACHEKEY key, u_int32_t fullhash, void **value_ptr, long *size_ptr, void *arg) {
*value_ptr = arg;
assert(fullhash==toku_cachetable_hash(f,key));
if (verbose) printf("test_dirty_fetch %p %" PRId64 " %p %ld %p\n", f, key.b, *value_ptr, *size_ptr, arg);
......@@ -553,6 +556,7 @@ static int test_size_debug;
static CACHEKEY test_size_flush_key;
static void test_size_flush_callback(CACHEFILE f,
int UU(fd),
CACHEKEY key,
void *value,
void *extra __attribute__((__unused__)),
......
......@@ -95,6 +95,7 @@ static void file_is_not_present(CACHEFILE cf) {
static void flush_forchain (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY key,
void *value,
void *extra __attribute__((__unused__)),
......@@ -111,7 +112,7 @@ static void flush_forchain (CACHEFILE f __attribute__((__unused__)),
//print_ints();
}
static int fetch_forchain (CACHEFILE f, CACHEKEY key, u_int32_t fullhash, void**value, long *sizep __attribute__((__unused__)), void*extraargs) {
static int fetch_forchain (CACHEFILE f, int UU(fd), CACHEKEY key, u_int32_t fullhash, void**value, long *sizep __attribute__((__unused__)), void*extraargs) {
assert(toku_cachetable_hash(f, key)==fullhash);
assert((long)extraargs==(long)key.b);
*value = (void*)(long)key.b;
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -16,6 +17,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
......@@ -3,6 +3,7 @@
static void
flush (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
void *v __attribute__((__unused__)),
void *e __attribute__((__unused__)),
......@@ -16,6 +17,7 @@ flush (CACHEFILE f __attribute__((__unused__)),
static int
fetch (CACHEFILE f __attribute__((__unused__)),
int UU(fd),
CACHEKEY k __attribute__((__unused__)),
u_int32_t fullhash __attribute__((__unused__)),
void **value __attribute__((__unused__)),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment