• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "file_operations_helper.h"
16 
17 #include <unistd.h>
18 
19 #include "file_operations_cloud.h"
20 #include "file_operations_local.h"
21 #include "securec.h"
22 #include "utils_log.h"
23 
24 namespace OHOS {
25 namespace FileManagement {
26 namespace CloudDisk {
27 using namespace std;
28 namespace {
29     static const string LOCAL_PATH_DATA_SERVICE_EL2 = "/data/service/el2/";
30     static const string LOCAL_PATH_HMDFS_CLOUD_DATA = "/hmdfs/cloud/data/";
31     static const string LOCAL_PATH_HMDFS_CLOUD = "/hmdfs/cloud/";
32 }
33 
GetCloudDiskRootPath(int32_t userId)34 string FileOperationsHelper::GetCloudDiskRootPath(int32_t userId)
35 {
36     return LOCAL_PATH_DATA_SERVICE_EL2 + to_string(userId) + LOCAL_PATH_HMDFS_CLOUD;
37 }
38 
GetCloudDiskLocalPath(int32_t userId,string fileName)39 string FileOperationsHelper::GetCloudDiskLocalPath(int32_t userId, string fileName)
40 {
41     if (fileName == "data") {
42         return LOCAL_PATH_DATA_SERVICE_EL2 + to_string(userId) +
43                LOCAL_PATH_HMDFS_CLOUD_DATA;
44     } else if (fileName == "/") {
45         return GetCloudDiskRootPath(userId);
46     } else {
47         return LOCAL_PATH_DATA_SERVICE_EL2 + to_string(userId) +
48                LOCAL_PATH_HMDFS_CLOUD_DATA + fileName;
49     }
50 }
51 
GetInodeAttr(shared_ptr<CloudDiskInode> ino,struct stat * statBuf)52 void FileOperationsHelper::GetInodeAttr(shared_ptr<CloudDiskInode> ino, struct stat *statBuf)
53 {
54     statBuf->st_ino = reinterpret_cast<fuse_ino_t>(ino.get());
55     statBuf->st_uid = ino->stat.st_uid;
56     statBuf->st_gid = ino->stat.st_gid;
57     statBuf->st_mtime = ino->stat.st_mtime;
58     statBuf->st_ctime = ino->stat.st_ctime;
59     statBuf->st_atime = ino->stat.st_atime;
60     statBuf->st_mode = ino->stat.st_mode;
61     statBuf->st_nlink = ino->stat.st_nlink;
62     if (statBuf->st_mode & S_IFREG) {
63         statBuf->st_size = ino->stat.st_size;
64     }
65 }
66 
GetNextLayer(fuse_ino_t ino)67 int32_t FileOperationsHelper::GetNextLayer(fuse_ino_t ino)
68 {
69     if (ino == FUSE_ROOT_ID) {
70         return CLOUD_DISK_INODE_ZERO_LAYER;
71     }
72     struct CloudDiskInode *inoPtr = reinterpret_cast<struct CloudDiskInode *>(ino);
73     if (inoPtr->layer >= CLOUD_DISK_INODE_OTHER_LAYER) {
74         return CLOUD_DISK_INODE_OTHER_LAYER;
75     } else {
76         return inoPtr->layer + 1;
77     }
78 }
79 
FindCloudDiskInode(struct CloudDiskFuseData * data,const string & key)80 shared_ptr<CloudDiskInode> FileOperationsHelper::FindCloudDiskInode(struct CloudDiskFuseData *data,
81                                                                     const string &key)
82 {
83     shared_ptr<CloudDiskInode> ret;
84     shared_lock<shared_mutex> rLock(data->cacheLock, std::defer_lock);
85     rLock.lock();
86     if (data->inodeCache.find(key) != data->inodeCache.end()) {
87         ret = data->inodeCache[key];
88     } else {
89         ret = nullptr;
90     }
91     rLock.unlock();
92     return ret;
93 }
94 
FindCloudDiskFile(struct CloudDiskFuseData * data,const string & key)95 shared_ptr<CloudDiskFile> FileOperationsHelper::FindCloudDiskFile(struct CloudDiskFuseData *data,
96                                                                   const string &key)
97 {
98     shared_ptr<CloudDiskFile> ret;
99     shared_lock<shared_mutex> rLock(data->fileLock, std::defer_lock);
100     rLock.lock();
101     if (data->fileCache.find(key) != data->fileCache.end()) {
102         ret = data->fileCache[key];
103     } else {
104         ret = nullptr;
105     }
106     rLock.unlock();
107     return ret;
108 }
109 
AddDirEntry(fuse_req_t req,std::string & buf,size_t & size,const char * name,std::shared_ptr<CloudDiskInode> ino)110 void FileOperationsHelper::AddDirEntry(fuse_req_t req, std::string &buf, size_t &size, const char *name,
111                                        std::shared_ptr<CloudDiskInode> ino)
112 {
113     size_t oldSize = size;
114     size += fuse_add_direntry(req, NULL, 0, name, NULL, 0);
115     buf.resize(size);
116     fuse_add_direntry(req, &buf[oldSize], size - oldSize, name, &ino->stat, size);
117 }
118 
FuseReplyLimited(fuse_req_t req,const char * buf,size_t bufSize,off_t off,size_t maxSize)119 void FileOperationsHelper::FuseReplyLimited(fuse_req_t req, const char *buf, size_t bufSize,
120                                             off_t off, size_t maxSize)
121 {
122     if (off < bufSize) {
123         size_t size = (bufSize - off) < maxSize ? (bufSize - off) : maxSize;
124         fuse_reply_buf(req, buf + off, size);
125     } else {
126         fuse_reply_buf(req, NULL, 0);
127     }
128 }
129 
GenerateCloudDiskInode(struct CloudDiskFuseData * data,struct CloudDiskInode * parent,const string & fileName,const string & path)130 shared_ptr<CloudDiskInode> FileOperationsHelper::GenerateCloudDiskInode(struct CloudDiskFuseData *data,
131                                                                         struct CloudDiskInode *parent,
132                                                                         const string &fileName,
133                                                                         const string &path)
134 {
135     std::unique_lock<std::shared_mutex> wLock(data->cacheLock, std::defer_lock);
136     shared_ptr<CloudDiskInode> child = make_shared<CloudDiskInode>();
137     int32_t err = stat(path.c_str(), &child->stat);
138     if (err != 0) {
139         LOGE("GenerateCloudDiskInode %{public}s error, err: %{public}d", path.c_str(), errno);
140         return nullptr;
141     }
142 
143     child->refCount++;
144     child->parent = reinterpret_cast<fuse_ino_t>(parent);
145     child->path = path;
146     child->layer = GetNextLayer(child->parent);
147     child->stat.st_ino = reinterpret_cast<fuse_ino_t>(child.get());
148     child->ops = make_shared<FileOperationsLocal>();
149     wLock.lock();
150     data->inodeCache[path] = child;
151     wLock.unlock();
152     if (child->layer == CLOUD_DISK_INODE_FIRST_LAYER) {
153         child->bundleName = fileName;
154         child->ops = make_shared<FileOperationsCloud>();
155     }
156     return child;
157 }
158 
PutCloudDiskInode(struct CloudDiskFuseData * data,shared_ptr<CloudDiskInode> inoPtr,uint64_t num,const string & key)159 void FileOperationsHelper::PutCloudDiskInode(struct CloudDiskFuseData *data,
160                                              shared_ptr<CloudDiskInode> inoPtr, uint64_t num, const string &key)
161 {
162     std::unique_lock<std::shared_mutex> wLock(data->cacheLock, std::defer_lock);
163     if (inoPtr == nullptr) {
164         LOGD("Get an invalid inode!");
165         return;
166     }
167     inoPtr->refCount -= num;
168     if (inoPtr->refCount == 0) {
169         LOGD("node released: %{public}s", key.c_str());
170         wLock.lock();
171         data->inodeCache.erase(key);
172         wLock.unlock();
173     }
174 }
175 
PutCloudDiskFile(struct CloudDiskFuseData * data,shared_ptr<CloudDiskFile> filePtr,const string & key)176 void FileOperationsHelper::PutCloudDiskFile(struct CloudDiskFuseData *data,
177                                             shared_ptr<CloudDiskFile> filePtr, const string &key)
178 {
179     std::unique_lock<std::shared_mutex> wLock(data->fileLock, std::defer_lock);
180     if (filePtr == nullptr) {
181         LOGD("Get an invalid file!");
182         return;
183     }
184     if (filePtr->refCount == 0) {
185         LOGD("file released: %{public}s", key.c_str());
186         wLock.lock();
187         data->fileCache.erase(key);
188         wLock.unlock();
189     }
190 }
191 } // namespace CloudDisk
192 } // namespace FileManagement
193 } // namespace OHOS
194