The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/fuse/fuse_ipc.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2007-2009 Google Inc. and Amit Singh
    3  * All rights reserved.
    4  * 
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are
    7  * met:
    8  * 
    9  * * Redistributions of source code must retain the above copyright
   10  *   notice, this list of conditions and the following disclaimer.
   11  * * Redistributions in binary form must reproduce the above
   12  *   copyright notice, this list of conditions and the following disclaimer
   13  *   in the documentation and/or other materials provided with the
   14  *   distribution.
   15  * * Neither the name of Google Inc. nor the names of its
   16  *   contributors may be used to endorse or promote products derived from
   17  *   this software without specific prior written permission.
   18  * 
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  * 
   31  * Copyright (C) 2005 Csaba Henk.
   32  * All rights reserved.
   33  * 
   34  * Redistribution and use in source and binary forms, with or without
   35  * modification, are permitted provided that the following conditions
   36  * are met:
   37  * 1. Redistributions of source code must retain the above copyright
   38  *    notice, this list of conditions and the following disclaimer.
   39  * 2. Redistributions in binary form must reproduce the above copyright
   40  *    notice, this list of conditions and the following disclaimer in the
   41  *    documentation and/or other materials provided with the distribution.
   42  * 
   43  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   46  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   47  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   53  * SUCH DAMAGE.
   54  *
   55  * $FreeBSD: releng/10.1/sys/fs/fuse/fuse_ipc.h 241519 2012-10-13 23:54:26Z attilio $
   56  */
   57 
   58 #ifndef _FUSE_IPC_H_
   59 #define _FUSE_IPC_H_
   60 
   61 #include <sys/param.h>
   62 #include <sys/refcount.h>
   63 
   64 struct fuse_iov {
   65     void   *base;
   66     size_t  len;
   67     size_t  allocated_size;
   68     int     credit;
   69 };
   70 
   71 void fiov_init(struct fuse_iov *fiov, size_t size);
   72 void fiov_teardown(struct fuse_iov *fiov);
   73 void fiov_refresh(struct fuse_iov *fiov);
   74 void fiov_adjust(struct fuse_iov *fiov, size_t size);
   75 
   76 #define FUSE_DIMALLOC(fiov, spc1, spc2, amnt)          \
   77 do {                                                   \
   78     fiov_adjust(fiov, (sizeof(*(spc1)) + (amnt)));     \
   79     (spc1) = (fiov)->base;                             \
   80     (spc2) = (char *)(fiov)->base + (sizeof(*(spc1))); \
   81 } while (0)
   82 
   83 #define FU_AT_LEAST(siz) max((siz), 160)
   84 
   85 #define FUSE_ASSERT_AW_DONE(ftick)                                      \
   86     KASSERT((ftick)->tk_aw_link.tqe_next == NULL &&                     \
   87         (ftick)->tk_aw_link.tqe_prev == NULL,                           \
   88         ("FUSE: ticket still on answer delivery list %p", (ftick)))     \
   89 
   90 #define FUSE_ASSERT_MS_DONE(ftick)                                      \
   91     KASSERT((ftick)->tk_ms_link.stqe_next == NULL,                      \
   92         ("FUSE: ticket still on message list %p", (ftick)))
   93 
   94 struct fuse_ticket;
   95 struct fuse_data;
   96 
   97 typedef int fuse_handler_t(struct fuse_ticket *ftick, struct uio *uio);
   98 
   99 struct fuse_ticket {
  100     /* fields giving the identity of the ticket */
  101     uint64_t                     tk_unique;
  102     struct fuse_data            *tk_data;
  103     int                          tk_flag;
  104     u_int                        tk_refcount;
  105 
  106     /* fields for initiating an upgoing message */
  107     struct fuse_iov              tk_ms_fiov;
  108     void                        *tk_ms_bufdata;
  109     size_t                       tk_ms_bufsize;
  110     enum { FT_M_FIOV, FT_M_BUF } tk_ms_type;
  111     STAILQ_ENTRY(fuse_ticket)    tk_ms_link;
  112 
  113     /* fields for handling answers coming from userspace */
  114     struct fuse_iov              tk_aw_fiov;
  115     void                        *tk_aw_bufdata;
  116     size_t                       tk_aw_bufsize;
  117     enum { FT_A_FIOV, FT_A_BUF } tk_aw_type;
  118 
  119     struct fuse_out_header       tk_aw_ohead;
  120     int                          tk_aw_errno;
  121     struct mtx                   tk_aw_mtx;
  122     fuse_handler_t              *tk_aw_handler;
  123     TAILQ_ENTRY(fuse_ticket)     tk_aw_link;
  124 };
  125 
  126 #define FT_ANSW  0x01  /* request of ticket has already been answered */
  127 #define FT_DIRTY 0x04  /* ticket has been used */
  128 
  129 static __inline__
  130 struct fuse_iov *
  131 fticket_resp(struct fuse_ticket *ftick)
  132 {
  133     return (&ftick->tk_aw_fiov);
  134 }
  135 
  136 static __inline__
  137 int
  138 fticket_answered(struct fuse_ticket *ftick)
  139 {
  140     DEBUGX(FUSE_DEBUG_IPC, "-> ftick=%p\n", ftick);
  141     mtx_assert(&ftick->tk_aw_mtx, MA_OWNED);
  142     return (ftick->tk_flag & FT_ANSW);
  143 }
  144 
  145 static __inline__
  146 void
  147 fticket_set_answered(struct fuse_ticket *ftick)
  148 {
  149     DEBUGX(FUSE_DEBUG_IPC, "-> ftick=%p\n", ftick);
  150     mtx_assert(&ftick->tk_aw_mtx, MA_OWNED);
  151     ftick->tk_flag |= FT_ANSW;
  152 }
  153 
  154 static __inline__
  155 enum fuse_opcode
  156 fticket_opcode(struct fuse_ticket *ftick)
  157 {
  158     DEBUGX(FUSE_DEBUG_IPC, "-> ftick=%p\n", ftick);
  159     return (((struct fuse_in_header *)(ftick->tk_ms_fiov.base))->opcode);
  160 }
  161 
  162 int fticket_pull(struct fuse_ticket *ftick, struct uio *uio);
  163 
  164 enum mountpri { FM_NOMOUNTED, FM_PRIMARY, FM_SECONDARY };
  165 
  166 /*
  167  * The data representing a FUSE session.
  168  */
  169 struct fuse_data {
  170     struct cdev               *fdev;
  171     struct mount              *mp;
  172     struct vnode              *vroot;
  173     struct ucred              *daemoncred;
  174     int                        dataflags;
  175     int                        ref; 
  176 
  177     struct mtx                 ms_mtx;
  178     STAILQ_HEAD(, fuse_ticket) ms_head;
  179 
  180     struct mtx                 aw_mtx;
  181     TAILQ_HEAD(, fuse_ticket)  aw_head;
  182 
  183     u_long                     ticketer;
  184 
  185     struct sx                  rename_lock;
  186 
  187     uint32_t                   fuse_libabi_major;
  188     uint32_t                   fuse_libabi_minor;
  189 
  190     uint32_t                   max_write;
  191     uint32_t                   max_read;
  192     uint32_t                   subtype;
  193     char                       volname[MAXPATHLEN];
  194 
  195     struct selinfo ks_rsel;
  196 
  197     int                        daemon_timeout;
  198     uint64_t                   notimpl;
  199 };
  200 
  201 #define FSESS_DEAD                0x0001 /* session is to be closed */
  202 #define FSESS_UNUSED0             0x0002 /* unused */
  203 #define FSESS_INITED              0x0004 /* session has been inited */
  204 #define FSESS_DAEMON_CAN_SPY      0x0010 /* let non-owners access this fs */
  205                                          /* (and being observed by the daemon) */
  206 #define FSESS_PUSH_SYMLINKS_IN    0x0020 /* prefix absolute symlinks with mp */
  207 #define FSESS_DEFAULT_PERMISSIONS 0x0040 /* kernel does permission checking */
  208 #define FSESS_NO_ATTRCACHE        0x0080 /* no attribute caching */
  209 #define FSESS_NO_READAHEAD        0x0100 /* no readaheads */
  210 #define FSESS_NO_DATACACHE        0x0200 /* disable buffer cache */
  211 #define FSESS_NO_NAMECACHE        0x0400 /* disable name cache */
  212 #define FSESS_NO_MMAP             0x0800 /* disable mmap */
  213 #define FSESS_BROKENIO            0x1000 /* fix broken io */
  214 
  215 extern int fuse_data_cache_enable;
  216 extern int fuse_data_cache_invalidate;
  217 extern int fuse_mmap_enable;
  218 extern int fuse_sync_resize;
  219 extern int fuse_fix_broken_io;
  220 
  221 static __inline__
  222 struct fuse_data *
  223 fuse_get_mpdata(struct mount *mp)
  224 {
  225     return mp->mnt_data;
  226 }
  227 
  228 static __inline int
  229 fsess_isimpl(struct mount *mp, int opcode)
  230 {
  231     struct fuse_data *data = fuse_get_mpdata(mp);
  232 
  233     return (data->notimpl & (1ULL << opcode)) == 0;
  234 
  235 }
  236 static __inline void
  237 fsess_set_notimpl(struct mount *mp, int opcode)
  238 {
  239     struct fuse_data *data = fuse_get_mpdata(mp);
  240 
  241     data->notimpl |= (1ULL << opcode);
  242 }
  243 
  244 static __inline int
  245 fsess_opt_datacache(struct mount *mp)
  246 {
  247     struct fuse_data *data = fuse_get_mpdata(mp);
  248 
  249     return (fuse_data_cache_enable ||
  250         (data->dataflags & FSESS_NO_DATACACHE) == 0);
  251 }
  252 
  253 static __inline int
  254 fsess_opt_mmap(struct mount *mp)
  255 {
  256     struct fuse_data *data = fuse_get_mpdata(mp);
  257 
  258     if (!(fuse_mmap_enable && fuse_data_cache_enable))
  259         return 0;
  260     return ((data->dataflags & (FSESS_NO_DATACACHE | FSESS_NO_MMAP)) == 0);
  261 }
  262 
  263 static __inline int
  264 fsess_opt_brokenio(struct mount *mp)
  265 {
  266     struct fuse_data *data = fuse_get_mpdata(mp);
  267 
  268     return (fuse_fix_broken_io || (data->dataflags & FSESS_BROKENIO));
  269 }
  270 
  271 static __inline__
  272 void
  273 fuse_ms_push(struct fuse_ticket *ftick)
  274 {
  275     DEBUGX(FUSE_DEBUG_IPC, "ftick=%p refcount=%d\n",
  276         ftick, ftick->tk_refcount + 1);
  277     mtx_assert(&ftick->tk_data->ms_mtx, MA_OWNED);
  278     refcount_acquire(&ftick->tk_refcount);
  279     STAILQ_INSERT_TAIL(&ftick->tk_data->ms_head, ftick, tk_ms_link);
  280 }
  281 
  282 static __inline__
  283 struct fuse_ticket *
  284 fuse_ms_pop(struct fuse_data *data)
  285 {
  286     struct fuse_ticket *ftick = NULL;
  287 
  288     mtx_assert(&data->ms_mtx, MA_OWNED);
  289 
  290     if ((ftick = STAILQ_FIRST(&data->ms_head))) {
  291         STAILQ_REMOVE_HEAD(&data->ms_head, tk_ms_link);
  292 #ifdef INVARIANTS
  293         ftick->tk_ms_link.stqe_next = NULL;
  294 #endif
  295     }
  296     DEBUGX(FUSE_DEBUG_IPC, "ftick=%p refcount=%d\n",
  297         ftick, ftick ? ftick->tk_refcount : -1);
  298 
  299     return ftick;
  300 }
  301 
  302 static __inline__
  303 void
  304 fuse_aw_push(struct fuse_ticket *ftick)
  305 {
  306     DEBUGX(FUSE_DEBUG_IPC, "ftick=%p refcount=%d\n",
  307         ftick, ftick->tk_refcount + 1);
  308     mtx_assert(&ftick->tk_data->aw_mtx, MA_OWNED);
  309     refcount_acquire(&ftick->tk_refcount);
  310     TAILQ_INSERT_TAIL(&ftick->tk_data->aw_head, ftick, tk_aw_link);
  311 }
  312 
  313 static __inline__
  314 void
  315 fuse_aw_remove(struct fuse_ticket *ftick)
  316 {
  317     DEBUGX(FUSE_DEBUG_IPC, "ftick=%p refcount=%d\n",
  318         ftick, ftick->tk_refcount);
  319     mtx_assert(&ftick->tk_data->aw_mtx, MA_OWNED);
  320     TAILQ_REMOVE(&ftick->tk_data->aw_head, ftick, tk_aw_link);
  321 #ifdef INVARIANTS
  322     ftick->tk_aw_link.tqe_next = NULL;
  323     ftick->tk_aw_link.tqe_prev = NULL;
  324 #endif
  325 }
  326 
  327 static __inline__
  328 struct fuse_ticket *
  329 fuse_aw_pop(struct fuse_data *data)
  330 {
  331     struct fuse_ticket *ftick = NULL;
  332 
  333     mtx_assert(&data->aw_mtx, MA_OWNED);
  334 
  335     if ((ftick = TAILQ_FIRST(&data->aw_head))) {
  336         fuse_aw_remove(ftick);
  337     }
  338     DEBUGX(FUSE_DEBUG_IPC, "ftick=%p refcount=%d\n",
  339         ftick, ftick ? ftick->tk_refcount : -1);
  340 
  341     return ftick;
  342 }
  343 
  344 struct fuse_ticket *fuse_ticket_fetch(struct fuse_data *data);
  345 int fuse_ticket_drop(struct fuse_ticket *ftick);
  346 void fuse_insert_callback(struct fuse_ticket *ftick, fuse_handler_t *handler);
  347 void fuse_insert_message(struct fuse_ticket *ftick);
  348 
  349 static __inline__
  350 int
  351 fuse_libabi_geq(struct fuse_data *data, uint32_t abi_maj, uint32_t abi_min)
  352 {
  353     return (data->fuse_libabi_major > abi_maj ||
  354             (data->fuse_libabi_major == abi_maj && data->fuse_libabi_minor >= abi_min));
  355 }
  356 
  357 struct fuse_data *fdata_alloc(struct cdev *dev, struct ucred *cred);
  358 void fdata_trydestroy(struct fuse_data *data);
  359 void fdata_set_dead(struct fuse_data *data);
  360 
  361 static __inline__
  362 int
  363 fdata_get_dead(struct fuse_data *data)
  364 {
  365     return (data->dataflags & FSESS_DEAD);
  366 }
  367 
  368 struct fuse_dispatcher {
  369 
  370     struct fuse_ticket    *tick;
  371     struct fuse_in_header *finh;
  372 
  373     void    *indata;
  374     size_t   iosize;
  375     uint64_t nodeid;
  376     int      answ_stat;
  377     void    *answ;
  378 };
  379 
  380 static __inline__
  381 void
  382 fdisp_init(struct fuse_dispatcher *fdisp, size_t iosize)
  383 {
  384     DEBUGX(FUSE_DEBUG_IPC, "-> fdisp=%p, iosize=%zx\n", fdisp, iosize);
  385     fdisp->iosize = iosize;
  386     fdisp->tick = NULL;
  387 }
  388 
  389 static __inline__
  390 void
  391 fdisp_destroy(struct fuse_dispatcher *fdisp)
  392 {
  393     DEBUGX(FUSE_DEBUG_IPC, "-> fdisp=%p, ftick=%p\n", fdisp, fdisp->tick);
  394     fuse_ticket_drop(fdisp->tick);
  395 #ifdef INVARIANTS
  396     fdisp->tick = NULL;
  397 #endif
  398 }
  399 
  400 void fdisp_make(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  401                 struct mount *mp, uint64_t nid, struct thread *td,
  402                 struct ucred *cred);
  403 
  404 void fdisp_make_pid(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  405                     struct mount *mp, uint64_t nid, pid_t pid,
  406                     struct ucred *cred);
  407 
  408 void fdisp_make_vp(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  409                    struct vnode *vp, struct thread *td, struct ucred *cred);
  410 
  411 int  fdisp_wait_answ(struct fuse_dispatcher *fdip);
  412 
  413 static __inline__
  414 int
  415 fdisp_simple_putget_vp(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  416                     struct vnode *vp, struct thread *td, struct ucred *cred)
  417 {
  418     DEBUGX(FUSE_DEBUG_IPC, "-> fdip=%p, opcode=%d, vp=%p\n", fdip, op, vp);
  419     fdisp_make_vp(fdip, op, vp, td, cred);
  420     return fdisp_wait_answ(fdip);
  421 }
  422 
  423 #endif /* _FUSE_IPC_H_ */

Cache object: 108225365b30973f3113369ce1dc5d11


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.