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