Guest User

Untitled

a guest
Jun 23rd, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.25 KB | None | 0 0
  1. // ospfs_dir_readdir(filp, dirent, filldir)
  2. // This function is called when the kernel reads the contents of a directory
  3. // (i.e. when file_operations.readdir is called for the inode).
  4. //
  5. // Inputs: filp -- The 'struct file' structure correspoding to
  6. // the open directory.
  7. // The most important member is 'filp->f_pos', the
  8. // File POSition. This remembers how far into the
  9. // directory we are, so if the user calls 'readdir'
  10. // twice, we don't forget our position.
  11. // This function must update 'filp->f_pos'.
  12. // dirent -- Used to pass to 'filldir'.
  13. // filldir -- A pointer to a callback function.
  14. // This function should call 'filldir' once for each
  15. // directory entry, passing it six arguments:
  16. // (1) 'dirent'.
  17. // (2) The directory entry's name.
  18. // (3) The length of the directory entry's name.
  19. // (4) The 'f_pos' value corresponding to the directory entry.
  20. // (5) The directory entry's inode number.
  21. // (6) DT_REG, for regular files; DT_DIR, for subdirectories;
  22. // or DT_LNK, for symbolic links.
  23. // This function should stop returning directory
  24. // entries either when the directory is complete, or
  25. // when 'filldir' returns < 0, whichever comes first.
  26. //
  27. // Returns: 1 at end of directory, 0 if filldir returns < 0 before the end
  28. // of the directory, and -(error number) on error.
  29. //
  30. // EXERCISE: Finish implementing this function.
  31.  
  32. static int
  33. ospfs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
  34. {
  35. struct inode *dir_inode = filp->f_dentry->d_inode;
  36. ospfs_inode_t *dir_oi = ospfs_inode(dir_inode->i_ino);
  37. uint32_t f_pos = filp->f_pos;
  38. int r = 0; /* Error return value, if any */
  39. int ok_so_far = 0; /* Return value from 'filldir' */
  40.  
  41. // f_pos is an offset into the directory's data, plus two.
  42. // The "plus two" is to account for "." and "..".
  43. if (r == 0 && f_pos == 0) {
  44. ok_so_far = filldir(dirent, ".", 1, f_pos, dir_inode->i_ino, DT_DIR);
  45. if (ok_so_far >= 0)
  46. f_pos++;
  47. }
  48.  
  49. if (r == 0 && ok_so_far >= 0 && f_pos == 1) {
  50. ok_so_far = filldir(dirent, "..", 2, f_pos, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR);
  51. if (ok_so_far >= 0)
  52. f_pos++;
  53. }
  54.  
  55. // actual entries
  56. while (r == 0 && ok_so_far >= 0 && f_pos >= 2) {
  57. ospfs_direntry_t *od;
  58. ospfs_inode_t *entry_oi;
  59.  
  60. /* If at the end of the directory, set 'r' to 1 and exit
  61. * the loop. For now we do this all the time.
  62. *
  63. * EXERCISE: Your code here */
  64. if ((f_pos - 2) * OSPFS_DIRENTRY_SIZE >= dir_oi->oi_size) {
  65. r = 1;
  66. break;
  67. }
  68.  
  69. /* Get a pointer to the next entry (od) in the directory.
  70. * The file system interprets the contents of a
  71. * directory-file as a sequence of ospfs_direntry structures.
  72. * You will find 'f_pos' and 'ospfs_inode_data' useful.
  73. *
  74. * Then use the fields of that file to fill in the directory
  75. * entry. To figure out whether a file is a regular file or
  76. * another directory, use 'ospfs_inode' to get the directory
  77. * entry's corresponding inode, and check out its 'oi_ftype'
  78. * member.
  79. *
  80. * Make sure you ignore blank directory entries! (Which have
  81. * an inode number of 0.)
  82. *
  83. * If the current entry is successfully read (the call to
  84. * filldir returns >= 0), or the current entry is skipped,
  85. * your function should advance f_pos by the proper amount to
  86. * advance to the next directory entry.
  87. */
  88.  
  89. /* EXERCISE: Your code here */
  90. od = ospfs_inode_data(dir_oi, (f_pos - 2) * OSPFS_DIRENTRY_SIZE);
  91. entry_oi = ospfs_inode(od->od_ino);
  92. if (!entry_oi) {
  93. f_pos++;
  94. continue;
  95. }
  96.  
  97. ok_so_far = filldir(dirent, od->od_name, strlen(od->od_name), f_pos,
  98. od->od_ino, entry_oi->oi_ftype == OSPFS_FTYPE_DIR ? DT_DIR :
  99. entry_oi->oi_ftype == OSPFS_FTYPE_SYMLINK ? DT_LNK : DT_REG);
  100.  
  101. f_pos++;
  102. }
  103.  
  104. // Save the file position and return!
  105. filp->f_pos = f_pos;
  106. return r;
  107. }
Add Comment
Please, Sign In to add comment