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