PageRenderTime 177ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 1ms

/core/10.5/fusefs/fuse_ipc.h

http://macfuse.googlecode.com/
C Header | 376 lines | 304 code | 64 blank | 8 comment | 4 complexity | a0799478e7c9b43b2b177441815ff22b MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. /*
  2. * Copyright (C) 2006-2008 Google. All Rights Reserved.
  3. * Amit Singh <singh@>
  4. */
  5. #ifndef _FUSE_IPC_H_
  6. #define _FUSE_IPC_H_
  7. #include <mach/mach_types.h>
  8. #include <sys/errno.h>
  9. #include <sys/mount.h>
  10. #include <sys/vnode.h>
  11. #include <sys/vnode_if.h>
  12. #include <sys/kernel_types.h>
  13. #include <sys/stat.h>
  14. #include <sys/dirent.h>
  15. #include <sys/uio.h>
  16. #include <sys/proc.h>
  17. #include <sys/vm.h>
  18. #include <sys/fcntl.h>
  19. #include <sys/select.h>
  20. #include <kern/assert.h>
  21. #include <libkern/libkern.h>
  22. #include <libkern/OSMalloc.h>
  23. #include <libkern/locks.h>
  24. #include "fuse.h"
  25. #include "fuse_device.h"
  26. #include "fuse_kludges.h"
  27. #include "fuse_locking.h"
  28. struct fuse_iov {
  29. void *base;
  30. size_t len;
  31. size_t allocated_size;
  32. ssize_t credit;
  33. };
  34. #define FUSE_DATA_LOCK_SHARED(d) fuse_lck_rw_lock_shared((d)->rwlock)
  35. #define FUSE_DATA_LOCK_EXCLUSIVE(d) fuse_lck_rw_lock_exclusive((d)->rwlock)
  36. #define FUSE_DATA_UNLOCK_SHARED(d) fuse_lck_rw_unlock_shared((d)->rwlock)
  37. #define FUSE_DATA_UNLOCK_EXCLUSIVE(d) fuse_lck_rw_unlock_exclusive((d)->rwlock)
  38. void fiov_init(struct fuse_iov *fiov, size_t size);
  39. void fiov_teardown(struct fuse_iov *fiov);
  40. void fiov_refresh(struct fuse_iov *fiov);
  41. void fiov_adjust(struct fuse_iov *fiov, size_t size);
  42. int fiov_adjust_canfail(struct fuse_iov *fiov, size_t size);
  43. #define FUSE_DIMALLOC(fiov, spc1, spc2, amnt) \
  44. do { \
  45. fiov_adjust(fiov, (sizeof(*(spc1)) + (amnt))); \
  46. (spc1) = (fiov)->base; \
  47. (spc2) = (char *)(fiov)->base + (sizeof(*(spc1))); \
  48. } while (0)
  49. #define FU_AT_LEAST(siz) max((size_t)(siz), (size_t)160)
  50. struct fuse_ticket;
  51. struct fuse_data;
  52. typedef int fuse_handler_t(struct fuse_ticket *ftick, uio_t uio);
  53. struct fuse_ticket {
  54. uint64_t tk_unique;
  55. struct fuse_data *tk_data;
  56. int tk_flag;
  57. uint32_t tk_age;
  58. STAILQ_ENTRY(fuse_ticket) tk_freetickets_link;
  59. TAILQ_ENTRY(fuse_ticket) tk_alltickets_link;
  60. struct fuse_iov tk_ms_fiov;
  61. void *tk_ms_bufdata;
  62. size_t tk_ms_bufsize;
  63. enum { FT_M_FIOV, FT_M_BUF } tk_ms_type;
  64. STAILQ_ENTRY(fuse_ticket) tk_ms_link;
  65. struct fuse_iov tk_aw_fiov;
  66. void *tk_aw_bufdata;
  67. size_t tk_aw_bufsize;
  68. enum { FT_A_FIOV, FT_A_BUF } tk_aw_type;
  69. struct fuse_out_header tk_aw_ohead;
  70. int tk_aw_errno;
  71. lck_mtx_t *tk_aw_mtx;
  72. fuse_handler_t *tk_aw_handler;
  73. TAILQ_ENTRY(fuse_ticket) tk_aw_link;
  74. };
  75. #define FT_ANSW 0x01 // request of ticket has already been answered
  76. #define FT_INVAL 0x02 // ticket is invalidated
  77. #define FT_DIRTY 0x04 // ticket has been used
  78. #define FT_KILLL 0x08 // ticket has been marked for death (KILLL => KILL_LATER)
  79. static __inline__
  80. struct fuse_iov *
  81. fticket_resp(struct fuse_ticket *ftick)
  82. {
  83. return &ftick->tk_aw_fiov;
  84. }
  85. static __inline__
  86. int
  87. fticket_answered(struct fuse_ticket *ftick)
  88. {
  89. return (ftick->tk_flag & FT_ANSW);
  90. }
  91. static __inline__
  92. void
  93. fticket_set_answered(struct fuse_ticket *ftick)
  94. {
  95. ftick->tk_flag |= FT_ANSW;
  96. }
  97. static __inline__
  98. void
  99. fticket_set_killl(struct fuse_ticket *ftick)
  100. {
  101. ftick->tk_flag |= FT_KILLL;
  102. }
  103. static __inline__
  104. enum fuse_opcode
  105. fticket_opcode(struct fuse_ticket *ftick)
  106. {
  107. return (((struct fuse_in_header *)(ftick->tk_ms_fiov.base))->opcode);
  108. }
  109. static __inline__
  110. void
  111. fticket_invalidate(struct fuse_ticket *ftick)
  112. {
  113. ftick->tk_flag |= FT_INVAL;
  114. }
  115. int fticket_pull(struct fuse_ticket *ftick, uio_t uio);
  116. enum mount_state { FM_NOTMOUNTED, FM_MOUNTED };
  117. struct fuse_data {
  118. fuse_device_t fdev;
  119. mount_t mp;
  120. vnode_t rootvp;
  121. enum mount_state mount_state;
  122. kauth_cred_t daemoncred;
  123. pid_t daemonpid;
  124. uint32_t dataflags; /* effective fuse_data flags */
  125. uint64_t mountaltflags; /* as-is copy of altflags */
  126. uint64_t noimplflags; /* not-implemented flags */
  127. #if M_MACFUSE_ENABLE_DSELECT
  128. struct fuse_selinfo d_rsel;
  129. #endif /* M_MACFUSE_ENABLE_DSELECT */
  130. lck_rw_t *rwlock;
  131. lck_mtx_t *ms_mtx;
  132. STAILQ_HEAD(, fuse_ticket) ms_head;
  133. lck_mtx_t *aw_mtx;
  134. TAILQ_HEAD(, fuse_ticket) aw_head;
  135. lck_mtx_t *ticket_mtx;
  136. STAILQ_HEAD(, fuse_ticket) freetickets_head;
  137. TAILQ_HEAD(, fuse_ticket) alltickets_head;
  138. uint32_t freeticket_counter;
  139. uint32_t deadticket_counter;
  140. uint64_t ticketer;
  141. #if M_MACFUSE_EXPLICIT_RENAME_LOCK
  142. lck_rw_t *rename_lock;
  143. #endif /* M_MACFUSE_EXPLICIT_RENAME_LOCK */
  144. uint32_t fuse_libabi_major;
  145. uint32_t fuse_libabi_minor;
  146. uint32_t max_write;
  147. uint32_t max_read;
  148. uint32_t blocksize;
  149. uint32_t iosize;
  150. uint32_t userkernel_bufsize;
  151. uint32_t fssubtype;
  152. char volname[MAXPATHLEN];
  153. uint32_t timeout_status;
  154. lck_mtx_t *timeout_mtx;
  155. struct timespec daemon_timeout;
  156. struct timespec *daemon_timeout_p;
  157. struct timespec init_timeout;
  158. };
  159. enum {
  160. FUSE_DAEMON_TIMEOUT_NONE = 0,
  161. FUSE_DAEMON_TIMEOUT_PROCESSING = 1,
  162. FUSE_DAEMON_TIMEOUT_DEAD = 2,
  163. };
  164. /* Not-Implemented Bits */
  165. #define FSESS_NOIMPLBIT(MSG) (1ULL << FUSE_##MSG)
  166. #define FSESS_DEAD 0x00000001 // session is to be closed
  167. #define FSESS_OPENED 0x00000002 // session device has been opened
  168. #define FSESS_INITED 0x00000004 // session has been inited
  169. #define FSESS_UNCONSCIOUS 0x00000008 // session is temporarily gone
  170. #define FSESS_ALLOW_OTHER 0x00000010
  171. #define FSESS_ALLOW_ROOT 0x00000020
  172. #define FSESS_AUTO_XATTR 0x00000040
  173. #define FSESS_DEFAULT_PERMISSIONS 0x00000080
  174. #define FSESS_DEFER_PERMISSIONS 0x00000100
  175. #define FSESS_DIRECT_IO 0x00000200
  176. #define FSESS_EXTENDED_SECURITY 0x00000400
  177. #define FSESS_JAIL_SYMLINKS 0x00000800
  178. #define FSESS_KILL_ON_UNMOUNT 0x00001000
  179. #define FSESS_LOCALVOL 0x00002000
  180. #define FSESS_NEGATIVE_VNCACHE 0x00004000
  181. #define FSESS_NO_ALERTS 0x00008000
  182. #define FSESS_NO_APPLEDOUBLE 0x00010000
  183. #define FSESS_NO_APPLEXATTR 0x00020000
  184. #define FSESS_NO_ATTRCACHE 0x00040000
  185. #define FSESS_NO_READAHEAD 0x00080000
  186. #define FSESS_NO_SYNCONCLOSE 0x00100000
  187. #define FSESS_NO_SYNCWRITES 0x00200000
  188. #define FSESS_NO_UBC 0x00400000
  189. #define FSESS_NO_VNCACHE 0x00800000
  190. #define FSESS_CASE_INSENSITIVE 0x01000000
  191. #define FSESS_VOL_RENAME 0x02000000
  192. #define FSESS_XTIMES 0x04000000
  193. #define FSESS_AUTO_CACHE 0x08000000
  194. #define FSESS_NATIVE_XATTR 0x10000000
  195. #define FSESS_SPARSE 0x20000000
  196. static __inline__
  197. struct fuse_data *
  198. fuse_get_mpdata(mount_t mp)
  199. {
  200. /*
  201. * data->mount_state should be FM_MOUNTED for it to be valid
  202. */
  203. return (struct fuse_data *)vfs_fsprivate(mp);
  204. }
  205. static __inline__
  206. void
  207. fuse_ms_push(struct fuse_ticket *ftick)
  208. {
  209. STAILQ_INSERT_TAIL(&ftick->tk_data->ms_head, ftick, tk_ms_link);
  210. }
  211. static __inline__
  212. void
  213. fuse_ms_push_head(struct fuse_ticket *ftick)
  214. {
  215. STAILQ_INSERT_HEAD(&ftick->tk_data->ms_head, ftick, tk_ms_link);
  216. }
  217. static __inline__
  218. struct fuse_ticket *
  219. fuse_ms_pop(struct fuse_data *data)
  220. {
  221. struct fuse_ticket *ftick = NULL;
  222. if ((ftick = STAILQ_FIRST(&data->ms_head))) {
  223. STAILQ_REMOVE_HEAD(&data->ms_head, tk_ms_link);
  224. }
  225. return ftick;
  226. }
  227. static __inline__
  228. void
  229. fuse_aw_push(struct fuse_ticket *ftick)
  230. {
  231. TAILQ_INSERT_TAIL(&ftick->tk_data->aw_head, ftick, tk_aw_link);
  232. }
  233. static __inline__
  234. void
  235. fuse_aw_remove(struct fuse_ticket *ftick)
  236. {
  237. TAILQ_REMOVE(&ftick->tk_data->aw_head, ftick, tk_aw_link);
  238. }
  239. static __inline__
  240. struct fuse_ticket *
  241. fuse_aw_pop(struct fuse_data *data)
  242. {
  243. struct fuse_ticket *ftick = NULL;
  244. if ((ftick = TAILQ_FIRST(&data->aw_head))) {
  245. fuse_aw_remove(ftick);
  246. }
  247. return ftick;
  248. }
  249. struct fuse_ticket *fuse_ticket_fetch(struct fuse_data *data);
  250. void fuse_ticket_drop(struct fuse_ticket *ftick);
  251. void fuse_ticket_drop_invalid(struct fuse_ticket *ftick);
  252. void fuse_ticket_kill(struct fuse_ticket *ftick);
  253. void fuse_insert_callback(struct fuse_ticket *ftick, fuse_handler_t *handler);
  254. void fuse_insert_message(struct fuse_ticket *ftick);
  255. void fuse_insert_message_head(struct fuse_ticket *ftick);
  256. static __inline__
  257. int
  258. fuse_libabi_geq(struct fuse_data *data, uint32_t abi_maj, uint32_t abi_min)
  259. {
  260. return (data->fuse_libabi_major > abi_maj ||
  261. (data->fuse_libabi_major == abi_maj &&
  262. data->fuse_libabi_minor >= abi_min));
  263. }
  264. struct fuse_data *fdata_alloc(struct proc *p);
  265. void fdata_destroy(struct fuse_data *data);
  266. int fdata_dead_get(struct fuse_data *data);
  267. void fdata_set_dead(struct fuse_data *data);
  268. struct fuse_dispatcher {
  269. struct fuse_ticket *tick;
  270. struct fuse_in_header *finh;
  271. void *indata;
  272. size_t iosize;
  273. uint64_t nodeid;
  274. int answ_stat;
  275. void *answ;
  276. };
  277. static __inline__
  278. void
  279. fdisp_init(struct fuse_dispatcher *fdisp, size_t iosize)
  280. {
  281. fdisp->iosize = iosize;
  282. fdisp->tick = NULL;
  283. }
  284. void fdisp_make(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  285. mount_t mp, uint64_t nid, vfs_context_t context);
  286. int fdisp_make_canfail(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  287. mount_t mp, uint64_t nid, vfs_context_t context);
  288. void fdisp_make_vp(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  289. vnode_t vp, vfs_context_t context);
  290. int fdisp_make_vp_canfail(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  291. vnode_t vp, vfs_context_t context);
  292. int fdisp_wait_answ(struct fuse_dispatcher *fdip);
  293. static __inline__
  294. int
  295. fdisp_simple_putget_vp(struct fuse_dispatcher *fdip, enum fuse_opcode op,
  296. vnode_t vp, vfs_context_t context)
  297. {
  298. fdisp_init(fdip, 0);
  299. fdisp_make_vp(fdip, op, vp, context);
  300. return fdisp_wait_answ(fdip);
  301. }
  302. static __inline__
  303. int
  304. fdisp_simple_vfs_getattr(struct fuse_dispatcher *fdip,
  305. mount_t mp,
  306. vfs_context_t context)
  307. {
  308. fdisp_init(fdip, 0);
  309. fdisp_make(fdip, FUSE_STATFS, mp, FUSE_ROOT_ID, context);
  310. return fdisp_wait_answ(fdip);
  311. }
  312. #endif /* _FUSE_IPC_H_ */