vfscwd.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. /*
  30. * VFS operations involving the current directory.
  31. */
  32. #include <types.h>
  33. #include <kern/errno.h>
  34. #include <stat.h>
  35. #include <lib.h>
  36. #include <uio.h>
  37. #include <proc.h>
  38. #include <current.h>
  39. #include <vfs.h>
  40. #include <fs.h>
  41. #include <vnode.h>
  42. /*
  43. * Get current directory as a vnode.
  44. */
  45. int
  46. vfs_getcurdir(struct vnode **ret)
  47. {
  48. int rv = 0;
  49. spinlock_acquire(&curproc->p_lock);
  50. if (curproc->p_cwd!=NULL) {
  51. VOP_INCREF(curproc->p_cwd);
  52. *ret = curproc->p_cwd;
  53. }
  54. else {
  55. rv = ENOENT;
  56. }
  57. spinlock_release(&curproc->p_lock);
  58. return rv;
  59. }
  60. /*
  61. * Set current directory as a vnode.
  62. * The passed vnode must in fact be a directory.
  63. */
  64. int
  65. vfs_setcurdir(struct vnode *dir)
  66. {
  67. struct vnode *old;
  68. mode_t vtype;
  69. int result;
  70. result = VOP_GETTYPE(dir, &vtype);
  71. if (result) {
  72. return result;
  73. }
  74. if (vtype != S_IFDIR) {
  75. return ENOTDIR;
  76. }
  77. VOP_INCREF(dir);
  78. spinlock_acquire(&curproc->p_lock);
  79. old = curproc->p_cwd;
  80. curproc->p_cwd = dir;
  81. spinlock_release(&curproc->p_lock);
  82. if (old!=NULL) {
  83. VOP_DECREF(old);
  84. }
  85. return 0;
  86. }
  87. /*
  88. * Set current directory to "none".
  89. */
  90. int
  91. vfs_clearcurdir(void)
  92. {
  93. struct vnode *old;
  94. spinlock_acquire(&curproc->p_lock);
  95. old = curproc->p_cwd;
  96. curproc->p_cwd = NULL;
  97. spinlock_release(&curproc->p_lock);
  98. if (old!=NULL) {
  99. VOP_DECREF(old);
  100. }
  101. return 0;
  102. }
  103. /*
  104. * Set current directory, as a pathname. Use vfs_lookup to translate
  105. * it to a vnode.
  106. */
  107. int
  108. vfs_chdir(char *path)
  109. {
  110. struct vnode *vn;
  111. int result;
  112. result = vfs_lookup(path, &vn);
  113. if (result) {
  114. return result;
  115. }
  116. result = vfs_setcurdir(vn);
  117. VOP_DECREF(vn);
  118. return result;
  119. }
  120. /*
  121. * Get current directory, as a pathname.
  122. * Use VOP_NAMEFILE to get the pathname and FSOP_GETVOLNAME to get the
  123. * volume name.
  124. */
  125. int
  126. vfs_getcwd(struct uio *uio)
  127. {
  128. struct vnode *cwd;
  129. int result;
  130. const char *name;
  131. char colon=':';
  132. KASSERT(uio->uio_rw==UIO_READ);
  133. result = vfs_getcurdir(&cwd);
  134. if (result) {
  135. return result;
  136. }
  137. /* The current dir must be a directory, and thus it is not a device. */
  138. KASSERT(cwd->vn_fs != NULL);
  139. name = FSOP_GETVOLNAME(cwd->vn_fs);
  140. if (name==NULL) {
  141. vfs_biglock_acquire();
  142. name = vfs_getdevname(cwd->vn_fs);
  143. vfs_biglock_release();
  144. }
  145. KASSERT(name != NULL);
  146. result = uiomove((char *)name, strlen(name), uio);
  147. if (result) {
  148. goto out;
  149. }
  150. result = uiomove(&colon, 1, uio);
  151. if (result) {
  152. goto out;
  153. }
  154. result = VOP_NAMEFILE(cwd, uio);
  155. out:
  156. VOP_DECREF(cwd);
  157. return result;
  158. }