⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfs.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
字号:
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * Copyright (c) 1997-2000 Columbia University * * For specific licensing information, see the COPYING file distributed with * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. * * This Copyright notice must be kept intact and distributed with all * fistgen sources INCLUDING sources generated by fistgen. *//* * Copyright (c) 1992, 1993, 1995 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software donated to Berkeley by * Jan-Simon Pendry. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)wrapfs_vfsops.c	8.2 (Berkeley) 1/21/94 * * @(#)lofs_vfsops.c	1.2 (Berkeley) 6/18/92 * $FreeBSD: src/sys/miscfs/wrapfs/wrapfs_vfsops.c,v 1.35.2.3 2001/07/26 20:37:11 iedowse Exp $ *//* * wrapfs Layer * (See wrapfs_vnops.c for a description of what this does.) */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H */#ifdef FISTGEN# include "fist_wrapfs.h"#endif /* FISTGEN */#include <fist.h>#include <wrapfs.h>#if 0#include "opt_debug.h"#include <sys/param.h>#include <sys/systm.h>#include <sys/kernel.h>#include <sys/proc.h>#include <sys/malloc.h>#include <sys/vnode.h>#include <sys/mount.h>#include <sys/namei.h>#include <miscfs/wrapfs/wrapfs.h>#endifstatic MALLOC_DEFINE(M_WRAPFSMNT, "WRAPFS mount", "WRAPFS mount structure");static int	wrapfs_fhtovp(struct mount *mp, struct fid *fidp,				   struct vnode **vpp);static int	wrapfs_checkexp(struct mount *mp, struct sockaddr *nam,				    int *extflagsp, struct ucred **credanonp);static int	wrapfs_mount(struct mount *mp, char *path, caddr_t data,				  struct nameidata *ndp, struct proc *p);static int	wrapfs_quotactl(struct mount *mp, int cmd, uid_t uid,				     caddr_t arg, struct proc *p);static int	wrapfs_root(struct mount *mp, struct vnode **vpp);static int	wrapfs_start(struct mount *mp, int flags, struct proc *p);static int	wrapfs_statfs(struct mount *mp, struct statfs *sbp,				   struct proc *p);static int	wrapfs_sync(struct mount *mp, int waitfor,				 struct ucred *cred, struct proc *p);static int	wrapfs_unmount(struct mount *mp, int mntflags, struct proc *p);static int	wrapfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp);static int	wrapfs_vptofh(struct vnode *vp, struct fid *fhp);static int	wrapfs_extattrctl(struct mount *mp, int cmd,			const char *attrname, caddr_t arg, struct proc *p);/* * Mount wrapfs layer */static intwrapfs_mount(mp, path, data, ndp, p)     struct mount *mp;     char *path;     caddr_t data;     struct nameidata *ndp;     struct proc *p;{  int error = 0;  struct wrapfs_args args;  struct vnode *lowerrootvp, *vp;  struct vnode *wrapfsm_rootvp;  struct wrapfs_mount *xmp;  u_int size;  int isvnunlocked = 0;  fist_dprint(2, "wrapfs_mount(mp = %p)\n", (void *)mp);  /*   * Update is a no-op   */  if (mp->mnt_flag & MNT_UPDATE) {    return (EOPNOTSUPP);    /* return VFS_MOUNT(MOUNTTOWRAPFSMOUNT(mp)->wrapfsm_vfs, path, data, ndp, p);*/  }  /*   * Get argument   */  error = copyin(data, (caddr_t)&args, sizeof(struct wrapfs_args));  if (error)    return (error);  /*   * Unlock lower node to avoid deadlock.   * (XXX) VOP_ISLOCKED is needed?   */  if ((mp->mnt_vnodecovered->v_op == wrapfs_vnodeop_p) &&      VOP_ISLOCKED(mp->mnt_vnodecovered, NULL)) {    VOP_UNLOCK(mp->mnt_vnodecovered, 0, p);    isvnunlocked = 1;  }  /*   * Find lower node   */  NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,	 UIO_USERSPACE, args.target, p);  error = namei(ndp);  /*   * Re-lock vnode.   */  if (isvnunlocked && !VOP_ISLOCKED(mp->mnt_vnodecovered, NULL))    vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY, p);  if (error)    return (error);  NDFREE(ndp, NDF_ONLY_PNBUF);  /*   * Sanity check on lower vnode   */  lowerrootvp = ndp->ni_vp;  vrele(ndp->ni_dvp);  ndp->ni_dvp = NULLVP;   /*   * Check multi wrapfs mount to avoid `lock against myself' panic.   */  if (lowerrootvp == VP_TO_WRAPFS(mp->mnt_vnodecovered)->wrapfs_lowervp) {     fist_dprint(2, "wrapfs_mount: multi wrapfs mount?\n");    vput(lowerrootvp);    return (EDEADLK);  }   xmp = (struct wrapfs_mount *) malloc(sizeof(struct wrapfs_mount),				       M_WRAPFSMNT, M_WAITOK);	/* XXX */  /*   * Save reference to underlying FS   */  xmp->wrapfsm_vfs = lowerrootvp->v_mount;  /*   * Save reference.  Each mount also holds   * a reference on the root vnode.   */  error = wrapfs_node_create(mp, lowerrootvp, &vp);  /*   * Unlock the node (either the lower or the alias)   */  VOP_UNLOCK(vp, 0, p);  /*   * Make sure the node alias worked   */  if (error) {    vrele(lowerrootvp);    free(xmp, M_WRAPFSMNT);	/* XXX */    return (error);  }  /*   * Keep a held reference to the root vnode.   * It is vrele'd in wrapfs_unmount.   */  wrapfsm_rootvp = vp;  wrapfsm_rootvp->v_flag |= VROOT;  xmp->wrapfsm_rootvp = wrapfsm_rootvp;  if (WRAPFS_VP_TO_LOWERVP(wrapfsm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)    mp->mnt_flag |= MNT_LOCAL;  mp->mnt_data = (qaddr_t) xmp;  vfs_getnewfsid(mp);  (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);  bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);  (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,		   &size);  bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);  (void)wrapfs_statfs(mp, &mp->mnt_stat, p);  fist_dprint(2, "wrapfs_mount: lower %s, alias at %s\n",	      mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);  print_location();  return (0);}/* * VFS start.  Nothing needed here - the start routine * on the underlying filesystem will have been called * when that filesystem was mounted. */static intwrapfs_start(mp, flags, p)	struct mount *mp;	int flags;	struct proc *p;{  return (0);  /* return VFS_START(MOUNTTOWRAPFSMOUNT(mp)->wrapfsm_vfs, flags, p); */}/* * Free reference to wrapfs layer */static intwrapfs_unmount(mp, mntflags, p)	struct mount *mp;	int mntflags;	struct proc *p;{  void *mntdata;  int error;  int flags = 0;  fist_dprint(2, "wrapfs_unmount: mp = %p\n", (void *)mp);  if (mntflags & MNT_FORCE)    flags |= FORCECLOSE;  /* There is 1 extra root vnode reference (wrapfsm_rootvp). */  error = vflush(mp, 1, flags);  if (error)    return (error);  /*   * Finally, throw away the wrapfs_mount structure   */  mntdata = mp->mnt_data;  mp->mnt_data = 0;  free(mntdata, M_WRAPFSMNT);  print_location();  return 0;}static intwrapfs_root(mp, vpp)	struct mount *mp;	struct vnode **vpp;{  struct proc *p = curproc;	/* XXX */  struct vnode *vp;  fist_dprint(2, "wrapfs_root(mp = %p, vp = %p->%p)\n", (void *)mp,	      (void *)MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp,	      (void *)WRAPFS_VP_TO_LOWERVP(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp));  /*   * Return locked reference to root.   */  vp = MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp;  VREF(vp);#ifdef FIST_DEBUG  if (VOP_ISLOCKED(vp, NULL)) {    Debugger("root vnode is locked.\n");    vrele(vp);    return (EDEADLK);  }#endif  vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);  *vpp = vp;  print_location();  return 0;}static intwrapfs_quotactl(mp, cmd, uid, arg, p)	struct mount *mp;	int cmd;	uid_t uid;	caddr_t arg;	struct proc *p;{  return VFS_QUOTACTL(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, cmd, uid, arg, p);}static intwrapfs_statfs(mp, sbp, p)	struct mount *mp;	struct statfs *sbp;	struct proc *p;{  int error;  struct statfs mstat;  fist_dprint(2, "wrapfs_statfs(mp = %p, vp = %p->%p)\n", (void *)mp,	      (void *)MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp,	      (void *)WRAPFS_VP_TO_LOWERVP(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp));  bzero(&mstat, sizeof(mstat));  error = VFS_STATFS(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, &mstat, p);  if (error)    return (error);  /* now copy across the "interesting" information and fake the rest */  sbp->f_type = mstat.f_type;  sbp->f_flags = mstat.f_flags;  sbp->f_bsize = mstat.f_bsize;  sbp->f_iosize = mstat.f_iosize;  sbp->f_blocks = mstat.f_blocks;  sbp->f_bfree = mstat.f_bfree;  sbp->f_bavail = mstat.f_bavail;  sbp->f_files = mstat.f_files;  sbp->f_ffree = mstat.f_ffree;  if (sbp != &mp->mnt_stat) {    bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));    bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);    bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);  }  print_location();  return (0);}static intwrapfs_sync(mp, waitfor, cred, p)	struct mount *mp;	int waitfor;	struct ucred *cred;	struct proc *p;{  /*   * XXX - Assumes no data cached at wrapfs layer.   */  return 0;}static intwrapfs_vget(mp, ino, vpp)	struct mount *mp;	ino_t ino;	struct vnode **vpp;{  fist_dprint(2, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  return VFS_VGET(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, ino, vpp);}static intwrapfs_fhtovp(mp, fidp, vpp)	struct mount *mp;	struct fid *fidp;	struct vnode **vpp;{  fist_dprint(2, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  return VFS_FHTOVP(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, fidp, vpp);}static intwrapfs_checkexp(mp, nam, extflagsp, credanonp)	struct mount *mp;	struct sockaddr *nam;	int *extflagsp; 	struct ucred **credanonp;{  fist_dprint(2, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  return VFS_CHECKEXP(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, nam, 		      extflagsp, credanonp);}static intwrapfs_vptofh(vp, fhp)	struct vnode *vp;	struct fid *fhp;{  fist_dprint(2, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  return VFS_VPTOFH(WRAPFS_VP_TO_LOWERVP(vp), fhp);}static int                        wrapfs_extattrctl(mp, cmd, attrname, arg, p)	struct mount *mp;	int cmd;	const char *attrname;	caddr_t arg;	struct proc *p;            {  fist_dprint(2, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  return VFS_EXTATTRCTL(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, cmd, attrname,			arg, p);}static struct vfsops wrapfs_vfsops = {  wrapfs_mount,  wrapfs_start,  wrapfs_unmount,  wrapfs_root,  wrapfs_quotactl,  wrapfs_statfs,  wrapfs_sync,  wrapfs_vget,  wrapfs_fhtovp,  wrapfs_checkexp,  wrapfs_vptofh,  wrapfs_init,  wrapfs_uninit,  wrapfs_extattrctl,};VFS_SET(wrapfs_vfsops, wrapfs, VFCF_LOOPBACK);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -