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