1 /*
2 * Copyright (c) 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 #include "clouddisk_notify_utils.h"
17 #include "clouddisk_rdb_utils.h"
18 #include "file_column.h"
19 #include "cloud_pref_impl.h"
20 #include "dfs_error.h"
21 #include "utils_log.h"
22
23 namespace OHOS::FileManagement::CloudDisk {
24 const uint32_t MAX_QUERY_TIMES = 1024;
25 const string BUNDLENAME_FLAG = "<BundleName>";
26 const string CLOUDDISK_URI_PREFIX = "file://<BundleName>/data/storage/el2/cloud";
27 const string BACKFLASH = "/";
28 const int32_t MOCKUSERID = 10;
29 const int32_t CloudDiskNotifyUtils::maxCacheCnt_;
30 list<pair<string, CacheNode>> CloudDiskNotifyUtils::cacheList_;
31 unordered_map<string, list<pair<string, CacheNode>>::iterator> CloudDiskNotifyUtils::cacheMap_;
32 mutex CloudDiskNotifyUtils::cacheMutex_;
33
isRoot(const fuse_ino_t & ino)34 static bool isRoot(const fuse_ino_t &ino)
35 {
36 return ino == FUSE_ROOT_ID;
37 }
38
GetUriRecursively(CloudDiskFuseData * data,FindCloudDiskInodeFunc func,shared_ptr<CloudDiskInode> inoPtr,string & uri)39 static int32_t GetUriRecursively(CloudDiskFuseData* data, FindCloudDiskInodeFunc func,
40 shared_ptr<CloudDiskInode> inoPtr, string &uri)
41 {
42 string bundleName = inoPtr->bundleName;
43 string realPrefix = CLOUDDISK_URI_PREFIX;
44 realPrefix.replace(realPrefix.find(BUNDLENAME_FLAG), BUNDLENAME_FLAG.length(), bundleName);
45 uint32_t queryTimes = 0;
46 while (!isRoot(inoPtr->parent)) {
47 inoPtr = func(data, inoPtr->parent);
48 if (!inoPtr || inoPtr->fileName.empty()) {
49 break;
50 }
51 uri = inoPtr->fileName + BACKFLASH + uri;
52 queryTimes++;
53 if (uri.length() > PATH_MAX || queryTimes > MAX_QUERY_TIMES) {
54 return E_INVAL_ARG;
55 }
56 }
57 uri = realPrefix + BACKFLASH + uri;
58 LOGD("GetUriRecursively uri: %{public}s", GetAnonyString(uri).c_str());
59 return E_OK;
60 }
61
GetNotifyData(CloudDiskFuseData * data,FindCloudDiskInodeFunc func,const fuse_ino_t & ino,NotifyData & notifyData)62 int32_t CloudDiskNotifyUtils::GetNotifyData(CloudDiskFuseData* data, FindCloudDiskInodeFunc func,
63 const fuse_ino_t &ino, NotifyData ¬ifyData)
64 {
65 if (data->userId == MOCKUSERID) {
66 LOGI("AAA");
67 return E_INVAL_ARG;
68 }
69 return E_OK;
70 }
71
GetNotifyData(CloudDiskFuseData * data,FindCloudDiskInodeFunc func,const fuse_ino_t & parent,const string & name,NotifyData & notifyData)72 int32_t CloudDiskNotifyUtils::GetNotifyData(CloudDiskFuseData* data, FindCloudDiskInodeFunc func,
73 const fuse_ino_t &parent, const string &name, NotifyData ¬ifyData)
74 {
75 if (data->userId == MOCKUSERID || name == "mock") {
76 return E_INVAL_ARG;
77 }
78 return E_OK;
79 }
80
GetNotifyData(CloudDiskFuseData * data,FindCloudDiskInodeFunc func,shared_ptr<CloudDiskInode> inoPtr,NotifyData & notifyData)81 int32_t CloudDiskNotifyUtils::GetNotifyData(CloudDiskFuseData* data, FindCloudDiskInodeFunc func,
82 shared_ptr<CloudDiskInode> inoPtr, NotifyData ¬ifyData)
83 {
84 if (data->userId == MOCKUSERID) {
85 return E_INVAL_ARG;
86 }
87 return E_OK;
88 }
89
GetNotifyData(CloudDiskFuseData * data,FindCloudDiskInodeFunc func,shared_ptr<CloudDiskInode> pInoPtr,const string & name,NotifyData & notifyData)90 int32_t CloudDiskNotifyUtils::GetNotifyData(CloudDiskFuseData* data, FindCloudDiskInodeFunc func,
91 shared_ptr<CloudDiskInode> pInoPtr, const string &name, NotifyData ¬ifyData)
92 {
93 if (data->userId == MOCKUSERID || name == "mock") {
94 return E_INVAL_ARG;
95 }
96 return E_OK;
97 }
98
GetCacheNode(const string & cloudId,CacheNode & cacheNode)99 int32_t CloudDiskNotifyUtils::GetCacheNode(const string &cloudId, CacheNode &cacheNode)
100 {
101 lock_guard<mutex> lock(cacheMutex_);
102 auto it = cacheMap_.find(cloudId);
103 if (it == cacheMap_.end()) {
104 LOGI("Not fount in cache, id: %{public}s", cloudId.c_str());
105 return E_INVAL_ARG;
106 }
107 cacheList_.splice(cacheList_.begin(), cacheList_, it->second);
108 cacheNode = it->second->second;
109 return E_OK;
110 }
111
PutCacheNode(const string & cloudId,const CacheNode & cacheNode)112 void CloudDiskNotifyUtils::PutCacheNode(const string &cloudId, const CacheNode &cacheNode)
113 {
114 if (cacheNode.isDir != TYPE_DIR_STR) {
115 return;
116 }
117 lock_guard<mutex> lock(cacheMutex_);
118 auto it = cacheMap_.find(cloudId);
119 if (it != cacheMap_.end()) {
120 LOGD("update cache name: %{public}s", GetAnonyString(cacheNode.fileName).c_str());
121 it->second->second = cacheNode;
122 cacheList_.splice(cacheList_.begin(), cacheList_, it->second);
123 return;
124 }
125 if (cacheMap_.size() == maxCacheCnt_) {
126 LOGI("upto max, delete last one");
127 string deleteCloudId = cacheList_.back().first;
128 cacheList_.pop_back();
129 cacheMap_.erase(deleteCloudId);
130 }
131 LOGD("insert to cache name: %{public}s", GetAnonyString(cacheNode.fileName).c_str());
132 cacheList_.emplace_front(cloudId, cacheNode);
133 cacheMap_[cloudId] = cacheList_.begin();
134 }
135
GetUriFromCache(const string & bundleName,const string & rootId,const CacheNode & cacheNode,string & uri)136 int32_t CloudDiskNotifyUtils::GetUriFromCache(const string &bundleName,
137 const string &rootId,
138 const CacheNode &cacheNode,
139 string &uri)
140 {
141 CacheNode tmpCacheNode;
142 PutCacheNode(cacheNode.cloudId, cacheNode);
143 uri = cacheNode.fileName;
144 tmpCacheNode = cacheNode;
145 int32_t ret;
146 while (tmpCacheNode.parentCloudId != rootId) {
147 ret = GetCacheNode(tmpCacheNode.parentCloudId, tmpCacheNode);
148 if (ret != E_OK) {
149 return ret;
150 }
151 uri = tmpCacheNode.fileName + BACKFLASH + uri;
152 }
153 string realPrefix = CLOUDDISK_URI_PREFIX;
154 realPrefix.replace(realPrefix.find(BUNDLENAME_FLAG), BUNDLENAME_FLAG.length(), bundleName);
155 uri = realPrefix + BACKFLASH + uri;
156 return E_OK;
157 }
158 } // namespace OHOS::FileManagement::CloudDisk