xref: /freebsd/sys/fs/fuse/fuse_internal.h (revision 560a55d094668823dc146287571c310366cdf737)
151369649SPedro F. Giffuni /*-
251369649SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
351369649SPedro F. Giffuni  *
45fe58019SAttilio Rao  * Copyright (c) 2007-2009 Google Inc. and Amit Singh
55fe58019SAttilio Rao  * All rights reserved.
65fe58019SAttilio Rao  *
75fe58019SAttilio Rao  * Redistribution and use in source and binary forms, with or without
85fe58019SAttilio Rao  * modification, are permitted provided that the following conditions are
95fe58019SAttilio Rao  * met:
105fe58019SAttilio Rao  *
115fe58019SAttilio Rao  * * Redistributions of source code must retain the above copyright
125fe58019SAttilio Rao  *   notice, this list of conditions and the following disclaimer.
135fe58019SAttilio Rao  * * Redistributions in binary form must reproduce the above
145fe58019SAttilio Rao  *   copyright notice, this list of conditions and the following disclaimer
155fe58019SAttilio Rao  *   in the documentation and/or other materials provided with the
165fe58019SAttilio Rao  *   distribution.
175fe58019SAttilio Rao  * * Neither the name of Google Inc. nor the names of its
185fe58019SAttilio Rao  *   contributors may be used to endorse or promote products derived from
195fe58019SAttilio Rao  *   this software without specific prior written permission.
205fe58019SAttilio Rao  *
215fe58019SAttilio Rao  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
225fe58019SAttilio Rao  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
235fe58019SAttilio Rao  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
245fe58019SAttilio Rao  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
255fe58019SAttilio Rao  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
265fe58019SAttilio Rao  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
275fe58019SAttilio Rao  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
285fe58019SAttilio Rao  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
295fe58019SAttilio Rao  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
305fe58019SAttilio Rao  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
315fe58019SAttilio Rao  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
325fe58019SAttilio Rao  *
335fe58019SAttilio Rao  * Copyright (C) 2005 Csaba Henk.
345fe58019SAttilio Rao  * All rights reserved.
355fe58019SAttilio Rao  *
365fe58019SAttilio Rao  * Redistribution and use in source and binary forms, with or without
375fe58019SAttilio Rao  * modification, are permitted provided that the following conditions
385fe58019SAttilio Rao  * are met:
395fe58019SAttilio Rao  * 1. Redistributions of source code must retain the above copyright
405fe58019SAttilio Rao  *    notice, this list of conditions and the following disclaimer.
415fe58019SAttilio Rao  * 2. Redistributions in binary form must reproduce the above copyright
425fe58019SAttilio Rao  *    notice, this list of conditions and the following disclaimer in the
435fe58019SAttilio Rao  *    documentation and/or other materials provided with the distribution.
445fe58019SAttilio Rao  *
455fe58019SAttilio Rao  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
465fe58019SAttilio Rao  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
475fe58019SAttilio Rao  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
485fe58019SAttilio Rao  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
495fe58019SAttilio Rao  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
505fe58019SAttilio Rao  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
515fe58019SAttilio Rao  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
525fe58019SAttilio Rao  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
535fe58019SAttilio Rao  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
545fe58019SAttilio Rao  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
555fe58019SAttilio Rao  * SUCH DAMAGE.
565fe58019SAttilio Rao  *
575fe58019SAttilio Rao  * $FreeBSD$
585fe58019SAttilio Rao  */
595fe58019SAttilio Rao 
605fe58019SAttilio Rao #ifndef _FUSE_INTERNAL_H_
615fe58019SAttilio Rao #define _FUSE_INTERNAL_H_
625fe58019SAttilio Rao 
635fe58019SAttilio Rao #include <sys/types.h>
64*560a55d0SAlan Somers #include <sys/counter.h>
655fe58019SAttilio Rao #include <sys/uio.h>
665fe58019SAttilio Rao #include <sys/stat.h>
675fe58019SAttilio Rao #include <sys/vnode.h>
685fe58019SAttilio Rao 
695fe58019SAttilio Rao #include "fuse_ipc.h"
705fe58019SAttilio Rao #include "fuse_node.h"
715fe58019SAttilio Rao 
72*560a55d0SAlan Somers extern counter_u64_t fuse_lookup_cache_hits;
73*560a55d0SAlan Somers extern counter_u64_t fuse_lookup_cache_misses;
740d2bf489SAlan Somers 
7502295cafSConrad Meyer static inline bool
765fe58019SAttilio Rao vfs_isrdonly(struct mount *mp)
775fe58019SAttilio Rao {
7802295cafSConrad Meyer 	return ((mp->mnt_flag & MNT_RDONLY) != 0);
795fe58019SAttilio Rao }
805fe58019SAttilio Rao 
8102295cafSConrad Meyer static inline struct mount *
825fe58019SAttilio Rao vnode_mount(struct vnode *vp)
835fe58019SAttilio Rao {
845fe58019SAttilio Rao 	return (vp->v_mount);
855fe58019SAttilio Rao }
865fe58019SAttilio Rao 
8702295cafSConrad Meyer static inline enum vtype
885fe58019SAttilio Rao vnode_vtype(struct vnode *vp)
895fe58019SAttilio Rao {
905fe58019SAttilio Rao 	return (vp->v_type);
915fe58019SAttilio Rao }
925fe58019SAttilio Rao 
9302295cafSConrad Meyer static inline bool
945fe58019SAttilio Rao vnode_isvroot(struct vnode *vp)
955fe58019SAttilio Rao {
9602295cafSConrad Meyer 	return ((vp->v_vflag & VV_ROOT) != 0);
975fe58019SAttilio Rao }
985fe58019SAttilio Rao 
9902295cafSConrad Meyer static inline bool
1005fe58019SAttilio Rao vnode_isreg(struct vnode *vp)
1015fe58019SAttilio Rao {
10202295cafSConrad Meyer 	return (vp->v_type == VREG);
1035fe58019SAttilio Rao }
1045fe58019SAttilio Rao 
10502295cafSConrad Meyer static inline bool
1065fe58019SAttilio Rao vnode_isdir(struct vnode *vp)
1075fe58019SAttilio Rao {
10802295cafSConrad Meyer 	return (vp->v_type == VDIR);
1095fe58019SAttilio Rao }
1105fe58019SAttilio Rao 
11102295cafSConrad Meyer static inline bool
1125fe58019SAttilio Rao vnode_islnk(struct vnode *vp)
1135fe58019SAttilio Rao {
11402295cafSConrad Meyer 	return (vp->v_type == VLNK);
1155fe58019SAttilio Rao }
1165fe58019SAttilio Rao 
11702295cafSConrad Meyer static inline ssize_t
1185fe58019SAttilio Rao uio_resid(struct uio *uio)
1195fe58019SAttilio Rao {
1205fe58019SAttilio Rao 	return (uio->uio_resid);
1215fe58019SAttilio Rao }
1225fe58019SAttilio Rao 
12302295cafSConrad Meyer static inline off_t
1245fe58019SAttilio Rao uio_offset(struct uio *uio)
1255fe58019SAttilio Rao {
1265fe58019SAttilio Rao 	return (uio->uio_offset);
1275fe58019SAttilio Rao }
1285fe58019SAttilio Rao 
12902295cafSConrad Meyer static inline void
1305fe58019SAttilio Rao uio_setoffset(struct uio *uio, off_t offset)
1315fe58019SAttilio Rao {
1325fe58019SAttilio Rao 	uio->uio_offset = offset;
1335fe58019SAttilio Rao }
1345fe58019SAttilio Rao 
1355fe58019SAttilio Rao /* miscellaneous */
1365fe58019SAttilio Rao 
13702295cafSConrad Meyer static inline bool
1385fe58019SAttilio Rao fuse_isdeadfs(struct vnode *vp)
1395fe58019SAttilio Rao {
1405fe58019SAttilio Rao 	struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp));
1415fe58019SAttilio Rao 
1425fe58019SAttilio Rao 	return (data->dataflags & FSESS_DEAD);
1435fe58019SAttilio Rao }
1445fe58019SAttilio Rao 
14502295cafSConrad Meyer static inline uint64_t
1465fe58019SAttilio Rao fuse_iosize(struct vnode *vp)
1475fe58019SAttilio Rao {
14802295cafSConrad Meyer 	return (vp->v_mount->mnt_stat.f_iosize);
1495fe58019SAttilio Rao }
1505fe58019SAttilio Rao 
15144f10c6eSAlan Somers /*
15244f10c6eSAlan Somers  * Make a cacheable timeout in bintime format value based on a fuse_attr_out
15344f10c6eSAlan Somers  * response
15444f10c6eSAlan Somers  */
15544f10c6eSAlan Somers static inline void
15644f10c6eSAlan Somers fuse_validity_2_bintime(uint64_t attr_valid, uint32_t attr_valid_nsec,
15744f10c6eSAlan Somers 	struct bintime *timeout)
15844f10c6eSAlan Somers {
15944f10c6eSAlan Somers 	struct timespec now, duration, timeout_ts;
16044f10c6eSAlan Somers 
16144f10c6eSAlan Somers 	getnanouptime(&now);
16244f10c6eSAlan Somers 	/* "+ 2" is the bound of attr_valid_nsec + now.tv_nsec */
16344f10c6eSAlan Somers 	/* Why oh why isn't there a TIME_MAX defined? */
16444f10c6eSAlan Somers 	if (attr_valid >= INT_MAX || attr_valid + now.tv_sec + 2 >= INT_MAX) {
16544f10c6eSAlan Somers 		timeout->sec = INT_MAX;
16644f10c6eSAlan Somers 	} else {
16744f10c6eSAlan Somers 		duration.tv_sec = attr_valid;
16844f10c6eSAlan Somers 		duration.tv_nsec = attr_valid_nsec;
16944f10c6eSAlan Somers 		timespecadd(&duration, &now, &timeout_ts);
17044f10c6eSAlan Somers 		timespec2bintime(&timeout_ts, timeout);
17144f10c6eSAlan Somers 	}
17244f10c6eSAlan Somers }
17344f10c6eSAlan Somers 
17444f10c6eSAlan Somers /*
17544f10c6eSAlan Somers  * Make a cacheable timeout value in timespec format based on the fuse_entry_out
17644f10c6eSAlan Somers  * response
17744f10c6eSAlan Somers  */
17844f10c6eSAlan Somers static inline void
17944f10c6eSAlan Somers fuse_validity_2_timespec(const struct fuse_entry_out *feo,
18044f10c6eSAlan Somers 	struct timespec *timeout)
18144f10c6eSAlan Somers {
18244f10c6eSAlan Somers 	struct timespec duration, now;
18344f10c6eSAlan Somers 
18444f10c6eSAlan Somers 	getnanouptime(&now);
18544f10c6eSAlan Somers 	/* "+ 2" is the bound of entry_valid_nsec + now.tv_nsec */
18644f10c6eSAlan Somers 	if (feo->entry_valid >= INT_MAX ||
18744f10c6eSAlan Somers 	    feo->entry_valid + now.tv_sec + 2 >= INT_MAX) {
18844f10c6eSAlan Somers 		timeout->tv_sec = INT_MAX;
18944f10c6eSAlan Somers 	} else {
19044f10c6eSAlan Somers 		duration.tv_sec = feo->entry_valid;
19144f10c6eSAlan Somers 		duration.tv_nsec = feo->entry_valid_nsec;
19244f10c6eSAlan Somers 		timespecadd(&duration, &now, timeout);
19344f10c6eSAlan Somers 	}
19444f10c6eSAlan Somers }
19544f10c6eSAlan Somers 
19644f10c6eSAlan Somers 
197eae1ae13SAlan Somers /* VFS ops */
198eae1ae13SAlan Somers int
199eae1ae13SAlan Somers fuse_internal_get_cached_vnode(struct mount*, ino_t, int, struct vnode**);
200eae1ae13SAlan Somers 
2015fe58019SAttilio Rao /* access */
20202295cafSConrad Meyer static inline int
2035fe58019SAttilio Rao fuse_match_cred(struct ucred *basecred, struct ucred *usercred)
2045fe58019SAttilio Rao {
2055fe58019SAttilio Rao 	if (basecred->cr_uid == usercred->cr_uid             &&
2065fe58019SAttilio Rao 	    basecred->cr_uid == usercred->cr_ruid            &&
2075fe58019SAttilio Rao 	    basecred->cr_uid == usercred->cr_svuid           &&
2085fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_groups[0] &&
2095fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_rgid      &&
2105fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_svgid)
21102295cafSConrad Meyer 		return (0);
2125fe58019SAttilio Rao 
21302295cafSConrad Meyer 	return (EPERM);
2145fe58019SAttilio Rao }
2155fe58019SAttilio Rao 
216ff4fbdf5SAlan Somers int fuse_internal_access(struct vnode *vp, accmode_t mode,
217666f8543SAlan Somers     struct thread *td, struct ucred *cred);
2185fe58019SAttilio Rao 
2195fe58019SAttilio Rao /* attributes */
2207e4844f7SAlan Somers void fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr,
2217e4844f7SAlan Somers 	uint64_t attr_valid, uint32_t attr_valid_nsec, struct vattr *vap);
2225fe58019SAttilio Rao 
2235fe58019SAttilio Rao /* fsync */
2245fe58019SAttilio Rao 
225915012e0SAlan Somers int fuse_internal_fsync(struct vnode *vp, struct thread *td, int waitfor,
226915012e0SAlan Somers 	bool datasync);
22702295cafSConrad Meyer int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
2285fe58019SAttilio Rao 
229cad67791SAlan Somers /* getattr */
2303d15b234SAlan Somers int fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap,
2313d15b234SAlan Somers 	struct ucred *cred, struct thread *td);
232cad67791SAlan Somers int fuse_internal_getattr(struct vnode *vp, struct vattr *vap,
233cad67791SAlan Somers 	struct ucred *cred, struct thread *td);
234cad67791SAlan Somers 
235c2d70d6eSAlan Somers /* asynchronous invalidation */
236c2d70d6eSAlan Somers int fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio);
237eae1ae13SAlan Somers int fuse_internal_invalidate_inode(struct mount *mp, struct uio *uio);
2385fe58019SAttilio Rao 
239d5ff2688SAlan Somers /* mknod */
240d5ff2688SAlan Somers int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp,
241d5ff2688SAlan Somers 	struct componentname *cnp, struct vattr *vap);
242d5ff2688SAlan Somers 
243d5ff2688SAlan Somers /* readdir */
244c2d70d6eSAlan Somers struct pseudo_dirent {
245c2d70d6eSAlan Somers 	uint32_t d_namlen;
246c2d70d6eSAlan Somers };
247e76986fdSAlan Somers int fuse_internal_readdir(struct vnode *vp, struct uio *uio, off_t startoff,
248e76986fdSAlan Somers     struct fuse_filehandle *fufh, struct fuse_iov *cookediov, int *ncookies,
249e76986fdSAlan Somers     u_long *cookies);
250e76986fdSAlan Somers int fuse_internal_readdir_processdata(struct uio *uio, off_t startoff,
251e76986fdSAlan Somers     int *fnd_start, size_t reqsize, void *buf, size_t bufsize,
252e76986fdSAlan Somers     struct fuse_iov *cookediov, int *ncookies, u_long **cookiesp);
2535fe58019SAttilio Rao 
2545fe58019SAttilio Rao /* remove */
2555fe58019SAttilio Rao 
25602295cafSConrad Meyer int fuse_internal_remove(struct vnode *dvp, struct vnode *vp,
25702295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op);
2585fe58019SAttilio Rao 
2595fe58019SAttilio Rao /* rename */
2605fe58019SAttilio Rao 
26102295cafSConrad Meyer int fuse_internal_rename(struct vnode *fdvp, struct componentname *fcnp,
26202295cafSConrad Meyer     struct vnode *tdvp, struct componentname *tcnp);
26302295cafSConrad Meyer 
2645fe58019SAttilio Rao /* revoke */
2655fe58019SAttilio Rao 
26602295cafSConrad Meyer void fuse_internal_vnode_disappear(struct vnode *vp);
2675fe58019SAttilio Rao 
268a90e32deSAlan Somers /* setattr */
269a90e32deSAlan Somers int fuse_internal_setattr(struct vnode *vp, struct vattr *va,
270a90e32deSAlan Somers 	struct thread *td, struct ucred *cred);
271a90e32deSAlan Somers 
2725fe58019SAttilio Rao /* strategy */
2735fe58019SAttilio Rao 
2745fe58019SAttilio Rao /* entity creation */
2755fe58019SAttilio Rao 
27602295cafSConrad Meyer static inline int
2775fe58019SAttilio Rao fuse_internal_checkentry(struct fuse_entry_out *feo, enum vtype vtyp)
2785fe58019SAttilio Rao {
2795fe58019SAttilio Rao 	if (vtyp != IFTOVT(feo->attr.mode)) {
28002295cafSConrad Meyer 		return (EINVAL);
2815fe58019SAttilio Rao 	}
2825fe58019SAttilio Rao 
2835fe58019SAttilio Rao 	if (feo->nodeid == FUSE_NULL_ID) {
28402295cafSConrad Meyer 		return (EINVAL);
2855fe58019SAttilio Rao 	}
2865fe58019SAttilio Rao 
2875fe58019SAttilio Rao 	if (feo->nodeid == FUSE_ROOT_ID) {
28802295cafSConrad Meyer 		return (EINVAL);
2895fe58019SAttilio Rao 	}
2905fe58019SAttilio Rao 
29102295cafSConrad Meyer 	return (0);
2925fe58019SAttilio Rao }
2935fe58019SAttilio Rao 
29402295cafSConrad Meyer int fuse_internal_newentry(struct vnode *dvp, struct vnode **vpp,
29502295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
2965fe58019SAttilio Rao     enum vtype vtyp);
2975fe58019SAttilio Rao 
29802295cafSConrad Meyer void fuse_internal_newentry_makerequest(struct mount *mp, uint64_t dnid,
29902295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
3005fe58019SAttilio Rao     struct fuse_dispatcher *fdip);
3015fe58019SAttilio Rao 
30202295cafSConrad Meyer int fuse_internal_newentry_core(struct vnode *dvp, struct vnode **vpp,
30302295cafSConrad Meyer     struct componentname *cnp, enum vtype vtyp, struct fuse_dispatcher *fdip);
3045fe58019SAttilio Rao 
3055fe58019SAttilio Rao /* entity destruction */
3065fe58019SAttilio Rao 
30702295cafSConrad Meyer int fuse_internal_forget_callback(struct fuse_ticket *tick, struct uio *uio);
30802295cafSConrad Meyer void fuse_internal_forget_send(struct mount *mp, struct thread *td,
30902295cafSConrad Meyer     struct ucred *cred, uint64_t nodeid, uint64_t nlookup);
3105fe58019SAttilio Rao 
3115fe58019SAttilio Rao /* fuse start/stop */
3125fe58019SAttilio Rao 
3135fe58019SAttilio Rao int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio);
3145fe58019SAttilio Rao void fuse_internal_send_init(struct fuse_data *data, struct thread *td);
3155fe58019SAttilio Rao 
316*560a55d0SAlan Somers /* module load/unload */
317*560a55d0SAlan Somers void fuse_internal_init(void);
318*560a55d0SAlan Somers void fuse_internal_destroy(void);
319*560a55d0SAlan Somers 
3205fe58019SAttilio Rao #endif /* _FUSE_INTERNAL_H_ */
321