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