コード例 #1
0
ファイル: barista_core.cpp プロジェクト: jkerfs/DecaFS
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);
  }
}
コード例 #2
0
ファイル: barista_core.cpp プロジェクト: jkerfs/DecaFS
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);
}
コード例 #3
0
ファイル: main.cpp プロジェクト: WardenGnaw/DecaFS
extern "C" void write_file (int fd, const void *buf, size_t count, struct client client) {

  send_write_result(client, fd, count);
}