diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h index c16ad24a5..cf3887584 100644 --- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h +++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.h @@ -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>::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 cowop_iter_; size_t ra_block_index_ = 0; diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp index 44b731912..c505c32a1 100644 --- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp +++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_dm_user.cpp @@ -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>& 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()) {