xref: /aosp_15_r20/system/update_engine/payload_consumer/extent_writer.cc (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2009 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker 
17*5a923131SAndroid Build Coastguard Worker #include "update_engine/payload_consumer/extent_writer.h"
18*5a923131SAndroid Build Coastguard Worker 
19*5a923131SAndroid Build Coastguard Worker #include <errno.h>
20*5a923131SAndroid Build Coastguard Worker #include <sys/types.h>
21*5a923131SAndroid Build Coastguard Worker #include <unistd.h>
22*5a923131SAndroid Build Coastguard Worker 
23*5a923131SAndroid Build Coastguard Worker #include <algorithm>
24*5a923131SAndroid Build Coastguard Worker 
25*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/utils.h"
26*5a923131SAndroid Build Coastguard Worker #include "update_engine/payload_consumer/payload_constants.h"
27*5a923131SAndroid Build Coastguard Worker 
28*5a923131SAndroid Build Coastguard Worker using std::min;
29*5a923131SAndroid Build Coastguard Worker 
30*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
31*5a923131SAndroid Build Coastguard Worker 
Write(const void * bytes,size_t count)32*5a923131SAndroid Build Coastguard Worker bool DirectExtentWriter::Write(const void* bytes, size_t count) {
33*5a923131SAndroid Build Coastguard Worker   if (count == 0)
34*5a923131SAndroid Build Coastguard Worker     return true;
35*5a923131SAndroid Build Coastguard Worker   const char* c_bytes = reinterpret_cast<const char*>(bytes);
36*5a923131SAndroid Build Coastguard Worker   size_t bytes_written = 0;
37*5a923131SAndroid Build Coastguard Worker   while (bytes_written < count) {
38*5a923131SAndroid Build Coastguard Worker     TEST_AND_RETURN_FALSE(cur_extent_ != extents_.end());
39*5a923131SAndroid Build Coastguard Worker     uint64_t bytes_remaining_cur_extent =
40*5a923131SAndroid Build Coastguard Worker         cur_extent_->num_blocks() * block_size_ - extent_bytes_written_;
41*5a923131SAndroid Build Coastguard Worker     CHECK_NE(bytes_remaining_cur_extent, static_cast<uint64_t>(0));
42*5a923131SAndroid Build Coastguard Worker     size_t bytes_to_write =
43*5a923131SAndroid Build Coastguard Worker         static_cast<size_t>(min(static_cast<uint64_t>(count - bytes_written),
44*5a923131SAndroid Build Coastguard Worker                                 bytes_remaining_cur_extent));
45*5a923131SAndroid Build Coastguard Worker     TEST_AND_RETURN_FALSE(bytes_to_write > 0);
46*5a923131SAndroid Build Coastguard Worker 
47*5a923131SAndroid Build Coastguard Worker     if (cur_extent_->start_block() != kSparseHole) {
48*5a923131SAndroid Build Coastguard Worker       const off64_t offset =
49*5a923131SAndroid Build Coastguard Worker           cur_extent_->start_block() * block_size_ + extent_bytes_written_;
50*5a923131SAndroid Build Coastguard Worker       TEST_AND_RETURN_FALSE_ERRNO(fd_->Seek(offset, SEEK_SET) !=
51*5a923131SAndroid Build Coastguard Worker                                   static_cast<off64_t>(-1));
52*5a923131SAndroid Build Coastguard Worker       TEST_AND_RETURN_FALSE(
53*5a923131SAndroid Build Coastguard Worker           utils::WriteAll(fd_, c_bytes + bytes_written, bytes_to_write));
54*5a923131SAndroid Build Coastguard Worker     }
55*5a923131SAndroid Build Coastguard Worker     bytes_written += bytes_to_write;
56*5a923131SAndroid Build Coastguard Worker     extent_bytes_written_ += bytes_to_write;
57*5a923131SAndroid Build Coastguard Worker     if (bytes_remaining_cur_extent == bytes_to_write) {
58*5a923131SAndroid Build Coastguard Worker       // We filled this extent
59*5a923131SAndroid Build Coastguard Worker       CHECK_EQ(extent_bytes_written_, cur_extent_->num_blocks() * block_size_);
60*5a923131SAndroid Build Coastguard Worker       // move to next extent
61*5a923131SAndroid Build Coastguard Worker       extent_bytes_written_ = 0;
62*5a923131SAndroid Build Coastguard Worker       cur_extent_++;
63*5a923131SAndroid Build Coastguard Worker     }
64*5a923131SAndroid Build Coastguard Worker   }
65*5a923131SAndroid Build Coastguard Worker   return true;
66*5a923131SAndroid Build Coastguard Worker }
67*5a923131SAndroid Build Coastguard Worker 
68*5a923131SAndroid Build Coastguard Worker }  // namespace chromeos_update_engine
69