void check_write_complete (uint32_t request_id) { assert (write_request_exists (request_id)); struct write_request request = write_request_lookups[request_id]; printf ("(BARISTA) Check write complete\n"); if (active_write_requests[request].info.chunks_expected == 0) { printf ("\tall stripes have not been sent yet, write not complete.\n"); return; } if (active_write_requests[request].info.chunks_expected == active_write_requests[request].info.chunks_received && active_write_requests[request].replica_info.chunks_expected == active_write_requests[request].replica_info.chunks_received) { printf ("\tWRITE COMPLETE\n"); if (send_write_result (active_write_requests[request].info.client, active_write_requests[request].fd, active_write_requests[request].count) < 0) { printf ("\tWrite result could not reach client.\n"); } active_write_requests.erase (request); write_request_lookups.erase (request.request_id); write_request_lookups.erase (request.replica_request_id); } else { printf ("\t%d/%d chunks received\n", active_write_requests[request].info.chunks_received, active_write_requests[request].info.chunks_expected); printf ("\t%d/%d replicas received\n", active_write_requests[request].replica_info.chunks_received, active_write_requests[request].replica_info.chunks_expected); } }
extern "C" void write_file (int fd, const void *buf, size_t count, struct client client) { struct file_instance inst; struct decafs_file_stat stat; uint32_t stripe_id, num_chunks = 0, num_replica_chunks = 0; uint32_t chunks_written, replica_chunks_written; int file_offset, stripe_offset, bytes_written = 0, write_size = 0; uint32_t request_id = get_new_request_id(); uint32_t replica_request_id = get_new_request_id(); struct write_request request = {request_id, replica_request_id}; assert (fd > 0); inst = get_file_info((uint32_t)fd); printf ("\n(BARISTA) Write request (%d bytes) from file %d\n", (int)count, (int)inst.file_id); // If the client does not have permission to write, return an error if (has_exclusive_lock (client, inst.file_id) <= 0) { if (send_write_result (client, 0, FILE_NOT_OPEN_FOR_WRITE) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } if (decafs_file_stat (inst.file_id, &stat, client) < 0) { if (send_write_result (client, 0, UNABLE_TO_STAT_FILE) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } if ((file_offset = get_file_cursor (fd)) < 0) { if (send_write_result (client, 0, FILE_NOT_OPEN_FOR_WRITE) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } // If we are requesting 0 bytes, return 0 bytes written if (count == 0) { if (send_write_result (client, 0, 0) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } // Save the request id write_request_lookups[request_id] = request; write_request_lookups[replica_request_id] = request; active_write_requests[request] = write_request_info (client, inst.file_id, fd); // TODO: make some assertion about max write size here get_first_stripe (&stripe_id, &stripe_offset, stat.stripe_size, file_offset); while (bytes_written < (int)count) { if (count - bytes_written > stat.stripe_size - stripe_offset) { write_size = stat.stripe_size - stripe_offset; } else { write_size = count - bytes_written; } printf ("\t(request: (%d,%d)) sending stripe %d for processing (%d bytes)\n", request_id, replica_request_id, stripe_id, write_size); // TODO: add pathname here, get from persistent meta chunks_written = 0; replica_chunks_written = 0; process_write_stripe (request_id, replica_request_id, &chunks_written, &replica_chunks_written, inst.file_id, (char *)"", stripe_id, stat.stripe_size, stat.chunk_size, (uint8_t *)buf + bytes_written, stripe_offset, write_size); num_chunks += chunks_written; num_replica_chunks += replica_chunks_written; // TODO (?): Move the file size update and cursor to check_write_complete() update_file_size (inst.file_id, write_size, client); set_file_cursor (fd, get_file_cursor (fd) + write_size, client); stripe_offset = 0; bytes_written += write_size; ++stripe_id; } assert (write_request_exists (request_id)); active_write_requests[request].info.chunks_expected = num_chunks; active_write_requests[request].replica_info.chunks_expected = num_replica_chunks; check_write_complete(request_id); }
extern "C" void write_file (int fd, const void *buf, size_t count, struct client client) { send_write_result(client, fd, count); }