2
0

codir.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * 9p backend
  3. *
  4. * Copyright IBM, Corp. 2011
  5. *
  6. * Authors:
  7. * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2. See
  10. * the COPYING file in the top-level directory.
  11. *
  12. */
  13. #include "qemu/osdep.h"
  14. #include "fsdev/qemu-fsdev.h"
  15. #include "qemu/thread.h"
  16. #include "qemu/coroutine.h"
  17. #include "qemu/main-loop.h"
  18. #include "coth.h"
  19. int coroutine_fn v9fs_co_readdir(V9fsPDU *pdu, V9fsFidState *fidp,
  20. struct dirent **dent)
  21. {
  22. int err;
  23. V9fsState *s = pdu->s;
  24. if (v9fs_request_cancelled(pdu)) {
  25. return -EINTR;
  26. }
  27. v9fs_co_run_in_worker(
  28. {
  29. struct dirent *entry;
  30. errno = 0;
  31. entry = s->ops->readdir(&s->ctx, &fidp->fs);
  32. if (!entry && errno) {
  33. err = -errno;
  34. } else {
  35. *dent = entry;
  36. err = 0;
  37. }
  38. });
  39. return err;
  40. }
  41. off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
  42. {
  43. off_t err;
  44. V9fsState *s = pdu->s;
  45. if (v9fs_request_cancelled(pdu)) {
  46. return -EINTR;
  47. }
  48. v9fs_co_run_in_worker(
  49. {
  50. err = s->ops->telldir(&s->ctx, &fidp->fs);
  51. if (err < 0) {
  52. err = -errno;
  53. }
  54. });
  55. return err;
  56. }
  57. void coroutine_fn v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp,
  58. off_t offset)
  59. {
  60. V9fsState *s = pdu->s;
  61. if (v9fs_request_cancelled(pdu)) {
  62. return;
  63. }
  64. v9fs_co_run_in_worker(
  65. {
  66. s->ops->seekdir(&s->ctx, &fidp->fs, offset);
  67. });
  68. }
  69. void coroutine_fn v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
  70. {
  71. V9fsState *s = pdu->s;
  72. if (v9fs_request_cancelled(pdu)) {
  73. return;
  74. }
  75. v9fs_co_run_in_worker(
  76. {
  77. s->ops->rewinddir(&s->ctx, &fidp->fs);
  78. });
  79. }
  80. int coroutine_fn v9fs_co_mkdir(V9fsPDU *pdu, V9fsFidState *fidp,
  81. V9fsString *name, mode_t mode, uid_t uid,
  82. gid_t gid, struct stat *stbuf)
  83. {
  84. int err;
  85. FsCred cred;
  86. V9fsPath path;
  87. V9fsState *s = pdu->s;
  88. if (v9fs_request_cancelled(pdu)) {
  89. return -EINTR;
  90. }
  91. cred_init(&cred);
  92. cred.fc_mode = mode;
  93. cred.fc_uid = uid;
  94. cred.fc_gid = gid;
  95. v9fs_path_read_lock(s);
  96. v9fs_co_run_in_worker(
  97. {
  98. err = s->ops->mkdir(&s->ctx, &fidp->path, name->data, &cred);
  99. if (err < 0) {
  100. err = -errno;
  101. } else {
  102. v9fs_path_init(&path);
  103. err = v9fs_name_to_path(s, &fidp->path, name->data, &path);
  104. if (!err) {
  105. err = s->ops->lstat(&s->ctx, &path, stbuf);
  106. if (err < 0) {
  107. err = -errno;
  108. }
  109. }
  110. v9fs_path_free(&path);
  111. }
  112. });
  113. v9fs_path_unlock(s);
  114. return err;
  115. }
  116. int coroutine_fn v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
  117. {
  118. int err;
  119. V9fsState *s = pdu->s;
  120. if (v9fs_request_cancelled(pdu)) {
  121. return -EINTR;
  122. }
  123. v9fs_path_read_lock(s);
  124. v9fs_co_run_in_worker(
  125. {
  126. err = s->ops->opendir(&s->ctx, &fidp->path, &fidp->fs);
  127. if (err < 0) {
  128. err = -errno;
  129. } else {
  130. err = 0;
  131. }
  132. });
  133. v9fs_path_unlock(s);
  134. if (!err) {
  135. total_open_fd++;
  136. if (total_open_fd > open_fd_hw) {
  137. v9fs_reclaim_fd(pdu);
  138. }
  139. }
  140. return err;
  141. }
  142. int coroutine_fn v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs)
  143. {
  144. int err;
  145. V9fsState *s = pdu->s;
  146. if (v9fs_request_cancelled(pdu)) {
  147. return -EINTR;
  148. }
  149. v9fs_co_run_in_worker(
  150. {
  151. err = s->ops->closedir(&s->ctx, fs);
  152. if (err < 0) {
  153. err = -errno;
  154. }
  155. });
  156. if (!err) {
  157. total_open_fd--;
  158. }
  159. return err;
  160. }