Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/fs/fuse/fuse_internal.h
39586 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 2007-2009 Google Inc. and Amit Singh
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are
9
* met:
10
*
11
* * Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* * Redistributions in binary form must reproduce the above
14
* copyright notice, this list of conditions and the following disclaimer
15
* in the documentation and/or other materials provided with the
16
* distribution.
17
* * Neither the name of Google Inc. nor the names of its
18
* contributors may be used to endorse or promote products derived from
19
* this software without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*
33
* Copyright (C) 2005 Csaba Henk.
34
* All rights reserved.
35
*
36
* Copyright (c) 2019 The FreeBSD Foundation
37
*
38
* Portions of this software were developed by BFF Storage Systems, LLC under
39
* sponsorship from the FreeBSD Foundation.
40
*
41
* Redistribution and use in source and binary forms, with or without
42
* modification, are permitted provided that the following conditions
43
* are met:
44
* 1. Redistributions of source code must retain the above copyright
45
* notice, this list of conditions and the following disclaimer.
46
* 2. Redistributions in binary form must reproduce the above copyright
47
* notice, this list of conditions and the following disclaimer in the
48
* documentation and/or other materials provided with the distribution.
49
*
50
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
51
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
54
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60
* SUCH DAMAGE.
61
*/
62
63
#ifndef _FUSE_INTERNAL_H_
64
#define _FUSE_INTERNAL_H_
65
66
#include <sys/types.h>
67
#include <sys/counter.h>
68
#include <sys/limits.h>
69
#include <sys/uio.h>
70
#include <sys/stat.h>
71
#include <sys/vnode.h>
72
73
#include "fuse_ipc.h"
74
#include "fuse_node.h"
75
76
extern counter_u64_t fuse_lookup_cache_hits;
77
extern counter_u64_t fuse_lookup_cache_misses;
78
79
static inline bool
80
vfs_isrdonly(struct mount *mp)
81
{
82
return ((mp->mnt_flag & MNT_RDONLY) != 0);
83
}
84
85
static inline struct mount *
86
vnode_mount(struct vnode *vp)
87
{
88
return (vp->v_mount);
89
}
90
91
static inline __enum_uint8(vtype)
92
vnode_vtype(struct vnode *vp)
93
{
94
return (vp->v_type);
95
}
96
97
static inline bool
98
vnode_isvroot(struct vnode *vp)
99
{
100
return ((vp->v_vflag & VV_ROOT) != 0);
101
}
102
103
static inline bool
104
vnode_isreg(struct vnode *vp)
105
{
106
return (vp->v_type == VREG);
107
}
108
109
static inline bool
110
vnode_isdir(struct vnode *vp)
111
{
112
return (vp->v_type == VDIR);
113
}
114
115
static inline bool
116
vnode_islnk(struct vnode *vp)
117
{
118
return (vp->v_type == VLNK);
119
}
120
121
static inline ssize_t
122
uio_resid(struct uio *uio)
123
{
124
return (uio->uio_resid);
125
}
126
127
static inline off_t
128
uio_offset(struct uio *uio)
129
{
130
return (uio->uio_offset);
131
}
132
133
static inline void
134
uio_setoffset(struct uio *uio, off_t offset)
135
{
136
uio->uio_offset = offset;
137
}
138
139
/* miscellaneous */
140
141
static inline bool
142
fuse_isdeadfs(struct vnode *vp)
143
{
144
struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp));
145
146
return (data->dataflags & FSESS_DEAD);
147
}
148
149
static inline uint64_t
150
fuse_iosize(struct vnode *vp)
151
{
152
return (vp->v_mount->mnt_stat.f_iosize);
153
}
154
155
/*
156
* Make a cacheable timeout in bintime format value based on a fuse_attr_out
157
* response
158
*/
159
static inline void
160
fuse_validity_2_bintime(uint64_t attr_valid, uint32_t attr_valid_nsec,
161
struct bintime *timeout)
162
{
163
struct timespec now, duration, timeout_ts;
164
165
getnanouptime(&now);
166
/* "+ 2" is the bound of attr_valid_nsec + now.tv_nsec */
167
/* Why oh why isn't there a TIME_MAX defined? */
168
if (attr_valid >= INT_MAX || attr_valid + now.tv_sec + 2 >= INT_MAX) {
169
timeout->sec = INT_MAX;
170
} else {
171
duration.tv_sec = attr_valid;
172
duration.tv_nsec = attr_valid_nsec;
173
timespecadd(&duration, &now, &timeout_ts);
174
timespec2bintime(&timeout_ts, timeout);
175
}
176
}
177
178
/*
179
* Make a cacheable timeout value in timespec format based on the fuse_entry_out
180
* response
181
*/
182
static inline void
183
fuse_validity_2_timespec(const struct fuse_entry_out *feo,
184
struct timespec *timeout)
185
{
186
struct timespec duration, now;
187
188
getnanouptime(&now);
189
/* "+ 2" is the bound of entry_valid_nsec + now.tv_nsec */
190
if (feo->entry_valid >= INT_MAX ||
191
feo->entry_valid + now.tv_sec + 2 >= INT_MAX) {
192
timeout->tv_sec = INT_MAX;
193
} else {
194
duration.tv_sec = feo->entry_valid;
195
duration.tv_nsec = feo->entry_valid_nsec;
196
timespecadd(&duration, &now, timeout);
197
}
198
}
199
200
/* VFS ops */
201
int
202
fuse_internal_get_cached_vnode(struct mount*, ino_t, int, struct vnode**);
203
204
/* access */
205
static inline int
206
fuse_match_cred(struct ucred *basecred, struct ucred *usercred)
207
{
208
if (basecred->cr_uid == usercred->cr_uid &&
209
basecred->cr_uid == usercred->cr_ruid &&
210
basecred->cr_uid == usercred->cr_svuid &&
211
basecred->cr_gid == usercred->cr_gid &&
212
basecred->cr_gid == usercred->cr_rgid &&
213
basecred->cr_gid == usercred->cr_svgid)
214
return (0);
215
216
return (EPERM);
217
}
218
219
int fuse_internal_access(struct vnode *vp, accmode_t mode,
220
struct thread *td, struct ucred *cred);
221
222
/* attributes */
223
void fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr,
224
uint64_t attr_valid, uint32_t attr_valid_nsec, struct vattr *vap,
225
bool from_server);
226
227
/* fsync */
228
229
int fuse_internal_fsync(struct vnode *vp, struct thread *td, int waitfor,
230
bool datasync);
231
int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
232
233
/* getattr */
234
int fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap,
235
struct ucred *cred, struct thread *td);
236
int fuse_internal_getattr(struct vnode *vp, struct vattr *vap,
237
struct ucred *cred, struct thread *td);
238
239
/* asynchronous invalidation */
240
int fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio);
241
int fuse_internal_invalidate_inode(struct mount *mp, struct uio *uio);
242
243
/* mknod */
244
int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp,
245
struct componentname *cnp, struct vattr *vap);
246
247
/* readdir */
248
struct pseudo_dirent {
249
uint32_t d_namlen;
250
};
251
int fuse_internal_readdir(struct vnode *vp, struct uio *uio,
252
struct fuse_filehandle *fufh, struct fuse_iov *cookediov, int *ncookies,
253
uint64_t *cookies);
254
int fuse_internal_readdir_processdata(struct uio *uio, size_t reqsize,
255
void *buf, size_t bufsize, struct fuse_iov *cookediov, int *ncookies,
256
uint64_t **cookiesp);
257
258
/* remove */
259
260
int fuse_internal_remove(struct vnode *dvp, struct vnode *vp,
261
struct componentname *cnp, enum fuse_opcode op);
262
263
/* rename */
264
265
int fuse_internal_rename(struct vnode *fdvp, struct componentname *fcnp,
266
struct vnode *tdvp, struct componentname *tcnp);
267
268
/* revoke */
269
270
void fuse_internal_vnode_disappear(struct vnode *vp);
271
272
/* setattr */
273
int fuse_internal_setattr(struct vnode *vp, struct vattr *va,
274
struct thread *td, struct ucred *cred);
275
276
/* write */
277
void fuse_internal_clear_suid_on_write(struct vnode *vp, struct ucred *cred,
278
struct thread *td);
279
280
/* strategy */
281
282
/* entity creation */
283
284
static inline int
285
fuse_internal_checkentry(struct fuse_entry_out *feo, __enum_uint8(vtype) vtyp)
286
{
287
if (vtyp != IFTOVT(feo->attr.mode)) {
288
return (EINVAL);
289
}
290
291
if (feo->nodeid == FUSE_NULL_ID) {
292
return (EINVAL);
293
}
294
295
if (feo->nodeid == FUSE_ROOT_ID) {
296
return (EINVAL);
297
}
298
299
return (0);
300
}
301
302
int fuse_internal_newentry(struct vnode *dvp, struct vnode **vpp,
303
struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
304
__enum_uint8(vtype) vtyp);
305
306
void fuse_internal_newentry_makerequest(struct mount *mp, uint64_t dnid,
307
struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
308
struct fuse_dispatcher *fdip);
309
310
int fuse_internal_newentry_core(struct vnode *dvp, struct vnode **vpp,
311
struct componentname *cnp, __enum_uint8(vtype) vtyp, struct fuse_dispatcher *fdip);
312
313
/* entity destruction */
314
315
int fuse_internal_forget_callback(struct fuse_ticket *tick, struct uio *uio);
316
void fuse_internal_forget_send(struct mount *mp, struct thread *td,
317
struct ucred *cred, uint64_t nodeid, uint64_t nlookup);
318
319
/* fuse start/stop */
320
321
int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio);
322
void fuse_internal_send_init(struct fuse_data *data, struct thread *td);
323
324
/* module load/unload */
325
void fuse_internal_init(void);
326
void fuse_internal_destroy(void);
327
328
#endif /* _FUSE_INTERNAL_H_ */
329
330