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