int mydisk_write_block(int block_id, void *buffer) { /* TODO: this one is similar to read_block() except that * you need to mark it dirty */ printf("\n--- Start write block ---\n"); // printf("block id = %d\n", block_id); if (block_id >= max_blocks) { printf("ERROR: block id greater than max blocks"); return 1; } if (cache_enabled) { printf("cache enabled for write\n"); int i; // char tmp[BLOCK_SIZE]; // char *x; // x = &tmp; // char *x = malloc(BLOCK_SIZE); // print(); // *x = get_cached_block(block_id); char *y[BLOCK_SIZE]; *y = get_cached_block(block_id); if (*y == NULL) { printf("cache miss for write\n"); mark_dirty(block_id); memcpy(create_cached_block(block_id), buffer, BLOCK_SIZE); printf("_______________\n"); char *z = get_cached_block(block_id); for(i=0; i<BLOCK_SIZE; i++) { printf("%c", z[i]); } printf("________________\n"); return 0; } else { printf("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"); printf("cache hit for write\n"); printf("+++++++++ write this ++++++++\n"); for(i=0; i<BLOCK_SIZE; i++) { printf("%c", ((char*)buffer)[i]); } printf("\n+++++++++++++++++\n"); memcpy(get_cached_block(block_id), buffer, BLOCK_SIZE); printf("_______ should be same as top ________\n"); get_cached_block(block_id); printf("\n________________\n"); return -1; } } else { int i; char ch; fseek(thefile, block_id * BLOCK_SIZE, SEEK_SET); if(fwrite(buffer, BLOCK_SIZE, 1, thefile) != 1) { printf("ERROR\n"); return 1; } else { return 0; } } // fseek(thefile, 0, SEEK_SET); // i = 0; // while( ( ch = fgetc(thefile) ) != EOF ) { // printf("%c",ch); // if (i % BLOCK_SIZE == 0 && (i!=0)) { // printf("\n"); // } // i++; // } // printf("\n--- End write block ---\n"); return 0; }
int mydisk_read_block(int block_id, void *buffer) { printf("\n*** Start read block ***\n"); // printf("block id = %d\n", block_id); if (block_id >= max_blocks) { printf("ERROR: block id greater than max blocks"); return 1; } if (cache_enabled) { /* TODO: 1. check if the block is cached * 2. if not create a new entry for the block and read from disk * 3. fill the requested buffer with the data in the entry * 4. return proper return code */ printf("cache enabled for read\n"); int i; // char *x = get_cached_block(block_id); if (get_cached_block(block_id) == NULL) { printf("Cache miss\n"); fseek(thefile, block_id * BLOCK_SIZE, SEEK_SET); fread(buffer, BLOCK_SIZE, 1, thefile); printf("before-->\n"); print(); memcpy(create_cached_block(block_id), buffer, BLOCK_SIZE); printf("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n"); print(); // char *x = get_cached_block(block_id); // for (i=0; i<BLOCK_SIZE; i++) { // printf("%c", x[i]); // } // printf("\n"); // Cache miss return 0; } else { printf("Cache hit\n"); char *x = get_cached_block(block_id); for(i=0;i<BLOCK_SIZE;i++){ printf("%c", x[i]); } printf("\n"); memcpy(buffer, get_cached_block(block_id), BLOCK_SIZE); // Cache hit return -1; } } else { /* TODO: use standard C functiosn to read from disk */ fseek(thefile, block_id * BLOCK_SIZE, SEEK_SET); fread(buffer, BLOCK_SIZE, 1, thefile); // int i; // for(i=0; i<BLOCK_SIZE; i++) { // printf("%c", ((char*)buffer)[i]); // if(i%BLOCK_SIZE == 0 && i!=0) { // printf("\n"); // } // } // printf("\n*** End read block ***\n"); return 0; } }
/*! Returns the writable block data for the requested blockNumber. If \a cleared is true, the block is not read from disk; an empty block is returned. This is the only method to insert a block into a transaction. It makes sure that the previous block contents are preserved in that case. */ static void* get_writable_cached_block(block_cache* cache, fssh_off_t blockNumber, fssh_off_t base, fssh_off_t length, int32_t transactionID, bool cleared) { TRACE(("get_writable_cached_block(blockNumber = %Ld, transaction = %d)\n", blockNumber, transactionID)); if (blockNumber < 0 || blockNumber >= cache->max_blocks) { fssh_panic("get_writable_cached_block: invalid block number %" FSSH_B_PRIdOFF " (max %" FSSH_B_PRIdOFF ")", blockNumber, cache->max_blocks - 1); } bool allocated; cached_block* block = get_cached_block(cache, blockNumber, &allocated, !cleared); if (block == NULL) return NULL; block->discard = false; // if there is no transaction support, we just return the current block if (transactionID == -1) { if (cleared) fssh_memset(block->current_data, 0, cache->block_size); block->is_dirty = true; // mark the block as dirty return block->current_data; } cache_transaction* transaction = block->transaction; if (transaction != NULL && transaction->id != transactionID) { // TODO: we have to wait here until the other transaction is done. // Maybe we should even panic, since we can't prevent any deadlocks. fssh_panic("get_writable_cached_block(): asked to get busy writable block (transaction %d)\n", (int)transaction->id); put_cached_block(cache, block); return NULL; } if (transaction == NULL && transactionID != -1) { // get new transaction transaction = lookup_transaction(cache, transactionID); if (transaction == NULL) { fssh_panic("get_writable_cached_block(): invalid transaction %d!\n", (int)transactionID); put_cached_block(cache, block); return NULL; } if (!transaction->open) { fssh_panic("get_writable_cached_block(): transaction already done!\n"); put_cached_block(cache, block); return NULL; } block->transaction = transaction; // attach the block to the transaction block list block->transaction_next = transaction->first_block; transaction->first_block = block; transaction->num_blocks++; } bool wasUnchanged = block->original_data == NULL || block->previous_transaction != NULL; if (!(allocated && cleared) && block->original_data == NULL) { // we already have data, so we need to preserve it block->original_data = cache->Allocate(); if (block->original_data == NULL) { FATAL(("could not allocate original_data\n")); put_cached_block(cache, block); return NULL; } fssh_memcpy(block->original_data, block->current_data, cache->block_size); } if (block->parent_data == block->current_data) { // remember any previous contents for the parent transaction block->parent_data = cache->Allocate(); if (block->parent_data == NULL) { // TODO: maybe we should just continue the current transaction in this case... FATAL(("could not allocate parent\n")); put_cached_block(cache, block); return NULL; } fssh_memcpy(block->parent_data, block->current_data, cache->block_size); transaction->sub_num_blocks++; } else if (transaction != NULL && transaction->has_sub_transaction && block->parent_data == NULL && wasUnchanged) transaction->sub_num_blocks++; if (cleared) fssh_memset(block->current_data, 0, cache->block_size); block->is_dirty = true; return block->current_data; }