summaryrefslogtreecommitdiff
path: root/kernel/fuse_queue.h
blob: 5a0b8d36c987e84276b3892c88cb7cd47317ff38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */
#ifndef	_FUSE_QUEUE_H
#define	_FUSE_QUEUE_H
#include <sys/int_types.h>
#include <sys/cred.h>
#include "fuse.h"

#ifdef	__cplusplus
extern "C" {
#endif


#define	FUSE_SESSION_MUTEX_LOCK(se)	mutex_enter(&((se)->session_mutx))
#define	FUSE_SESSION_MUTEX_UNLOCK(se)	mutex_exit(&((se)->session_mutx))

#define	FUSE_MSG_MUTEX_LOCK(x)	mutex_enter(& x->fmn_mutx)
#define	FUSE_MSG_MUTEX_UNLOCK(x)	mutex_exit(& x->fmn_mutx)

/*
 * TODO: create an array of session each array element representing a minor
 * device
 */

/* session is a connection between a mount point and a minor device */
typedef struct fuse_session
{
	kmutex_t	session_mutx;
	ksema_t		session_sema; /* devops read sleeps over it */
	list_t		msg_list;  /* message awaiting service rests here */
	avl_tree_t	avl_cache; /* nodeid used to track associated vnode */
	minor_t		minor; /* Minor number associated with this session */
	uint32_t	state;
	uint64_t	unique; /* msg id used between lib and kernel module */
	cred_t		*usercred;  /* Credentials passed by fuse library */
	uint32_t	max_write;  /* Max Write value set by fuse lib */
	vfs_t		*vfs;
	uint32_t	mounted:1;
} fuse_session_t;


#define	FUSE_MAX_SESSIONS 1024

fuse_session_t *fuse_minor_get_session(minor_t ndx);
minor_t fuse_session_get_minor(fuse_session_t *se);

fuse_session_t *fuse_alloc_session();
void fuse_free_session(fuse_session_t *se);

void fuse_init_session(fuse_session_t *se);
void fuse_deinit_session(fuse_session_t *se);

void fuse_session_set_cred(fuse_session_t *se, cred_t *cr);
void fuse_session_set_vfs(fuse_session_t *se, vfs_t *vfs);

void fuse_session_umount(fuse_session_t *se);

typedef struct fuse_avl_cache_node {
	uint64_t facn_nodeid;
	uint64_t par_nodeid;
	vnode_t	*facn_vnode_p;
	char *name;
	unsigned short namelen;
	avl_node_t facn_cache_node;
} fuse_avl_cache_node_t;

#define	FUSE_MAX_MSG 8192

typedef struct fuse_req_data {
	char		frd_buf[FUSE_MAX_MSG];
	uint32_t	frd_cur_offset;
} fuse_req_data_t;

#define	FUSE_MSG_STATE_INIT  0
#define	FUSE_MSG_STATE_QUEUE 2
#define	FUSE_MSG_STATE_READ  3
#define	FUSE_MSG_STATE_WRITE  4
#define	FUSE_MSG_STATE_SIG  5
#define	FUSE_MSG_STATE_DONE  6

typedef struct fuse_msg_node fuse_msg_node_t;

struct fuse_msg_node
{
	list_node_t	fmn_link;
	ksema_t		fmn_sema;
	kcondvar_t	fmn_cv;
	kmutex_t	fmn_mutx;
	int		fmn_state;
	uint64_t	fmn_unique;  /* identifies a unique message */
	/* Message interchange struct between FUSE Kernel and FUSE lib. */
	fuse_req_data_t	fmn_req;
	void (*frd_on_request_complete)(fuse_session_t *ses_p,
	    fuse_msg_node_t *msg_p);
	struct fuse_data_in ipdata;  /* Data passed to the fuse lib */
	struct fuse_data_out opdata; /* Data received back from the fuse lib */
};

void fuse_queue_request_nowait(fuse_session_t *se, fuse_msg_node_t *req);
int  fuse_queue_request_wait(fuse_session_t *se, fuse_msg_node_t *req_p);

fuse_msg_node_t *fuse_alloc_msg();
void fuse_free_msg(fuse_msg_node_t *msgp);

uint64_t fuse_bake_cookie();

void fuse_avl_cache_node_destroy(fuse_avl_cache_node_t *node);
fuse_avl_cache_node_t *fuse_avl_cache_node_create(vnode_t *np, uint64_t inode,
    uint64_t par_nodeid, unsigned short namelen, char *name);
fuse_msg_node_t *fuse_setup_message(size_t argsize, enum fuse_opcode op,
    uint64_t nodeid, cred_t *credp, uint64_t unique);

#ifdef	__cplusplus
}
#endif
#endif /* _FUSE_QUEUE_H */