PageRenderTime 28ms CodeModel.GetById 13ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 1ms

/core/10.5/fusefs/fuse_file.c

http://macfuse.googlecode.com/
C | 167 lines | 122 code | 27 blank | 18 comment | 20 complexity | 4df3a862d9d68e617439918508aab337 MD5 | raw file
  1/*
  2 * Copyright (C) 2006-2008 Google. All Rights Reserved.
  3 * Amit Singh <singh@>
  4 */
  5
  6#include "fuse.h"
  7#include "fuse_file.h"
  8#include "fuse_internal.h"
  9#include "fuse_ipc.h"
 10#include "fuse_node.h"
 11#include "fuse_sysctl.h"
 12
 13/*
 14 * Because of the vagaries of how a filehandle can be used, we try not to
 15 * be too smart in here (we try to be smart elsewhere). It is required that
 16 * you come in here only if you really do not have the said filehandle--else
 17 * we panic.
 18 */
 19int
 20fuse_filehandle_get(vnode_t       vp,
 21                    vfs_context_t context,
 22                    fufh_type_t   fufh_type,
 23                    int           mode)
 24{
 25    struct fuse_dispatcher  fdi;
 26    struct fuse_open_in    *foi;
 27    struct fuse_open_out   *foo;
 28    struct fuse_filehandle *fufh;
 29    struct fuse_vnode_data *fvdat = VTOFUD(vp);
 30
 31    int err    = 0;
 32    int isdir  = 0;
 33    int oflags = 0;
 34    int op     = FUSE_OPEN;
 35
 36    fuse_trace_printf("fuse_filehandle_get(vp=%p, fufh_type=%d, mode=%x)\n",
 37                      vp, fufh_type, mode);
 38
 39    fufh = &(fvdat->fufh[fufh_type]);
 40
 41    if (FUFH_IS_VALID(fufh)) {
 42        panic("MacFUSE: filehandle_get called despite valid fufh (type=%d)",
 43              fufh_type);
 44        /* NOTREACHED */
 45    }
 46
 47    /*
 48     * Note that this means we are effectively FILTERING OUT open() flags.
 49     */
 50    (void)mode;
 51    oflags = fuse_filehandle_xlate_to_oflags(fufh_type);
 52
 53    if (vnode_isdir(vp)) {
 54        isdir = 1;
 55        op = FUSE_OPENDIR;
 56        if (fufh_type != FUFH_RDONLY) {
 57            IOLog("MacFUSE: non-rdonly fufh requested for directory\n");
 58            fufh_type = FUFH_RDONLY;
 59        }
 60    }
 61
 62    fdisp_init(&fdi, sizeof(*foi));
 63    fdisp_make_vp(&fdi, op, vp, context);
 64
 65    if (vnode_islnk(vp) && (mode & O_SYMLINK)) {
 66        oflags |= O_SYMLINK;
 67    }
 68
 69    foi = fdi.indata;
 70    foi->flags = oflags;
 71
 72    FUSE_OSAddAtomic(1, (SInt32 *)&fuse_fh_upcall_count);
 73    if ((err = fdisp_wait_answ(&fdi))) {
 74#if M_MACFUSE_ENABLE_UNSUPPORTED
 75        const char *vname = vnode_getname(vp);
 76#endif /* M_MACFUSE_ENABLE_UNSUPPORTED */
 77        if (err == ENOENT) {
 78            /*
 79             * See comment in fuse_vnop_reclaim().
 80             */
 81            cache_purge(vp);
 82        }
 83#if M_MACFUSE_ENABLE_UNSUPPORTED
 84        IOLog("MacFUSE: filehandle_get: failed for %s "
 85              "(type=%d, err=%d, caller=%p)\n",
 86              (vname) ? vname : "?", fufh_type, err,
 87               __builtin_return_address(0));
 88        if (vname) {
 89            vnode_putname(vname);
 90        }
 91#endif /* M_MACFUSE_ENABLE_UNSUPPORTED */
 92        if (err == ENOENT) {
 93            fuse_internal_vnode_disappear(vp, context, REVOKE_SOFT);
 94        }
 95        return err;
 96    }
 97    FUSE_OSAddAtomic(1, (SInt32 *)&fuse_fh_current);
 98
 99    foo = fdi.answ;
100
101    fufh->fh_id = foo->fh;
102    fufh->open_count = 1;
103    fufh->open_flags = oflags;
104    fufh->fuse_open_flags = foo->open_flags;
105    fufh->aux_count = 0;
106    
107    fuse_ticket_drop(fdi.tick);
108
109    return 0;
110}
111
112int
113fuse_filehandle_put(vnode_t vp, vfs_context_t context, fufh_type_t fufh_type,
114                    fuse_op_waitfor_t waitfor)
115{
116    struct fuse_dispatcher  fdi;
117    struct fuse_release_in *fri;
118    struct fuse_vnode_data *fvdat = VTOFUD(vp);
119    struct fuse_filehandle *fufh  = NULL;
120
121    int err   = 0;
122    int isdir = 0;
123    int op    = FUSE_RELEASE;
124
125    fuse_trace_printf("fuse_filehandle_put(vp=%p, fufh_type=%d)\n",
126                      vp, fufh_type);
127
128    fufh = &(fvdat->fufh[fufh_type]);
129
130    if (FUFH_IS_VALID(fufh)) {
131        panic("MacFUSE: filehandle_put called on a valid fufh (type=%d)",
132              fufh_type);
133        /* NOTREACHED */
134    }
135
136    if (fuse_isdeadfs(vp)) {
137        goto out;
138    }
139
140    if (vnode_isdir(vp)) {
141        op = FUSE_RELEASEDIR;
142        isdir = 1;
143    }
144
145    fdisp_init(&fdi, sizeof(*fri));
146    fdisp_make_vp(&fdi, op, vp, context);
147    fri = fdi.indata;
148    fri->fh = fufh->fh_id;
149    fri->flags = fufh->open_flags;
150
151    if (waitfor == FUSE_OP_FOREGROUNDED) {
152        if ((err = fdisp_wait_answ(&fdi))) {
153            goto out;
154        } else {
155            fuse_ticket_drop(fdi.tick);
156        }
157    } else {
158        fuse_insert_callback(fdi.tick, NULL);
159        fuse_insert_message(fdi.tick);
160    }
161
162out:
163    FUSE_OSAddAtomic(-1, (SInt32 *)&fuse_fh_current);
164    fuse_invalidate_attr(vp);
165
166    return err;
167}