2009-05-20 21:23:51 +00:00
|
|
|
#include <stasis/pageHandle.h>
|
|
|
|
|
2007-03-13 08:40:31 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2008-03-02 23:21:39 +00:00
|
|
|
|
2007-07-18 20:09:14 +00:00
|
|
|
/**
|
2007-03-13 08:40:31 +00:00
|
|
|
@todo Make sure this doesn't need to be atomic. (It isn't!) Can
|
|
|
|
we get in trouble by setting the page clean after it's written
|
2007-07-18 20:09:14 +00:00
|
|
|
out, or forcing the log too early?
|
2007-03-13 08:40:31 +00:00
|
|
|
*/
|
2009-05-08 04:56:34 +00:00
|
|
|
static void phWrite(stasis_page_handle_t * ph, Page * ret) {
|
2007-03-13 08:40:31 +00:00
|
|
|
if(!ret->dirty) { return; }
|
2007-07-18 20:09:14 +00:00
|
|
|
// This lock is only held to make the page implementation happy. We should
|
|
|
|
// implicitly have exclusive access to the page before this function is called,
|
|
|
|
// or we'll deadlock.
|
|
|
|
writelock(ret->rwlatch,0);
|
2007-10-02 00:18:33 +00:00
|
|
|
stasis_page_flushed(ret);
|
2009-05-13 18:04:53 +00:00
|
|
|
if(ph->log) { stasis_log_force(ph->log, ret->LSN, LOG_FORCE_WAL); }
|
2009-05-08 04:56:34 +00:00
|
|
|
int err = ((stasis_handle_t*)ph->impl)->write(ph->impl, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
|
2007-03-13 08:40:31 +00:00
|
|
|
if(err) {
|
|
|
|
printf("Couldn't write to page file: %s\n", strerror(err));
|
|
|
|
fflush(stdout);
|
|
|
|
abort();
|
|
|
|
}
|
2009-05-20 21:23:51 +00:00
|
|
|
stasis_dirty_page_table_set_clean(ph->dirtyPages, ret);
|
2007-07-18 20:09:14 +00:00
|
|
|
unlock(ret->rwlatch);
|
2007-03-13 08:40:31 +00:00
|
|
|
}
|
2009-07-10 01:19:44 +00:00
|
|
|
static void phRead(stasis_page_handle_t * ph, Page * ret, pagetype_t type) {
|
2007-07-18 20:09:14 +00:00
|
|
|
writelock(ret->rwlatch,0);
|
2009-05-08 04:56:34 +00:00
|
|
|
int err = ((stasis_handle_t*)ph->impl)->read(ph->impl, PAGE_SIZE * ret->id, ret->memAddr, PAGE_SIZE);
|
2007-03-13 08:40:31 +00:00
|
|
|
if(err) {
|
2007-07-18 20:09:14 +00:00
|
|
|
if(err == EDOM) {
|
2007-03-13 08:40:31 +00:00
|
|
|
// tried to read off end of file...
|
|
|
|
memset(ret->memAddr, 0, PAGE_SIZE);
|
2007-07-18 20:09:14 +00:00
|
|
|
} else {
|
2007-03-13 08:40:31 +00:00
|
|
|
printf("Couldn't read from page file: %s\n", strerror(err));
|
|
|
|
fflush(stdout);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret->dirty = 0;
|
2009-07-10 01:19:44 +00:00
|
|
|
stasis_page_loaded(ret, type);
|
2007-07-18 20:09:14 +00:00
|
|
|
unlock(ret->rwlatch);
|
2007-03-13 08:40:31 +00:00
|
|
|
}
|
2009-05-08 04:56:34 +00:00
|
|
|
static void phForce(stasis_page_handle_t * ph) {
|
|
|
|
int err = ((stasis_handle_t*)ph->impl)->force(ph->impl);
|
2007-10-23 01:51:03 +00:00
|
|
|
assert(!err);
|
2007-03-13 08:40:31 +00:00
|
|
|
}
|
2009-05-08 04:56:34 +00:00
|
|
|
static void phForceRange(stasis_page_handle_t * ph, lsn_t start, lsn_t stop) {
|
|
|
|
int err = ((stasis_handle_t*)ph->impl)->force_range(ph->impl,start,stop);
|
2007-11-11 23:22:21 +00:00
|
|
|
assert(!err);
|
|
|
|
}
|
2009-05-08 04:56:34 +00:00
|
|
|
static void phClose(stasis_page_handle_t * ph) {
|
|
|
|
int err = ((stasis_handle_t*)ph->impl)->close(ph->impl);
|
2007-06-01 21:06:18 +00:00
|
|
|
DEBUG("Closing pageHandle\n");
|
2007-03-13 08:40:31 +00:00
|
|
|
if(err) {
|
|
|
|
printf("Couldn't close page file: %s\n", strerror(err));
|
|
|
|
fflush(stdout);
|
|
|
|
abort();
|
2009-05-08 04:56:34 +00:00
|
|
|
}
|
|
|
|
free(ph);
|
2007-03-13 08:40:31 +00:00
|
|
|
}
|
2009-05-13 18:04:53 +00:00
|
|
|
stasis_page_handle_t * stasis_page_handle_open(stasis_handle_t * handle,
|
2009-05-20 21:23:51 +00:00
|
|
|
stasis_log_t * log, stasis_dirty_page_table_t * dpt) {
|
2007-06-01 21:06:18 +00:00
|
|
|
DEBUG("Using pageHandle implementation\n");
|
2009-05-08 04:56:34 +00:00
|
|
|
stasis_page_handle_t * ret = malloc(sizeof(*ret));
|
|
|
|
ret->write = phWrite;
|
|
|
|
ret->read = phRead;
|
|
|
|
ret->force_file = phForce;
|
|
|
|
ret->force_range = phForceRange;
|
|
|
|
ret->close = phClose;
|
2009-05-13 18:04:53 +00:00
|
|
|
ret->log = log;
|
2009-05-20 21:23:51 +00:00
|
|
|
ret->dirtyPages = dpt;
|
2009-05-08 04:56:34 +00:00
|
|
|
ret->impl = handle;
|
|
|
|
return ret;
|
2007-03-13 08:40:31 +00:00
|
|
|
}
|