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

📄 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 * $Id: vfs.c,v 1.4 2002/12/27 20:18:53 ezk 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 <wrapfs.h>#endifstatic MALLOC_DEFINE(M_WRAPFSMNT, "WRAPFS mount", "WRAPFS mount structure");static int wrapfs_fhtovp __P((struct mount *mp, struct fid * fidp,			      struct vnode **vpp));static int wrapfs_checkexp __P((struct mount *mp, struct sockaddr *nam,				int *extflagsp, struct ucred **credanonp));static int wrapfs_mount __P((struct mount *mp, char *path, caddr_t data,			     struct nameidata * ndp, struct proc * p));static int wrapfs_quotactl __P((struct mount *mp, int cmd, uid_t uid,				caddr_t arg, struct proc * p));static int wrapfs_root __P((struct mount *mp, struct vnode ** vpp));static int wrapfs_start __P((struct mount *mp, int flags, struct proc * p));static int wrapfs_statfs __P((struct mount *mp, struct statfs * sbp,			      struct proc * p));static int wrapfs_sync __P((struct mount *mp, int waitfor,			    struct ucred * cred, struct proc * p));static int wrapfs_unmount __P((struct mount *mp, int mntflags,			       struct proc * p));static int wrapfs_vget __P((struct mount *mp, ino_t ino,			    struct vnode ** vpp));static int wrapfs_vptofh __P((struct vnode * vp, struct fid * fhp));static int wrapfs_extattrctl __P((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;#ifdef DIAGNOSTIC  printf("wrapfs_mount(mp = %p)\n", mp);#endif  /*   * 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) {#ifdef DEBUG    printf("wrapfs_mount: multi wrapfs mount?\n");#endif    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);#ifdef DEBUG  printf("wrapfs_mount: lower %s, alias at %s\n",	 mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);#endif  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;{  struct vnode *wrapfsm_rootvp = MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp;  int error;  int flags = 0;#ifdef DEBUG  printf("wrapfs_unmount(mp = %p)\n", mp);#endif  if (mntflags & MNT_FORCE)    flags |= FORCECLOSE;  /*   * Clear out buffer cache.  I don't think we   * ever get anything cached at this level at the   * moment, but who knows...   */#if 0  mntflushbuf(mp, 0);  if (mntinvalbuf(mp, 1))    return (EBUSY);#endif  if (wrapfsm_rootvp->v_usecount > 1)    return (EBUSY);  error = vflush(mp, wrapfsm_rootvp, flags);  if (error)    return (error);#ifdef DEBUG  vprint("alias root of lower", wrapfsm_rootvp);#endif  /*   * Release reference on underlying root vnode   */  vrele(wrapfsm_rootvp);  /*   * And blow it away for future re-use   */  vgone(wrapfsm_rootvp);  /*   * Finally, throw away the wrapfs_mount structure   */  free(mp->mnt_data, M_WRAPFSMNT);	/* XXX */  mp->mnt_data = 0;  return 0;}static intwrapfs_root(mp, vpp)     struct mount *mp;     struct vnode **vpp;{  struct proc *p = curproc;	/* XXX */  struct vnode *vp;#ifdef DEBUG  printf("wrapfs_root(mp = %p, vp = %x->%x)\n", mp,	 MOUNTTOWRAPFSMOUNT(mp)->wrapfsm_rootvp,	 WRAPFSVPTOLOWERVP(MOUNTTOWRAPFSMOUNT(mp)->wrapfsm_rootvp)    );#endif  /*   * Return locked reference to root.   */  vp = MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_rootvp;  VREF(vp);  if (VOP_ISLOCKED(vp, NULL)) {    /*     * XXX     * Should we check type of node?     */#ifdef DEBUG    printf("wrapfs_root: multi wrapfs mount?\n");#endif    vrele(vp);    return (EDEADLK);  } else    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);  *vpp = vp;  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;#ifdef DEBUG  printf("wrapfs_statfs(mp = %p, vp = %x->%x)\n", mp,	 MOUNTTOWRAPFSMOUNT(mp)->wrapfsm_rootvp,	 WRAPFSVPTOLOWERVP(MOUNTTOWRAPFSMOUNT(mp)->wrapfsm_rootvp)    );#endif  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);  }  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.   */  fist_dprint(4, "WRAPFS_SYNC: vfs=0x%x\n", (int) mp);  return (0);}static intwrapfs_vget(mp, ino, vpp)     struct mount *mp;     ino_t ino;     struct vnode **vpp;{  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;{  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;{  return VFS_CHECKEXP(MOUNT_TO_WRAPFS_MOUNT(mp)->wrapfsm_vfs, nam,		      extflagsp, credanonp);}static intwrapfs_vptofh(vp, fhp)     struct vnode *vp;     struct fid *fhp;{  return VFS_VPTOFH(WRAPFS_VP_TO_LOWERVP(vp), fhp);}static intwrapfs_extattrctl(mp, cmd, attrname, arg, p)     struct mount *mp;     int cmd;     const char *attrname;     caddr_t arg;     struct proc *p;{  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,  vfs_stduninit,  wrapfs_extattrctl,};VFS_SET(wrapfs_vfsops, wrapfs, VFCF_LOOPBACK);

⌨️ 快捷键说明

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