Merge "snapuserd: Make header_response a state variable."

This commit is contained in:
David Anderson 2023-06-26 22:51:41 +00:00 committed by Gerrit Code Review
commit 53bb327f29
2 changed files with 27 additions and 26 deletions

View file

@ -120,7 +120,7 @@ class Worker {
// Functions interacting with dm-user
bool ReadDmUserHeader();
bool WriteDmUserPayload(size_t size, bool header_response);
bool WriteDmUserPayload(size_t size);
bool DmuserReadRequest();
// IO Path
@ -130,11 +130,11 @@ class Worker {
bool ReadDataFromBaseDevice(sector_t sector, size_t read_size);
bool ReadFromSourceDevice(const CowOperation* cow_op);
bool ReadAlignedSector(sector_t sector, size_t sz, bool header_response);
bool ReadAlignedSector(sector_t sector, size_t sz);
bool ReadUnalignedSector(sector_t sector, size_t size);
int ReadUnalignedSector(sector_t sector, size_t size,
std::vector<std::pair<sector_t, const CowOperation*>>::iterator& it);
bool RespondIOError(bool header_response);
bool RespondIOError();
// Processing COW operations
bool ProcessCowOp(const CowOperation* cow_op);
@ -176,6 +176,7 @@ class Worker {
unique_fd backing_store_fd_;
unique_fd base_path_merge_fd_;
unique_fd ctrl_fd_;
bool header_response_ = false;
std::unique_ptr<ICowOpIter> cowop_iter_;
size_t ra_block_index_ = 0;

View file

@ -306,10 +306,10 @@ bool Worker::ReadDmUserHeader() {
}
// Send the payload/data back to dm-user misc device.
bool Worker::WriteDmUserPayload(size_t size, bool header_response) {
bool Worker::WriteDmUserPayload(size_t size) {
size_t payload_size = size;
void* buf = bufsink_.GetPayloadBufPtr();
if (header_response) {
if (header_response_) {
payload_size += sizeof(struct dm_user_header);
buf = bufsink_.GetBufPtr();
}
@ -319,6 +319,9 @@ bool Worker::WriteDmUserPayload(size_t size, bool header_response) {
return false;
}
// After the first header is sent in response to a request, we cannot
// send any additional headers.
header_response_ = false;
return true;
}
@ -341,7 +344,7 @@ bool Worker::ReadDataFromBaseDevice(sector_t sector, size_t read_size) {
return true;
}
bool Worker::ReadAlignedSector(sector_t sector, size_t sz, bool header_response) {
bool Worker::ReadAlignedSector(sector_t sector, size_t sz) {
struct dm_user_header* header = bufsink_.GetHeaderPtr();
size_t remaining_size = sz;
std::vector<std::pair<sector_t, const CowOperation*>>& chunk_vec = snapuserd_->GetChunkVec();
@ -389,7 +392,7 @@ bool Worker::ReadAlignedSector(sector_t sector, size_t sz, bool header_response)
// Just return the header if it is an error
if (header->type == DM_USER_RESP_ERROR) {
if (!RespondIOError(header_response)) {
if (!RespondIOError()) {
return false;
}
@ -404,14 +407,12 @@ bool Worker::ReadAlignedSector(sector_t sector, size_t sz, bool header_response)
}
if (!io_error) {
if (!WriteDmUserPayload(total_bytes_read, header_response)) {
if (!WriteDmUserPayload(total_bytes_read)) {
return false;
}
SNAP_LOG(DEBUG) << "WriteDmUserPayload success total_bytes_read: " << total_bytes_read
<< " header-response: " << header_response
<< " remaining_size: " << remaining_size;
header_response = false;
remaining_size -= total_bytes_read;
}
} while (remaining_size > 0 && !io_error);
@ -484,7 +485,6 @@ bool Worker::ReadUnalignedSector(sector_t sector, size_t size) {
// to any COW ops. In that case, we just need to read from the base
// device.
bool merge_complete = false;
bool header_response = true;
if (it == chunk_vec.end()) {
if (chunk_vec.size() > 0) {
// I/O request beyond the last mapped sector
@ -503,7 +503,7 @@ bool Worker::ReadUnalignedSector(sector_t sector, size_t size) {
--it;
}
} else {
return ReadAlignedSector(sector, size, header_response);
return ReadAlignedSector(sector, size);
}
loff_t requested_offset = sector << SECTOR_SHIFT;
@ -537,7 +537,7 @@ bool Worker::ReadUnalignedSector(sector_t sector, size_t size) {
if (ret < 0) {
SNAP_LOG(ERROR) << "ReadUnalignedSector failed for sector: " << sector
<< " size: " << size << " it->sector: " << it->first;
return RespondIOError(header_response);
return RespondIOError();
}
remaining_size -= ret;
@ -545,14 +545,13 @@ bool Worker::ReadUnalignedSector(sector_t sector, size_t size) {
sector += (ret >> SECTOR_SHIFT);
// Send the data back
if (!WriteDmUserPayload(total_bytes_read, header_response)) {
if (!WriteDmUserPayload(total_bytes_read)) {
return false;
}
header_response = false;
// If we still have pending data to be processed, this will be aligned I/O
if (remaining_size) {
return ReadAlignedSector(sector, remaining_size, header_response);
return ReadAlignedSector(sector, remaining_size);
}
} else {
// This is all about handling I/O request to be routed to base device
@ -566,21 +565,21 @@ bool Worker::ReadUnalignedSector(sector_t sector, size_t size) {
CHECK(diff_size <= BLOCK_SZ);
if (remaining_size < diff_size) {
if (!ReadDataFromBaseDevice(sector, remaining_size)) {
return RespondIOError(header_response);
return RespondIOError();
}
total_bytes_read += remaining_size;
if (!WriteDmUserPayload(total_bytes_read, header_response)) {
if (!WriteDmUserPayload(total_bytes_read)) {
return false;
}
} else {
if (!ReadDataFromBaseDevice(sector, diff_size)) {
return RespondIOError(header_response);
return RespondIOError();
}
total_bytes_read += diff_size;
if (!WriteDmUserPayload(total_bytes_read, header_response)) {
if (!WriteDmUserPayload(total_bytes_read)) {
return false;
}
@ -588,17 +587,16 @@ bool Worker::ReadUnalignedSector(sector_t sector, size_t size) {
size_t num_sectors_read = (diff_size >> SECTOR_SHIFT);
sector += num_sectors_read;
CHECK(IsBlockAligned(sector << SECTOR_SHIFT));
header_response = false;
// If we still have pending data to be processed, this will be aligned I/O
return ReadAlignedSector(sector, remaining_size, header_response);
return ReadAlignedSector(sector, remaining_size);
}
}
return true;
}
bool Worker::RespondIOError(bool header_response) {
bool Worker::RespondIOError() {
struct dm_user_header* header = bufsink_.GetHeaderPtr();
header->type = DM_USER_RESP_ERROR;
// This is an issue with the dm-user interface. There
@ -610,9 +608,9 @@ bool Worker::RespondIOError(bool header_response) {
// this back to dm-user.
//
// TODO: Fix the interface
CHECK(header_response);
CHECK(header_response_);
if (!WriteDmUserPayload(0, header_response)) {
if (!WriteDmUserPayload(0)) {
return false;
}
@ -629,7 +627,7 @@ bool Worker::DmuserReadRequest() {
return ReadUnalignedSector(header->sector, header->len);
}
return ReadAlignedSector(header->sector, header->len, true);
return ReadAlignedSector(header->sector, header->len);
}
bool Worker::ProcessIORequest() {
@ -645,6 +643,8 @@ bool Worker::ProcessIORequest() {
SNAP_LOG(DEBUG) << "Daemon: msg->type: " << std::dec << header->type;
SNAP_LOG(DEBUG) << "Daemon: msg->flags: " << std::dec << header->flags;
header_response_ = true;
switch (header->type) {
case DM_USER_REQ_MAP_READ: {
if (!DmuserReadRequest()) {