• 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 "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