fuse.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef LIBRARIES_NACL_IO_FUSE_H_
6#define LIBRARIES_NACL_IO_FUSE_H_
7
8#include "osinttypes.h"
9#include "ostypes.h"
10
11// These interfaces are copied from the FUSE library.
12//
13// FUSE has two interfaces that can be implemented: low-level and high-level.
14// In nacl_io, we only support the high-level interface.
15//
16// See http://fuse.sourceforge.net/ for more information.
17
18// This struct is typically passed to functions that would normally use return
19// or receive an fd; that is, operations to open/create a node, or operations
20// that act on an already opened node.
21struct fuse_file_info {
22  // This is filled with the flags passed to open()
23  int flags;
24  // Deprecated in FUSE. Use fh instead.
25  unsigned long fh_old;
26  int writepage;
27  // Currently unsupported
28  unsigned int direct_io : 1;
29  // Currently unsupported
30  unsigned int keep_cache : 1;
31  // Currently unsupported
32  unsigned int flush : 1;
33  // Currently unsupported
34  unsigned int nonseekable : 1;
35  // Currently unsupported
36  unsigned int padding : 27;
37  // This value is not used by nacl_io. It can be filled by the developer when
38  // open() is called, and reused for subsequent calls on the same node.
39  uint64_t fh;
40  // Currently unsupported
41  uint64_t lock_owner;
42  // Currently unsupported
43  uint32_t poll_events;
44};
45
46// A dummy structure that currently exists only to match the FUSE interface.
47struct fuse_conn_info {};
48
49// A function of this type will be passed to readdir (see below). The developer
50// should call this function once for each directory entry.
51//
52// See the documentation for readdir() below for more information on how to use
53// this function.
54typedef int (*fuse_fill_dir_t)(void* buf,
55                               const char* name,
56                               const struct stat* stbuf,
57                               off_t off);
58
59// This structure defines the interface to create a user filesystem. Pass this
60// to
61// nacl_io_register_fs_type(). (see nacl_io.h)
62//
63// Example:
64//
65//     struct fuse_operations g_my_fuse_operations = { ... };
66//     ...
67//     nacl_io_register_fs_type("myfusefs", &g_my_fuse_operations);
68//     ...
69//     mount("", "/fs/fuse", "myfusefs", 0, NULL);
70//
71// It is not necessary to implement every function -- nacl_io will first check
72// if the function pointer is NULL before calling it. If it is NULL and
73// required by the current operation, the call will fail and return ENOSYS in
74// errno.
75//
76// Except where specified below, each function should return one of the
77// following values:
78// == 0: operation completed successfully.
79// <  0: operation failed. The error is a negative errno. e.g. -EACCES, -EPERM,
80//       etc. The sign will be flipped when the error is actually set.
81//
82// Some functions (e.g. read, write) also return a positive count, which is the
83// number of bytes read/written.
84//
85struct fuse_operations {
86  // Currently unsupported
87  unsigned int flag_nopath : 1;
88  unsigned int flag_reserved : 31;
89
90  // Called when a filesystem of this type is initialized.
91  void* (*init)(struct fuse_conn_info* conn);
92  // Called when a filesystem of this type is unmounted.
93  void (*destroy)(void*);
94  // Called by access()
95  int (*access)(const char* path, int mode);
96  // Called when O_CREAT is passed to open()
97  int (*create)(const char* path, mode_t mode, struct fuse_file_info*);
98  // Called by stat()/fstat(). If this function pointer is non-NULL, it is
99  // called, otherwise fuse_operations.getattr will be called.
100  int (*fgetattr)(const char* path, struct stat*, struct fuse_file_info*);
101  // Called by fsync(). The datasync paramater is not currently supported.
102  int (*fsync)(const char* path, int datasync, struct fuse_file_info*);
103  // Called by ftruncate()
104  int (*ftruncate)(const char* path, off_t, struct fuse_file_info*);
105  // Called by stat()/fstat(), but only when fuse_operations.fgetattr is NULL.
106  // Also called by open() to determine if the path is a directory or a regular
107  // file.
108  int (*getattr)(const char* path, struct stat*);
109  // Called by mkdir()
110  int (*mkdir)(const char* path, mode_t);
111  // Called when O_CREAT is passed to open(), but only if fuse_operations.create
112  // is non-NULL.
113  int (*mknod)(const char* path, mode_t, dev_t);
114  // Called by open()
115  int (*open)(const char* path, struct fuse_file_info*);
116  // Called by getdents(), which is called by the more standard functions
117  // opendir()/readdir().
118  int (*opendir)(const char* path, struct fuse_file_info*);
119  // Called by read(). Note that FUSE specifies that all reads will fill the
120  // entire requested buffer. If this function returns less than that, the
121  // remainder of the buffer is zeroed.
122  int (*read)(const char* path, char* buf, size_t count, off_t,
123              struct fuse_file_info*);
124  // Called by getdents(), which is called by the more standard function
125  // readdir().
126  //
127  // NOTE: it is the responsibility of this function to add the "." and ".."
128  // entries.
129  //
130  // This function can be implemented one of two ways:
131  // 1) Ignore the offset, and always write every entry in a given directory.
132  //    In this case, you should always call filler() with an offset of 0. You
133  //    can ignore the return value of the filler.
134  //
135  //   int my_readdir(const char* path, void* buf, fuse_fill_dir_t filler,
136  //                  off_t offset, struct fuse_file_info*) {
137  //     ...
138  //     filler(buf, ".", NULL, 0);
139  //     filler(buf, "..", NULL, 0);
140  //     filler(buf, "file1", &file1stat, 0);
141  //     filler(buf, "file2", &file2stat, 0);
142  //     return 0;
143  //   }
144  //
145  // 2) Only write entries starting from offset. Always pass the correct offset
146  //    to the filler function. When the filler function returns 1, the buffer
147  //    is full so you can exit readdir.
148  //
149  //   int my_readdir(const char* path, void* buf, fuse_fill_dir_t filler,
150  //                  off_t offset, struct fuse_file_info*) {
151  //     ...
152  //     size_t kNumEntries = 4;
153  //     const char* my_entries[] = { ".", "..", "file1", "file2" };
154  //     int entry_index = offset / sizeof(dirent);
155  //     offset = entry_index * sizeof(dirent);
156  //     while (entry_index < kNumEntries) {
157  //       int result = filler(buf, my_entries[entry_index], NULL, offset);
158  //       if (filler == 1) {
159  //         // buffer filled, we're done.
160  //         return 0;
161  //       }
162  //       offset += sizeof(dirent);
163  //       entry_index++;
164  //     }
165  //
166  //     // No more entries, we're done.
167  //     return 0;
168  //   }
169  //
170  int (*readdir)(const char* path, void* buf, fuse_fill_dir_t filldir, off_t,
171                 struct fuse_file_info*);
172  // Called when the last reference to this node is released. This is only
173  // called for regular files. For directories, fuse_operations.releasedir is
174  // called instead.
175  int (*release)(const char* path, struct fuse_file_info*);
176  // Called when the last reference to this node is released. This is only
177  // called for directories. For regular files, fuse_operations.release is
178  // called instead.
179  int (*releasedir)(const char* path, struct fuse_file_info*);
180  // Called by rename()
181  int (*rename)(const char* path, const char* new_path);
182  // Called by rmdir()
183  int (*rmdir)(const char* path);
184  // Called by truncate(), as well as open() when O_TRUNC is passed.
185  int (*truncate)(const char* path, off_t);
186  // Called by unlink()
187  int (*unlink)(const char* path);
188  // Called by write(). Note that FUSE specifies that a write should always
189  // return the full count, unless an error occurs.
190  int (*write)(const char* path, const char* buf, size_t count, off_t,
191               struct fuse_file_info*);
192
193  // The following functions are not currently called by the nacl_io
194  // implementation of FUSE.
195  int (*bmap)(const char*, size_t blocksize, uint64_t* idx);
196  int (*chmod)(const char*, mode_t);
197  int (*chown)(const char*, uid_t, gid_t);
198  int (*fallocate)(const char*, int, off_t, off_t, struct fuse_file_info*);
199  int (*flock)(const char*, struct fuse_file_info*, int op);
200  int (*flush)(const char*, struct fuse_file_info*);
201  int (*fsyncdir)(const char*, int, struct fuse_file_info*);
202  int (*getxattr)(const char*, const char*, char*, size_t);
203  int (*ioctl)(const char*, int cmd, void* arg, struct fuse_file_info*,
204               unsigned int flags, void* data);
205  int (*link)(const char*, const char*);
206  int (*listxattr)(const char*, char*, size_t);
207  int (*lock)(const char*, struct fuse_file_info*, int cmd, struct flock*);
208  int (*poll)(const char*, struct fuse_file_info*, struct fuse_pollhandle* ph,
209              unsigned* reventsp);
210  int (*read_buf)(const char*, struct fuse_bufvec** bufp, size_t size,
211                  off_t off, struct fuse_file_info*);
212  int (*readlink)(const char*, char*, size_t);
213  int (*removexattr)(const char*, const char*);
214  int (*setxattr)(const char*, const char*, const char*, size_t, int);
215  int (*statfs)(const char*, struct statvfs*);
216  int (*symlink)(const char*, const char*);
217  int (*utimens)(const char*, const struct timespec tv[2]);
218  int (*write_buf)(const char*, struct fuse_bufvec* buf, off_t off,
219                   struct fuse_file_info*);
220};
221
222#endif  // LIBRARIES_NACL_IO_FUSE_H_
223