xref: /freebsd/sys/fs/fuse/fuse_internal.h (revision a90e32de25869ee579ad6b793e2e58c635ad9ac2)
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>
645fe58019SAttilio Rao #include <sys/uio.h>
655fe58019SAttilio Rao #include <sys/stat.h>
665fe58019SAttilio Rao #include <sys/vnode.h>
675fe58019SAttilio Rao 
685fe58019SAttilio Rao #include "fuse_ipc.h"
695fe58019SAttilio Rao #include "fuse_node.h"
705fe58019SAttilio Rao 
7102295cafSConrad Meyer static inline bool
725fe58019SAttilio Rao vfs_isrdonly(struct mount *mp)
735fe58019SAttilio Rao {
7402295cafSConrad Meyer 	return ((mp->mnt_flag & MNT_RDONLY) != 0);
755fe58019SAttilio Rao }
765fe58019SAttilio Rao 
7702295cafSConrad Meyer static inline struct mount *
785fe58019SAttilio Rao vnode_mount(struct vnode *vp)
795fe58019SAttilio Rao {
805fe58019SAttilio Rao 	return (vp->v_mount);
815fe58019SAttilio Rao }
825fe58019SAttilio Rao 
8302295cafSConrad Meyer static inline enum vtype
845fe58019SAttilio Rao vnode_vtype(struct vnode *vp)
855fe58019SAttilio Rao {
865fe58019SAttilio Rao 	return (vp->v_type);
875fe58019SAttilio Rao }
885fe58019SAttilio Rao 
8902295cafSConrad Meyer static inline bool
905fe58019SAttilio Rao vnode_isvroot(struct vnode *vp)
915fe58019SAttilio Rao {
9202295cafSConrad Meyer 	return ((vp->v_vflag & VV_ROOT) != 0);
935fe58019SAttilio Rao }
945fe58019SAttilio Rao 
9502295cafSConrad Meyer static inline bool
965fe58019SAttilio Rao vnode_isreg(struct vnode *vp)
975fe58019SAttilio Rao {
9802295cafSConrad Meyer 	return (vp->v_type == VREG);
995fe58019SAttilio Rao }
1005fe58019SAttilio Rao 
10102295cafSConrad Meyer static inline bool
1025fe58019SAttilio Rao vnode_isdir(struct vnode *vp)
1035fe58019SAttilio Rao {
10402295cafSConrad Meyer 	return (vp->v_type == VDIR);
1055fe58019SAttilio Rao }
1065fe58019SAttilio Rao 
10702295cafSConrad Meyer static inline bool
1085fe58019SAttilio Rao vnode_islnk(struct vnode *vp)
1095fe58019SAttilio Rao {
11002295cafSConrad Meyer 	return (vp->v_type == VLNK);
1115fe58019SAttilio Rao }
1125fe58019SAttilio Rao 
11302295cafSConrad Meyer static inline ssize_t
1145fe58019SAttilio Rao uio_resid(struct uio *uio)
1155fe58019SAttilio Rao {
1165fe58019SAttilio Rao 	return (uio->uio_resid);
1175fe58019SAttilio Rao }
1185fe58019SAttilio Rao 
11902295cafSConrad Meyer static inline off_t
1205fe58019SAttilio Rao uio_offset(struct uio *uio)
1215fe58019SAttilio Rao {
1225fe58019SAttilio Rao 	return (uio->uio_offset);
1235fe58019SAttilio Rao }
1245fe58019SAttilio Rao 
12502295cafSConrad Meyer static inline void
1265fe58019SAttilio Rao uio_setoffset(struct uio *uio, off_t offset)
1275fe58019SAttilio Rao {
1285fe58019SAttilio Rao 	uio->uio_offset = offset;
1295fe58019SAttilio Rao }
1305fe58019SAttilio Rao 
1315fe58019SAttilio Rao /* miscellaneous */
1325fe58019SAttilio Rao 
13302295cafSConrad Meyer static inline bool
1345fe58019SAttilio Rao fuse_isdeadfs(struct vnode *vp)
1355fe58019SAttilio Rao {
1365fe58019SAttilio Rao 	struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp));
1375fe58019SAttilio Rao 
1385fe58019SAttilio Rao 	return (data->dataflags & FSESS_DEAD);
1395fe58019SAttilio Rao }
1405fe58019SAttilio Rao 
14102295cafSConrad Meyer static inline uint64_t
1425fe58019SAttilio Rao fuse_iosize(struct vnode *vp)
1435fe58019SAttilio Rao {
14402295cafSConrad Meyer 	return (vp->v_mount->mnt_stat.f_iosize);
1455fe58019SAttilio Rao }
1465fe58019SAttilio Rao 
14744f10c6eSAlan Somers /*
14844f10c6eSAlan Somers  * Make a cacheable timeout in bintime format value based on a fuse_attr_out
14944f10c6eSAlan Somers  * response
15044f10c6eSAlan Somers  */
15144f10c6eSAlan Somers static inline void
15244f10c6eSAlan Somers fuse_validity_2_bintime(uint64_t attr_valid, uint32_t attr_valid_nsec,
15344f10c6eSAlan Somers 	struct bintime *timeout)
15444f10c6eSAlan Somers {
15544f10c6eSAlan Somers 	struct timespec now, duration, timeout_ts;
15644f10c6eSAlan Somers 
15744f10c6eSAlan Somers 	getnanouptime(&now);
15844f10c6eSAlan Somers 	/* "+ 2" is the bound of attr_valid_nsec + now.tv_nsec */
15944f10c6eSAlan Somers 	/* Why oh why isn't there a TIME_MAX defined? */
16044f10c6eSAlan Somers 	if (attr_valid >= INT_MAX || attr_valid + now.tv_sec + 2 >= INT_MAX) {
16144f10c6eSAlan Somers 		timeout->sec = INT_MAX;
16244f10c6eSAlan Somers 	} else {
16344f10c6eSAlan Somers 		duration.tv_sec = attr_valid;
16444f10c6eSAlan Somers 		duration.tv_nsec = attr_valid_nsec;
16544f10c6eSAlan Somers 		timespecadd(&duration, &now, &timeout_ts);
16644f10c6eSAlan Somers 		timespec2bintime(&timeout_ts, timeout);
16744f10c6eSAlan Somers 	}
16844f10c6eSAlan Somers }
16944f10c6eSAlan Somers 
17044f10c6eSAlan Somers /*
17144f10c6eSAlan Somers  * Make a cacheable timeout value in timespec format based on the fuse_entry_out
17244f10c6eSAlan Somers  * response
17344f10c6eSAlan Somers  */
17444f10c6eSAlan Somers static inline void
17544f10c6eSAlan Somers fuse_validity_2_timespec(const struct fuse_entry_out *feo,
17644f10c6eSAlan Somers 	struct timespec *timeout)
17744f10c6eSAlan Somers {
17844f10c6eSAlan Somers 	struct timespec duration, now;
17944f10c6eSAlan Somers 
18044f10c6eSAlan Somers 	getnanouptime(&now);
18144f10c6eSAlan Somers 	/* "+ 2" is the bound of entry_valid_nsec + now.tv_nsec */
18244f10c6eSAlan Somers 	if (feo->entry_valid >= INT_MAX ||
18344f10c6eSAlan Somers 	    feo->entry_valid + now.tv_sec + 2 >= INT_MAX) {
18444f10c6eSAlan Somers 		timeout->tv_sec = INT_MAX;
18544f10c6eSAlan Somers 	} else {
18644f10c6eSAlan Somers 		duration.tv_sec = feo->entry_valid;
18744f10c6eSAlan Somers 		duration.tv_nsec = feo->entry_valid_nsec;
18844f10c6eSAlan Somers 		timespecadd(&duration, &now, timeout);
18944f10c6eSAlan Somers 	}
19044f10c6eSAlan Somers }
19144f10c6eSAlan Somers 
19244f10c6eSAlan Somers 
1935fe58019SAttilio Rao /* access */
19402295cafSConrad Meyer static inline int
1955fe58019SAttilio Rao fuse_match_cred(struct ucred *basecred, struct ucred *usercred)
1965fe58019SAttilio Rao {
1975fe58019SAttilio Rao 	if (basecred->cr_uid == usercred->cr_uid             &&
1985fe58019SAttilio Rao 	    basecred->cr_uid == usercred->cr_ruid            &&
1995fe58019SAttilio Rao 	    basecred->cr_uid == usercred->cr_svuid           &&
2005fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_groups[0] &&
2015fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_rgid      &&
2025fe58019SAttilio Rao 	    basecred->cr_groups[0] == usercred->cr_svgid)
20302295cafSConrad Meyer 		return (0);
2045fe58019SAttilio Rao 
20502295cafSConrad Meyer 	return (EPERM);
2065fe58019SAttilio Rao }
2075fe58019SAttilio Rao 
208ff4fbdf5SAlan Somers int fuse_internal_access(struct vnode *vp, accmode_t mode,
209666f8543SAlan Somers     struct thread *td, struct ucred *cred);
2105fe58019SAttilio Rao 
2115fe58019SAttilio Rao /* attributes */
2127e4844f7SAlan Somers void fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr,
2137e4844f7SAlan Somers 	uint64_t attr_valid, uint32_t attr_valid_nsec, struct vattr *vap);
2145fe58019SAttilio Rao 
2155fe58019SAttilio Rao /* fsync */
2165fe58019SAttilio Rao 
217915012e0SAlan Somers int fuse_internal_fsync(struct vnode *vp, struct thread *td, int waitfor,
218915012e0SAlan Somers 	bool datasync);
21902295cafSConrad Meyer int fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
2205fe58019SAttilio Rao 
221cad67791SAlan Somers /* getattr */
222cad67791SAlan Somers int fuse_internal_getattr(struct vnode *vp, struct vattr *vap,
223cad67791SAlan Somers 	struct ucred *cred, struct thread *td);
224cad67791SAlan Somers 
2255fe58019SAttilio Rao /* readdir */
2265fe58019SAttilio Rao 
2275fe58019SAttilio Rao struct pseudo_dirent {
2285fe58019SAttilio Rao 	uint32_t d_namlen;
2295fe58019SAttilio Rao };
2305fe58019SAttilio Rao 
23102295cafSConrad Meyer int fuse_internal_readdir(struct vnode *vp, struct uio *uio,
23202295cafSConrad Meyer     struct fuse_filehandle *fufh, struct fuse_iov *cookediov);
23302295cafSConrad Meyer int fuse_internal_readdir_processdata(struct uio *uio, size_t reqsize,
23402295cafSConrad Meyer     void *buf, size_t bufsize, void *param);
2355fe58019SAttilio Rao 
2365fe58019SAttilio Rao /* remove */
2375fe58019SAttilio Rao 
23802295cafSConrad Meyer int fuse_internal_remove(struct vnode *dvp, struct vnode *vp,
23902295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op);
2405fe58019SAttilio Rao 
2415fe58019SAttilio Rao /* rename */
2425fe58019SAttilio Rao 
24302295cafSConrad Meyer int fuse_internal_rename(struct vnode *fdvp, struct componentname *fcnp,
24402295cafSConrad Meyer     struct vnode *tdvp, struct componentname *tcnp);
24502295cafSConrad Meyer 
2465fe58019SAttilio Rao /* revoke */
2475fe58019SAttilio Rao 
24802295cafSConrad Meyer void fuse_internal_vnode_disappear(struct vnode *vp);
2495fe58019SAttilio Rao 
250*a90e32deSAlan Somers /* setattr */
251*a90e32deSAlan Somers int fuse_internal_setattr(struct vnode *vp, struct vattr *va,
252*a90e32deSAlan Somers 	struct thread *td, struct ucred *cred);
253*a90e32deSAlan Somers 
2545fe58019SAttilio Rao /* strategy */
2555fe58019SAttilio Rao 
2565fe58019SAttilio Rao /* entity creation */
2575fe58019SAttilio Rao 
25802295cafSConrad Meyer static inline int
2595fe58019SAttilio Rao fuse_internal_checkentry(struct fuse_entry_out *feo, enum vtype vtyp)
2605fe58019SAttilio Rao {
2615fe58019SAttilio Rao 	if (vtyp != IFTOVT(feo->attr.mode)) {
26202295cafSConrad Meyer 		return (EINVAL);
2635fe58019SAttilio Rao 	}
2645fe58019SAttilio Rao 
2655fe58019SAttilio Rao 	if (feo->nodeid == FUSE_NULL_ID) {
26602295cafSConrad Meyer 		return (EINVAL);
2675fe58019SAttilio Rao 	}
2685fe58019SAttilio Rao 
2695fe58019SAttilio Rao 	if (feo->nodeid == FUSE_ROOT_ID) {
27002295cafSConrad Meyer 		return (EINVAL);
2715fe58019SAttilio Rao 	}
2725fe58019SAttilio Rao 
27302295cafSConrad Meyer 	return (0);
2745fe58019SAttilio Rao }
2755fe58019SAttilio Rao 
27602295cafSConrad Meyer int fuse_internal_newentry(struct vnode *dvp, struct vnode **vpp,
27702295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
2785fe58019SAttilio Rao     enum vtype vtyp);
2795fe58019SAttilio Rao 
28002295cafSConrad Meyer void fuse_internal_newentry_makerequest(struct mount *mp, uint64_t dnid,
28102295cafSConrad Meyer     struct componentname *cnp, enum fuse_opcode op, void *buf, size_t bufsize,
2825fe58019SAttilio Rao     struct fuse_dispatcher *fdip);
2835fe58019SAttilio Rao 
28402295cafSConrad Meyer int fuse_internal_newentry_core(struct vnode *dvp, struct vnode **vpp,
28502295cafSConrad Meyer     struct componentname *cnp, enum vtype vtyp, struct fuse_dispatcher *fdip);
2865fe58019SAttilio Rao 
2875fe58019SAttilio Rao /* entity destruction */
2885fe58019SAttilio Rao 
28902295cafSConrad Meyer int fuse_internal_forget_callback(struct fuse_ticket *tick, struct uio *uio);
29002295cafSConrad Meyer void fuse_internal_forget_send(struct mount *mp, struct thread *td,
29102295cafSConrad Meyer     struct ucred *cred, uint64_t nodeid, uint64_t nlookup);
2925fe58019SAttilio Rao 
2935fe58019SAttilio Rao /* fuse start/stop */
2945fe58019SAttilio Rao 
2955fe58019SAttilio Rao int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio);
2965fe58019SAttilio Rao void fuse_internal_send_init(struct fuse_data *data, struct thread *td);
2975fe58019SAttilio Rao 
2985fe58019SAttilio Rao #endif /* _FUSE_INTERNAL_H_ */
299