Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix checksumming, refactor code #62

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 111 additions & 100 deletions splitfs/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ uint32_t crc32_for_byte(uint32_t r) {
return r ^ (uint32_t)0xFF000000L;
}

static void set_filenames(char* fname1, char *fname2, void *data, struct op_log_entry* op_entry);
static void set_filename1(char* fname1, void *data, struct op_log_entry* op_entry);
static void set_filename2(char* fname2, void *data, struct op_log_entry* op_entry);


static void set_filenames(char* fname1, char *fname2, void *data, struct op_log_entry* op_entry) {
set_filename1(fname1, data, op_entry);
set_filename2(fname2, data, op_entry);
}

static void set_filename1(char* fname1, void *data, struct op_log_entry* op_entry) {
memcpy(fname1, data, op_entry->file1_size);
fname1[op_entry->file1_size] = '\0';
}

static void set_filename2(char* fname2, void *data, struct op_log_entry* op_entry) {
memcpy(fname2, data + op_entry->file1_size, op_entry->file2_size);
fname2[op_entry->file2_size] = '\0';
}

void create_crc32(const void *data, size_t n_bytes, uint32_t* crc) {
static uint32_t table[0x100];
if(!*table)
Expand Down Expand Up @@ -58,10 +78,11 @@ void persist_op_entry(uint32_t op_type,
loff_t checksum_pos = 0;
loff_t checksum_computation_pos = 0;
struct op_log_entry op_entry;
memset(&op_entry, 0, sizeof(op_entry));

DEBUG_FILE("%s: START\n", __func__);

op_entry.entry_size = OP_LOG_ENTRY_SIZE + strlen(fname1) - sizeof(uint32_t);
op_entry.entry_size = OP_LOG_ENTRY_SIZE + strlen(fname1);
op_entry.file1_size = strlen(fname1);
if (fname2 != NULL) {
op_entry.entry_size += strlen(fname2);
Expand All @@ -83,16 +104,15 @@ void persist_op_entry(uint32_t op_type,
op_entry.flags = flags;
checksum_pos = (void*)op_log + log_off;
checksum_computation_pos = (void*)op_log + log_off + sizeof(uint32_t);
op_entry.checksum = 0;

//create_crc32((void *) &(op_entry.entry_size), op_entry.entry_size, &(op_entry.checksum));

MEMCPY_NON_TEMPORAL((void *)op_log + log_off + sizeof(uint32_t),
MEMCPY_NON_TEMPORAL((void *)op_log + log_off,
&op_entry,
OP_LOG_ENTRY_SIZE);
#if NVM_DELAY
perfmodel_add_delay(0, OP_LOG_ENTRY_SIZE);
#endif
log_off += OP_LOG_ENTRY_SIZE + sizeof(uint32_t);
log_off += OP_LOG_ENTRY_SIZE;
MEMCPY_NON_TEMPORAL((void *)op_log + log_off,
fname1,
strlen(fname1));
Expand All @@ -110,7 +130,8 @@ void persist_op_entry(uint32_t op_type,
log_off += strlen(fname2);
}
if (padding != 0) {
char padstr[padding];
char padstr[64];
memset(padstr, 0, 64);
MEMCPY_NON_TEMPORAL((void *)op_log + log_off,
padstr,
padding);
Expand All @@ -120,7 +141,12 @@ void persist_op_entry(uint32_t op_type,
}

DEBUG_FILE("%s: Got the checksum. log_off = %lu, op_log = %lu\n", __func__, log_off, op_log);
create_crc32((void *) &(checksum_computation_pos), op_entry.entry_size, &(checksum_pos));

// Always set this to 0 because checksum value depends on initial value of crc argument
// Using 0 everywhere for consistent checksums
uint32_t temp = 0;
create_crc32((void *) (checksum_computation_pos), op_entry.entry_size-sizeof(uint32_t), &(temp));
MEMCPY_NON_TEMPORAL(checksum_pos, &temp, sizeof(uint32_t));

_mm_sfence();
}
Expand Down Expand Up @@ -311,32 +337,54 @@ void sync_and_clear_op_log() {
__sync_bool_compare_and_swap(&clearing_op_log, 1, 0);
}

void ledger_op_log_recovery() {
static int verify_checksum(void* crc32_data, size_t crc32_size, struct op_log_entry * op_entry) {
uint32_t computed_checksum = 0;
create_crc32(crc32_data, crc32_size, &computed_checksum);

int flags = 0, ret = 0;
if (computed_checksum != op_entry->checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
return -1;
}
// SUCCESS
return 0;
}

void ledger_op_log_recovery() {
char fname1[256], fname2[256];
struct op_log_entry op_entry;
uint32_t computed_checksum = 0;
op_log_tail = 0;
loff_t op_log_tail_recovery = 0;
int ret = 0;
void * crc32_data;
size_t crc32_size;
void *log_data;

while(op_log_tail < op_log_lim) {
if (app_log + app_log_tail == '0')
goto end;
char *charp;
while(op_log_tail_recovery < op_log_lim) {
memset(&op_entry, 0, sizeof(op_entry));
memset(fname1, 0, 256);
memset(fname2, 0, 256);
ret = 0;
charp = (char *)(op_log);

if (charp[op_log_tail_recovery] == '0')
goto end;

memcpy(&op_entry,
(void *) (op_log + op_log_tail),
(void *) (op_log + op_log_tail_recovery),
OP_LOG_ENTRY_SIZE);

// MSG("Retrieved op log entry: type = %d; file1_size = %d; checksum = %d total size = %d; op_log_tail_recovery = %d\n",
// op_entry.op_type, op_entry.file1_size, op_entry.checksum, op_entry.entry_size, op_log_tail_recovery);

crc32_data = (void *)(op_log + op_log_tail_recovery + sizeof(uint32_t));
crc32_size = op_entry.entry_size - sizeof(uint32_t);
log_data = (void *) (op_log + op_log_tail_recovery + OP_LOG_ENTRY_SIZE);

switch (op_entry.op_type) {
case LOG_DIR_CREATE:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filename1(fname1, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname1, F_OK);
Expand All @@ -349,27 +397,19 @@ void ledger_op_log_recovery() {
assert(0);
}
}
ret = mkdir(fname1, op_entry.mode);
// Use posix operation to ensure we don't come back to splitfs implementation
// TODO: Persist this
ret = _hub_find_fileop("posix")->MKDIR(fname1, op_entry.mode);
if (ret != 0) {
MSG("%s: mkdir failed. Err = %s\n",
__func__, strerror(errno));
assert(0);
}
break;
case LOG_RENAME:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
memcpy(fname2,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE + op_entry.file1_size),
op_entry.file2_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filenames(fname1, fname2, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname2, F_OK);
Expand All @@ -382,27 +422,18 @@ void ledger_op_log_recovery() {
assert(0);
}
}
ret = rename(fname1, fname2);
// TODO: Make this persistent
ret = _hub_find_fileop("posix")->RENAME(fname1, fname2);
if (ret != 0) {
MSG("%s: rename failed. Err = %s\n",
__func__, strerror(errno));
assert(0);
}
break;
case LOG_LINK:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
memcpy(fname2,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE + op_entry.file1_size),
op_entry.file2_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filenames(fname1, fname2, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname2, F_OK);
Expand All @@ -415,27 +446,18 @@ void ledger_op_log_recovery() {
assert(0);
}
}
ret = link(fname1, fname2);
// TODO: Make this persistent
ret = _hub_find_fileop("posix")->LINK(fname1, fname2);
if (ret != 0) {
MSG("%s: link failed. Err = %s\n",
__func__, strerror(errno));
assert(0);
}
break;
case LOG_SYMLINK:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
memcpy(fname2,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE + op_entry.file1_size),
op_entry.file2_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filenames(fname1, fname2, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname2, F_OK);
Expand All @@ -448,23 +470,18 @@ void ledger_op_log_recovery() {
assert(0);
}
}
ret = symlink(fname1, fname2);
// TODO: Make this persistent
ret = _hub_find_fileop("posix")->SYMLINK(fname1, fname2);
if (ret != 0) {
MSG("%s: symlink failed. Err = %s\n",
__func__, strerror(errno));
assert(0);
}
break;
case LOG_DIR_DELETE:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filename1(fname1, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname1, F_OK);
Expand All @@ -477,23 +494,18 @@ void ledger_op_log_recovery() {
else
goto next;
}
ret = rmdir(fname1);
// TODO: Make this persistent
ret = _hub_find_fileop("posix")->RMDIR(fname1);
if (ret != 0) {
MSG("%s: rmdir failed. Err = %s\n",
__func__, strerror(errno));
assert(0);
}
break;
case LOG_FILE_CREATE:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filename1(fname1, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname1, F_OK);
Expand All @@ -506,23 +518,21 @@ void ledger_op_log_recovery() {
assert(0);
}
}
ret = open(fname1, op_entry.flags, op_entry.mode);
int fd;
fd = _hub_find_fileop("posix")->OPEN(fname1, op_entry.flags, op_entry.mode);
if (ret < 0) {
MSG("%s: create file failed. Err = %s\n",
__func__, strerror(errno));
assert(0);
}
ret = _hub_find_fileop("posix")->CLOSE(ret);
ret = _hub_find_fileop("posix")->FSYNC(fd);
assert(ret == 0);
break;
case LOG_FILE_UNLINK:
memcpy(fname1,
(void *) (op_log + op_log_tail + OP_LOG_ENTRY_SIZE),
op_entry.file1_size
);
create_crc32((void *) (op_log + op_log_tail + sizeof(uint32_t)),
op_entry.entry_size,
&(computed_checksum));
if (computed_checksum != op_entry.checksum) {
DEBUG_FILE("%s: checksum missmatch\n", __func__);
set_filename1(fname1, log_data, &op_entry);
ret = verify_checksum(crc32_data, crc32_size, &op_entry);
if(ret != 0) {
return;
}
ret = access(fname1, F_OK);
Expand All @@ -535,7 +545,8 @@ void ledger_op_log_recovery() {
else
goto next;
}
ret = unlink(fname1);
// TODO: Make this persistent
ret = _hub_find_fileop("posix")->UNLINK(fname1);
if (ret != 0) {
MSG("%s: unlink failed. Err = %s\n",
__func__, strerror(errno));
Expand All @@ -545,9 +556,9 @@ void ledger_op_log_recovery() {
}

next:
op_log_tail += op_entry.entry_size;
if (op_log_tail % CLFLUSH_SIZE != 0) {
op_log_tail += (CLFLUSH_SIZE - (op_log_tail % CLFLUSH_SIZE));
op_log_tail_recovery += op_entry.entry_size;
if (op_log_tail_recovery % CLFLUSH_SIZE != 0) {
op_log_tail_recovery += (CLFLUSH_SIZE - (op_log_tail_recovery % CLFLUSH_SIZE));
}
}

Expand Down