ufs_harvey.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * This file is part of the Harvey operating system. It is subject to the
  3. * license terms of the GNU GPL v2 in LICENSE.gpl found in the top-level
  4. * directory of this distribution and at http://www.gnu.org/licenses/gpl-2.0.txt
  5. *
  6. * No part of Harvey operating system, including this file, may be copied,
  7. * modified, propagated, or distributed except according to the terms
  8. * contained in the LICENSE.gpl file.
  9. */
  10. #include "u.h"
  11. #include "port/lib.h"
  12. #include "mem.h"
  13. #include "dat.h"
  14. #include "fns.h"
  15. #include <ufs/ufsdat.h>
  16. #include <ufs/freebsd_util.h>
  17. #include "ufs_harvey.h"
  18. #include "ufs_mountpoint.h"
  19. #include "ufs_ext.h"
  20. #include "ufs/quota.h"
  21. #include "ufs/inode.h"
  22. #include "ufs_extern.h"
  23. #include "ffs_extern.h"
  24. int
  25. findexistingvnode(MountPoint *mp, ino_t ino, vnode **vpp)
  26. {
  27. *vpp = findvnode(mp, ino);
  28. return 0;
  29. }
  30. /*
  31. * Return the next vnode from the free list.
  32. */
  33. int
  34. getnewvnode(MountPoint *mp, vnode **vpp)
  35. {
  36. vnode *vp = nil;
  37. //struct lock_object *lo;
  38. //static int cyclecount;
  39. //int error = 0;
  40. //alloc:
  41. vp = getfreevnode(mp);
  42. if (vp == nil) {
  43. return 0;
  44. }
  45. // TODO HARVEY Revisit locking of vnodes
  46. // TODO HARVEY Revisit counters
  47. #if 0
  48. /*
  49. * Locks are given the generic name "vnode" when created.
  50. * Follow the historic practice of using the filesystem
  51. * name when they allocated, e.g., "zfs", "ufs", "nfs, etc.
  52. *
  53. * Locks live in a witness group keyed on their name. Thus,
  54. * when a lock is renamed, it must also move from the witness
  55. * group of its old name to the witness group of its new name.
  56. *
  57. * The change only needs to be made when the vnode moves
  58. * from one filesystem type to another. We ensure that each
  59. * filesystem use a single static name pointer for its tag so
  60. * that we can compare pointers rather than doing a strcmp().
  61. */
  62. lo = &vp->v_vnlock->lock_object;
  63. if (lo->lo_name != tag) {
  64. lo->lo_name = tag;
  65. WITNESS_DESTROY(lo);
  66. WITNESS_INIT(lo, tag);
  67. }
  68. /*
  69. * By default, don't allow shared locks unless filesystems opt-in.
  70. */
  71. vp->v_vnlock->lock_object.lo_flags |= LK_NOSHARE;
  72. /*
  73. * Finalize various vnode identity bits.
  74. */
  75. KASSERT(vp->v_object == NULL, ("stale v_object %p", vp));
  76. KASSERT(vp->v_lockf == NULL, ("stale v_lockf %p", vp));
  77. KASSERT(vp->v_pollinfo == NULL, ("stale v_pollinfo %p", vp));
  78. #endif // 0
  79. vp->type = VNON;
  80. vp->mount = mp;
  81. #if 0
  82. v_init_counters(vp);
  83. //vp->v_bufobj.bo_ops = &buf_ops_bio;
  84. #ifdef DIAGNOSTIC
  85. if (mp == NULL && vops != &dead_vnodeops)
  86. printf("NULL mp in getnewvnode(9), tag %s\n", tag);
  87. #endif
  88. #ifdef MAC
  89. mac_vnode_init(vp);
  90. if (mp != NULL && (mp->mnt_flag & MNT_MULTILABEL) == 0)
  91. mac_vnode_associate_singlelabel(mp, vp);
  92. #endif
  93. if (mp != NULL) {
  94. vp->v_bufobj.bo_bsize = mp->mnt_stat.f_iosize;
  95. if ((mp->mnt_kern_flag & MNTK_NOKNOTE) != 0)
  96. vp->v_vflag |= VV_NOKNOTE;
  97. }
  98. #endif // 0
  99. /*
  100. * For the filesystems which do not use vfs_hash_insert(),
  101. * still initialize v_hash to have vfs_hash_index() useful.
  102. * E.g., nullfs uses vfs_hash_index() on the lower vnode for
  103. * its own hashing.
  104. */
  105. //vp->v_hash = (uintptr_t)vp >> vnsz2log;
  106. *vpp = vp;
  107. return (0);
  108. }
  109. void
  110. releaseufsvnode(vnode *vn)
  111. {
  112. releasevnode(vn);
  113. }
  114. vnode *
  115. ufs_open_ino(MountPoint *mp, ino_t ino) {
  116. vnode *vn;
  117. int rcode = ffs_vget(mp, ino, LK_SHARED, &vn);
  118. if (rcode) {
  119. error("cannot get file to open");
  120. }
  121. return vn;
  122. }
  123. int
  124. lookuppath(MountPoint *mp, char *path, vnode **vn)
  125. {
  126. // Get the root
  127. vnode *root = nil;
  128. int rcode = ufs_root(mp, LK_EXCLUSIVE, &root);
  129. if (rcode != 0) {
  130. print("couldn't get root: %d", rcode);
  131. return -1;
  132. }
  133. // TODO UFS caches lookups. We could do that in devufs.
  134. ComponentName cname = { .cn_pnbuf = path, .cn_nameiop = LOOKUP };
  135. rcode = ufs_lookup_ino(root, vn, &cname, nil);
  136. if (rcode != 0) {
  137. print("couldn't lookup path: %s: %d", path, rcode);
  138. return -1;
  139. }
  140. return 0;
  141. }
  142. static void
  143. vfs_badlock(const char *msg, const char *str, vnode *vp)
  144. {
  145. print("*** %s: %p %s\n", str, (void *)vp, msg);
  146. }
  147. void
  148. assert_vop_locked(vnode *vp, const char *str)
  149. {
  150. if (vp == nil) {
  151. print("assert_vop_locked: vnode is nil (checking %s)\n", str);
  152. } else if (vp->vnlock.readers == 0 && vp->vnlock.writer == 0) {
  153. vfs_badlock("is not locked but should be", str, vp);
  154. }
  155. }
  156. void
  157. assert_vop_elocked(vnode *vp, const char *str)
  158. {
  159. if (vp == nil) {
  160. print("assert_vop_elocked: vnode is nil (checking %s)\n", str);
  161. } else if (vp->vnlock.writer == 0) {
  162. vfs_badlock("is not exclusive locked but should be", str, vp);
  163. }
  164. }
  165. /*
  166. * Wrapper to enable Harvey's channel read function to be used like FreeBSD's
  167. * block read function.
  168. */
  169. int32_t
  170. bread(MountPoint *mp, ufs2_daddr_t blockno, size_t size, void **buf)
  171. {
  172. *buf = smalloc(size);
  173. Chan *c = mp->chan;
  174. int64_t offset = dbtob(blockno);
  175. int32_t bytesRead = c->dev->read(c, *buf, size, offset);
  176. if (bytesRead != size) {
  177. error("bread returned wrong size");
  178. }
  179. return 0;
  180. }