dfs_mqueue.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-07-04 zhkag first Version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include <dfs_file.h>
  13. #include "dfs_mqueue.h"
  14. static rt_list_t _mqueue_file_list = RT_LIST_OBJECT_INIT(_mqueue_file_list);
  15. struct rt_spinlock mqueue_lock;
  16. void dfs_mqueue_insert_after(rt_list_t *n) {
  17. rt_spin_lock(&mqueue_lock);
  18. rt_list_insert_after(&(_mqueue_file_list), n);
  19. rt_spin_unlock(&mqueue_lock);
  20. }
  21. struct mqueue_file *dfs_mqueue_lookup(const char *path, rt_size_t *size) {
  22. struct mqueue_file *file;
  23. rt_list_t *node;
  24. rt_spin_lock(&mqueue_lock);
  25. rt_list_for_each(node, &_mqueue_file_list) {
  26. file = rt_list_entry(node, struct mqueue_file, list);
  27. if (rt_strncmp(file->name, path, RT_NAME_MAX) == 0) {
  28. *size = file->size;
  29. rt_spin_unlock(&mqueue_lock);
  30. return file;
  31. }
  32. }
  33. rt_spin_unlock(&mqueue_lock);
  34. return RT_NULL;
  35. }
  36. int dfs_mqueue_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) {
  37. return RT_EOK;
  38. }
  39. int dfs_mqueue_unmount(struct dfs_filesystem *fs) { return RT_EOK; }
  40. int dfs_mqueue_statfs(struct dfs_filesystem *fs, struct statfs *buf) { return RT_EOK; }
  41. int dfs_mqueue_close(struct dfs_file *file) { return RT_EOK; }
  42. int dfs_mqueue_open(struct dfs_file *file) {
  43. rt_size_t size;
  44. if ((file->vnode->path[0] == '/') && (file->vnode->path[1] == '\0'))
  45. return 0;
  46. if (file->flags & O_DIRECTORY)
  47. return -ENOENT;
  48. struct mqueue_file *mq_file;
  49. mq_file = dfs_mqueue_lookup(file->vnode->path + 1, &size);
  50. if (mq_file == RT_NULL && !(file->flags & O_CREAT))
  51. return -ENOENT;
  52. if (mq_file == RT_NULL) {
  53. mq_file = (struct mqueue_file *)rt_malloc(sizeof(struct mqueue_file));
  54. if (mq_file == RT_NULL) {
  55. return -ENFILE;
  56. }
  57. mq_file->msg_size = 8192;
  58. mq_file->max_msgs = 10;
  59. strncpy(mq_file->name, file->vnode->path + 1, RT_NAME_MAX);
  60. dfs_mqueue_insert_after(&(mq_file->list));
  61. }
  62. if (file->flags & O_CREAT) {
  63. rt_mq_t mq = rt_mq_create(file->vnode->path + 1, mq_file->msg_size, mq_file->max_msgs,
  64. RT_IPC_FLAG_FIFO);
  65. mq_file->data = (void *)mq;
  66. file->vnode->data = mq_file;
  67. file->vnode->size = 0;
  68. }
  69. return 0;
  70. }
  71. int dfs_mqueue_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) {
  72. st->st_dev = 0;
  73. st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
  74. st->st_size = 0;
  75. st->st_mtime = 0;
  76. return RT_EOK;
  77. }
  78. int dfs_mqueue_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count) {
  79. rt_size_t index, end;
  80. struct dirent *d;
  81. count = (count / sizeof(struct dirent));
  82. end = file->pos + count;
  83. index = 0;
  84. count = 0;
  85. struct mqueue_file *mq_file;
  86. rt_list_t *node;
  87. rt_spin_lock(&mqueue_lock);
  88. rt_list_for_each(node, &_mqueue_file_list) {
  89. if (index >= (rt_size_t)file->pos) {
  90. mq_file = rt_list_entry(node, struct mqueue_file, list);
  91. d = dirp + count;
  92. d->d_namlen = RT_NAME_MAX;
  93. d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
  94. rt_strncpy(d->d_name, mq_file->name, RT_NAME_MAX);
  95. count += 1;
  96. file->pos += 1;
  97. }
  98. index += 1;
  99. if (index >= end) {
  100. break;
  101. }
  102. }
  103. rt_spin_unlock(&mqueue_lock);
  104. return count * sizeof(struct dirent);
  105. }
  106. int dfs_mqueue_unlink(struct dfs_filesystem *fs, const char *path) {
  107. rt_size_t size;
  108. struct mqueue_file *mq_file;
  109. mq_file = dfs_mqueue_lookup(path + 1, &size);
  110. if (mq_file == RT_NULL)
  111. return -ENOENT;
  112. rt_list_remove(&(mq_file->list));
  113. if (mq_file->data != RT_NULL)
  114. rt_mq_delete((rt_mq_t)mq_file->data);
  115. rt_free(mq_file);
  116. return RT_EOK;
  117. }
  118. static const struct dfs_file_ops _mqueue_fops = {
  119. .open = dfs_mqueue_open,
  120. .close = dfs_mqueue_close,
  121. .getdents = dfs_mqueue_getdents,
  122. };
  123. static const struct dfs_filesystem_ops _mqueue = {
  124. .name = "mqueue",
  125. .flags = DFS_FS_FLAG_DEFAULT,
  126. .fops = &_mqueue_fops,
  127. .mount = dfs_mqueue_mount,
  128. .unmount = dfs_mqueue_unmount,
  129. .statfs = dfs_mqueue_statfs,
  130. .unlink = dfs_mqueue_unlink,
  131. .stat = dfs_mqueue_stat,
  132. };
  133. int dfs_mqueue_init(void) {
  134. /* register mqueue file system */
  135. dfs_register(&_mqueue);
  136. mkdir("/dev/mqueue", 0x777);
  137. if (dfs_mount(RT_NULL, "/dev/mqueue", "mqueue", 0, 0) != 0) {
  138. rt_kprintf("Dir /dev/mqueue mount failed!\n");
  139. }
  140. return 0;
  141. }
  142. INIT_ENV_EXPORT(dfs_mqueue_init);