aboutsummaryrefslogtreecommitdiff
path: root/include/fuse_lowlevel.h
blob: 8b189592d82d842fffe7dc0578ff50e64d58e677 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
    FUSE: Filesystem in Userspace
    Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>

    This program can be distributed under the terms of the GNU LGPL.
    See the file COPYING.LIB.
*/

#ifndef _FUSE_LOWLEVEL_H_
#define _FUSE_LOWLEVEL_H_

/* ----------------------------------------------------------- *
 * Low level API                                               *
 * ----------------------------------------------------------- */

#include "fuse_common.h"

#include <utime.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statfs.h>

#ifdef __cplusplus
extern "C" {
#endif

/** The node ID of the root inode */
#define FUSE_ROOT_ID 1

typedef unsigned long fuse_ino_t;
typedef struct fuse_req *fuse_req_t;
struct fuse_ll;

struct fuse_entry_param {
    fuse_ino_t ino;
    unsigned long generation;
    struct stat attr;
    double attr_timeout;
    double entry_timeout;
};

struct fuse_lock_param {
    int type;
    off_t start;
    off_t end;
    unsigned long long owner;
    pid_t pid;
};

struct fuse_ctx {
    /** User ID of the calling process */
    uid_t uid;

    /** Group ID of the calling process */
    gid_t gid;

    /** Thread ID of the calling process */
    pid_t pid;
};

/* 'to_set' flags in setattr */
#define FUSE_SET_ATTR_MODE	(1 << 0)
#define FUSE_SET_ATTR_UID	(1 << 1)
#define FUSE_SET_ATTR_GID	(1 << 2)
#define FUSE_SET_ATTR_SIZE	(1 << 3)
#define FUSE_SET_ATTR_ATIME	(1 << 4)
#define FUSE_SET_ATTR_MTIME	(1 << 5)
#define FUSE_SET_ATTR_CTIME	(1 << 6)

/* ------------------------------------------ */

struct fuse_ll_operations {
    void* (*init)  (void *);
    void (*destroy)(void *);

    void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
    void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup);
    void (*getattr)(fuse_req_t req, fuse_ino_t ino);
    void (*setattr)(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
                     int to_set);
    void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
    void (*readlink)(fuse_req_t req, fuse_ino_t ino);
    void (*mknod)  (fuse_req_t req, fuse_ino_t parent, const char *name,
                    mode_t mode, dev_t rdev);
    void (*mkdir)  (fuse_req_t req, fuse_ino_t parent, const char *name,
                    mode_t mode);
    void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
    void (*rmdir)  (fuse_req_t req, fuse_ino_t parent, const char *name);
    void (*symlink)(fuse_req_t req, const char *link, fuse_ino_t parent,
                    const char *name);
    void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
                    fuse_ino_t newparent, const char *newname);
    void (*link)   (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
                    const char *newname);
    void (*open)   (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
    void (*read)   (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
                    struct fuse_file_info *fi);
    void (*write)  (fuse_req_t req, fuse_ino_t ino, const char *buf,
                    size_t size, off_t off, struct fuse_file_info *fi);
    void (*flush)  (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
    void (*release)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
    void (*fsync)  (fuse_req_t req, fuse_ino_t ino, int datasync,
                    struct fuse_file_info *fi);
    void (*opendir)(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
    void (*readdir)(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
                    struct fuse_file_info *fi);
    void (*releasedir)(fuse_req_t req, fuse_ino_t ino,
                       struct fuse_file_info *fi);
    void (*fsyncdir)(fuse_req_t req, fuse_ino_t ino, int datasync,
                     struct fuse_file_info *fi);
    void (*statfs) (fuse_req_t req);
    void (*setxattr)(fuse_req_t req, fuse_ino_t ino, const char *name,
                     const char *value, size_t size, int flags);
    void (*getxattr)(fuse_req_t req, fuse_ino_t ino, const char *name,
                     size_t size);
    void (*listxattr)(fuse_req_t req, fuse_ino_t ino, size_t size);
    void (*removexattr)(fuse_req_t req, fuse_ino_t ino, const char *name);
    void (*getlk)  (fuse_req_t req, fuse_ino_t ino,
                    const struct fuse_lock_param *lk);
    void (*setlk)  (fuse_req_t req, fuse_ino_t ino, int sleep,
                    const struct fuse_lock_param *lk);
};

/* ------------------------------------------ */

/* all except forget */
int fuse_reply_err(fuse_req_t req, int err);

/* forget */
int fuse_reply_none(fuse_req_t req);

/* lookup, mknod, mkdir, symlink, link */
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);

/* getattr, setattr */
int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
                    double attr_timeout);

/* readlink */
int fuse_reply_readlink(fuse_req_t req, const char *link);

/* open, opendir */
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi);

/* write */
int fuse_reply_write(fuse_req_t req, size_t count);

/* read, readdir, getxattr, listxattr */
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);

/* statfs */
int fuse_reply_statfs(fuse_req_t req, const struct statfs *stbuf);

/* getxattr, listxattr */
int fuse_reply_xattr(fuse_req_t req, size_t count);

/* getlk */
int fuse_reply_getlk(fuse_req_t req, const struct fuse_lock_param *lk);

/* ------------------------------------------ */

/* return the size of a directory entry */
size_t fuse_dirent_size(size_t namelen);

/* add a directory entry to the buffer */
char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf,
                      off_t off);

/* ------------------------------------------ */

void *fuse_req_userdata(fuse_req_t req);

const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);

/* ------------------------------------------ */

typedef void (*fuse_ll_processor_t)(struct fuse_ll *, struct fuse_cmd *, void *);

struct fuse_ll *fuse_ll_new(int fd, const char *opts,
                            const struct fuse_ll_operations *op,
                            size_t op_size, void *userdata);

void fuse_ll_destroy(struct fuse_ll *f);

int fuse_ll_is_lib_option(const char *opt);

int fuse_ll_loop(struct fuse_ll *f);

void fuse_ll_exit(struct fuse_ll *f);

int fuse_ll_exited(struct fuse_ll* f);

struct fuse_cmd *fuse_ll_read_cmd(struct fuse_ll *f);

void fuse_ll_process_cmd(struct fuse_ll *f, struct fuse_cmd *cmd);

int fuse_ll_loop_mt(struct fuse_ll *f);

int fuse_ll_loop_mt_proc(struct fuse_ll *f, fuse_ll_processor_t proc, void *data);

/* ------------------------------------------ */

#ifdef __cplusplus
}
#endif

#endif /* _FUSE_LOWLEVEL_H_ */