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