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

📄 vnode.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* XXX to be checked */    goto out;  }  /* just in case someone tries to pull a fast one */  if (uiop->uio_resid == 0) {    error = 0;    goto out;  }  cleartext_start_loffset = uiop->uio_loffset;  cleartext_end_loffset = uiop->uio_loffset + uiop->uio_resid;  if (ioflag & FAPPEND) {    fist_dprint(6, "WRITE: turning off append flag\n");    cleartext_start_loffset += va.va_size;    cleartext_end_loffset += va.va_size;  }  start_loffset = MIN(cleartext_start_loffset, va.va_size) & ~(PAGESIZE - 1);  real_start_loffset = cleartext_start_loffset & ~(PAGESIZE - 1);  first_page_bytes = MIN(cleartext_start_loffset, va.va_size) - start_loffset;  /* must use this to avoid shifting a quad w/ gcc */  real_first_page = (int)(real_start_loffset - start_loffset) >> PAGESHIFT;  end_loffset = cleartext_end_loffset & ~(PAGESIZE - 1);  ASSERT(first_page_bytes <= PAGESIZE);  /*   * 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;  if (num_pages == 1)    first_page_bytes = PAGESIZE;  temp_iovec = kmem_zalloc(num_pages * sizeof(iovec_t), KM_SLEEP);  free_iovec = kmem_zalloc(num_pages * sizeof(iovec_t), KM_SLEEP);  for (i = 0; i < num_pages; i++) {    temp_iovec[i].iov_len = free_iovec[i].iov_len = PAGESIZE;    /* we need the pages to be zeroed out */    temp_iovec[i].iov_base = free_iovec[i].iov_base = kmem_zalloc(PAGESIZE, KM_SLEEP);  }  fist_dprint(6,	      "WRITE: so=%d eo=%d cso=%d ceo=%d rso=%d res=%d np=%d rfp=%d\n",	      (int) start_loffset,	      (int) end_loffset,	      (int) cleartext_start_loffset,	      (int) cleartext_end_loffset,	      (int) real_start_loffset,	      resid,	      num_pages,	      real_first_page	      );  current_loffset = start_loffset;  /* read first block XXX check length of file */  temp_uio.uio_iov = temp_iovec;  temp_uio.uio_iovcnt = 1;  temp_uio.uio_loffset = start_loffset;  temp_uio.uio_segflg = UIO_SYSSPACE;  temp_uio.uio_fmode = FREAD;  temp_uio.uio_llimit = uiop->uio_llimit;  temp_uio.uio_resid = first_page_bytes;  fist_print_uios("WRITE (before VOP_READ 1)", &temp_uio);  error = VOP_READ(hidden_vp, &temp_uio, hidden_ioflag, cr);  if (error) {    fist_dprint(5, "VOP_READ returned error - not good\n");    /* XXX to be checked */    goto out_free;  }  fist_print_uios("WRITE (after VOP_READ 1)", &temp_uio);  bytes_read = PAGESIZE - temp_iovec[0].iov_len;  temp_iovec[0].iov_base -= bytes_read;  temp_iovec[0].iov_len = PAGESIZE;  /* decode block read */  wrapfs_decode_block(temp_iovec[0].iov_base, temp_iovec[0].iov_base, bytes_read, vp, vp->v_vfsp);  /*   * if num_pages == 1, we already read the page... don't clobber it   * if num_pages > 1, then we must read the last page, and decodes it   * completely, before clobbering it.   * XXX: if end offset is on page boundary, we don't have to do this.   */  if (num_pages > 1) {    /* read last block XXX check length of file */    temp_uio.uio_iov = temp_iovec + (num_pages - 1);    temp_uio.uio_iovcnt = 1;    temp_uio.uio_loffset = end_loffset - PAGESIZE;    temp_uio.uio_segflg = UIO_SYSSPACE;    temp_uio.uio_fmode = FREAD;    temp_uio.uio_llimit = uiop->uio_llimit;    temp_uio.uio_resid = PAGESIZE;    fist_print_uios("WRITE (before VOP_READ 2)", &temp_uio);    error = VOP_READ(hidden_vp, &temp_uio, hidden_ioflag, cr);    fist_print_uios("WRITE (after VOP_READ 3)", &temp_uio);    if (error) {      fist_dprint(4, "VOP_READ returned error - not good\n");      /* XXX to be checked */      goto out_free;    }    bytes_read = PAGESIZE - temp_iovec[num_pages - 1].iov_len;    temp_iovec[num_pages - 1].iov_base -= bytes_read;    temp_iovec[num_pages - 1].iov_len = PAGESIZE;    /* decodes block read */    wrapfs_decode_block(temp_iovec[num_pages-1].iov_base, temp_iovec[num_pages-1].iov_base, bytes_read, vp, vp->v_vfsp);  }  /*   * Now we are ready to write the bytes within the start/end   * cleartext offsets in the buffers we allocated.   */  for (i = 0; i < num_pages; i++) {    if (i >= real_first_page) {      bytes_read = PAGESIZE;      current_base = temp_iovec[i].iov_base;      if (i == real_first_page) {#define real_first_page_offset (cleartext_start_loffset - real_start_loffset)	bytes_read -= real_first_page_offset;	current_loffset += real_first_page_offset;	current_base += real_first_page_offset;#undef real_first_page_offset      }      if (current_loffset + bytes_read > cleartext_end_loffset) {	bytes_read = cleartext_end_loffset - current_loffset;      }      if ((error = uiomove(current_base, bytes_read, UIO_WRITE, uiop)))	break;    }    /* encode block before writing */    wrapfs_encode_block(temp_iovec[i].iov_base, temp_iovec[i].iov_base, PAGESIZE, vp, vp->v_vfsp);    current_loffset += bytes_read;  }  fist_print_uios("WRITE (after for loop 4)", &temp_uio);  if (va.va_size < end_loffset) {    if (va.va_size < cleartext_end_loffset)      resid -= end_loffset - cleartext_end_loffset;    else      resid -= end_loffset - va.va_size;  }  /* XXX: no need for full initialization here */  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;  /*   * pass operation to hidden filesystem, and return status   */  fist_print_uios("WRITE (before write)", &temp_uio);  error = VOP_WRITE(hidden_vp, &temp_uio, hidden_ioflag, cr);  fist_print_uios("WRITE (after write)", &temp_uio);  if (temp_uio.uio_loffset < cleartext_end_loffset) {    /* incomplete write: this case is an error and should not happen */    uiop->uio_loffset = temp_uio.uio_loffset;    uiop->uio_resid = cleartext_end_loffset - temp_uio.uio_loffset;  } else {    /*     * we may have written more than what was asked of us to preserve the     * encoding/decoding over a whole page     */    uiop->uio_loffset = cleartext_end_loffset;    uiop->uio_resid = 0;  }  /* if FAPPEND was used, return offset of 0 to upper level */  if (ioflag & FAPPEND) {    uiop->uio_loffset = 0;  }out_free:  for (i = 0; i < num_pages; i++) {    fist_dprint(6, "PRINT_BASE1 %d: 0x%x (len=%d)\n", i,		temp_iovec[i].iov_base,		temp_iovec[i].iov_len);    fist_dprint(6, "PRINT_BASE2 %d: 0x%x (len=%d)\n", i,		free_iovec[i].iov_base,		free_iovec[i].iov_len);    kmem_free(free_iovec[i].iov_base, PAGESIZE);  }  kmem_free(free_iovec, num_pages * sizeof(iovec_t));  kmem_free(temp_iovec, num_pages * sizeof(iovec_t));out:  mutex_exit(&vp->v_lock);#ifdef FIST_DEBUG  fist_print_uios("wrapfs_write (END)", uiop);#endif /* FIST_DEBUG */  print_location();  return (error);}static intwrapfs_ioctl(	     vnode_t * vp,	     int cmd,	     int arg,	     int flag,	     cred_t * cr,	     int *rvalp){  int error = 0;  vnode_t *hidden_vp;  vfs_t *this_vfs = vp->v_vfsp;  vnode_t *this_vnode = vp;#ifdef FIST_DEBUG  int val = 0;#endif /* FIST_DEBUG */  fist_dprint(4, "wrapfs_ioctl this_vfs %x vp %x cmd %d\n", this_vfs, vp, cmd);  /* check if asked for local commands */  switch (cmd) {#ifdef FIST_DEBUG  case FIST_IOCTL_GET_DEBUG_VALUE:    if (copyin((caddr_t) arg, (caddr_t) & val, sizeof(int))) {      error = EFAULT;      goto out;    }    val = fist_get_debug_value();    if (copyout((caddr_t) & val, (caddr_t) arg, sizeof(int))) {      error = EFAULT;      goto out;    }    error = 0;    goto out;    break;  case FIST_IOCTL_SET_DEBUG_VALUE:    if (copyin((caddr_t) arg, (caddr_t) & val, sizeof(int))) {      error = EFAULT;      goto out;    }    if (val < 0 || val > 20) {      error = EINVAL;      goto out;    }    fist_dprint(6, "IOCTL: got arg %d\n", val);    fist_set_debug_value(val);    error = 0;    goto out;    break;#endif /* FIST_DEBUG */    /* add non-debugging fist ioctl's here */FIST_IOCTL_ECLS  default:    hidden_vp = vntofwn(vp)->fwn_vnodep;    /* pass operation to hidden filesystem, and return status */    error = VOP_IOCTL(hidden_vp, cmd, arg, flag, cr, rvalp);  } /* end of switch statement */#ifdef FIST_DEBUGout:#endif /* FIST_DEBUG */  print_location();  return (error);}static intwrapfs_setfl(	     vnode_t * vp,	     int oflags,	     int nflags,	     cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  fist_dprint(4, "wrapfs_setfl vp %x\n", vp);  hidden_vp = vntofwn(vp)->fwn_vnodep;  /* pass operation to hidden filesystem, and return status */  error = VOP_SETFL(hidden_vp, oflags, nflags, cr);  print_location();  return (error);}static intwrapfs_getattr(	       vnode_t * vp,	       vattr_t * vap,	       int flags,	       cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  fist_dprint(4, "wrapfs_getattr vp %x\n", vp);  hidden_vp = vntofwn(vp)->fwn_vnodep;  /* pass operation to hidden filesystem, and return status */  error = VOP_GETATTR(hidden_vp, vap, flags, cr);  if (error) {    fist_dprint(4, "ERROR: wrapfs_getattr %d\n", error);  }  print_location();  return (error);}static intwrapfs_setattr(	       vnode_t * vp,	       vattr_t * vap,	       int flags,	       cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  fist_dprint(4, "wrapfs_setattr vp %x\n", vp);  hidden_vp = vntofwn(vp)->fwn_vnodep;  /* pass operation to hidden filesystem, and return status */  error = VOP_SETATTR(hidden_vp, vap, flags, cr);  print_location();  return (error);}static intwrapfs_access(	      vnode_t * vp,	      int mode,	      int flags,	      cred_t * cr){  int error = EPERM;  vnode_t *hidden_vp;  fist_dprint(4, "wrapfs_access vp %x\n", vp);  hidden_vp = vntofwn(vp)->fwn_vnodep;  /* pass operation to hidden filesystem, and return status */  error = VOP_ACCESS(hidden_vp, mode, flags, cr);  print_location();  return (error);}static intwrapfs_lookup(	      vnode_t * dvp,	      char *name,	      vnode_t ** vpp,	      pathname_t * pnp,	      int flags,	      vnode_t * rdir,	      cred_t * cr){  int err = EPERM;  vnode_t *this_vnode = dvp;  vnode_t *hidden_dvp;  vnode_t *this_dir = dvp;  char *encoded_name = name;#ifdef FIST_FILTER_NAME  int encoded_length;#endif /* FIST_FILTER_NAME */  fist_dprint(4, "wrapfs_lookup dvp %x, rdir %x, name \"%s\"\n",	      dvp, rdir, (name ? name : "Null"));  hidden_dvp = vntofwn(this_vnode)->fwn_vnodep;  FIST_OP_LOOKUP_PRECALL;#ifdef FIST_FILTER_NAME  encoded_length = wrapfs_encode_filename(name, strlen(name), &encoded_name, SKIP_DOTS, dvp, dvp->v_vfsp);#endif /* FIST_FILTER_NAME */  /* pass operation to hidden filesystem, and return status */  err = VOP_LOOKUP(hidden_dvp, encoded_name, vpp, pnp, flags, rdir, cr);  FIST_OP_LOOKUP_POSTCALL;  /* if no error, interpose vnode */  if (!err) {    fist_dprint(6, "WRAPFS_LOOKUP1: hidden_vp->v_count=%d, vpp->v_type=%d\n",		(*vpp)->v_count, (*vpp)->v_type);    *vpp = wrapfs_interpose(*vpp, dvp->v_vfsp);    fist_dprint(6, "WRAPFS_LOOKUP2: vpp->v_count=%d, hidden_vp->v_count=%d, vpp->v_type=%d\n",		(*vpp)->v_count, vntofwn(*vpp)->fwn_vnodep->v_count,		(*vpp)->v_type);  }#ifdef FIST_FILTER_NAME  kmem_free(encoded_name, encoded_length);#endif /* FIST_FILTER_NAME */  if (err) {    fist_dprint(4, "ERROR: wrapfs_lookup %d\n", err);  }  FIST_OP_LOOKUP_POSTCALL;  print_location();  return (err);}static intwrapfs_create(	      vnode_t * dvp,	      char *name,	      vattr_t * vap,	      vcexcl_t excl,	      int mode,	      vnode_t ** vpp,	      cred_t * cr,	      int flag  /* XXX: EZK: new in 2.6, why? 64-bit support? */){  int error = EPERM;  vnode_t *hidden_vp;  char *encoded_name = name;#ifdef FIST_FILTER_NAME  int encoded_length;#endif /* FIST_FILTER_NAME */  fist_dprint(4, "wrapfs_create vp=%x name=\"%s\" mode=%x\n", dvp, name, mode);  hidden_vp = vntofwn(dvp)->fwn_vnodep;#ifdef FIST_FILTER_NAME  encoded_length = wrapfs_encode_filename(name, strlen(name), &encoded_name, SKIP_DOTS, dvp, dvp->v_vfsp);#endif /* FIST_FILTER_NAME */  /* pass operation to hidden filesystem, and return status */  error = VOP_CREATE(hidden_vp, encoded_name, vap, excl, mode, vpp, cr, flag);  /* if no error, interpose vnode */  if (!error) {    fist_dprint(6, "WRAPFS_CREATE1: hidden_vp->v_count %d\n", (*vpp)->v_count);    *vpp = wrapfs_interpose(*vpp, dvp->v_vfsp);    fist_dprint(6, "WRAPFS_CREATE2: vpp->v_count %d, hidden_vp->v_count %d\n",		(*vpp)->v_count, vntofwn(*vpp)->fwn_vnodep->v_count);  }#ifdef FIST_FILTER_NAME  kmem_free(encoded_name, encoded_length);#endif /* FIST_FILTER_NAME */

⌨️ 快捷键说明

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