1 /* 2 * Copyright (c) 2023 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 <memory> 21 #include <mutex> 22 #include <map> 23 #include <string> 24 #include <vector> 25 #include <sys/stat.h> 26 27 #include "unique_fd.h" 28 29 namespace OHOS { 30 namespace FileManagement { 31 32 struct MetaBase; 33 class MetaFile { 34 public: 35 MetaFile() = delete; 36 ~MetaFile(); 37 explicit MetaFile(uint32_t userId, const std::string &path); 38 39 int32_t DoCreate(const MetaBase &base); 40 int32_t HandleFileByFd(unsigned long &endBlock, uint32_t &level); 41 int32_t DoRemove(const MetaBase &base); 42 int32_t DoUpdate(const MetaBase &base); 43 int32_t DoRename(const MetaBase &oldBase, const std::string &newName); 44 int32_t DoLookup(MetaBase &base); 45 int32_t LoadChildren(std::vector<MetaBase> &bases); 46 47 static std::string GetParentDir(const std::string &path); 48 static std::string GetFileName(const std::string &path); 49 50 private: 51 std::mutex mtx_{}; 52 std::string path_{}; 53 std::string cacheFile_{}; 54 UniqueFd fd_{}; 55 uint64_t dentryCount_{0}; 56 std::shared_ptr<MetaFile> parentMetaFile_{nullptr}; 57 }; 58 59 enum { 60 FILE_TYPE_CONTENT = 0, 61 FILE_TYPE_THUMBNAIL, 62 FILE_TYPE_LCD, 63 }; 64 65 class MetaFileMgr { 66 public: 67 static MetaFileMgr& GetInstance(); 68 /* recordId is hex string of 256 bits, convert to u8 cloudId[32] to kernel */ 69 static std::string RecordIdToCloudId(const std::string hexStr); 70 static std::string CloudIdToRecordId(const std::string cloudId); 71 std::shared_ptr<MetaFile> GetMetaFile(uint32_t userId, const std::string &path); 72 void ClearAll(); 73 private: 74 MetaFileMgr() = default; 75 ~MetaFileMgr() = default; 76 MetaFileMgr(const MetaFileMgr &m) = delete; 77 const MetaFileMgr &operator=(const MetaFileMgr &m) = delete; 78 79 std::recursive_mutex mtx_{}; 80 std::map<std::pair<uint32_t, std::string>, std::shared_ptr<MetaFile>> metaFiles_; 81 }; 82 83 struct MetaBase { MetaBaseMetaBase84 MetaBase(const std::string &name) : name(name) {} MetaBaseMetaBase85 MetaBase(const std::string &name, const std::string &cloudId) : name(name), cloudId(cloudId) {} 86 MetaBase() = default; 87 inline bool operator!=(const MetaBase &other) const 88 { 89 return !operator==(other); 90 } 91 inline bool operator==(const MetaBase &other) const 92 { 93 return other.cloudId == cloudId && other.name == name && other.size == size; 94 } 95 uint64_t mtime{0}; 96 uint64_t size{0}; 97 uint32_t mode{S_IFREG}; 98 uint32_t fileType{FILE_TYPE_CONTENT}; 99 std::string name{}; 100 std::string cloudId{}; 101 }; 102 103 struct BitOps { 104 static const uint8_t BIT_PER_BYTE = 8; TestBitBitOps105 static int TestBit(uint32_t nr, const uint8_t addr[]) 106 { 107 return 1 & (addr[nr / BIT_PER_BYTE] >> (nr & (BIT_PER_BYTE - 1))); 108 } 109 ClearBitBitOps110 static void ClearBit(uint32_t nr, uint8_t addr[]) 111 { 112 addr[nr / BIT_PER_BYTE] &= ~(1UL << ((nr) % BIT_PER_BYTE)); 113 } 114 SetBitBitOps115 static void SetBit(uint32_t nr, uint8_t addr[]) 116 { 117 addr[nr / BIT_PER_BYTE] |= (1UL << ((nr) % BIT_PER_BYTE)); 118 } 119 FindNextBitBitOps120 static uint32_t FindNextBit(const uint8_t addr[], uint32_t maxSlots, uint32_t start) 121 { 122 while (start < maxSlots) { 123 if (BitOps::TestBit(start, addr)) { 124 return start; 125 } 126 start++; 127 } 128 return maxSlots; 129 } 130 FindNextZeroBitBitOps131 static uint32_t FindNextZeroBit(const uint8_t addr[], uint32_t maxSlots, uint32_t start) 132 { 133 while (start < maxSlots) { 134 if (!BitOps::TestBit(start, addr)) { 135 return start; 136 } 137 start++; 138 } 139 return maxSlots; 140 } 141 }; 142 143 } // namespace FileManagement 144 } // namespace OHOS 145 146 #endif // META_FILE_H 147