📄 vfs.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 by Sun Microsystems, Inc. */#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 <sys/param.h>#include <sys/errno.h>#include <sys/proc.h>#include <sys/vfs.h>#include <sys/vnode.h>#include <sys/uio.h>#include <sys/kmem.h>#include <sys/cred.h>#include <sys/statvfs.h>#include <sys/mount.h>#include <sys/tiuser.h>#include <sys/cmn_err.h>#include <sys/debug.h>#include <sys/mkdev.h>#include <sys/systm.h>#include <sys/sysmacros.h>#include <sys/pathname.h>#include <sys/fs_subr.h>#include <fist.h>#include <wrapfs.h>#endifint wrapfs_init(vfssw_t *, int);/* * This is the loadable module wrapfs. */#include <sys/modctl.h>extern vfsops_t wrapfs_vfsops;int wrapfs_major;int wrapfs_minor;kmutex_t wrapfs_minor_lock;static vfssw_t vfw ={ "wrapfs", wrapfs_init, &wrapfs_vfsops, 0};/* * Module linkage information for the kernel. */extern struct mod_ops mod_fsops;static struct modlfs modlfs ={ &mod_fsops, "filesystem for wrapfs", &vfw};static struct modlinkage modlinkage ={ MODREV_1, { (void *) &modlfs, NULL, }};/* * This is the module initialization routine. *//* * A counter for how many filesystems are mounted using this counter. * If greater than 0, it means the module is unloadable. */static int module_keepcnt = 0;/* * There are not enough stubs for rpcmod so we must force load it */char _depends_on[] = "strmod/rpcmod";int_init(void){ print_location(); return (mod_install(&modlinkage));}int_fini(void){ if (module_keepcnt != 0) { fist_dprint(4, "wrapfs_vfsops: _fini(), module_keepcnt=%d.\n", module_keepcnt); return (EBUSY); } fist_dprint(4, "wrapfs_vfsops: _fini(): removing module.\n"); return (mod_remove(&modlinkage));}int_info(struct modinfo *modinfop){ int error; fist_dprint(4, "wrapfs_vfsops: _info(): returning info on module.\n"); error = mod_info(&modlinkage, modinfop); fist_dprint(4, "wrapfs_vfsops: module wrapfs successfully loaded at address 0x%x, size 0x%x\n", modinfop->mi_base, modinfop->mi_size); return error;}static kmutex_t fist_wrapfs_node_count_lock;extern struct vnodeops wrapfs_vnodeops;static int wrapfs_fstype;/* * fist_wrapfs vfs operations. */static int wrapfs_mount(vfs_t *, vnode_t *, struct mounta *, cred_t *);static int wrapfs_unmount(vfs_t *, cred_t *);static int wrapfs_root(vfs_t *, vnode_t **);static int wrapfs_statvfs(vfs_t *, struct statvfs64 *);static int wrapfs_sync(vfs_t *, short, cred_t *);static int wrapfs_vget(vfs_t *, vnode_t **, fid_t *);static int wrapfs_mountroot(vfs_t *, enum whymountroot);static int wrapfs_swapvp(vfs_t *, vnode_t **, char *);struct vfsops wrapfs_vfsops ={ wrapfs_mount, /* mount */ wrapfs_unmount, /* unmount */ wrapfs_root, /* root */ wrapfs_statvfs, /* statvfs */ wrapfs_sync, /* sync */ wrapfs_vget, /* vget */ wrapfs_mountroot, /* mountroot */ wrapfs_swapvp /* swapvp */};#define MAJOR_MIN 128#define vfsNVFS (&vfssw[nfstype])intwrapfs_init( vfssw_t * vswp, int fstype){ fist_dprint(5, "wrapfs_init: vspw %x, fstype %d\n", (int) vswp, fstype); fist_set_debug_value(4); if (vswp) { if (vswp->vsw_name) fist_dprint(5, "wrapfs_init: vswp->vsw_name \"%s\"\n", vswp->vsw_name); if (vswp->vsw_init) fist_dprint(5, "wrapfs_init: vswp->vsw_init %x\n", (int) vswp->vsw_init); fist_dprint(5, "wrapfs_init: wrapfs_init %x\n", (int) wrapfs_init); if (vswp->vsw_vfsops) { fist_dprint(5, "wrapfs_init: vswp->vsw_vfsops %x\n", (int) vswp->vsw_vfsops); fist_dprint(5, "wrapfs_init: wrapfs_vfsops %x\n", (int) &wrapfs_vfsops); if (vswp->vsw_vfsops->vfs_mount) fist_dprint(5, "wrapfs_init: vswp->vsw_vfsops->vfs_mount %x\n", (int) vswp->vsw_vfsops->vfs_mount); fist_dprint(5, "wrapfs_init: wrapfs_mount %x\n", (int) wrapfs_mount); } } wrapfs_fstype = fstype; ASSERT(wrapfs_fstype != 0); /* * Associate VFS ops vector with this fstype */ vswp->vsw_vfsops = &wrapfs_vfsops; mutex_init(&wrapfs_minor_lock, "fist_wrapfs minor lock", MUTEX_DEFAULT, NULL); mutex_init(&fist_wrapfs_node_count_lock, "fist_wrapfs_node count lock", MUTEX_DEFAULT, NULL); /* * Assign unique major number for all fist_wrapfs mounts */ if ((wrapfs_major = getudev()) == -1) { cmn_err(CE_WARN, "fist_wrapfs: wrapfs_init: can't get unique device number"); wrapfs_major = 0; } wrapfs_minor = 0; print_location(); return (0);}static intwrapfs_mount( vfs_t * vfsp, /* pre-made vfs structure to mount */ vnode_t * vp, /* existing vnode to mount on */ struct mounta *uap, /* user-area mount(2) arguments */ cred_t * cr /* user credentials */){ int error = 0; char namebuf[TYPICALMAXPATHLEN + 4]; /* +4 because of bug 1170077 */ int len = 0; /* struct wrapfs_args args; */ /* char datalen = uap->datalen; */ struct fist_wrapfs_info *fwip; /* fist_wrapfs_node_t *fwnp; */ dev_t wrapfs_dev; struct vnode *rootvp; vnode_t *interposed_vp; /* interposed vnode */ if (vfsp) fist_print_vfs("wrapfs_mount", vfsp); if (vp) { fist_dprint(4, "%s: wrapfs_vnodeops %x\n", "wrapfs_mount", (int) &wrapfs_vnodeops); fist_print_vnode("wrapfs_mount", vp); } if (uap) fist_print_uap("wrapfs_mount", uap); /* * Now we can increment the count of module instances. * meaning that from now, the mounting cannot fail. */ ++module_keepcnt; /* * Make sure we're root */ if (!suser(cr)) { error = EPERM; goto out; } /* Make sure we mount on a directory */ if (vp->v_type != VDIR) { error = ENOTDIR; goto out; } /* * check if vnode is already a root of a filesystem (i.e., there * is already a mount on this vnode). */ mutex_enter(&vp->v_lock); if ((uap->flags & MS_REMOUNT) == 0 && (uap->flags & MS_OVERLAY) == 0 && (vp->v_count != 1 || (vp->v_flag & VROOT))) { mutex_exit(&vp->v_lock); error = EBUSY; goto out; } mutex_exit(&vp->v_lock); /* * Get arguments: XXX: NOT NEEDED YET. */ /* * Get vnode for interposed directory. */ /* make sure special dir is a valid absolute pathname string */ if (!uap || !uap->spec) { error = EINVAL; goto out; } /* check if special dir starts with a '/' */ error = copyinstr(uap->spec, namebuf, TYPICALMAXPATHLEN, &len); if (error) goto out; if (namebuf[0] != '/') { error = EINVAL; goto out; } error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP, &interposed_vp); if (error) goto out; /* Make sure the thing we just looked up is a directory */ if (interposed_vp->v_type != VDIR) { VN_RELE(interposed_vp); error = ENOTDIR; goto out; }/************************************************************************** * FIST_WRAPFSINFO: * The private information stored by the vfs for fist_wrapfs. */ /* this implicitly allocates one vnode to be used for root vnode */ /* XXX: enter this vnode in dnlc? */ fwip = (struct fist_wrapfs_info *) kmem_alloc(sizeof(struct fist_wrapfs_info), KM_SLEEP); /* store the vfs of the stacked filesystem (pushed onto "stack") */ fwip->fwi_mountvfs = vp->v_vfsp; /* initialize number of interposed vnodes */ fwip->fwi_num_vnodes = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -