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 "fuse_operations.h"
16
17 #include "cloud_disk_inode.h"
18 #include "file_operations_helper.h"
19 #include "file_operations_local.h"
20 #include "utils_log.h"
21
22 namespace OHOS {
23 namespace FileManagement {
24 namespace CloudDisk {
25 using namespace std;
26
GetCloudDiskInode(fuse_req_t req,fuse_ino_t ino)27 static std::shared_ptr<CloudDiskInode> GetCloudDiskInode(fuse_req_t req, fuse_ino_t ino)
28 {
29 struct CloudDiskFuseData *data = reinterpret_cast<struct CloudDiskFuseData *>(fuse_req_userdata(req));
30 return FileOperationsHelper::FindCloudDiskInode(data, static_cast<int64_t>(ino));
31 }
32
Lookup(fuse_req_t req,fuse_ino_t parent,const char * name)33 void FuseOperations::Lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
34 {
35 if (parent == FUSE_ROOT_ID) {
36 auto opsPtr = make_shared<FileOperationsLocal>();
37 opsPtr->Lookup(req, parent, name);
38 return;
39 }
40 auto inoPtr = GetCloudDiskInode(req, parent);
41 if (inoPtr == nullptr) {
42 fuse_reply_err(req, EINVAL);
43 LOGE("parent inode not found");
44 return;
45 }
46 inoPtr->ops->Lookup(req, parent, name);
47 }
48
Access(fuse_req_t req,fuse_ino_t ino,int mask)49 void FuseOperations::Access(fuse_req_t req, fuse_ino_t ino, int mask)
50 {
51 if (ino == FUSE_ROOT_ID) {
52 auto opsPtr = make_shared<FileOperationsLocal>();
53 opsPtr->Access(req, ino, mask);
54 return;
55 }
56 auto inoPtr = GetCloudDiskInode(req, ino);
57 if (inoPtr == nullptr) {
58 fuse_reply_err(req, EINVAL);
59 LOGE("inode not found");
60 return;
61 }
62 inoPtr->ops->Access(req, ino, mask);
63 }
64
GetAttr(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)65 void FuseOperations::GetAttr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
66 {
67 if (ino == FUSE_ROOT_ID) {
68 auto opsPtr = make_shared<FileOperationsLocal>();
69 opsPtr->GetAttr(req, ino, fi);
70 return;
71 }
72 auto inoPtr = GetCloudDiskInode(req, ino);
73 if (inoPtr == nullptr) {
74 fuse_reply_err(req, EINVAL);
75 LOGE("inode not found");
76 return;
77 }
78 inoPtr->ops->GetAttr(req, ino, fi);
79 }
80
Open(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)81 void FuseOperations::Open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
82 {
83 if (ino == FUSE_ROOT_ID) {
84 auto opsPtr = make_shared<FileOperationsLocal>();
85 opsPtr->Open(req, ino, fi);
86 return;
87 }
88 auto inoPtr = GetCloudDiskInode(req, ino);
89 if (inoPtr == nullptr) {
90 fuse_reply_err(req, EINVAL);
91 LOGE("inode not found");
92 return;
93 }
94 inoPtr->ops->Open(req, ino, fi);
95 }
96
Forget(fuse_req_t req,fuse_ino_t ino,uint64_t nLookup)97 void FuseOperations::Forget(fuse_req_t req, fuse_ino_t ino, uint64_t nLookup)
98 {
99 if (ino == FUSE_ROOT_ID) {
100 auto opsPtr = make_shared<FileOperationsLocal>();
101 opsPtr->Forget(req, ino, nLookup);
102 return;
103 }
104 auto inoPtr = GetCloudDiskInode(req, ino);
105 if (inoPtr == nullptr) {
106 fuse_reply_err(req, EINVAL);
107 LOGE("inode not found");
108 return;
109 }
110 inoPtr->ops->Forget(req, ino, nLookup);
111 }
112
ForgetMulti(fuse_req_t req,size_t count,struct fuse_forget_data * forgets)113 void FuseOperations::ForgetMulti(fuse_req_t req, size_t count, struct fuse_forget_data *forgets)
114 {
115 if (count == 0 || forgets[0].ino == FUSE_ROOT_ID) {
116 return;
117 }
118 auto inoPtr = GetCloudDiskInode(req, forgets[0].ino);
119 if (inoPtr == nullptr) {
120 fuse_reply_err(req, EINVAL);
121 LOGE("inode not found");
122 return;
123 }
124 inoPtr->ops->ForgetMulti(req, count, forgets);
125 }
126
MkNod(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t mode,dev_t rdev)127 void FuseOperations::MkNod(fuse_req_t req, fuse_ino_t parent, const char *name,
128 mode_t mode, dev_t rdev)
129 {
130 if (parent == FUSE_ROOT_ID) {
131 auto opsPtr = make_shared<FileOperationsLocal>();
132 opsPtr->MkNod(req, parent, name, mode, rdev);
133 return;
134 }
135 auto inoPtr = GetCloudDiskInode(req, parent);
136 if (inoPtr == nullptr) {
137 fuse_reply_err(req, EINVAL);
138 LOGE("parent inode not found");
139 return;
140 }
141 inoPtr->ops->MkNod(req, parent, name, mode, rdev);
142 }
143
Create(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t mode,struct fuse_file_info * fi)144 void FuseOperations::Create(fuse_req_t req, fuse_ino_t parent, const char *name,
145 mode_t mode, struct fuse_file_info *fi)
146 {
147 if (parent == FUSE_ROOT_ID) {
148 auto opsPtr = make_shared<FileOperationsLocal>();
149 opsPtr->Create(req, parent, name, mode, fi);
150 return;
151 }
152 auto inoPtr = GetCloudDiskInode(req, parent);
153 if (inoPtr == nullptr) {
154 fuse_reply_err(req, EINVAL);
155 LOGE("parent inode not found");
156 return;
157 }
158 inoPtr->ops->Create(req, parent, name, mode, fi);
159 }
160
ReadDir(fuse_req_t req,fuse_ino_t ino,size_t size,off_t off,struct fuse_file_info * fi)161 void FuseOperations::ReadDir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
162 struct fuse_file_info *fi)
163 {
164 (void) fi;
165 if (ino == FUSE_ROOT_ID) {
166 auto opsPtr = make_shared<FileOperationsLocal>();
167 opsPtr->ReadDir(req, ino, size, off, fi);
168 return;
169 }
170 auto inoPtr = GetCloudDiskInode(req, ino);
171 if (inoPtr == nullptr) {
172 fuse_reply_err(req, EINVAL);
173 LOGE("inode not found");
174 return;
175 }
176 inoPtr->ops->ReadDir(req, ino, size, off, fi);
177 }
178
SetXattr(fuse_req_t req,fuse_ino_t ino,const char * name,const char * value,size_t size,int flags)179 void FuseOperations::SetXattr(fuse_req_t req, fuse_ino_t ino, const char *name,
180 const char *value, size_t size, int flags)
181 {
182 if (ino == FUSE_ROOT_ID) {
183 auto opsPtr = make_shared<FileOperationsLocal>();
184 opsPtr->SetXattr(req, ino, name, value, size, flags);
185 return;
186 }
187 auto inoPtr = GetCloudDiskInode(req, ino);
188 if (inoPtr == nullptr) {
189 fuse_reply_err(req, EINVAL);
190 LOGE("inode not found");
191 return;
192 }
193 inoPtr->ops->SetXattr(req, ino, name, value, size, flags);
194 }
195
GetXattr(fuse_req_t req,fuse_ino_t ino,const char * name,size_t size)196 void FuseOperations::GetXattr(fuse_req_t req, fuse_ino_t ino, const char *name,
197 size_t size)
198 {
199 if (ino == FUSE_ROOT_ID) {
200 auto opsPtr = make_shared<FileOperationsLocal>();
201 opsPtr->GetXattr(req, ino, name, size);
202 return;
203 }
204 auto inoPtr = GetCloudDiskInode(req, ino);
205 if (inoPtr == nullptr) {
206 fuse_reply_err(req, EINVAL);
207 LOGE("inode not found");
208 return;
209 }
210 inoPtr->ops->GetXattr(req, ino, name, size);
211 }
212
MkDir(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t mode)213 void FuseOperations::MkDir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode)
214 {
215 if (parent == FUSE_ROOT_ID) {
216 auto opsPtr = make_shared<FileOperationsLocal>();
217 opsPtr->MkDir(req, parent, name, mode);
218 return;
219 }
220 auto inoPtr = GetCloudDiskInode(req, parent);
221 if (inoPtr == nullptr) {
222 fuse_reply_err(req, EINVAL);
223 LOGE("parent inode not found");
224 return;
225 }
226 inoPtr->ops->MkDir(req, parent, name, mode);
227 }
228
RmDir(fuse_req_t req,fuse_ino_t parent,const char * name)229 void FuseOperations::RmDir(fuse_req_t req, fuse_ino_t parent, const char *name)
230 {
231 if (parent == FUSE_ROOT_ID) {
232 auto opsPtr = make_shared<FileOperationsLocal>();
233 opsPtr->RmDir(req, parent, name);
234 return;
235 }
236 auto inoPtr = GetCloudDiskInode(req, parent);
237 if (inoPtr == nullptr) {
238 fuse_reply_err(req, EINVAL);
239 LOGE("parent inode not found");
240 return;
241 }
242 inoPtr->ops->RmDir(req, parent, name);
243 }
244
Unlink(fuse_req_t req,fuse_ino_t parent,const char * name)245 void FuseOperations::Unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
246 {
247 if (parent == FUSE_ROOT_ID) {
248 auto opsPtr = make_shared<FileOperationsLocal>();
249 opsPtr->Unlink(req, parent, name);
250 return;
251 }
252 auto inoPtr = GetCloudDiskInode(req, parent);
253 if (inoPtr == nullptr) {
254 fuse_reply_err(req, EINVAL);
255 LOGE("parent inode not found");
256 return;
257 }
258 inoPtr->ops->Unlink(req, parent, name);
259 }
260
Rename(fuse_req_t req,fuse_ino_t parent,const char * name,fuse_ino_t newParent,const char * newName,unsigned int flags)261 void FuseOperations::Rename(fuse_req_t req, fuse_ino_t parent, const char *name,
262 fuse_ino_t newParent, const char *newName, unsigned int flags)
263 {
264 if (parent == FUSE_ROOT_ID) {
265 auto opsPtr = make_shared<FileOperationsLocal>();
266 opsPtr->Rename(req, parent, name, newParent, newName, flags);
267 return;
268 }
269 auto inoPtr = GetCloudDiskInode(req, parent);
270 if (inoPtr == nullptr) {
271 fuse_reply_err(req, EINVAL);
272 LOGE("parent inode not found");
273 return;
274 }
275 inoPtr->ops->Rename(req, parent, name, newParent, newName, flags);
276 }
277
Read(fuse_req_t req,fuse_ino_t ino,size_t size,off_t offset,struct fuse_file_info * fi)278 void FuseOperations::Read(fuse_req_t req, fuse_ino_t ino, size_t size,
279 off_t offset, struct fuse_file_info *fi)
280 {
281 if (ino == FUSE_ROOT_ID) {
282 auto opsPtr = make_shared<FileOperationsLocal>();
283 opsPtr->Read(req, ino, size, offset, fi);
284 return;
285 }
286 auto inoPtr = GetCloudDiskInode(req, ino);
287 if (inoPtr == nullptr) {
288 fuse_reply_err(req, EINVAL);
289 LOGE("inode not found");
290 return;
291 }
292 inoPtr->ops->Read(req, ino, size, offset, fi);
293 }
294
WriteBuf(fuse_req_t req,fuse_ino_t ino,struct fuse_bufvec * bufv,off_t off,struct fuse_file_info * fi)295 void FuseOperations::WriteBuf(fuse_req_t req, fuse_ino_t ino, struct fuse_bufvec *bufv,
296 off_t off, struct fuse_file_info *fi)
297 {
298 if (ino == FUSE_ROOT_ID) {
299 auto opsPtr = make_shared<FileOperationsLocal>();
300 opsPtr->WriteBuf(req, ino, bufv, off, fi);
301 return;
302 }
303 auto inoPtr = GetCloudDiskInode(req, ino);
304 if (inoPtr == nullptr) {
305 fuse_reply_err(req, EINVAL);
306 LOGE("inode not found");
307 return;
308 }
309 inoPtr->ops->WriteBuf(req, ino, bufv, off, fi);
310 }
311
Release(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)312 void FuseOperations::Release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
313 {
314 if (ino == FUSE_ROOT_ID) {
315 auto opsPtr = make_shared<FileOperationsLocal>();
316 opsPtr->Release(req, ino, fi);
317 return;
318 }
319 auto inoPtr = GetCloudDiskInode(req, ino);
320 if (inoPtr == nullptr) {
321 fuse_reply_err(req, EINVAL);
322 LOGE("inode not found");
323 return;
324 }
325 inoPtr->ops->Release(req, ino, fi);
326 }
SetAttr(fuse_req_t req,fuse_ino_t ino,struct stat * attr,int valid,struct fuse_file_info * fi)327 void FuseOperations::SetAttr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
328 int valid, struct fuse_file_info *fi)
329 {
330 if (ino == FUSE_ROOT_ID) {
331 auto opsPtr = make_shared<FileOperationsLocal>();
332 opsPtr->SetAttr(req, ino, attr, valid, fi);
333 return;
334 }
335 auto inoPtr = GetCloudDiskInode(req, ino);
336 if (inoPtr == nullptr) {
337 fuse_reply_err(req, EINVAL);
338 LOGE("inode not found");
339 return;
340 }
341 inoPtr->ops->SetAttr(req, ino, attr, valid, fi);
342 }
Lseek(fuse_req_t req,fuse_ino_t ino,off_t off,int whence,struct fuse_file_info * fi)343 void FuseOperations::Lseek(fuse_req_t req, fuse_ino_t ino, off_t off, int whence,
344 struct fuse_file_info *fi)
345 {
346 if (ino == FUSE_ROOT_ID) {
347 auto opsPtr = make_shared<FileOperationsLocal>();
348 opsPtr->Lseek(req, ino, off, whence, fi);
349 return;
350 }
351 auto inoPtr = GetCloudDiskInode(req, ino);
352 if (inoPtr == nullptr) {
353 fuse_reply_err(req, EINVAL);
354 LOGE("inode not found");
355 return;
356 }
357 inoPtr->ops->Lseek(req, ino, off, whence, fi);
358 }
359 } // namespace CloudDisk
360 } // namespace FileManagement
361 } // namespace OHOS
362