503-yaffs-3.12-convert-readdir-to-iterate.patch 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. --- a/fs/yaffs2/yaffs_vfs.c
  2. +++ b/fs/yaffs2/yaffs_vfs.c
  3. @@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
  4. /*-----------------------------------------------------------------*/
  5. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
  6. +static int yaffs_readdir(struct file *file, struct dir_context *ctx)
  7. +{
  8. + struct yaffs_obj *obj;
  9. + struct yaffs_dev *dev;
  10. + struct yaffs_search_context *sc;
  11. + struct inode *inode = file->f_dentry->d_inode;
  12. + unsigned long offset, curoffs;
  13. + struct yaffs_obj *l;
  14. + int ret_val = 0;
  15. +
  16. + char name[YAFFS_MAX_NAME_LENGTH + 1];
  17. +
  18. + obj = yaffs_dentry_to_obj(file->f_dentry);
  19. + dev = obj->my_dev;
  20. +
  21. + yaffs_gross_lock(dev);
  22. +
  23. + yaffs_dev_to_lc(dev)->readdir_process = current;
  24. +
  25. + offset = ctx->pos;
  26. +
  27. + sc = yaffs_new_search(obj);
  28. + if (!sc) {
  29. + ret_val = -ENOMEM;
  30. + goto out;
  31. + }
  32. +
  33. + yaffs_trace(YAFFS_TRACE_OS,
  34. + "yaffs_readdir: starting at %d", (int)offset);
  35. +
  36. + if (offset == 0) {
  37. + yaffs_trace(YAFFS_TRACE_OS,
  38. + "yaffs_readdir: entry . ino %d",
  39. + (int)inode->i_ino);
  40. + yaffs_gross_unlock(dev);
  41. + if (!dir_emit_dot(file, ctx)) {
  42. + yaffs_gross_lock(dev);
  43. + goto out;
  44. + }
  45. + yaffs_gross_lock(dev);
  46. + offset++;
  47. + ctx->pos++;
  48. + }
  49. + if (offset == 1) {
  50. + yaffs_trace(YAFFS_TRACE_OS,
  51. + "yaffs_readdir: entry .. ino %d",
  52. + (int)file->f_dentry->d_parent->d_inode->i_ino);
  53. + yaffs_gross_unlock(dev);
  54. + if (!dir_emit_dotdot(file, ctx)) {
  55. + yaffs_gross_lock(dev);
  56. + goto out;
  57. + }
  58. + yaffs_gross_lock(dev);
  59. + offset++;
  60. + ctx->pos++;
  61. + }
  62. +
  63. + curoffs = 1;
  64. +
  65. + /* If the directory has changed since the open or last call to
  66. + readdir, rewind to after the 2 canned entries. */
  67. + if (file->f_version != inode->i_version) {
  68. + offset = 2;
  69. + ctx->pos = offset;
  70. + file->f_version = inode->i_version;
  71. + }
  72. +
  73. + while (sc->next_return) {
  74. + curoffs++;
  75. + l = sc->next_return;
  76. + if (curoffs >= offset) {
  77. + int this_inode = yaffs_get_obj_inode(l);
  78. + int this_type = yaffs_get_obj_type(l);
  79. +
  80. + yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
  81. + yaffs_trace(YAFFS_TRACE_OS,
  82. + "yaffs_readdir: %s inode %d",
  83. + name, yaffs_get_obj_inode(l));
  84. +
  85. + yaffs_gross_unlock(dev);
  86. +
  87. + if (!dir_emit(ctx, name, strlen(name),
  88. + this_inode, this_type) < 0) {
  89. + yaffs_gross_lock(dev);
  90. + goto out;
  91. + }
  92. +
  93. + yaffs_gross_lock(dev);
  94. +
  95. + offset++;
  96. + ctx->pos++;
  97. + }
  98. + yaffs_search_advance(sc);
  99. + }
  100. +
  101. +out:
  102. + yaffs_search_end(sc);
  103. + yaffs_dev_to_lc(dev)->readdir_process = NULL;
  104. + yaffs_gross_unlock(dev);
  105. +
  106. + return ret_val;
  107. +}
  108. +#else
  109. static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
  110. {
  111. struct yaffs_obj *obj;
  112. @@ -1807,10 +1911,15 @@ out:
  113. return ret_val;
  114. }
  115. +#endif
  116. static const struct file_operations yaffs_dir_operations = {
  117. .read = generic_read_dir,
  118. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
  119. + .iterate = yaffs_readdir,
  120. +#else
  121. .readdir = yaffs_readdir,
  122. +#endif
  123. .fsync = yaffs_sync_object,
  124. .llseek = generic_file_llseek,
  125. };