dir.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. RAWFS: Raw file system for NAND flash
  3. Copyright (C) 2012-2015 Perry Hsu <perry.hsu@mediatek.com>"
  4. This program can be distributed under the terms of the GNU GPL.
  5. See the file COPYING.
  6. */
  7. #if defined(CONFIG_MT_ENG_BUILD)
  8. #define DEBUG 1
  9. #endif
  10. #include <linux/module.h>
  11. #include <linux/fs.h>
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/slab.h>
  15. #include <linux/crc32.h>
  16. #include "rawfs.h"
  17. int rawfs_readdir(struct file *filp, struct dir_context *ctx)
  18. {
  19. struct inode *inode = filp->f_path.dentry->d_inode;
  20. struct dentry *dentry = filp->f_path.dentry;
  21. struct super_block *sb = inode->i_sb;
  22. struct rawfs_sb_info *sbi = RAWFS_SB(sb);
  23. int total_cnt = 0; /* Total entries we found in hlist */
  24. loff_t cpos;
  25. cpos = ctx->pos;
  26. /* Read dir will execute twice. */
  27. if (inode->i_ino == RAWFS_ROOT_INO)
  28. RAWFS_PRINT(RAWFS_DBG_DIR, "rawfs_readdir, root, pos %lld\n", cpos);
  29. else
  30. RAWFS_PRINT(RAWFS_DBG_DIR, "rawfs_readdir, %s, i_id %X, i_ino %X, pos %lld\n",
  31. dentry->d_name.name, RAWFS_I(inode)->i_id, (unsigned)inode->i_ino, cpos);
  32. switch (cpos) {
  33. case 0:
  34. if (!dir_emit_dot(filp, ctx))
  35. break;
  36. ctx->pos++;
  37. cpos++;
  38. /* fallthrough */
  39. case 1:
  40. if (!dir_emit_dotdot(filp, ctx))
  41. break;
  42. ctx->pos++;
  43. cpos++;
  44. /* fallthrough */
  45. default:
  46. {
  47. struct rawfs_file_list_entry *entry;
  48. struct list_head *lists[2];
  49. int i;
  50. lists[0] = &sbi->folder_list;
  51. lists[1] = &sbi->file_list;
  52. mutex_lock(&sbi->file_list_lock);
  53. for (i = 0; i < 2; i++) {
  54. list_for_each_entry(entry, lists[i], list) {
  55. int name_len;
  56. /* Matching sub-directory */
  57. if (entry->file_info.i_parent_folder_id !=
  58. RAWFS_I(dentry->d_inode)->i_id) {
  59. RAWFS_PRINT(RAWFS_DBG_DIR,
  60. "readdir: skip %s, parent folder id %X, target folder %X\n",
  61. entry->file_info.i_name,
  62. entry->file_info.i_parent_folder_id,
  63. RAWFS_I(dentry->d_inode)->i_id);
  64. continue;
  65. }
  66. total_cnt++;
  67. if ((total_cnt+2) <= cpos) { /* skip first N + 2 (. & ..)
  68. entiries, if cpos doesn't start from zero */
  69. RAWFS_PRINT(RAWFS_DBG_DIR,
  70. "readdir: cpos=%lld, total cnt=%d, %s\n", cpos, total_cnt,
  71. entry->file_info.i_name);
  72. continue;
  73. }
  74. name_len = strlen(entry->file_info.i_name);
  75. if (!dir_emit(ctx,
  76. entry->file_info.i_name,
  77. name_len,
  78. entry->file_info.i_id,
  79. (S_ISDIR(entry->file_info.i_mode)?DT_DIR:DT_REG)))
  80. goto out;
  81. ctx->pos++;
  82. cpos++;
  83. }
  84. }
  85. }
  86. out:
  87. mutex_unlock(&sbi->file_list_lock);
  88. break;
  89. }
  90. return 0;
  91. }
  92. EXPORT_SYMBOL_GPL(rawfs_readdir);
  93. int rawfs_file_sync(struct file *file, loff_t start, loff_t end,
  94. int datasync)
  95. {
  96. RAWFS_PRINT(RAWFS_DBG_DIR, "fsync, i_ino %ld\n",
  97. file->f_path.dentry->d_inode->i_ino);
  98. return 0;
  99. }
  100. EXPORT_SYMBOL_GPL(rawfs_file_sync);
  101. MODULE_AUTHOR("Perry Hsu <perry.hsu@mediatek.com>");
  102. MODULE_DESCRIPTION("RAW file system for NAND flash");
  103. MODULE_LICENSE("GPL");