Home | History | Annotate | Download | only in libappfuse
      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 = 128 * 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