void check_read_complete (uint32_t request_id) { assert (read_request_exists (request_id)); if (active_read_requests[request_id].info.chunks_expected == 0) { return; } if (active_read_requests[request_id].info.chunks_expected == active_read_requests[request_id].info.chunks_received) { int count = 0; uint8_t *buffer_offset = active_read_requests[request_id].buf; std::map<struct file_chunk, struct read_buffer*> packet_map = active_read_requests[request_id].response_packets; std::map<struct file_chunk, struct read_buffer*>::iterator it = packet_map.begin(); while (it != packet_map.end()) { struct read_buffer *cur_packet = it->second; memcpy (buffer_offset, cur_packet->buf, cur_packet->size); buffer_offset += cur_packet->size; count += cur_packet->size; it++; delete (cur_packet); } if (send_read_result (active_read_requests[request_id].info.client, active_read_requests[request_id].fd, count, active_read_requests[request_id].buf) < 0) { printf ("\tRead result could not reach client.\n"); } active_read_requests.erase (request_id); } }
extern "C" void read_file (int fd, size_t count, struct client client) { char fake_buffer[2500]; memset(fake_buffer, 48, count); send_read_result(client, fd, count, fake_buffer); }
extern "C" void read_file (int fd, size_t count, struct client client) { struct file_instance inst; struct decafs_file_stat stat; uint32_t stripe_id, num_chunks = 0; int file_offset, stripe_offset, bytes_read = 0, read_size = 0; uint8_t *buf; uint32_t request_id = get_new_request_id(); assert (fd > 0); // Allocate space for the read request buf = (uint8_t *)malloc (count); inst = get_file_info((uint32_t)fd); printf ("\n(BARISTA) Read request (%d bytes)\n", (int)count); // If the client does not have permission to read, return an error if (has_exclusive_lock (client, inst.file_id) <= 0) { if (has_shared_lock (client, inst.file_id) <= 0) { if (send_read_result (client, 0, FILE_NOT_OPEN_FOR_READ, NULL) < 0) { printf ("\tRead result could not reach client.\n"); } return; } } if (decafs_file_stat (inst.file_id, &stat, client) < 0) { if (send_read_result (client, 0, UNABLE_TO_STAT_FILE, NULL) < 0) { printf ("\tRead result could not reach client.\n"); } return; } if ((file_offset = get_file_cursor (fd)) < 0) { if (send_read_result (client, 0, FILE_NOT_OPEN_FOR_READ, NULL) < 0) { printf ("\tRead result could not reach client.\n"); } return; } // TODO: make some assertion about max read size here // If we are trying to read past EOF or requesting 0 bytes, // return 0 bytes read if (file_offset >= (int)stat.size || count == 0) { if (send_read_result (client, fd, 0, NULL) < 0) { printf ("\tRead result could not reach client.\n"); } return; } // Save the request id. active_read_requests[request_id] = read_request_info (client, inst.file_id, fd, buf); get_first_stripe (&stripe_id, &stripe_offset, stat.stripe_size, file_offset); while (bytes_read < (int)count) { printf ("file cursor: %d\n", get_file_cursor(fd)); if (count - bytes_read > stat.stripe_size - stripe_offset) { read_size = stat.stripe_size - stripe_offset; } else { read_size = count - bytes_read; } printf ("\t(request: %d) sending stripe (%d) information for processing (%d bytes)\n", request_id, stripe_id, read_size); // TODO: add pathname here, get from persistent meta num_chunks += process_read_stripe (request_id, inst.file_id, (char *)"", stripe_id, stat.stripe_size, stat.chunk_size, (uint8_t *)buf + bytes_read, stripe_offset, read_size); set_file_cursor (fd, get_file_cursor (fd) + read_size, client); stripe_offset = 0; bytes_read += read_size; ++stripe_id; } assert (read_request_exists (request_id)); active_read_requests[request_id].info.chunks_expected = num_chunks; check_read_complete(request_id); }