xref: /freebsd/sys/fs/fuse/fuse_internal.h (revision 5d94aaacb5180798b2f698e33937f068386004eb)
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  *
368aafc8c3SAlan Somers  * Copyright (c) 2019 The FreeBSD Foundation
378aafc8c3SAlan Somers  *
388aafc8c3SAlan Somers  * Portions of this software were developed by BFF Storage Systems, LLC under
398aafc8c3SAlan Somers  * sponsorship from the FreeBSD Foundation.
408aafc8c3SAlan Somers  *
415fe58019SAttilio Rao  * Redistribution and use in source and binary forms, with or without
425fe58019SAttilio Rao  * modification, are permitted provided that the following conditions
435fe58019SAttilio Rao  * are met:
445fe58019SAttilio Rao  * 1. Redistributions of source code must retain the above copyright
455fe58019SAttilio Rao  *    notice, this list of conditions and the following disclaimer.
465fe58019SAttilio Rao  * 2. Redistributions in binary form must reproduce the above copyright
475fe58019SAttilio Rao  *    notice, this list of conditions and the following disclaimer in the
485fe58019SAttilio Rao  *    documentation and/or other materials provided with the distribution.
495fe58019SAttilio Rao  *
505fe58019SAttilio Rao  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
515fe58019SAttilio Rao  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
525fe58019SAttilio Rao  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
535fe58019SAttilio Rao  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
545fe58019SAttilio Rao  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
555fe58019SAttilio Rao  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
565fe58019SAttilio Rao  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
575fe58019SAttilio Rao  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
585fe58019SAttilio Rao  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
595fe58019SAttilio Rao  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
605fe58019SAttilio Rao  * SUCH DAMAGE.
615fe58019SAttilio Rao  *
625fe58019SAttilio Rao  * $FreeBSD$
635fe58019SAttilio Rao  */
645fe58019SAttilio Rao 
655fe58019SAttilio Rao #ifndef _FUSE_INTERNAL_H_
665fe58019SAttilio Rao #define _FUSE_INTERNAL_H_
675fe58019SAttilio Rao 
685fe58019SAttilio Rao #include <sys/types.h>
69560a55d0SAlan Somers #include <sys/counter.h>
70508abc94SAlan Somers #include <sys/limits.h>
715fe58019SAttilio Rao #include <sys/uio.h>
725fe58019SAttilio Rao #include <sys/stat.h>
735fe58019SAttilio Rao #include <sys/vnode.h>
745fe58019SAttilio Rao 
755fe58019SAttilio Rao #include "fuse_ipc.h"
765fe58019SAttilio Rao #include "fuse_node.h"
775fe58019SAttilio Rao 
78560a55d0SAlan Somers extern counter_u64_t fuse_lookup_cache_hits;
79560a55d0SAlan Somers extern counter_u64_t fuse_lookup_cache_misses;
800d2bf489SAlan Somers 
8102295cafSConrad Meyer static inline bool
825fe58019SAttilio Rao vfs_isrdonly(struct mount *mp)
835fe58019SAttilio Rao {
8402295cafSConrad Meyer 	return ((mp->mnt_flag & MNT_RDONLY) != 0);
855fe58019SAttilio Rao }
865fe58019SAttilio Rao 
8702295cafSConrad Meyer static inline struct mount *
885fe58019SAttilio Rao vnode_mount(struct vnode *vp)
895fe58019SAttilio Rao {
905fe58019SAttilio Rao 	return (vp->v_mount);
915fe58019SAttilio Rao }
925fe58019SAttilio Rao 
9302295cafSConrad Meyer static inline enum vtype
945fe58019SAttilio Rao vnode_vtype(struct vnode *vp)
955fe58019SAttilio Rao {
965fe58019SAttilio Rao 	return (vp->v_type);
975fe58019SAttilio Rao }
985fe58019SAttilio Rao 
9902295cafSConrad Meyer static inline bool
1005fe58019SAttilio Rao vnode_isvroot(struct vnode *vp)
1015fe58019SAttilio Rao {
10202295cafSConrad Meyer 	return ((vp->v_vflag & VV_ROOT) != 0);
1035fe58019SAttilio Rao }
1045fe58019SAttilio Rao 
10502295cafSConrad Meyer static inline bool
1065fe58019SAttilio Rao vnode_isreg(struct vnode *vp)
1075fe58019SAttilio Rao {
10802295cafSConrad Meyer 	return (vp->v_type == VREG);
1095fe58019SAttilio Rao }
1105fe58019SAttilio Rao 
11102295cafSConrad Meyer static inline bool
1125fe58019SAttilio Rao vnode_isdir(struct vnode *vp)
1135fe58019SAttilio Rao {
11402295cafSConrad Meyer 	return (vp->v_type == VDIR);
1155fe58019SAttilio Rao }
1165fe58019SAttilio Rao 
11702295cafSConrad Meyer static inline bool
1185fe58019SAttilio Rao vnode_islnk(struct vnode *vp)
1195fe58019SAttilio Rao {
12002295cafSConrad Meyer 	return (vp->v_type == VLNK);
1215fe58019SAttilio Rao }
1225fe58019SAttilio Rao 
12302295cafSConrad Meyer static inline ssize_t
1245fe58019SAttilio Rao uio_resid(struct uio *uio)
1255fe58019SAttilio Rao {
1265fe58019SAttilio Rao 	return (uio->uio_resid);
1275fe58019SAttilio Rao }
1285fe58019SAttilio Rao 
12902295cafSConrad Meyer static inline off_t
1305fe58019SAttilio Rao uio_offset(struct uio *uio)
1315fe58019SAttilio Rao {
1325fe58019SAttilio Rao 	return (uio->uio_offset);
1335fe58019SAttilio Rao }
1345fe58019SAttilio Rao 
13502295cafSConrad Meyer static inline void
1365fe58019SAttilio Rao uio_setoffset(struct uio *uio, off_t offset)
1375fe58019SAttilio Rao {
1385fe58019SAttilio Rao 	uio->uio_offset = offset;
1395fe58019SAttilio Rao }
1405fe58019SAttilio Rao 
1415fe58019SAttilio Rao /* miscellaneous */
1425fe58019SAttilio Rao 
14302295cafSConrad Meyer static inline bool
1445fe58019SAttilio Rao fuse_isdeadfs(struct vnode *vp)
1455fe58019SAttilio Rao {
1465fe58019SAttilio Rao 	struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp));
1475fe58019SAttilio Rao 
1485fe58019SAttilio Rao 	return (data->dataflags & FSESS_DEAD);
1495fe58019SAttilio Rao }
1505fe58019SAttilio Rao 
15102295cafSConrad Meyer static inline uint64_t
1525fe58019SAttilio Rao fuse_iosize(struct vnode *vp)
1535fe58019SAttilio Rao {
15402295cafSConrad Meyer 	return (vp->v_mount->mnt_stat.f_iosize);
1555fe58019SAttilio Rao }
1565fe58019SAttilio Rao 
15744f10c6eSAlan Somers /*
15844f10c6eSAlan Somers  * Make a cacheable timeout in bintime format value based on a fuse_attr_out
15944f10c6eSAlan Somers  * response
16044f10c6eSAlan Somers  */
16144f10c6eSAlan Somers static inline void
16244f10c6eSAlan Somers fuse_validity_2_bintime(uint64_t attr_valid, uint32_t attr_valid_nsec,
16344f10c6eSAlan Somers 	struct bintime *timeout)
16444f10c6eSAlan Somers {
16544f10c6eSAlan Somers 	struct timespec now, duration, timeout_ts;
16644f10c6eSAlan Somers 
16744f10c6eSAlan Somers 	getnanouptime(&now);
16844f10c6eSAlan Somers 	/* "+ 2" is the bound of attr_valid_nsec + now.tv_nsec */
16944f10c6eSAlan Somers 	/* Why oh why isn't there a TIME_MAX defined? */
17044f10c6eSAlan Somers 	if (attr_valid >= INT_MAX || attr_valid + now.tv_sec + 2 >= INT_MAX) {
17144f10c6eSAlan Somers 		timeout->sec = INT_MAX;
17244f10c6eSAlan Somers 	} else {
17344f10c6eSAlan Somers 		duration.tv_sec = attr_valid;
17444f10c6eSAlan Somers 		duration.tv_nsec = attr_valid_nsec;
17544f10c6eSAlan Somers 		timespecadd(&duration, &now, &timeout_ts);
17644f10c6eSAlan Somers 		timespec2bintime(&timeout_ts, timeout);
17744f10c6eSAlan Somers 	}
17844f10c6eSAlan Somers }
17944f10c6eSAlan Somers 
18044f10c6eSAlan Somers /*
18144f10c6eSAlan Somers  * Make a cacheable timeout value in timespec format based on the fuse_entry_out
18244f10c6eSAlan Somers  * response
18344f10c6eSAlan Somers  */
18444f10c6eSAlan Somers static inline void
18544f10c6eSAlan Somers fuse_validity_2_timespec(const struct fuse_entry_out *feo,
18644f10c6eSAlan Somers 	struct timespec *timeout)
18744f10c6eSAlan Somers {
18844f10c6eSAlan Somers 	struct timespec duration, now;
18944f10c6eSAlan Somers 
19044f10c6eSAlan Somers 	getnanouptime(&now);
19144f10c6eSAlan Somers 	/* "+ 2" is the bound of entry_valid_nsec + now.tv_nsec */
19244f10c6eSAlan Somers 	if (feo->entry_valid >= INT_MAX ||
19344f10c6eSAlan Somers 	    feo->entry_valid + now.tv_sec + 2 >= INT_MAX) {
19444f10c6eSAlan Somers 		timeout->tv_sec = INT_MAX;
19544f10c6eSAlan Somers 	} else {
19644f10c6eSAlan Somers 		duration.tv_sec = feo->entry_valid;
19744f10c6eSAlan Somers 		duration.tv_nsec = feo->entry_valid_nsec;
19844f10c6eSAlan Somers 		timespecadd(&duration, &now, timeout);
19944f10c6eSAlan Somers 	}
20044f10c6eSAlan Somers }
20144f10c6eSAlan Somers 
202eae1ae13SAlan Somers /* VFS ops */
203eae1ae13SAlan Somers int
204eae1ae13SAlan Somers fuse_internal_get_cached_vnode(struct mount*, ino_t, int, struct vnode**);
205eae1ae13SAlan Somers 
2065fe58019SAttilio Rao /* access */
20702295cafSConrad Meyer static inline int
2085fe58019SAttilio Rao fuse_match_cred(struct ucred *basecred, struct ucred *usercred)
2095fe58019SAttilio Rao {
2105fe58019SAttilio Rao 	if (basecred->cr_uid == usercred->cr_uid             &&
2115fe58019SAttilio Rao 	    basecred->cr_uid == usercred->cr_ruid            &&
2125fe58019SAttilio Rao 	    basecred->cr_uid == usercred->cr_svuid           &&
2135fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_groups[0] &&
2145fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_rgid      &&
2155fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_svgid)
21602295cafSConrad Meyer 		return (0);
2175fe58019SAttilio Rao 
21802295cafSConrad Meyer 	return (EPERM);
2195fe58019SAttilio Rao }
2205fe58019SAttilio Rao 
221ff4fbdf5SAlan Somers int fuse_internal_access(struct vnode *vp, accmode_t mode,
222666f8543SAlan Somers     struct thread *td, struct ucred *cred);
2235fe58019SAttilio Rao 
2245fe58019SAttilio Rao /* attributes */
2257e4844f7SAlan Somers void fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr,
226*5d94aaacSAlan Somers 	uint64_t attr_valid, uint32_t attr_valid_nsec, struct vattr *vap,
227*5d94aaacSAlan Somers 	bool from_server);
2285fe58019SAttilio Rao 
2295fe58019SAttilio Rao /* fsync */
2305fe58019SAttilio Rao 
231915012e0SAlan Somers int fuse_internal_fsync(struct vnode *vp, struct thread *td, int waitfor,
232915012e0SAlan Somers 	bool datasync);
23302295cafSConrad Meyer int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
2345fe58019SAttilio Rao 
235cad67791SAlan Somers /* getattr */
2363d15b234SAlan Somers int fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap,
2373d15b234SAlan Somers 	struct ucred *cred, struct thread *td);
238cad67791SAlan Somers int fuse_internal_getattr(struct vnode *vp, struct vattr *vap,
239cad67791SAlan Somers 	struct ucred *cred, struct thread *td);
240cad67791SAlan Somers 
241c2d70d6eSAlan Somers /* asynchronous invalidation */
242c2d70d6eSAlan Somers int fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio);
243eae1ae13SAlan Somers int fuse_internal_invalidate_inode(struct mount *mp, struct uio *uio);
2445fe58019SAttilio Rao 
245d5ff2688SAlan Somers /* mknod */
246d5ff2688SAlan Somers int fuse_internal_mknod(struct vnode *dvp, struct vnode **vpp,
247d5ff2688SAlan Somers 	struct componentname *cnp, struct vattr *vap);
248d5ff2688SAlan Somers 
249d5ff2688SAlan Somers /* readdir */
250c2d70d6eSAlan Somers struct pseudo_dirent {
251c2d70d6eSAlan Somers 	uint32_t d_namlen;
252c2d70d6eSAlan Somers };
253e76986fdSAlan Somers int fuse_internal_readdir(struct vnode *vp, struct uio *uio, off_t startoff,
254e76986fdSAlan Somers     struct fuse_filehandle *fufh, struct fuse_iov *cookediov, int *ncookies,
255e76986fdSAlan Somers     u_long *cookies);
256e76986fdSAlan Somers int fuse_internal_readdir_processdata(struct uio *uio, off_t startoff,
257e76986fdSAlan Somers     int *fnd_start, size_t reqsize, void *buf, size_t bufsize,
258e76986fdSAlan Somers     struct fuse_iov *cookediov, int *ncookies, u_long **cookiesp);
2595fe58019SAttilio Rao 
2605fe58019SAttilio Rao /* remove */
2615fe58019SAttilio Rao 
26202295cafSConrad Meyer int fuse_internal_remove(struct vnode *dvp, struct vnode *vp,
26302295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op);
2645fe58019SAttilio Rao 
2655fe58019SAttilio Rao /* rename */
2665fe58019SAttilio Rao 
26702295cafSConrad Meyer int fuse_internal_rename(struct vnode *fdvp, struct componentname *fcnp,
26802295cafSConrad Meyer     struct vnode *tdvp, struct componentname *tcnp);
26902295cafSConrad Meyer 
2705fe58019SAttilio Rao /* revoke */
2715fe58019SAttilio Rao 
27202295cafSConrad Meyer void fuse_internal_vnode_disappear(struct vnode *vp);
2735fe58019SAttilio Rao 
274a90e32deSAlan Somers /* setattr */
275a90e32deSAlan Somers int fuse_internal_setattr(struct vnode *vp, struct vattr *va,
276a90e32deSAlan Somers 	struct thread *td, struct ucred *cred);
277a90e32deSAlan Somers 
27892bbfe1fSAlan Somers /* write */
27992bbfe1fSAlan Somers void fuse_internal_clear_suid_on_write(struct vnode *vp, struct ucred *cred,
28092bbfe1fSAlan Somers     struct thread *td);
28192bbfe1fSAlan Somers 
2825fe58019SAttilio Rao /* strategy */
2835fe58019SAttilio Rao 
2845fe58019SAttilio Rao /* entity creation */
2855fe58019SAttilio Rao 
28602295cafSConrad Meyer static inline int
2875fe58019SAttilio Rao fuse_internal_checkentry(struct fuse_entry_out *feo, enum vtype vtyp)
2885fe58019SAttilio Rao {
2895fe58019SAttilio Rao 	if (vtyp != IFTOVT(feo->attr.mode)) {
29002295cafSConrad Meyer 		return (EINVAL);
2915fe58019SAttilio Rao 	}
2925fe58019SAttilio Rao 
2935fe58019SAttilio Rao 	if (feo->nodeid == FUSE_NULL_ID) {
29402295cafSConrad Meyer 		return (EINVAL);
2955fe58019SAttilio Rao 	}
2965fe58019SAttilio Rao 
2975fe58019SAttilio Rao 	if (feo->nodeid == FUSE_ROOT_ID) {
29802295cafSConrad Meyer 		return (EINVAL);
2995fe58019SAttilio Rao 	}
3005fe58019SAttilio Rao 
30102295cafSConrad Meyer 	return (0);
3025fe58019SAttilio Rao }
3035fe58019SAttilio Rao 
30402295cafSConrad Meyer int fuse_internal_newentry(struct vnode *dvp, struct vnode **vpp,
30502295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
3065fe58019SAttilio Rao     enum vtype vtyp);
3075fe58019SAttilio Rao 
30802295cafSConrad Meyer void fuse_internal_newentry_makerequest(struct mount *mp, uint64_t dnid,
30902295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
3105fe58019SAttilio Rao     struct fuse_dispatcher *fdip);
3115fe58019SAttilio Rao 
31202295cafSConrad Meyer int fuse_internal_newentry_core(struct vnode *dvp, struct vnode **vpp,
31302295cafSConrad Meyer     struct componentname *cnp, enum vtype vtyp, struct fuse_dispatcher *fdip);
3145fe58019SAttilio Rao 
3155fe58019SAttilio Rao /* entity destruction */
3165fe58019SAttilio Rao 
31702295cafSConrad Meyer int fuse_internal_forget_callback(struct fuse_ticket *tick, struct uio *uio);
31802295cafSConrad Meyer void fuse_internal_forget_send(struct mount *mp, struct thread *td,
31902295cafSConrad Meyer     struct ucred *cred, uint64_t nodeid, uint64_t nlookup);
3205fe58019SAttilio Rao 
3215fe58019SAttilio Rao /* fuse start/stop */
3225fe58019SAttilio Rao 
3235fe58019SAttilio Rao int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio);
3245fe58019SAttilio Rao void fuse_internal_send_init(struct fuse_data *data, struct thread *td);
3255fe58019SAttilio Rao 
326560a55d0SAlan Somers /* module load/unload */
327560a55d0SAlan Somers void fuse_internal_init(void);
328560a55d0SAlan Somers void fuse_internal_destroy(void);
329560a55d0SAlan Somers 
3305fe58019SAttilio Rao #endif /* _FUSE_INTERNAL_H_ */
331