1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "partition.h"
17
18 #include <linux/fs.h>
19 #include <sys/ioctl.h>
20 #include <sys/mount.h>
21 #include <vector>
22 #include "flashd_define.h"
23 #include "flashd_utils.h"
24 #include "fs_manager/mount.h"
25 #include "utils.h"
26
27 namespace Flashd {
DoFlash(const uint8_t * buffer,int bufferSize) const28 int Partition::DoFlash(const uint8_t *buffer, int bufferSize) const
29 {
30 if (buffer == nullptr || bufferSize <= 0 || writer_ == nullptr) {
31 FLASHD_LOGE("buffer is null or writer_ is null or bufferSize is invaild");
32 return FLASHING_ARG_INVALID;
33 }
34
35 if (auto ret = writer_->Write(devName_, buffer, bufferSize); ret != 0) {
36 FLASHD_LOGE("Write fail, ret = %d", ret);
37 return ret;
38 }
39 return 0;
40 }
41
DoErase() const42 int Partition::DoErase() const
43 {
44 auto fd = open(GetPartitionRealPath(devName_).c_str(), O_RDWR);
45 if (fd < 0) {
46 FLASHD_LOGE("open partition %s fail, error = %d", devName_.c_str(), errno);
47 return FLASHING_OPEN_PART_ERROR;
48 }
49
50 uint64_t size = GetBlockDeviceSize(fd);
51 uint64_t range[2] = { 0, size };
52 if (ioctl(fd, BLKSECDISCARD, &range) >= 0) {
53 close(fd);
54 return 0;
55 }
56
57 range[0] = 0;
58 range[1] = size;
59 if (ioctl(fd, BLKDISCARD, &range) < 0) {
60 close(fd);
61 FLASHD_LOGE("BLKDISCARD fail");
62 return FLASHING_NOPERMISSION;
63 }
64 std::vector<uint8_t> buffer(BLOCK_SIZE, 0);
65 if (!Updater::Utils::WriteFully(fd, buffer.data(), buffer.size())) {
66 close(fd);
67 FLASHD_LOGE("WriteFully fail");
68 return FLASHING_PART_WRITE_ERROR;
69 }
70 fsync(fd);
71 close(fd);
72 return 0;
73 }
74
DoFormat() const75 int Partition::DoFormat() const
76 {
77 auto name = "/" + devName_;
78 if (auto ret = Updater::FormatPartition(name); ret != 0) {
79 FLASHD_LOGE("FormatPartition fail, ret = %d", ret);
80 return ret;
81 }
82
83 if (auto ret = Updater::MountForPath(name); ret != 0) {
84 FLASHD_LOGE("MountForPath fail, ret = %d", ret);
85 return ret;
86 }
87 return 0;
88 }
89
GetBlockDeviceSize(int fd) const90 uint64_t Partition::GetBlockDeviceSize(int fd) const
91 {
92 uint64_t size = 0;
93 return (ioctl(fd, BLKGETSIZE64, &size) == 0) ? size : 0;
94 }
95 }
96