• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 #ifndef OHOS_FILEMGMT_DENTRY_META_FILE_H
17 #define OHOS_FILEMGMT_DENTRY_META_FILE_H
18 
19 #include <atomic>
20 #include <functional>
21 #include <list>
22 #include <map>
23 #include <memory>
24 #include <mutex>
25 #include <string>
26 #include <sys/stat.h>
27 #include <vector>
28 
29 #include "unique_fd.h"
30 
31 namespace OHOS {
32 namespace FileManagement {
33 
34 const std::string RECYCLE_NAME = ".trash";
35 const std::string RECYCLE_CLOUD_ID = ".trash";
36 const std::string ROOT_CLOUD_ID = "rootId";
37 const unsigned int STAT_MODE_DIR = 0771;
38 constexpr int32_t LOCAL = 1;
39 constexpr uint32_t MAX_META_FILE_NUM = 100;
40 constexpr uint32_t MAX_CLOUDDISK_META_FILE_NUM = 150;
41 
42 struct MetaBase;
43 struct RestoreInfo;
44 class MetaFile {
45 public:
46     MetaFile() = delete;
47     ~MetaFile();
48     using CloudDiskMetaFileCallBack = std::function<void(MetaBase &)>;
49     explicit MetaFile(uint32_t userId, const std::string &path);
50     explicit MetaFile(uint32_t userId, const std::string &bundleName, const std::string &parentCloudId);
51     int32_t DoLookupAndUpdate(const std::string &name, CloudDiskMetaFileCallBack updateFunc);
52     int32_t DoLookupAndRemove(MetaBase &metaBase);
53     int32_t DoCreate(const MetaBase &base);
54     int32_t HandleFileByFd(unsigned long &endBlock, uint32_t &level);
55     int32_t DoRemove(const MetaBase &base);
56     int32_t DoUpdate(const MetaBase &base);
57     int32_t DoRename(const MetaBase &oldBase, const std::string &newName);
58     int32_t DoRename(MetaBase &metaBase, const std::string &newName, std::shared_ptr<MetaFile> newMetaFile);
59     int32_t DoLookup(MetaBase &base);
60     int32_t LoadChildren(std::vector<MetaBase> &bases);
61 
62     static std::string GetParentDir(const std::string &path);
63     static std::string GetFileName(const std::string &path);
64 
65 private:
66     std::mutex mtx_{};
67     std::string path_{};
68     std::string cacheFile_{};
69     std::string bundleName_{};
70     std::string cloudId_{};
71     std::string name_{};
72     UniqueFd fd_{};
73     uint32_t userId_{};
74     std::shared_ptr<MetaFile> parentMetaFile_{nullptr};
75 };
76 
77 class CloudDiskMetaFile {
78 public:
79     CloudDiskMetaFile() = delete;
80     ~CloudDiskMetaFile();
81     using CloudDiskMetaFileCallBack = std::function<void(MetaBase &)>;
82     explicit CloudDiskMetaFile(uint32_t userId, const std::string &bundleName, const std::string &cloudId);
83 
84     int32_t DoLookupAndCreate(const std::string &name, CloudDiskMetaFileCallBack metaFileCallBack);
85     int32_t DoLookupAndUpdate(const std::string &name, CloudDiskMetaFileCallBack updateFunc);
86     int32_t DoChildUpdate(const std::string &name, CloudDiskMetaFileCallBack updateFunc);
87     int32_t DoLookupAndRemove(MetaBase &metaBase);
88     int32_t DoCreate(const MetaBase &base);
89     int32_t HandleFileByFd(unsigned long &endBlock, uint32_t &level);
90     int32_t DoRemove(const MetaBase &base);
91     int32_t DoUpdate(const MetaBase &base);
92     int32_t DoRename(MetaBase &metaBase, const std::string &newName,
93         std::shared_ptr<CloudDiskMetaFile> newMetaFile);
94     int32_t DoLookup(MetaBase &base);
95     int32_t LoadChildren(std::vector<MetaBase> &bases);
96     std::string GetDentryFilePath();
97 
98 private:
99     int32_t GetCreateInfo(const MetaBase &base, uint32_t &bitPos, uint32_t &namehash,
100         unsigned long &bidx, struct HmdfsDentryGroup &dentryBlk);
101     std::mutex mtx_{};
102     std::string path_{};
103     std::string cacheFile_{};
104     std::string bundleName_{};
105     std::string cloudId_{};
106     std::string name_{};
107     UniqueFd fd_{};
108     uint32_t userId_{};
109     std::shared_ptr<MetaFile> parentMetaFile_{nullptr};
110 };
111 
112 enum {
113     NEED_UPLOAD = 0,
114     NO_UPLOAD,
115 };
116 
117 enum {
118     FILE_TYPE_CONTENT = 0,
119     FILE_TYPE_THUMBNAIL,
120     FILE_TYPE_LCD,
121 };
122 
123 enum {
124     POSITION_UNKNOWN = 0,
125     POSITION_LOCAL = 0x01,
126     POSITION_CLOUD = 0x02,
127     POSITION_LOCAL_AND_CLOUD = POSITION_LOCAL | POSITION_CLOUD,
128 };
129 
130 typedef std::pair<uint32_t, std::string> MetaFileKey;
131 typedef std::pair<MetaFileKey, std::shared_ptr<CloudDiskMetaFile>> CloudDiskMetaFileListEle;
132 typedef std::pair<MetaFileKey, std::shared_ptr<MetaFile>> MetaFileListEle;
133 
134 class MetaFileMgr {
135 public:
136     static MetaFileMgr& GetInstance();
137     /* recordId is hex string of 256 bits, convert to u8 cloudId[32] to kernel */
138     static std::string RecordIdToCloudId(const std::string hexStr, bool isHdc = false);
139     static std::string CloudIdToRecordId(const std::string cloudId, bool isHdc = false);
140     std::shared_ptr<MetaFile> GetMetaFile(uint32_t userId, const std::string &path);
141     std::shared_ptr<CloudDiskMetaFile> GetCloudDiskMetaFile(uint32_t userId, const std::string &bundleName,
142         const std::string &cloudId);
143     void ClearAll();
144     void CloudDiskClearAll();
145     void Clear(uint32_t userId, const std::string &bundleName, const std::string &cloudId);
146     int32_t CreateRecycleDentry(uint32_t userId, const std::string &bundleName);
147     int32_t MoveIntoRecycleDentryfile(uint32_t userId, const std::string &bundleName,
148         const struct RestoreInfo &restoreInfo);
149     int32_t RemoveFromRecycleDentryfile(uint32_t userId, const std::string &bundleName,
150         const struct RestoreInfo &restoreinfo);
151     int32_t GetNewName(std::shared_ptr<CloudDiskMetaFile> metaFile,
152         const std::string &oldName, std::string &newName);
153     int32_t CheckMetaFileSize();
154 private:
155     MetaFileMgr() = default;
156     ~MetaFileMgr() = default;
157     MetaFileMgr(const MetaFileMgr &m) = delete;
158     const MetaFileMgr &operator=(const MetaFileMgr &m) = delete;
159 
160     std::recursive_mutex mtx_{};
161     std::mutex cloudDiskMutex_{};
162     std::list<MetaFileListEle> metaFileList_;
163     std::map<MetaFileKey, std::list<MetaFileListEle>::iterator> metaFiles_;
164     std::list<CloudDiskMetaFileListEle> cloudDiskMetaFileList_;
165     std::map<MetaFileKey, std::list<CloudDiskMetaFileListEle>::iterator> cloudDiskMetaFile_;
166 };
167 
168 struct MetaBase {
MetaBaseMetaBase169     MetaBase(const std::string &name) : name(name) {}
MetaBaseMetaBase170     MetaBase(const std::string &name, const std::string &cloudId) : name(name), cloudId(cloudId) {}
171     MetaBase() = default;
172     inline bool operator!=(const MetaBase &other) const
173     {
174         return !operator==(other);
175     }
176     inline bool operator==(const MetaBase &other) const
177     {
178         return other.cloudId == cloudId && other.name == name && other.size == size;
179     }
180     uint64_t atime{0};
181     uint64_t mtime{0};
182     uint64_t size{0};
183     uint32_t mode{S_IFREG};
184     uint8_t position{POSITION_LOCAL};
185     uint8_t fileType{FILE_TYPE_CONTENT};
186     uint8_t noUpload{NEED_UPLOAD};
187     std::string name{};
188     std::string cloudId{};
189     off_t nextOff{0};
190 };
191 
192 struct BitOps {
193     static const uint8_t BIT_PER_BYTE = 8;
TestBitBitOps194     static int TestBit(uint32_t nr, const uint8_t addr[])
195     {
196         return 1 & (addr[nr / BIT_PER_BYTE] >> (nr & (BIT_PER_BYTE - 1)));
197     }
198 
ClearBitBitOps199     static void ClearBit(uint32_t nr, uint8_t addr[])
200     {
201         addr[nr / BIT_PER_BYTE] &= ~(1UL << ((nr) % BIT_PER_BYTE));
202     }
203 
SetBitBitOps204     static void SetBit(uint32_t nr, uint8_t addr[])
205     {
206         addr[nr / BIT_PER_BYTE] |= (1UL << ((nr) % BIT_PER_BYTE));
207     }
208 
FindNextBitBitOps209     static uint32_t FindNextBit(const uint8_t addr[], uint32_t maxSlots, uint32_t start)
210     {
211         while (start < maxSlots) {
212             if (BitOps::TestBit(start, addr)) {
213                 return start;
214             }
215             start++;
216         }
217         return maxSlots;
218     }
219 
FindNextZeroBitBitOps220     static uint32_t FindNextZeroBit(const uint8_t addr[], uint32_t maxSlots, uint32_t start)
221     {
222         while (start < maxSlots) {
223             if (!BitOps::TestBit(start, addr)) {
224                 return start;
225             }
226             start++;
227         }
228         return maxSlots;
229     }
230 };
231 
232 struct MetaHelper {
233     static void SetFileType(struct HmdfsDentry *de, uint8_t fileType);
234     static void SetPosition(struct HmdfsDentry *de, uint8_t position);
235     static void SetNoUpload(struct HmdfsDentry *de, uint8_t noUpload);
236     static uint8_t GetFileType(const struct HmdfsDentry *de);
237     static uint8_t GetPosition(const struct HmdfsDentry *de);
238     static uint8_t GetNoUpload(const struct HmdfsDentry *de);
239 };
240 
241 struct RestoreInfo {
242     std::string oldName;
243     std::string parentCloudId;
244     std::string newName;
245     int64_t rowId = 0;
246 };
247 } // namespace FileManagement
248 } // namespace OHOS
249 
250 #endif // META_FILE_H
251