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