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 class MetaFile { 44 public: 45 MetaFile() = delete; 46 ~MetaFile(); 47 using CloudDiskMetaFileCallBack = std::function<void(MetaBase &)>; 48 explicit MetaFile(uint32_t userId, const std::string &path); 49 explicit MetaFile(uint32_t userId, const std::string &bundleName, const std::string &parentCloudId); 50 int32_t DoLookupAndUpdate(const std::string &name, CloudDiskMetaFileCallBack updateFunc); 51 int32_t DoLookupAndRemove(MetaBase &metaBase); 52 int32_t DoCreate(const MetaBase &base); 53 int32_t HandleFileByFd(unsigned long &endBlock, uint32_t &level); 54 int32_t DoRemove(const MetaBase &base); 55 int32_t DoUpdate(const MetaBase &base); 56 int32_t DoRename(const MetaBase &oldBase, const std::string &newName); 57 int32_t DoRename(MetaBase &metaBase, const std::string &newName, std::shared_ptr<MetaFile> newMetaFile); 58 int32_t DoLookup(MetaBase &base); 59 int32_t LoadChildren(std::vector<MetaBase> &bases); 60 61 static std::string GetParentDir(const std::string &path); 62 static std::string GetFileName(const std::string &path); 63 64 private: 65 std::mutex mtx_{}; 66 std::string path_{}; 67 std::string cacheFile_{}; 68 std::string bundleName_{}; 69 std::string cloudId_{}; 70 std::string name_{}; 71 UniqueFd fd_{}; 72 uint32_t userId_{}; 73 std::shared_ptr<MetaFile> parentMetaFile_{nullptr}; 74 }; 75 76 class CloudDiskMetaFile { 77 public: 78 CloudDiskMetaFile() = delete; 79 ~CloudDiskMetaFile(); 80 using CloudDiskMetaFileCallBack = std::function<void(MetaBase &)>; 81 explicit CloudDiskMetaFile(uint32_t userId, const std::string &bundleName, const std::string &cloudId); 82 83 int32_t DoLookupAndUpdate(const std::string &name, CloudDiskMetaFileCallBack updateFunc); 84 int32_t DoChildUpdate(const std::string &name, CloudDiskMetaFileCallBack updateFunc); 85 int32_t DoLookupAndRemove(MetaBase &metaBase); 86 int32_t DoCreate(const MetaBase &base); 87 int32_t HandleFileByFd(unsigned long &endBlock, uint32_t &level); 88 int32_t DoRemove(const MetaBase &base); 89 int32_t DoUpdate(const MetaBase &base); 90 int32_t DoRename(MetaBase &metaBase, const std::string &newName, 91 std::shared_ptr<CloudDiskMetaFile> newMetaFile); 92 int32_t DoLookup(MetaBase &base); 93 int32_t LoadChildren(std::vector<MetaBase> &bases); 94 std::string GetDentryFilePath(); 95 96 private: 97 std::mutex mtx_{}; 98 std::string path_{}; 99 std::string cacheFile_{}; 100 std::string bundleName_{}; 101 std::string cloudId_{}; 102 std::string name_{}; 103 UniqueFd fd_{}; 104 uint32_t userId_{}; 105 std::shared_ptr<MetaFile> parentMetaFile_{nullptr}; 106 }; 107 108 enum { 109 NEED_UPLOAD = 0, 110 NO_UPLOAD, 111 }; 112 113 enum { 114 FILE_TYPE_CONTENT = 0, 115 FILE_TYPE_THUMBNAIL, 116 FILE_TYPE_LCD, 117 }; 118 119 enum { 120 POSITION_UNKNOWN = 0, 121 POSITION_LOCAL = 0x01, 122 POSITION_CLOUD = 0x02, 123 POSITION_LOCAL_AND_CLOUD = POSITION_LOCAL | POSITION_CLOUD, 124 }; 125 126 typedef std::pair<uint32_t, std::string> MetaFileKey; 127 typedef std::pair<MetaFileKey, std::shared_ptr<CloudDiskMetaFile>> CloudDiskMetaFileListEle; 128 typedef std::pair<MetaFileKey, std::shared_ptr<MetaFile>> MetaFileListEle; 129 130 class MetaFileMgr { 131 public: 132 static MetaFileMgr& GetInstance(); 133 /* recordId is hex string of 256 bits, convert to u8 cloudId[32] to kernel */ 134 static std::string RecordIdToCloudId(const std::string hexStr); 135 static std::string CloudIdToRecordId(const std::string cloudId); 136 std::shared_ptr<MetaFile> GetMetaFile(uint32_t userId, const std::string &path); 137 std::shared_ptr<CloudDiskMetaFile> GetCloudDiskMetaFile(uint32_t userId, const std::string &bundleName, 138 const std::string &cloudId); 139 void ClearAll(); 140 void CloudDiskClearAll(); 141 void Clear(uint32_t userId, const std::string &bundleName, const std::string &cloudId); 142 int32_t CreateRecycleDentry(uint32_t userId, const std::string &bundleName); 143 int32_t MoveIntoRecycleDentryfile(uint32_t userId, const std::string &bundleName, 144 const std::string &name, const std::string &parentCloudId, int64_t rowId); 145 int32_t RemoveFromRecycleDentryfile(uint32_t userId, const std::string &bundleName, 146 const std::string &name, const std::string &parentCloudId, int64_t rowId); 147 private: 148 MetaFileMgr() = default; 149 ~MetaFileMgr() = default; 150 MetaFileMgr(const MetaFileMgr &m) = delete; 151 const MetaFileMgr &operator=(const MetaFileMgr &m) = delete; 152 153 std::recursive_mutex mtx_{}; 154 std::mutex cloudDiskMutex_{}; 155 std::list<MetaFileListEle> metaFileList_; 156 std::map<MetaFileKey, std::list<MetaFileListEle>::iterator> metaFiles_; 157 std::list<CloudDiskMetaFileListEle> cloudDiskMetaFileList_; 158 std::map<MetaFileKey, std::list<CloudDiskMetaFileListEle>::iterator> cloudDiskMetaFile_; 159 }; 160 161 struct MetaBase { MetaBaseMetaBase162 MetaBase(const std::string &name) : name(name) {} MetaBaseMetaBase163 MetaBase(const std::string &name, const std::string &cloudId) : name(name), cloudId(cloudId) {} 164 MetaBase() = default; 165 inline bool operator!=(const MetaBase &other) const 166 { 167 return !operator==(other); 168 } 169 inline bool operator==(const MetaBase &other) const 170 { 171 return other.cloudId == cloudId && other.name == name && other.size == size; 172 } 173 uint64_t atime{0}; 174 uint64_t mtime{0}; 175 uint64_t size{0}; 176 uint32_t mode{S_IFREG}; 177 uint8_t position{POSITION_LOCAL}; 178 uint8_t fileType{FILE_TYPE_CONTENT}; 179 uint8_t noUpload{NEED_UPLOAD}; 180 std::string name{}; 181 std::string cloudId{}; 182 off_t nextOff{0}; 183 bool hasDownloaded{false}; 184 }; 185 186 struct BitOps { 187 static const uint8_t BIT_PER_BYTE = 8; TestBitBitOps188 static int TestBit(uint32_t nr, const uint8_t addr[]) 189 { 190 return 1 & (addr[nr / BIT_PER_BYTE] >> (nr & (BIT_PER_BYTE - 1))); 191 } 192 ClearBitBitOps193 static void ClearBit(uint32_t nr, uint8_t addr[]) 194 { 195 addr[nr / BIT_PER_BYTE] &= ~(1UL << ((nr) % BIT_PER_BYTE)); 196 } 197 SetBitBitOps198 static void SetBit(uint32_t nr, uint8_t addr[]) 199 { 200 addr[nr / BIT_PER_BYTE] |= (1UL << ((nr) % BIT_PER_BYTE)); 201 } 202 FindNextBitBitOps203 static uint32_t FindNextBit(const uint8_t addr[], uint32_t maxSlots, uint32_t start) 204 { 205 while (start < maxSlots) { 206 if (BitOps::TestBit(start, addr)) { 207 return start; 208 } 209 start++; 210 } 211 return maxSlots; 212 } 213 FindNextZeroBitBitOps214 static uint32_t FindNextZeroBit(const uint8_t addr[], uint32_t maxSlots, uint32_t start) 215 { 216 while (start < maxSlots) { 217 if (!BitOps::TestBit(start, addr)) { 218 return start; 219 } 220 start++; 221 } 222 return maxSlots; 223 } 224 }; 225 226 struct MetaHelper { 227 static void SetFileType(struct HmdfsDentry *de, uint8_t fileType); 228 static void SetPosition(struct HmdfsDentry *de, uint8_t position); 229 static uint8_t GetFileType(const struct HmdfsDentry *de); 230 static uint8_t GetPosition(const struct HmdfsDentry *de); 231 }; 232 } // namespace FileManagement 233 } // namespace OHOS 234 235 #endif // META_FILE_H 236