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 63cf169498SAlan Somers #include <sys/param.h> 6407e86257SAlan Somers #include <sys/systm.h> 65560a55d0SAlan Somers #include <sys/counter.h> 665fe58019SAttilio Rao #include <sys/module.h> 675fe58019SAttilio Rao #include <sys/errno.h> 685fe58019SAttilio Rao #include <sys/kernel.h> 695fe58019SAttilio Rao #include <sys/conf.h> 705fe58019SAttilio Rao #include <sys/uio.h> 715fe58019SAttilio Rao #include <sys/malloc.h> 725fe58019SAttilio Rao #include <sys/queue.h> 735fe58019SAttilio Rao #include <sys/lock.h> 745fe58019SAttilio Rao #include <sys/sx.h> 755fe58019SAttilio Rao #include <sys/mutex.h> 765fe58019SAttilio Rao #include <sys/proc.h> 775fe58019SAttilio Rao #include <sys/mount.h> 785fe58019SAttilio Rao #include <sys/vnode.h> 79cf169498SAlan Somers #include <sys/sdt.h> 805fe58019SAttilio Rao #include <sys/sysctl.h> 815fe58019SAttilio Rao 825fe58019SAttilio Rao #include "fuse.h" 835fe58019SAttilio Rao #include "fuse_file.h" 845fe58019SAttilio Rao #include "fuse_internal.h" 85a7e81cb3SAlan Somers #include "fuse_io.h" 865fe58019SAttilio Rao #include "fuse_ipc.h" 875fe58019SAttilio Rao #include "fuse_node.h" 885fe58019SAttilio Rao 891cedd6dfSAlan Somers MALLOC_DEFINE(M_FUSE_FILEHANDLE, "fuse_filefilehandle", "FUSE file handle"); 901cedd6dfSAlan Somers 91419e7ff6SAlan Somers SDT_PROVIDER_DECLARE(fusefs); 92cf169498SAlan Somers /* 93cf169498SAlan Somers * Fuse trace probe: 94cf169498SAlan Somers * arg0: verbosity. Higher numbers give more verbose messages 95cf169498SAlan Somers * arg1: Textual message 96cf169498SAlan Somers */ 97419e7ff6SAlan Somers SDT_PROBE_DEFINE2(fusefs, , file, trace, "int", "char*"); 985fe58019SAttilio Rao 9938c86346SAlan Somers static counter_u64_t fuse_fh_count; 1005fe58019SAttilio Rao 101560a55d0SAlan Somers SYSCTL_COUNTER_U64(_vfs_fusefs_stats, OID_AUTO, filehandle_count, CTLFLAG_RD, 102560a55d0SAlan Somers &fuse_fh_count, "number of open FUSE filehandles"); 1035fe58019SAttilio Rao 1049e444871SAlan Somers /* Get the FUFH type for a particular access mode */ 1059e444871SAlan Somers static inline fufh_type_t 1069e444871SAlan Somers fflags_2_fufh_type(int fflags) 1079e444871SAlan Somers { 1089e444871SAlan Somers if ((fflags & FREAD) && (fflags & FWRITE)) 1099e444871SAlan Somers return FUFH_RDWR; 1109e444871SAlan Somers else if (fflags & (FWRITE)) 1119e444871SAlan Somers return FUFH_WRONLY; 1129e444871SAlan Somers else if (fflags & (FREAD)) 1139e444871SAlan Somers return FUFH_RDONLY; 1149e444871SAlan Somers else if (fflags & (FEXEC)) 1159e444871SAlan Somers return FUFH_EXEC; 1169e444871SAlan Somers else 1179e444871SAlan Somers panic("FUSE: What kind of a flag is this (%x)?", fflags); 1189e444871SAlan Somers } 1199e444871SAlan Somers 1205fe58019SAttilio Rao int 1219e444871SAlan Somers fuse_filehandle_open(struct vnode *vp, int a_mode, 12202295cafSConrad Meyer struct fuse_filehandle **fufhp, struct thread *td, struct ucred *cred) 1235fe58019SAttilio Rao { 1247124d2bcSAlan Somers struct mount *mp = vnode_mount(vp); 1255fe58019SAttilio Rao struct fuse_dispatcher fdi; 1267124d2bcSAlan Somers const struct fuse_open_out default_foo = { 1277124d2bcSAlan Somers .fh = 0, 1287124d2bcSAlan Somers .open_flags = FOPEN_KEEP_CACHE, 1297124d2bcSAlan Somers .padding = 0 1307124d2bcSAlan Somers }; 1317124d2bcSAlan Somers struct fuse_open_in *foi = NULL; 1327124d2bcSAlan Somers const struct fuse_open_out *foo; 1339e444871SAlan Somers fufh_type_t fufh_type; 1345fe58019SAttilio Rao int err = 0; 1355fe58019SAttilio Rao int oflags = 0; 1365fe58019SAttilio Rao int op = FUSE_OPEN; 1377124d2bcSAlan Somers int relop = FUSE_RELEASE; 1385fe58019SAttilio Rao 1399e444871SAlan Somers fufh_type = fflags_2_fufh_type(a_mode); 1409e444871SAlan Somers oflags = fufh_type_2_fflags(fufh_type); 1415fe58019SAttilio Rao 1425fe58019SAttilio Rao if (vnode_isdir(vp)) { 1435fe58019SAttilio Rao op = FUSE_OPENDIR; 1447124d2bcSAlan Somers relop = FUSE_RELEASEDIR; 145363a7416SAlan Somers /* vn_open_vnode already rejects FWRITE on directories */ 146363a7416SAlan Somers MPASS(fufh_type == FUFH_RDONLY || fufh_type == FUFH_EXEC); 1475fe58019SAttilio Rao } 1485fe58019SAttilio Rao fdisp_init(&fdi, sizeof(*foi)); 149*f0f596bdSCismonX if (fsess_not_impl(mp, op)) { 1507124d2bcSAlan Somers /* The operation implicitly succeeds */ 1517124d2bcSAlan Somers foo = &default_foo; 1527124d2bcSAlan Somers } else { 1535fe58019SAttilio Rao fdisp_make_vp(&fdi, op, vp, td, cred); 1545fe58019SAttilio Rao 1555fe58019SAttilio Rao foi = fdi.indata; 1565fe58019SAttilio Rao foi->flags = oflags; 1575fe58019SAttilio Rao 1587124d2bcSAlan Somers err = fdisp_wait_answ(&fdi); 159*f0f596bdSCismonX if (err == ENOSYS) { 1607124d2bcSAlan Somers /* The operation implicitly succeeds */ 1617124d2bcSAlan Somers foo = &default_foo; 1627124d2bcSAlan Somers fsess_set_notimpl(mp, op); 1637124d2bcSAlan Somers fsess_set_notimpl(mp, relop); 1647124d2bcSAlan Somers err = 0; 1657124d2bcSAlan Somers } else if (err) { 166419e7ff6SAlan Somers SDT_PROBE2(fusefs, , file, trace, 1, 167cf169498SAlan Somers "OUCH ... daemon didn't give fh"); 1687124d2bcSAlan Somers if (err == ENOENT) 1695fe58019SAttilio Rao fuse_internal_vnode_disappear(vp); 1705fe58019SAttilio Rao goto out; 1717124d2bcSAlan Somers } else { 1725fe58019SAttilio Rao foo = fdi.answ; 173*f0f596bdSCismonX fsess_set_impl(mp, op); 1747124d2bcSAlan Somers } 1757124d2bcSAlan Somers } 1765fe58019SAttilio Rao 177a7e81cb3SAlan Somers fuse_filehandle_init(vp, fufh_type, fufhp, td, cred, foo); 1785fe58019SAttilio Rao fuse_vnode_open(vp, foo->open_flags, td); 1795fe58019SAttilio Rao 1805fe58019SAttilio Rao out: 1817124d2bcSAlan Somers if (foi) 1825fe58019SAttilio Rao fdisp_destroy(&fdi); 1835fe58019SAttilio Rao return err; 1845fe58019SAttilio Rao } 1855fe58019SAttilio Rao 1865fe58019SAttilio Rao int 1875ec10aa5SAlan Somers fuse_filehandle_close(struct vnode *vp, struct fuse_filehandle *fufh, 18802295cafSConrad Meyer struct thread *td, struct ucred *cred) 1895fe58019SAttilio Rao { 1907124d2bcSAlan Somers struct mount *mp = vnode_mount(vp); 1915fe58019SAttilio Rao struct fuse_dispatcher fdi; 1925fe58019SAttilio Rao struct fuse_release_in *fri; 1935fe58019SAttilio Rao 1945fe58019SAttilio Rao int err = 0; 1955fe58019SAttilio Rao int op = FUSE_RELEASE; 1965fe58019SAttilio Rao 1975fe58019SAttilio Rao if (fuse_isdeadfs(vp)) { 1985fe58019SAttilio Rao goto out; 1995fe58019SAttilio Rao } 2003dc1c7d6SConrad Meyer if (vnode_isdir(vp)) 2015fe58019SAttilio Rao op = FUSE_RELEASEDIR; 2027124d2bcSAlan Somers 2037124d2bcSAlan Somers if (fsess_not_impl(mp, op)) 2047124d2bcSAlan Somers goto out; 2057124d2bcSAlan Somers 2065fe58019SAttilio Rao fdisp_init(&fdi, sizeof(*fri)); 2075fe58019SAttilio Rao fdisp_make_vp(&fdi, op, vp, td, cred); 2085fe58019SAttilio Rao fri = fdi.indata; 2095fe58019SAttilio Rao fri->fh = fufh->fh_id; 2109e444871SAlan Somers fri->flags = fufh_type_2_fflags(fufh->fufh_type); 211f067b609SAlan Somers /* 212f067b609SAlan Somers * If the file has a POSIX lock then we're supposed to set lock_owner. 213f067b609SAlan Somers * If not, then lock_owner is undefined. So we may as well always set 214f067b609SAlan Somers * it. 215f067b609SAlan Somers */ 216f067b609SAlan Somers fri->lock_owner = td->td_proc->p_pid; 2175fe58019SAttilio Rao 2185fe58019SAttilio Rao err = fdisp_wait_answ(&fdi); 2195fe58019SAttilio Rao fdisp_destroy(&fdi); 2205fe58019SAttilio Rao 2215fe58019SAttilio Rao out: 222560a55d0SAlan Somers counter_u64_add(fuse_fh_count, -1); 2231cedd6dfSAlan Somers LIST_REMOVE(fufh, next); 2241cedd6dfSAlan Somers free(fufh, M_FUSE_FILEHANDLE); 2255fe58019SAttilio Rao 2265fe58019SAttilio Rao return err; 2275fe58019SAttilio Rao } 2285fe58019SAttilio Rao 229e6e24456SRick Macklem /* 230e6e24456SRick Macklem * Check for a valid file handle, first the type requested, but if that 231e6e24456SRick Macklem * isn't valid, try for FUFH_RDWR. 232f8d4af10SAlan Somers * Return true if there is any file handle with the correct credentials and 233f8d4af10SAlan Somers * a fufh type that includes the provided one. 234f8d4af10SAlan Somers * A pid of 0 means "don't care" 235e6e24456SRick Macklem */ 236f8d4af10SAlan Somers bool 2379e444871SAlan Somers fuse_filehandle_validrw(struct vnode *vp, int mode, 238f8d4af10SAlan Somers struct ucred *cred, pid_t pid) 2395fe58019SAttilio Rao { 2405fe58019SAttilio Rao struct fuse_vnode_data *fvdat = VTOFUD(vp); 2415fe58019SAttilio Rao struct fuse_filehandle *fufh; 2429e444871SAlan Somers fufh_type_t fufh_type = fflags_2_fufh_type(mode); 2435fe58019SAttilio Rao 244f8d4af10SAlan Somers /* 245f8d4af10SAlan Somers * Unlike fuse_filehandle_get, we want to search for a filehandle with 246f8d4af10SAlan Somers * the exact cred, and no fallback 247f8d4af10SAlan Somers */ 248f8d4af10SAlan Somers LIST_FOREACH(fufh, &fvdat->handles, next) { 2499e444871SAlan Somers if (fufh->fufh_type == fufh_type && 250f8d4af10SAlan Somers fufh->uid == cred->cr_uid && 251f8d4af10SAlan Somers fufh->gid == cred->cr_rgid && 252f8d4af10SAlan Somers (pid == 0 || fufh->pid == pid)) 253f8d4af10SAlan Somers return true; 254f8d4af10SAlan Somers } 255f8d4af10SAlan Somers 256f8d4af10SAlan Somers if (fufh_type == FUFH_EXEC) 257f8d4af10SAlan Somers return false; 258f8d4af10SAlan Somers 259f8d4af10SAlan Somers /* Fallback: find a RDWR list entry with the right cred */ 260f8d4af10SAlan Somers LIST_FOREACH(fufh, &fvdat->handles, next) { 2619e444871SAlan Somers if (fufh->fufh_type == FUFH_RDWR && 262f8d4af10SAlan Somers fufh->uid == cred->cr_uid && 263f8d4af10SAlan Somers fufh->gid == cred->cr_rgid && 264f8d4af10SAlan Somers (pid == 0 || fufh->pid == pid)) 265f8d4af10SAlan Somers return true; 266f8d4af10SAlan Somers } 267f8d4af10SAlan Somers 268f8d4af10SAlan Somers return false; 269f8d4af10SAlan Somers } 270f8d4af10SAlan Somers 271f8d4af10SAlan Somers int 2729f10f423SAlan Somers fuse_filehandle_get(struct vnode *vp, int fflag, 273f8d4af10SAlan Somers struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid) 274f8d4af10SAlan Somers { 275f8d4af10SAlan Somers struct fuse_vnode_data *fvdat = VTOFUD(vp); 276f8d4af10SAlan Somers struct fuse_filehandle *fufh; 2779f10f423SAlan Somers fufh_type_t fufh_type; 278f8d4af10SAlan Somers 2799f10f423SAlan Somers fufh_type = fflags_2_fufh_type(fflag); 280e76986fdSAlan Somers /* cred can be NULL for in-kernel clients */ 281f8d4af10SAlan Somers if (cred == NULL) 282f8d4af10SAlan Somers goto fallback; 283f8d4af10SAlan Somers 284f8d4af10SAlan Somers LIST_FOREACH(fufh, &fvdat->handles, next) { 2859e444871SAlan Somers if (fufh->fufh_type == fufh_type && 286f8d4af10SAlan Somers fufh->uid == cred->cr_uid && 287f8d4af10SAlan Somers fufh->gid == cred->cr_rgid && 288f8d4af10SAlan Somers (pid == 0 || fufh->pid == pid)) 289f8d4af10SAlan Somers goto found; 290f8d4af10SAlan Somers } 291f8d4af10SAlan Somers 292f8d4af10SAlan Somers fallback: 2935ec10aa5SAlan Somers /* Fallback: find a list entry with the right flags */ 2941cedd6dfSAlan Somers LIST_FOREACH(fufh, &fvdat->handles, next) { 2959e444871SAlan Somers if (fufh->fufh_type == fufh_type) 2961cedd6dfSAlan Somers break; 2971cedd6dfSAlan Somers } 2981cedd6dfSAlan Somers 2991cedd6dfSAlan Somers if (fufh == NULL) 3005fe58019SAttilio Rao return EBADF; 301f8d4af10SAlan Somers 302f8d4af10SAlan Somers found: 3035fe58019SAttilio Rao if (fufhp != NULL) 3045fe58019SAttilio Rao *fufhp = fufh; 3055fe58019SAttilio Rao return 0; 3065fe58019SAttilio Rao } 3075fe58019SAttilio Rao 308f067b609SAlan Somers /* Get a file handle with any kind of flags */ 309f067b609SAlan Somers int 310f067b609SAlan Somers fuse_filehandle_get_anyflags(struct vnode *vp, 311f067b609SAlan Somers struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid) 312f067b609SAlan Somers { 313f067b609SAlan Somers struct fuse_vnode_data *fvdat = VTOFUD(vp); 314f067b609SAlan Somers struct fuse_filehandle *fufh; 315f067b609SAlan Somers 316f067b609SAlan Somers if (cred == NULL) 317f067b609SAlan Somers goto fallback; 318f067b609SAlan Somers 319f067b609SAlan Somers LIST_FOREACH(fufh, &fvdat->handles, next) { 320f067b609SAlan Somers if (fufh->uid == cred->cr_uid && 321f067b609SAlan Somers fufh->gid == cred->cr_rgid && 322f067b609SAlan Somers (pid == 0 || fufh->pid == pid)) 323f067b609SAlan Somers goto found; 324f067b609SAlan Somers } 325f067b609SAlan Somers 326f067b609SAlan Somers fallback: 327f067b609SAlan Somers /* Fallback: find any list entry */ 328f067b609SAlan Somers fufh = LIST_FIRST(&fvdat->handles); 329f067b609SAlan Somers 330f067b609SAlan Somers if (fufh == NULL) 331f067b609SAlan Somers return EBADF; 332f067b609SAlan Somers 333f067b609SAlan Somers found: 334f067b609SAlan Somers if (fufhp != NULL) 335f067b609SAlan Somers *fufhp = fufh; 336f067b609SAlan Somers return 0; 337f067b609SAlan Somers } 338f067b609SAlan Somers 3395fe58019SAttilio Rao int 3409f10f423SAlan Somers fuse_filehandle_getrw(struct vnode *vp, int fflag, 341f8d4af10SAlan Somers struct fuse_filehandle **fufhp, struct ucred *cred, pid_t pid) 3425fe58019SAttilio Rao { 3431cedd6dfSAlan Somers int err; 3445fe58019SAttilio Rao 3459f10f423SAlan Somers err = fuse_filehandle_get(vp, fflag, fufhp, cred, pid); 3461cedd6dfSAlan Somers if (err) 3479f10f423SAlan Somers err = fuse_filehandle_get(vp, FREAD | FWRITE, fufhp, cred, pid); 3481cedd6dfSAlan Somers return err; 3495fe58019SAttilio Rao } 3505fe58019SAttilio Rao 3515fe58019SAttilio Rao void 35202295cafSConrad Meyer fuse_filehandle_init(struct vnode *vp, fufh_type_t fufh_type, 3537124d2bcSAlan Somers struct fuse_filehandle **fufhp, struct thread *td, const struct ucred *cred, 3547124d2bcSAlan Somers const struct fuse_open_out *foo) 3555fe58019SAttilio Rao { 3565fe58019SAttilio Rao struct fuse_vnode_data *fvdat = VTOFUD(vp); 3575fe58019SAttilio Rao struct fuse_filehandle *fufh; 3585fe58019SAttilio Rao 3591cedd6dfSAlan Somers fufh = malloc(sizeof(struct fuse_filehandle), M_FUSE_FILEHANDLE, 3601cedd6dfSAlan Somers M_WAITOK); 3611cedd6dfSAlan Somers MPASS(fufh != NULL); 3629e444871SAlan Somers fufh->fh_id = foo->fh; 3639e444871SAlan Somers fufh->fufh_type = fufh_type; 364f8d4af10SAlan Somers fufh->gid = cred->cr_rgid; 365f8d4af10SAlan Somers fufh->uid = cred->cr_uid; 366a7e81cb3SAlan Somers fufh->pid = td->td_proc->p_pid; 3679e444871SAlan Somers fufh->fuse_open_flags = foo->open_flags; 3685fe58019SAttilio Rao if (!FUFH_IS_VALID(fufh)) { 3695fe58019SAttilio Rao panic("FUSE: init: invalid filehandle id (type=%d)", fufh_type); 3705fe58019SAttilio Rao } 3711cedd6dfSAlan Somers LIST_INSERT_HEAD(&fvdat->handles, fufh, next); 3725fe58019SAttilio Rao if (fufhp != NULL) 3735fe58019SAttilio Rao *fufhp = fufh; 3745fe58019SAttilio Rao 375560a55d0SAlan Somers counter_u64_add(fuse_fh_count, 1); 376a7e81cb3SAlan Somers 377a7e81cb3SAlan Somers if (foo->open_flags & FOPEN_DIRECT_IO) { 378a7e81cb3SAlan Somers ASSERT_VOP_ELOCKED(vp, __func__); 379a7e81cb3SAlan Somers VTOFUD(vp)->flag |= FN_DIRECTIO; 380a7e81cb3SAlan Somers fuse_io_invalbuf(vp, td); 381a7e81cb3SAlan Somers } else { 382a7e81cb3SAlan Somers if ((foo->open_flags & FOPEN_KEEP_CACHE) == 0) 383a7e81cb3SAlan Somers fuse_io_invalbuf(vp, td); 384a7e81cb3SAlan Somers VTOFUD(vp)->flag &= ~FN_DIRECTIO; 385a7e81cb3SAlan Somers } 386a7e81cb3SAlan Somers 3875fe58019SAttilio Rao } 388560a55d0SAlan Somers 389560a55d0SAlan Somers void 390560a55d0SAlan Somers fuse_file_init(void) 391560a55d0SAlan Somers { 392560a55d0SAlan Somers fuse_fh_count = counter_u64_alloc(M_WAITOK); 393560a55d0SAlan Somers } 394560a55d0SAlan Somers 395560a55d0SAlan Somers void 396560a55d0SAlan Somers fuse_file_destroy(void) 397560a55d0SAlan Somers { 398560a55d0SAlan Somers counter_u64_free(fuse_fh_count); 399560a55d0SAlan Somers } 400