《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.7 KiB

12 years ago
  1. #include <defs.h>
  2. #include <string.h>
  3. #include <vfs.h>
  4. #include <inode.h>
  5. #include <error.h>
  6. #include <assert.h>
  7. /*
  8. * get_device- Common code to pull the device name, if any, off the front of a
  9. * path and choose the inode to begin the name lookup relative to.
  10. */
  11. static int
  12. get_device(char *path, char **subpath, struct inode **node_store) {
  13. int i, slash = -1, colon = -1;
  14. for (i = 0; path[i] != '\0'; i ++) {
  15. if (path[i] == ':') { colon = i; break; }
  16. if (path[i] == '/') { slash = i; break; }
  17. }
  18. if (colon < 0 && slash != 0) {
  19. /* *
  20. * No colon before a slash, so no device name specified, and the slash isn't leading
  21. * or is also absent, so this is a relative path or just a bare filename. Start from
  22. * the current directory, and use the whole thing as the subpath.
  23. * */
  24. *subpath = path;
  25. return vfs_get_curdir(node_store);
  26. }
  27. if (colon > 0) {
  28. /* device:path - get root of device's filesystem */
  29. path[colon] = '\0';
  30. /* device:/path - skip slash, treat as device:path */
  31. while (path[++ colon] == '/');
  32. *subpath = path + colon;
  33. return vfs_get_root(path, node_store);
  34. }
  35. /* *
  36. * we have either /path or :path
  37. * /path is a path relative to the root of the "boot filesystem"
  38. * :path is a path relative to the root of the current filesystem
  39. * */
  40. int ret;
  41. if (*path == '/') {
  42. if ((ret = vfs_get_bootfs(node_store)) != 0) {
  43. return ret;
  44. }
  45. }
  46. else {
  47. assert(*path == ':');
  48. struct inode *node;
  49. if ((ret = vfs_get_curdir(&node)) != 0) {
  50. return ret;
  51. }
  52. /* The current directory may not be a device, so it must have a fs. */
  53. assert(node->in_fs != NULL);
  54. *node_store = fsop_get_root(node->in_fs);
  55. vop_ref_dec(node);
  56. }
  57. /* ///... or :/... */
  58. while (*(++ path) == '/');
  59. *subpath = path;
  60. return 0;
  61. }
  62. /*
  63. * vfs_lookup - get the inode according to the path filename
  64. */
  65. int
  66. vfs_lookup(char *path, struct inode **node_store) {
  67. int ret;
  68. struct inode *node;
  69. if ((ret = get_device(path, &path, &node)) != 0) {
  70. return ret;
  71. }
  72. if (*path != '\0') {
  73. ret = vop_lookup(node, path, node_store);
  74. vop_ref_dec(node);
  75. return ret;
  76. }
  77. *node_store = node;
  78. return 0;
  79. }
  80. /*
  81. * vfs_lookup_parent - Name-to-vnode translation.
  82. * (In BSD, both of these are subsumed by namei().)
  83. */
  84. int
  85. vfs_lookup_parent(char *path, struct inode **node_store, char **endp){
  86. int ret;
  87. struct inode *node;
  88. if ((ret = get_device(path, &path, &node)) != 0) {
  89. return ret;
  90. }
  91. *endp = path;
  92. *node_store = node;
  93. return 0;
  94. }