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

📄 vnode.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
				      struct proc *p;				      } */ *ap;{  struct vnode *vp = ap->a_vp;  struct vnode *lowervp = VP_TO_WRAPFS(vp) ? WRAPFS_VP_TO_LOWERVP(vp) : NULL;  int error = 0;  fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  if (vp->v_type == VNON || lowervp == NULL) {    error = EINVAL; /* xxx - is this right */    goto retn;  }  /* create object for higher level vnode */  error = vop_stdcreatevobject(ap);  if (error)    goto retn;  /* now create the object for the lower layer */  error = VOP_CREATEVOBJECT(lowervp, ap->a_cred, ap->a_p);  if (error) {    struct vop_destroyvobject_args destroy;    destroy.a_vp = vp;    vop_stddestroyvobject(&destroy);  }retn:  print_location();  return (error);}#else /* not FIST_FILTER_DATA *//* let the underlying filesystem do the work */static intwrapfs_createvobject(ap)     struct vop_createvobject_args /* {				      struct vnode *vp;				      struct ucred *cred;				      struct proc *p;				      } */ *ap;{  struct vnode *vp = ap->a_vp;  struct vnode *lowervp = VP_TO_WRAPFS(vp) ? WRAPFS_VP_TO_LOWERVP(vp) : NULL;  int error = 0;  fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  if (vp->v_type == VNON || lowervp == NULL) {    goto retn; /* returns 0! */  }  error = VOP_CREATEVOBJECT(lowervp, ap->a_cred, ap->a_p);  if (error)    goto retn;  vp->v_flag |= VOBJBUF;retn:  print_location();  return (error);}#endif /* not FIST_FILTER_DATA */#ifdef FIST_FILTER_DATA /* * if FIST_FILTER_DATA, then if the object of the higher vnode  * or lower level vnode exists, then delete them */static intwrapfs_destroyvobject(ap)     struct vop_destroyvobject_args /* {                                       struct vnode *vp;                                       } */ *ap;{  int error = 0;  struct vnode *vp = ap->a_vp;  struct vnode *lvp = WRAPFS_VP_TO_LOWERVP(vp);  vm_object_t obj = vp->v_object;  vm_object_t lower_obj;  struct vop_destroyvobject_args destroy;  fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  /* if the lower vnode exists destroy its object */  if (lvp) {    error = VOP_GETVOBJECT(lvp, &lower_obj);    if (!error)       error = VOP_DESTROYVOBJECT(lvp);    if (error) {      printk(" error destroying the lowervp \n");    }  }  destroy.a_vp = vp;  vop_stddestroyvobject(&destroy);  print_location();  return (error);}#else /* not FIST_FILTER_DATA *//* do nothing */static intwrapfs_destroyvobject(ap)     struct vop_destroyvobject_args /* {                                       struct vnode *vp;                                       } */ *ap;{  int error = 0;  struct vnode *vp = ap->a_vp;  fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  vp->v_flag &= ~VOBJBUF;  print_location();  return (error);}#endif /* not FIST_FILTER_DATA */#ifdef FIST_FILTER_DATAstatic intwrapfs_getvobject(ap)     struct vop_getvobject_args /* {                                   struct vnode *vp;                                   struct vm_object **objpp;                                   } */ *ap;{  struct vnode *vp = ap->a_vp;  struct vnode *lowervp = WRAPFS_VP_TO_LOWERVP(ap->a_vp);  struct vm_object **objpp = ap->a_objpp;  fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  /* XXX hack */  if (lowervp == NULL)    return EINVAL;  if (objpp)    *objpp = vp->v_object;  print_location();  return (vp->v_object ? 0 : EINVAL);}#else /* not FIST_FILTER_DATA */static intwrapfs_getvobject(ap)     struct vop_getvobject_args /* {				   struct vnode *vp;				   struct vm_object **objpp;				   } */ *ap;{  struct vnode *lvp = WRAPFS_VP_TO_LOWERVP(ap->a_vp);  fist_dprint(4, "FXN=%s FILE=%s LINE=%d\n",__FUNCTION__,__FILE__,__LINE__);  if (lvp == NULL)    return EINVAL;  print_location();  return (VOP_GETVOBJECT(lvp, ap->a_objpp));}#endif /* not FIST_FILTER_DATA *//****************************************************************************/#ifdef FIST_FILTER_DATA/* * Create a page in the vnode and insert data into it. * This is used to synchronize data between the VM and read/write interface. * That that was written using write() gets pages containing the same data, so * that subsequent mmap() ops get valid data. */voidwrapfs_fill_page(vnode_t *vp, char *buf, long long offset){  vm_page_t pp;  vm_offset_t kva;  caddr_t ca;  fist_dprint(4, "FILL_PAGE: vp=0x%x, buf=0x%x, offset=0x%x\n",              (int) vp, (int) buf, buf[0], buf[1], buf[2], (int) offset);  fist_dprint(1, "FILL_PAGE: vp=0x%x, buf=0x%x [%d,%d,%d], offset=0x%x\n",              (int) vp, (int) buf, buf[0], buf[1], buf[2], (int) offset);  pp = vm_page_grab(vp->v_object, OFF_TO_IDX(offset),                    VM_ALLOC_NORMAL | VM_ALLOC_RETRY);  if (!pp) {    printf("vm_page_grab returned NULL for offset 0x%x!\n", (int) offset);    return;  }  kva = vm_pager_map_page(pp);  ca = (caddr_t) kva;  bcopy(buf, ca, PAGE_SIZE);  vm_pager_unmap_page(kva);  vm_page_set_validclean(pp, 0, PAGE_SIZE);  if (pp->wire_count == 0 && pp->hold_count == 0 &&      pp->busy == 0  && pp->flags & PG_BUSY ) {      vm_page_free(pp);  }  /*  if (pp->flags & PG_WANTED) {    vm_page_activate(pp);  } else {    vm_page_deactivate(pp);    }*/  vm_page_wakeup(pp);  print_location();}static intwrapfs_read(ap)     struct vop_read_args /* {                             struct vnode *a_vp;                             struct uio *a_uio;                             int  a_ioflag;                             struct ucred *a_cred;                             } */ *ap;{  /* easy mappings */  vnode_t *vp = ap->a_vp;  uio_t *uiop = ap->a_uio;  int ioflag = ap->a_ioflag;  cred_t *cr = ap->a_cred;  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, "fist_wrapfs_read vp %x\n", (int) vp);#ifdef FIST_DEBUG  fist_print_uios("fist_wrapfs_read", uiop);#endif /* FIST_DEBUG */  cleartext_start_loffset = uiop->uio_offset;  cleartext_end_loffset = uiop->uio_offset + uiop->uio_resid;  start_loffset = cleartext_start_loffset & ~(PAGE_SIZE - 1);  end_loffset = cleartext_end_loffset & ~(PAGE_SIZE - 1);  /* if not multiple of PAGE_SIZE, then the above formula loses one page.   * adjust for it */  if (cleartext_end_loffset > end_loffset)    end_loffset += PAGE_SIZE;  resid = end_loffset - start_loffset;  num_pages = resid >> PAGE_SHIFT;  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,              PAGE_SIZE);  temp_iovec = kmem_zalloc(num_pages * sizeof(iovec_t));  for (i = 0; i < num_pages; i++) {    temp_iovec[i].iov_len = PAGE_SIZE;    temp_iovec[i].iov_base = kmem_zalloc(PAGE_SIZE);    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_offset = start_loffset;  temp_uio.uio_segflg = UIO_SYSSPACE;  temp_uio.uio_rw = uiop->uio_rw;  temp_uio.uio_procp = uiop->uio_procp;  temp_uio.uio_resid = resid;  hidden_vp = WRAPFS_VP_TO_LOWERVP(vp);  /*   * 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 = PAGE_SIZE - temp_iovec[i].iov_len;     if (bytes_read == 0)      break;    temp_iovec[i].iov_base -= bytes_read;    current_base = temp_iovec[i].iov_base;    /* decode the page/block */    wrapfs_decode_block( current_base, current_base, bytes_read, vp, 			 vp->v_mount, OFF_TO_IDX(current_loffset));    /*     * save the original size, for kmem_free.     * no need for it w/ wrapfs; size is always PAGE_SIZE, 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 = fist_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);  }  kmem_free(temp_iovec);#ifdef FIST_DEBUG  fist_print_uios("fist_wrapfs_read (END)", uiop);#endif /* FIST_DEBUG */  print_location();  return (error);}static intwrapfs_write(ap)     struct vop_write_args /* {			     struct vnode *a_vp;			     struct uio *a_uio;			     int  a_ioflag;			     struct ucred *a_cred;			     } */ *ap;{  /* easy mappings */  vnode_t *vp = ap->a_vp;  uio_t *uiop = ap->a_uio;  int ioflag = ap->a_ioflag;  cred_t *cr = ap->a_cred;  struct proc *p = curproc;	/* XXX */  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;  long long page_loffset; /* maintain offset to be passed to wrapfs_fill_page */  int hidden_ioflag = (ioflag & ~IO_APPEND);  fist_dprint(4, "fist_wrapfs_write vp=0x%x ioflag=0x%x offset=0x%x resid=%d iovcnt=%x\n",	      (int) vp, ioflag, (int) uiop->uio_offset, uiop->uio_resid, uiop->uio_iovcnt);#ifdef FIST_DEBUG  fist_print_uios("fist_wrapfs_write (START)", uiop);#endif /* FIST_DEBUG */  hidden_vp = WRAPFS_VP_TO_LOWERVP(vp);  /* we don't want anybody to do updates while we write, so lock the vnode */#ifdef DO_WLOCK  VREF(hidden_vp);		/* XXX: is this needed? */  vn_lock(hidden_vp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE, p);#endif  /* get the attributes, length is necessary for correct updates */  if ((error = VOP_GETATTR(hidden_vp, &va, cr, p))) {    fist_dprint(4, "VOP_GETATTR returned error - not good\n");    /* 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_offset;  cleartext_end_loffset = uiop->uio_offset + uiop->uio_resid;  if (ioflag & IO_APPEND) {    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) & ~(PAGE_SIZE - 1);  real_start_loffset = cleartext_start_loffset & ~(PAGE_SIZE - 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) >> PAGE_SHIFT;  end_loffset = cleartext_end_loffset & ~(PAGE_SIZE - 1);  ASSERT(first_page_bytes <= PAGE_SIZE);  /*   * if not multiple of PAGE_SIZE, then the above formula loses one page.   * adjust for it   */  if (cleartext_end_loffset > end_loffset)    end_loffset += PAGE_SIZE;  resid = end_loffset - start_loffset;  num_pages = resid >> PAGE_SHIFT;  if (num_pages == 1)    first_page_bytes = PAGE_SIZE;  temp_iovec = kmem_zalloc(num_pages * sizeof(iovec_t));  free_iovec = kmem_zalloc(num_pages * sizeof(iovec_t));  for (i = 0; i < num_pages; i++) {    temp_iovec[i].iov_len = free_iovec[i].iov_len = PAGE_SIZE;    /* we need the pages to be zeroed out */    temp_iovec[i].iov_base = free_iovec[i].iov_base = kmem_zalloc(PAGE_SIZE);  }  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,

⌨️ 快捷键说明

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