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

📄 vnode.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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/systm.h>#include <sys/errno.h>#include <sys/vnode.h>#include <sys/vfs.h>#include <sys/uio.h>#include <sys/cred.h>#include <sys/pathname.h>#include <sys/dirent.h>#include <sys/debug.h>#include <sys/sysmacros.h>#include <sys/tiuser.h>#include <sys/cmn_err.h>#include <sys/stat.h>#include <sys/mode.h>#include <rpc/types.h>#include <rpc/auth.h>#include <rpc/clnt.h>#include <sys/fs_subr.h>#include <sys/mman.h>#include <sys/vm.h>#include <vm/as.h>#include <vm/pvn.h>#include <vm/seg_vn.h>#include <vm/seg_kp.h>#include <vm/seg_map.h>#include <vm/page.h>#include <fist.h>#include <wrapfs.h>#endif/* *  Vnode ops for fist_wrapfs */static int wrapfs_open(vnode_t **, int, cred_t *);static int wrapfs_close(vnode_t *, int, int, offset_t, cred_t *);static int wrapfs_getattr(vnode_t *, vattr_t *, int, cred_t *);static int wrapfs_access(vnode_t *, int, int, cred_t *);static int wrapfs_lookup(vnode_t *, char *, vnode_t **,			     pathname_t *, int, vnode_t *, cred_t *);static int wrapfs_remove(vnode_t *, char *, cred_t *);static int wrapfs_rename(vnode_t *, char *, vnode_t *, char *, cred_t *);static int wrapfs_mkdir(vnode_t *, char *, vattr_t *, vnode_t **, cred_t *);static int wrapfs_rmdir(vnode_t *, char *, vnode_t *, cred_t *);static int wrapfs_readdir(vnode_t *, uio_t *, cred_t *, int *);static int wrapfs_symlink(vnode_t *, char *, vattr_t *, char *, cred_t *);static int wrapfs_fsync(vnode_t *, int, cred_t *);static void wrapfs_inactive(vnode_t *, cred_t *);static void wrapfs_rwlock(vnode_t *, int);static void wrapfs_rwunlock(vnode_t * vp, int);static int wrapfs_seek(vnode_t * vp, offset_t, offset_t *);static int wrapfs_cmp(vnode_t *, vnode_t *);static int wrapfs_read(vnode_t *, uio_t *, int, cred_t *);static int wrapfs_write(vnode_t *, uio_t *, int, cred_t *);static int wrapfs_ioctl(vnode_t *, int, int, int, cred_t *, int *);static int wrapfs_setfl(vnode_t *, int, int, cred_t *);static int wrapfs_setattr(vnode_t *, vattr_t *, int, cred_t *);static int wrapfs_create(vnode_t *, char *, vattr_t *, vcexcl_t, int,			     vnode_t **, cred_t *, int);static int wrapfs_link(vnode_t *, vnode_t *, char *, cred_t *);static int wrapfs_readlink(vnode_t *, uio_t *, cred_t *);static int wrapfs_fid(vnode_t *, fid_t *);static int wrapfs_frlock(vnode_t *, int, struct flock64 *, int, offset_t, cred_t *);static int wrapfs_space(vnode_t *, int, struct flock64 *, int, offset_t, cred_t *);static int wrapfs_realvp(vnode_t *, vnode_t **);extern int wrapfs_getpage(vnode_t *, offset_t, u_int, u_int *, page_t **,		       u_int, struct seg *, caddr_t, enum seg_rw, cred_t *);extern int wrapfs_getapage(vnode_t *, u_int, u_int, u_int *, page_t **,		       u_int, struct seg *, caddr_t, enum seg_rw, cred_t *);extern int wrapfs_putpage(vnode_t *, offset_t, u_int, int, cred_t *);extern int wrapfs_putapage(struct vnode *vp, page_t * pp, u_offset_t * offp, u_int * lenp, int flags, struct cred *cr);extern int wrapfs_map(vnode_t *, offset_t, struct as *, caddr_t *, u_int,			  u_char, u_char, u_int, cred_t *);extern int wrapfs_addmap(vnode_t *, offset_t, struct as *, caddr_t, u_int,			     u_char, u_char, u_int, cred_t *);extern int wrapfs_delmap(vnode_t *, offset_t, struct as *, caddr_t, u_int,			     u_int, u_int, u_int, cred_t *);static int wrapfs_poll(vnode_t *, short, int, short *, pollhead_t **);static int wrapfs_dump(vnode_t *, caddr_t, int, int);static int wrapfs_pathconf(vnode_t *, int, u_long *, cred_t *);static int wrapfs_pageio(vnode_t *, page_t *, u_offset_t, u_int, int, cred_t *);static int wrapfs_dumpctl(vnode_t *, int);static void wrapfs_dispose(vnode_t *, page_t *, int, int, cred_t *);static int wrapfs_setsecattr(vnode_t *, vsecattr_t *, int, cred_t *);static int wrapfs_getsecattr(vnode_t *, vsecattr_t *, int, cred_t *);vnodeops_t wrapfs_vnodeops ={  wrapfs_open,			/* open */  wrapfs_close,			/* close */  wrapfs_read,			/* read */  wrapfs_write,			/* write */  wrapfs_ioctl,			/* ioctl */  wrapfs_setfl,			/* setfl */  wrapfs_getattr,		/* getattr */  wrapfs_setattr,		/* setattr */  wrapfs_access,		/* access */  wrapfs_lookup,		/* lookup */  wrapfs_create,		/* create */  wrapfs_remove,		/* remove */  wrapfs_link,			/* link */  wrapfs_rename,		/* rename */  wrapfs_mkdir,			/* mkdir */  wrapfs_rmdir,			/* rmdir */  wrapfs_readdir,		/* readdir */  wrapfs_symlink,		/* symlink */  wrapfs_readlink,		/* readlink */  wrapfs_fsync,			/* fsync */  wrapfs_inactive,		/* inactive */  wrapfs_fid,			/* fid */  wrapfs_rwlock,		/* rwlock */  wrapfs_rwunlock,		/* rwunlock */  wrapfs_seek,			/* seek */  wrapfs_cmp,			/* cmp */  wrapfs_frlock,		/* frlock */  wrapfs_space,			/* space */  wrapfs_realvp,		/* realvp */  wrapfs_getpage,		/* getpage */  wrapfs_putpage,		/* putpage */  wrapfs_map,			/* map */  wrapfs_addmap,		/* addmap */  wrapfs_delmap,		/* delmap */  wrapfs_poll,			/* poll */  wrapfs_dump,			/* dump */  wrapfs_pathconf,		/* pathconf */  wrapfs_pageio,		/* pageio */  wrapfs_dumpctl,		/* dumpctl */  wrapfs_dispose,		/* dispose */  wrapfs_setsecattr,		/* setsecattr */  wrapfs_getsecattr		/* getsecattr */};/* interpose on an old vnode and return new one */vnode_t *wrapfs_interpose(vnode_t * hidden_vp, vfs_t * this_vfsp){  vnode_t *fw_vp;  fist_wrapfs_node_t *fwnp;  struct fist_wrapfs_info *fwip = NULL;  mutex_enter(&vfstofwi(this_vfsp)->fwi_ht_lock);  /* look if entry exists in HT */  fw_vp = fist_ht_find_vp(hidden_vp, this_vfsp);  if (fw_vp) {    fist_dprint(6, "WRAPFS_INTERPOSE found vp in HT!\n");    VN_HOLD(fw_vp);		/* maybe VN_RELE(hidden_vp) */    VN_RELE(hidden_vp);    goto out;  }  /* allocate new vnode */  fw_vp = kmem_zalloc(sizeof(vnode_t), KM_SLEEP);  /* XXX: need VN_INIT2 that will reuse lock var of interposed vnode */  VN_INIT(fw_vp, this_vfsp, hidden_vp->v_type, (dev_t) NULL);  /* allocate and fill in fist_wrapfs_node_t */  fwnp = (fist_wrapfs_node_t *)    kmem_zalloc(sizeof(fist_wrapfs_node_t), KM_SLEEP);  if (!fwnp) {    kmem_free(fw_vp, sizeof(vnode_t));    fw_vp = NULL;    goto out;  }  /* init fwnp */  fwnp->fwn_mapcnt = 0;		/* no mapped pages */  mutex_init(&fwnp->fwn_lock, "fist_wrapfs private data lock",	     MUTEX_DEFAULT, NULL);  /* store new vnode */  fwnp->fwn_vnodep = hidden_vp;  fw_vp->v_data = (caddr_t) fwnp;  /* operations are fist_wrapfs vnode ops */  fw_vp->v_op = &wrapfs_vnodeops;  /* set rest of fields to NULL */  fw_vp->v_vfsmountedhere = NULL;  fw_vp->v_filocks = NULL;  /* don't do this one for now */  /* fw_vp->v_cv = NULL; */  /* increment interposed vnodes counter */  fwip = vfstofwi(this_vfsp);  fwip->fwi_num_vnodes++;  /* insert into HT */  fist_ht_insert_vp(hidden_vp, fw_vp);  /* VN_RELE(hidden_vp); */#if 0  /* hold our vnode */  VN_HOLD(fw_vp);#endifout:  mutex_exit(&vfstofwi(this_vfsp)->fwi_ht_lock);  print_location();  /* finally  return vnode to this newly created one */  return (fw_vp);}static intwrapfs_open(	    vnode_t ** vpp,	    int flag,	    cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp, *new_vp;  fist_dprint(4, "wrapfs_open vpp %x, flag 0x%x\n", vpp, flag);  if (flag & FAPPEND) {    fist_dprint(6, "***WARNING*** file is opened in append-only mode!!!\n");    flag &= ~FAPPEND;		/* turn off FAPPEND flag */  }  new_vp = hidden_vp = vntofwn(*vpp)->fwn_vnodep;  /* we NEED read access */  flag |= FREAD;  /* pass operation to hidden filesystem, and return status */  error = VOP_OPEN(&hidden_vp, flag, cr);  /* check if a new vnode was returned (cloned) */  if (!error && new_vp != hidden_vp) {    fist_dprint(6, "WRAPFS_OPEN1: hidden_vp->v_count %d\n",		hidden_vp->v_count);    /*     * yes: need to allocate a new fist_wrapfs vnode,     * initialize it, store interposed vnode in it, and     * finally return the fist_wrapfs vnode back.     */    *vpp = wrapfs_interpose(hidden_vp, (*vpp)->v_vfsp);    fist_dprint(6, "WRAPFS_OPEN2: vpp->v_count %d, hidden_vp->v_count %d\n",		(*vpp)->v_count, hidden_vp->v_count);  }  print_location();  return (error);}static intwrapfs_close(	     vnode_t * vp,	     int flag,	     int count,	     offset_t offset,	     cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  fist_dprint(4, "wrapfs_close vp %x\n", vp);  hidden_vp = vntofwn(vp)->fwn_vnodep;  fist_dprint(6, "WRAPFS_CLOSE1: vp->v_count %d, hidden_vp->v_count %d\n",	      vp->v_count, hidden_vp->v_count);  /* pass operation to hidden filesystem, and return status */  error = VOP_CLOSE(hidden_vp, flag, count, offset, cr);  fist_dprint(6, "WRAPFS_CLOSE2: vp->v_count %d, hidden_vp->v_count %d\n",	      vp->v_count, hidden_vp->v_count);  print_location();  return (error);}static intwrapfs_read(	    vnode_t * vp,	    uio_t * uiop,	    int ioflag,	    cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  uio_t temp_uio;  iovec_t *temp_iovec;  caddr_t current_base;  int i, bytes_read;  int num_pages, resid;  long long start_loffset, end_loffset;  long long cleartext_start_loffset, cleartext_end_loffset, current_loffset;  fist_dprint(4, "wrapfs_read vp %x\n", vp);#ifdef FIST_DEBUG  fist_print_uios("wrapfs_read", uiop);#endif /* FIST_DEBUG */  cleartext_start_loffset = uiop->uio_loffset;  cleartext_end_loffset = uiop->uio_loffset + uiop->uio_resid;  start_loffset = cleartext_start_loffset & ~(PAGESIZE - 1);  end_loffset = cleartext_end_loffset & ~(PAGESIZE - 1);  /*   * if not multiple of PAGESIZE, then the above formula loses one page.   * adjust for it   */  if (cleartext_end_loffset > end_loffset)    end_loffset += PAGESIZE;  resid = end_loffset - start_loffset;  num_pages = resid >> PAGESHIFT;  fist_dprint(6,	      "READ: so=%d eo=%d cs=%d es=%d res=%d np=%d ps=%d\n",	      (int) start_loffset,	      (int) end_loffset,	      (int) cleartext_start_loffset,	      (int) cleartext_end_loffset,	      resid,	      num_pages,	      PAGESIZE);  temp_iovec = kmem_zalloc(num_pages * sizeof(iovec_t), KM_SLEEP);  for (i = 0; i < num_pages; i++) {    temp_iovec[i].iov_len = PAGESIZE;    temp_iovec[i].iov_base = kmem_zalloc(PAGESIZE, KM_SLEEP);    fist_dprint(6, "READ allocated %d address 0x%x\n",		i, temp_iovec[i].iov_base);  }  temp_uio.uio_iov = temp_iovec;  temp_uio.uio_iovcnt = num_pages;  temp_uio.uio_loffset = start_loffset;  temp_uio.uio_segflg = UIO_SYSSPACE;  temp_uio.uio_fmode = uiop->uio_fmode;  temp_uio.uio_llimit = uiop->uio_llimit;  temp_uio.uio_resid = resid;  hidden_vp = vntofwn(vp)->fwn_vnodep;  /*   * pass operation to hidden filesystem, and return status   */  error = VOP_READ(hidden_vp, &temp_uio, ioflag, cr);  if (error) {    fist_dprint(4, "VOP_READ in read returned error - not good\n");    /* XXX to be checked */    goto out_free;  }  current_loffset = start_loffset;  for (i = 0; i < num_pages; i++) {    bytes_read = PAGESIZE - temp_iovec[i].iov_len;    if (bytes_read == 0)      break;    temp_iovec[i].iov_base -= bytes_read;    current_base = temp_iovec[i].iov_base;    /* decodes the page/block */    wrapfs_decode_block(current_base, current_base, bytes_read, vp, vp->v_vfsp);    /*     * save the original size, for kmem_free.     * no need for it w/ wrapfs; size is always PAGESIZE, hence this line     * is commented out:     *		temp_iovec[i].iov_len = uiop->uio_iov[i].iov_len;     */    /* treat first and last iovec separately, not all data in them is needed */    if (current_loffset + bytes_read > cleartext_end_loffset) {      bytes_read = cleartext_end_loffset - current_loffset;    }    if (i == 0) {      bytes_read -= cleartext_start_loffset - start_loffset;      current_loffset += cleartext_start_loffset - start_loffset;      current_base += cleartext_start_loffset - start_loffset;    }    if ((error = uiomove(current_base, bytes_read, UIO_READ, uiop)))      /*       * XXX: we have to see the exact semantics of returning with an       * EFAULT from read       */      break;    current_loffset += bytes_read;  }out_free:  for (i = 0; i < num_pages; i++) {    fist_dprint(6, "READ freeing %d address 0x%x\n",		i, temp_iovec[i].iov_base);    kmem_free(temp_iovec[i].iov_base, PAGESIZE);  }  kmem_free(temp_iovec, num_pages * sizeof(iovec_t));#ifdef FIST_DEBUG  fist_print_uios("wrapfs_read (END)", uiop);#endif /* FIST_DEBUG */  print_location();  return (error);}static intwrapfs_write(	     vnode_t * vp,	     uio_t * uiop,	     int ioflag,	     cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  vattr_t va;  uio_t temp_uio;  iovec_t *temp_iovec;  iovec_t *free_iovec;		/* for freeing allocated memory */  int i;  caddr_t current_base;  int resid, bytes_read, num_pages, first_page_bytes, real_first_page;  long long start_loffset, end_loffset, real_start_loffset;  long long cleartext_start_loffset, cleartext_end_loffset, current_loffset;  int hidden_ioflag = (ioflag & ~FAPPEND);  fist_dprint(4, "wrapfs_write vp %x, ioflag 0x5x\n", vp, ioflag);#ifdef FIST_DEBUG  fist_print_uios("wrapfs_write (START)", uiop);#endif /* FIST_DEBUG */  hidden_vp = vntofwn(vp)->fwn_vnodep;  /* we don't want anybody to do updates while we write, so lock the vnode */  mutex_enter(&vp->v_lock);  /* get the attributes, length is necessary for correct updates */  va.va_mask = AT_SIZE;  if ((error = VOP_GETATTR(hidden_vp, &va, 0, cr))) {    fist_dprint(4, "VOP_GETATTR returned error - not good\n");

⌨️ 快捷键说明

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