1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specic language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_LIBAPPFUSE_FUSEBUFFER_H_
18 #define ANDROID_LIBAPPFUSE_FUSEBUFFER_H_
19 
20 #include <android-base/unique_fd.h>
21 #include <linux/fuse.h>
22 
23 namespace android {
24 namespace fuse {
25 
26 // The numbers came from sdcard.c.
27 // Maximum number of bytes to write/read in one request/one reply.
28 constexpr size_t kFuseMaxWrite = 256 * 1024;
29 constexpr size_t kFuseMaxRead = 128 * 1024;
30 constexpr int32_t kFuseSuccess = 0;
31 
32 // Setup sockets to transfer FuseMessage.
33 bool SetupMessageSockets(base::unique_fd (*sockets)[2]);
34 
35 enum class ResultOrAgain {
36     kSuccess,
37     kFailure,
38     kAgain,
39 };
40 
41 template<typename T>
42 class FuseMessage {
43  public:
44   bool Read(int fd);
45   bool Write(int fd) const;
46   bool WriteWithBody(int fd, size_t max_size, const void* data) const;
47   ResultOrAgain ReadOrAgain(int fd);
48   ResultOrAgain WriteOrAgain(int fd) const;
49 };
50 
51 // FuseRequest represents file operation requests from /dev/fuse. It starts
52 // from fuse_in_header. The body layout depends on the operation code.
53 struct FuseRequest : public FuseMessage<FuseRequest> {
54   fuse_in_header header;
55   union {
56     // for FUSE_WRITE
57     struct {
58       fuse_write_in write_in;
59       char write_data[kFuseMaxWrite];
60     };
61     // for FUSE_OPEN
62     fuse_open_in open_in;
63     // for FUSE_INIT
64     fuse_init_in init_in;
65     // for FUSE_READ
66     fuse_read_in read_in;
67     // for FUSE_LOOKUP
68     char lookup_name[kFuseMaxWrite];
69   };
70   void Reset(uint32_t data_length, uint32_t opcode, uint64_t unique);
71 };
72 
73 // FuseResponse represents file operation responses to /dev/fuse. It starts
74 // from fuse_out_header. The body layout depends on the operation code.
75 template <size_t N>
76 struct FuseResponseBase : public FuseMessage<FuseResponseBase<N>> {
77     fuse_out_header header;
78     union {
79         // for FUSE_INIT
80         fuse_init_out init_out;
81         // for FUSE_LOOKUP
82         fuse_entry_out entry_out;
83         // for FUSE_GETATTR
84         fuse_attr_out attr_out;
85         // for FUSE_OPEN
86         fuse_open_out open_out;
87         // for FUSE_READ
88         char read_data[N];
89         // for FUSE_WRITE
90         fuse_write_out write_out;
91     };
92     void Reset(uint32_t data_length, int32_t error, uint64_t unique);
93     void ResetHeader(uint32_t data_length, int32_t error, uint64_t unique);
94 };
95 
96 using FuseResponse = FuseResponseBase<kFuseMaxRead>;
97 using FuseSimpleResponse = FuseResponseBase<0u>;
98 
99 // To reduce memory usage, FuseBuffer shares the memory region for request and
100 // response.
101 union FuseBuffer final {
102   FuseRequest request;
103   FuseResponse response;
104 
105   void HandleInit();
106   void HandleNotImpl();
107 };
108 
109 }  // namespace fuse
110 }  // namespace android
111 
112 #endif  // ANDROID_LIBAPPFUSE_FUSEBUFFER_H_
113