mfs_vfsops.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /* $OpenBSD: mfs_vfsops.c,v 1.48 2015/03/14 03:38:52 jsg Exp $ */
  2. /* $NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $ */
  3. /*
  4. * Copyright (c) 1989, 1990, 1993, 1994
  5. * The Regents of the University of California. All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the University nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94
  32. */
  33. #include <sys/param.h>
  34. #include <sys/systm.h>
  35. #include <sys/time.h>
  36. #include <sys/proc.h>
  37. #include <sys/buf.h>
  38. #include <sys/mount.h>
  39. #include <sys/signalvar.h>
  40. #include <sys/vnode.h>
  41. #include <sys/malloc.h>
  42. #include <sys/kthread.h>
  43. #include <ufs/ufs/quota.h>
  44. #include <ufs/ufs/inode.h>
  45. #include <ufs/ufs/ufsmount.h>
  46. #include <ufs/ufs/ufs_extern.h>
  47. #include <ufs/ffs/fs.h>
  48. #include <ufs/ffs/ffs_extern.h>
  49. #include <ufs/mfs/mfsnode.h>
  50. #include <ufs/mfs/mfs_extern.h>
  51. static int mfs_minor; /* used for building internal dev_t */
  52. /*
  53. * mfs vfs operations.
  54. */
  55. const struct vfsops mfs_vfsops = {
  56. mfs_mount,
  57. mfs_start,
  58. ffs_unmount,
  59. ufs_root,
  60. ufs_quotactl,
  61. mfs_statfs,
  62. ffs_sync,
  63. ffs_vget,
  64. ffs_fhtovp,
  65. ffs_vptofh,
  66. mfs_init,
  67. ffs_sysctl,
  68. mfs_checkexp
  69. };
  70. /*
  71. * VFS Operations.
  72. *
  73. * mount system call
  74. */
  75. /* ARGSUSED */
  76. int
  77. mfs_mount(struct mount *mp, const char *path, void *data,
  78. struct nameidata *ndp, struct proc *p)
  79. {
  80. struct vnode *devvp;
  81. struct mfs_args args;
  82. struct ufsmount *ump;
  83. struct fs *fs;
  84. struct mfsnode *mfsp;
  85. char fspec[MNAMELEN];
  86. int flags, error;
  87. error = copyin(data, &args, sizeof(struct mfs_args));
  88. if (error)
  89. return (error);
  90. /*
  91. * If updating, check whether changing from read-only to
  92. * read/write; if there is no device name, that's all we do.
  93. */
  94. if (mp->mnt_flag & MNT_UPDATE) {
  95. ump = VFSTOUFS(mp);
  96. fs = ump->um_fs;
  97. if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
  98. flags = WRITECLOSE;
  99. if (mp->mnt_flag & MNT_FORCE)
  100. flags |= FORCECLOSE;
  101. error = ffs_flushfiles(mp, flags, p);
  102. if (error)
  103. return (error);
  104. }
  105. if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
  106. fs->fs_ronly = 0;
  107. #ifdef EXPORTMFS
  108. if (args.fspec == NULL)
  109. return (vfs_export(mp, &ump->um_export,
  110. &args.export_info));
  111. #endif
  112. return (0);
  113. }
  114. error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
  115. if (error)
  116. return (error);
  117. error = getnewvnode(VT_MFS, NULL, &mfs_vops, &devvp);
  118. if (error)
  119. return (error);
  120. devvp->v_type = VBLK;
  121. if (checkalias(devvp, makedev(255, mfs_minor), (struct mount *)0))
  122. panic("mfs_mount: dup dev");
  123. mfs_minor++;
  124. mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK | M_ZERO);
  125. devvp->v_data = mfsp;
  126. mfsp->mfs_baseoff = args.base;
  127. mfsp->mfs_size = args.size;
  128. mfsp->mfs_vnode = devvp;
  129. mfsp->mfs_pid = p->p_pid;
  130. bufq_init(&mfsp->mfs_bufq, BUFQ_FIFO);
  131. if ((error = ffs_mountfs(devvp, mp, p)) != 0) {
  132. mfsp->mfs_shutdown = 1;
  133. vrele(devvp);
  134. return (error);
  135. }
  136. ump = VFSTOUFS(mp);
  137. fs = ump->um_fs;
  138. memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt));
  139. strlcpy(fs->fs_fsmnt, path, sizeof(fs->fs_fsmnt));
  140. memcpy(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN);
  141. memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
  142. strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN);
  143. memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN);
  144. strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
  145. memcpy(&mp->mnt_stat.mount_info.mfs_args, &args, sizeof(args));
  146. return (0);
  147. }
  148. int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */
  149. /*
  150. * Used to grab the process and keep it in the kernel to service
  151. * memory filesystem I/O requests.
  152. *
  153. * Loop servicing I/O requests.
  154. * Copy the requested data into or out of the memory filesystem
  155. * address space.
  156. */
  157. /* ARGSUSED */
  158. int
  159. mfs_start(struct mount *mp, int flags, struct proc *p)
  160. {
  161. struct vnode *vp = VFSTOUFS(mp)->um_devvp;
  162. struct mfsnode *mfsp = VTOMFS(vp);
  163. struct buf *bp;
  164. int sleepreturn = 0;
  165. while (1) {
  166. while (1) {
  167. if (mfsp->mfs_shutdown == 1)
  168. break;
  169. bp = bufq_dequeue(&mfsp->mfs_bufq);
  170. if (bp == NULL)
  171. break;
  172. mfs_doio(mfsp, bp);
  173. wakeup(bp);
  174. }
  175. if (mfsp->mfs_shutdown == 1)
  176. break;
  177. /*
  178. * If a non-ignored signal is received, try to unmount.
  179. * If that fails, clear the signal (it has been "processed"),
  180. * otherwise we will loop here, as tsleep will always return
  181. * EINTR/ERESTART.
  182. */
  183. if (sleepreturn != 0) {
  184. if (vfs_busy(mp, VB_WRITE|VB_NOWAIT) ||
  185. dounmount(mp,
  186. (CURSIG(p) == SIGKILL) ? MNT_FORCE : 0, p, NULL))
  187. CLRSIG(p, CURSIG(p));
  188. sleepreturn = 0;
  189. continue;
  190. }
  191. sleepreturn = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0);
  192. }
  193. return (0);
  194. }
  195. /*
  196. * Get file system statistics.
  197. */
  198. int
  199. mfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
  200. {
  201. int error;
  202. error = ffs_statfs(mp, sbp, p);
  203. strncpy(&sbp->f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
  204. if (sbp != &mp->mnt_stat)
  205. memcpy(&sbp->mount_info.mfs_args,
  206. &mp->mnt_stat.mount_info.mfs_args, sizeof(struct mfs_args));
  207. return (error);
  208. }
  209. /*
  210. * check export permission, not supported
  211. */
  212. /* ARGUSED */
  213. int
  214. mfs_checkexp(struct mount *mp, struct mbuf *nam, int *exflagsp,
  215. struct ucred **credanonp)
  216. {
  217. return (EOPNOTSUPP);
  218. }
  219. /*
  220. * Memory based filesystem initialization.
  221. */
  222. int
  223. mfs_init(struct vfsconf *vfsp)
  224. {
  225. return (ffs_init(vfsp));
  226. }