int main() { int size; mydisk_init("diskfile", MAX_BLOCKS, 0); init_cache(CACHED_BLOCKS); /* Test case 1: read/write block */ size = BLOCK_SIZE; memset(buffer, 0, size); strcpy(buffer, "hello world\n"); mydisk_write_block(0, buffer); memset(buffer2, 0, size); mydisk_read_block(0, buffer2); check_test(memcmp(buffer2, "hello world\n", 13)); /* Test case 2: basic read/write */ memset(buffer, 0, size); mydisk_read(0, 13, buffer); check_test(memcmp(buffer, "hello world\n", 13)); /* Test case 3: read in the middle */ memset(buffer, 0, BLOCK_SIZE); mydisk_read(8, 5, buffer); check_test(memcmp(buffer, "rld\n", 5)); /* Test case 4: read/write across blocks */ size = BLOCK_SIZE; rand_str(buffer, size); mydisk_write(144, size, buffer); memset(buffer2, 0, size); mydisk_read(144, size, buffer2); check_test(memcmp(buffer, buffer2, size)); /* Test case 5: large read/write */ size = BLOCK_SIZE * (MAX_BLOCKS - 1); rand_str(buffer, size); mydisk_write(276, size, buffer); mydisk_read(276, size, buffer2); check_test(memcmp(buffer, buffer2, size)); /* Test case 6~9: read/write exception */ check_test(!mydisk_read(-1, 0, buffer)); check_test(!mydisk_read(0, -10, buffer)); check_test(!mydisk_read(100, BLOCK_SIZE * MAX_BLOCKS, buffer)); check_test(mydisk_write(0, 0, buffer)); check_test(stress_test()); check_test(stress_test2()); close_cache(); mydisk_close(); return 0; }
int stress_test() { int i, id; static char dataset[MAX_BLOCKS][BLOCK_SIZE]; char tmp[BLOCK_SIZE]; for (i = 0; i < MAX_BLOCKS; ++i) { rand_str(dataset[i], BLOCK_SIZE); } for (i = 0; i < 10000; ++i) { id = rand() % MAX_BLOCKS; mydisk_write_block(id, dataset[id]); } for (i = 0; i < MAX_BLOCKS; ++i) { mydisk_read_block(i, tmp); if (memcmp(dataset[i], tmp, BLOCK_SIZE)) { return 1; } } return 0; }
int sfs_write_block(void *buf, blkid bid) { mydisk_write_block(bid, buf); return 0; }
int mydisk_write(int start_address, int nbytes, void *buffer) { /* TODO: similar to read, except the partial write problem * When a block is modified partially, you need to first read the block, * modify the portion and then write the whole block back */ // printf("\n$$$ Start write $$$\n"); int offset, remaining, amount, block_id; if ( !(start_address >= 0) || !(start_address <= (start_address + nbytes)) || !(start_address + nbytes < max_blocks * BLOCK_SIZE)) { printf("ERROR: invalid parameters"); return 1; } char tmp[BLOCK_SIZE]; int start_block = start_address / BLOCK_SIZE; int end_block = (start_address + nbytes) / BLOCK_SIZE; printf("start_block = %d\nend_block = %d\n", start_block, end_block); remaining = nbytes; offset = start_address % BLOCK_SIZE; if ((BLOCK_SIZE - offset) > remaining) { amount = remaining; } else { amount = BLOCK_SIZE - offset; } // printf("OLD -> remaining = %d , offset = %d , amount = %d \n", remaining, offset, amount); int i; for (i=start_block; i<=end_block; i++) { printf("round %d\n", i); mydisk_read_block(i, tmp); // printf("tmp + %d\n", offset); // printf("buffer + %d\n", (nbytes - remaining)); // printf("amount = %d\n", amount); memcpy(tmp + offset, buffer + (nbytes - remaining), amount); printf("buffer[nbytes-remaining] = %c\n", ((char*)buffer)[nbytes-remaining]); printf("Need to write this in the new block : \n"); int j; for(j=0; j< 512; j++) { printf("%c", tmp[j]); } printf("\n"); mydisk_write_block(i, tmp); remaining = remaining - amount; offset = 0; if (remaining - BLOCK_SIZE < 0) { amount = remaining; } else { amount = BLOCK_SIZE; } // printf("NEW -> remaining = %d , offset = %d , amount = %d \n", remaining, offset, amount); } // printf("$$$ End write $$$\n"); return 0; }