[BACK]Return to spec_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / miscfs / specfs

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/miscfs/specfs/spec_vnops.c between version 1.104 and 1.104.2.5

version 1.104, 2007/08/03 08:45:36 version 1.104.2.5, 2007/12/03 16:15:05
Line 52  __KERNEL_RCSID(0, "$NetBSD$");
Line 52  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/lockf.h>  #include <sys/lockf.h>
 #include <sys/tty.h>  #include <sys/tty.h>
 #include <sys/kauth.h>  #include <sys/kauth.h>
   #include <sys/fstrans.h>
   
 #include <miscfs/genfs/genfs.h>  #include <miscfs/genfs/genfs.h>
 #include <miscfs/specfs/specdev.h>  #include <miscfs/specfs/specdev.h>
Line 166  spec_open(void *v)
Line 167  spec_open(void *v)
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int  a_mode;                  int  a_mode;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct lwp *l = ap->a_l;          struct lwp *l = curlwp;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         dev_t dev = (dev_t)vp->v_rdev;          dev_t dev = (dev_t)vp->v_rdev;
         int error;          int error;
Line 195  spec_open(void *v)
Line 195  spec_open(void *v)
                         return (error);                          return (error);
   
                 if (cdev_type(dev) == D_TTY)                  if (cdev_type(dev) == D_TTY)
                         vp->v_flag |= VISTTY;                          vp->v_vflag |= VV_ISTTY;
                 VOP_UNLOCK(vp, 0);                  VOP_UNLOCK(vp, 0);
                 error = cdev_open(dev, ap->a_mode, S_IFCHR, l);                  error = cdev_open(dev, ap->a_mode, S_IFCHR, l);
                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);                  vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
Line 295  spec_read(void *v)
Line 295  spec_read(void *v)
                         error = bread(vp, bn, bsize, NOCRED, &bp);                          error = bread(vp, bn, bsize, NOCRED, &bp);
                         n = min(n, bsize - bp->b_resid);                          n = min(n, bsize - bp->b_resid);
                         if (error) {                          if (error) {
                                 brelse(bp);                                  brelse(bp, 0);
                                 return (error);                                  return (error);
                         }                          }
                         error = uiomove((char *)bp->b_data + on, n, uio);                          error = uiomove((char *)bp->b_data + on, n, uio);
                         brelse(bp);                          brelse(bp, 0);
                 } while (error == 0 && uio->uio_resid > 0 && n != 0);                  } while (error == 0 && uio->uio_resid > 0 && n != 0);
                 return (error);                  return (error);
   
Line 370  spec_write(void *v)
Line 370  spec_write(void *v)
                         else                          else
                                 error = bread(vp, bn, bsize, NOCRED, &bp);                                  error = bread(vp, bn, bsize, NOCRED, &bp);
                         if (error) {                          if (error) {
                                 brelse(bp);                                  brelse(bp, 0);
                                 return (error);                                  return (error);
                         }                          }
                         n = min(n, bsize - bp->b_resid);                          n = min(n, bsize - bp->b_resid);
                         error = uiomove((char *)bp->b_data + on, n, uio);                          error = uiomove((char *)bp->b_data + on, n, uio);
                         if (error)                          if (error)
                                 brelse(bp);                                  brelse(bp, 0);
                         else {                          else {
                                 if (n + on == bsize)                                  if (n + on == bsize)
                                         bawrite(bp);                                          bawrite(bp);
                                 else                                  else
                                         bdwrite(bp);                                          bdwrite(bp);
                                 if (bp->b_error != 0)                                  error = bp->b_error;
                                         error = bp->b_error;  
                         }                          }
                 } while (error == 0 && uio->uio_resid > 0 && n != 0);                  } while (error == 0 && uio->uio_resid > 0 && n != 0);
                 return (error);                  return (error);
Line 407  spec_ioctl(void *v)
Line 406  spec_ioctl(void *v)
                 void  *a_data;                  void  *a_data;
                 int  a_fflag;                  int  a_fflag;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp;          struct vnode *vp;
         dev_t dev;          dev_t dev;
Line 420  spec_ioctl(void *v)
Line 418  spec_ioctl(void *v)
         vp = ap->a_vp;          vp = ap->a_vp;
         dev = NODEV;          dev = NODEV;
         simple_lock(&vp->v_interlock);          simple_lock(&vp->v_interlock);
         if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) {          if ((vp->v_iflag & VI_XLOCK) == 0 && vp->v_specinfo) {
                 dev = vp->v_rdev;                  dev = vp->v_rdev;
         }          }
         simple_unlock(&vp->v_interlock);          simple_unlock(&vp->v_interlock);
Line 432  spec_ioctl(void *v)
Line 430  spec_ioctl(void *v)
   
         case VCHR:          case VCHR:
                 return cdev_ioctl(dev, ap->a_command, ap->a_data,                  return cdev_ioctl(dev, ap->a_command, ap->a_data,
                     ap->a_fflag, ap->a_l);                      ap->a_fflag, curlwp);
   
         case VBLK:          case VBLK:
                 if (ap->a_command == 0 && (long)ap->a_data == B_TAPE) {  
                         if (bdev_type(dev) == D_TAPE)  
                                 return (0);  
                         else  
                                 return (1);  
                 }  
                 return bdev_ioctl(dev, ap->a_command, ap->a_data,                  return bdev_ioctl(dev, ap->a_command, ap->a_data,
                    ap->a_fflag, ap->a_l);                     ap->a_fflag, curlwp);
   
         default:          default:
                 panic("spec_ioctl");                  panic("spec_ioctl");
Line 457  spec_poll(void *v)
Line 449  spec_poll(void *v)
         struct vop_poll_args /* {          struct vop_poll_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int a_events;                  int a_events;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp;          struct vnode *vp;
         dev_t dev;          dev_t dev;
Line 470  spec_poll(void *v)
Line 461  spec_poll(void *v)
         vp = ap->a_vp;          vp = ap->a_vp;
         dev = NODEV;          dev = NODEV;
         simple_lock(&vp->v_interlock);          simple_lock(&vp->v_interlock);
         if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) {          if ((vp->v_iflag & VI_XLOCK) == 0 && vp->v_specinfo) {
                 dev = vp->v_rdev;                  dev = vp->v_rdev;
         }          }
         simple_unlock(&vp->v_interlock);          simple_unlock(&vp->v_interlock);
Line 481  spec_poll(void *v)
Line 472  spec_poll(void *v)
         switch (vp->v_type) {          switch (vp->v_type) {
   
         case VCHR:          case VCHR:
                 return cdev_poll(dev, ap->a_events, ap->a_l);                  return cdev_poll(dev, ap->a_events, curlwp);
   
         default:          default:
                 return (genfs_poll(v));                  return (genfs_poll(v));
Line 522  spec_mmap(void *v)
Line 513  spec_mmap(void *v)
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 vm_prot_t a_prot;                  vm_prot_t a_prot;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
   
Line 546  spec_fsync(void *v)
Line 536  spec_fsync(void *v)
                 int  a_flags;                  int  a_flags;
                 off_t offlo;                  off_t offlo;
                 off_t offhi;                  off_t offhi;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
   
Line 567  spec_strategy(void *v)
Line 556  spec_strategy(void *v)
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct buf *bp = ap->a_bp;          struct buf *bp = ap->a_bp;
         int error, s;          int error;
         struct spec_cow_entry *e;  
   
         error = 0;          error = 0;
         bp->b_dev = vp->v_rdev;          bp->b_dev = vp->v_rdev;
         if (!(bp->b_flags & B_READ) &&          if (!(bp->b_flags & B_READ) &&
             (LIST_FIRST(&bp->b_dep)) != NULL && bioops.io_start)              (LIST_FIRST(&bp->b_dep)) != NULL && bioopsp)
                 (*bioops.io_start)(bp);                  bioopsp->io_start(bp);
   
         if (!(bp->b_flags & B_READ) && !SLIST_EMPTY(&vp->v_spec_cow_head)) {          if (!(bp->b_flags & B_READ))
                 SPEC_COW_LOCK(vp->v_specinfo, s);                  error = fscow_run(bp, false);
                 while (vp->v_spec_cow_req > 0)  
                         ltsleep(&vp->v_spec_cow_req, PRIBIO, "cowlist", 0,  
                             &vp->v_spec_cow_slock);  
                 vp->v_spec_cow_count++;  
                 SPEC_COW_UNLOCK(vp->v_specinfo, s);  
   
                 SLIST_FOREACH(e, &vp->v_spec_cow_head, ce_list) {  
                         if ((error = (*e->ce_func)(e->ce_cookie, bp)) != 0)  
                                 break;  
                 }  
   
                 SPEC_COW_LOCK(vp->v_specinfo, s);  
                 vp->v_spec_cow_count--;  
                 if (vp->v_spec_cow_req && vp->v_spec_cow_count == 0)  
                         wakeup(&vp->v_spec_cow_req);  
                 SPEC_COW_UNLOCK(vp->v_specinfo, s);  
         }  
   
         if (error) {          if (error) {
                 bp->b_error = error;                  bp->b_error = error;
Line 653  spec_close(void *v)
Line 624  spec_close(void *v)
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int  a_fflag;                  int  a_fflag;
                 kauth_cred_t a_cred;                  kauth_cred_t a_cred;
                 struct lwp *a_l;  
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct session *sess;          struct session *sess;
Line 661  spec_close(void *v)
Line 631  spec_close(void *v)
         int mode, error, count, flags, flags1;          int mode, error, count, flags, flags1;
   
         count = vcount(vp);          count = vcount(vp);
         flags = vp->v_flag;          flags = vp->v_iflag;
   
         switch (vp->v_type) {          switch (vp->v_type) {
   
Line 680  spec_close(void *v)
Line 650  spec_close(void *v)
                  * actual tty device.                   * actual tty device.
                  */                   */
                 mutex_enter(&proclist_lock);                  mutex_enter(&proclist_lock);
                 if (count == 2 && ap->a_l &&                  if (count == 2 &&
                     vp == (sess = ap->a_l->l_proc->p_session)->s_ttyvp) {                      vp == (sess = curlwp->l_proc->p_session)->s_ttyvp) {
                         sess->s_ttyvp = NULL;                          sess->s_ttyvp = NULL;
                         if (sess->s_ttyp->t_session != NULL) {                          if (sess->s_ttyp->t_session != NULL) {
                                 sess->s_ttyp->t_pgrp = NULL;                                  sess->s_ttyp->t_pgrp = NULL;
Line 703  spec_close(void *v)
Line 673  spec_close(void *v)
                  * of forcably closing the device, otherwise we only                   * of forcably closing the device, otherwise we only
                  * close on last reference.                   * close on last reference.
                  */                   */
                 if (count > 1 && (flags & VXLOCK) == 0)                  if (count > 1 && (flags & VI_XLOCK) == 0)
                         return (0);                          return (0);
                 mode = S_IFCHR;                  mode = S_IFCHR;
                 break;                  break;
Line 714  spec_close(void *v)
Line 684  spec_close(void *v)
                  * we must invalidate any in core blocks, so that                   * we must invalidate any in core blocks, so that
                  * we can, for instance, change floppy disks.                   * we can, for instance, change floppy disks.
                  */                   */
                 error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_l, 0, 0);                  error = vinvalbuf(vp, V_SAVE, ap->a_cred, curlwp, 0, 0);
                 if (error)                  if (error)
                         return (error);                          return (error);
                 /*                  /*
Line 726  spec_close(void *v)
Line 696  spec_close(void *v)
                  * sum of the reference counts on all the aliased                   * sum of the reference counts on all the aliased
                  * vnodes descends to one, we are on last close.                   * vnodes descends to one, we are on last close.
                  */                   */
                 if (count > 1 && (flags & VXLOCK) == 0)                  if (count > 1 && (flags & VI_XLOCK) == 0)
                         return (0);                          return (0);
                 mode = S_IFBLK;                  mode = S_IFBLK;
                 break;                  break;
Line 738  spec_close(void *v)
Line 708  spec_close(void *v)
         flags1 = ap->a_fflag;          flags1 = ap->a_fflag;
   
         /*          /*
          * if VXLOCK is set, then we're going away soon, so make this           * if VI_XLOCK is set, then we're going away soon, so make this
          * non-blocking. Also ensures that we won't wedge in vn_lock below.           * non-blocking. Also ensures that we won't wedge in vn_lock below.
          */           */
         if (flags & VXLOCK)          if (flags & VI_XLOCK)
                 flags1 |= FNONBLOCK;                  flags1 |= FNONBLOCK;
   
         /*          /*
          * If we're able to block, release the vnode lock & reacquire. We           * If we're able to block, release the vnode lock & reacquire. We
          * might end up sleeping for someone else who wants our queues. They           * might end up sleeping for someone else who wants our queues. They
          * won't get them if we hold the vnode locked. Also, if VXLOCK is           * won't get them if we hold the vnode locked. Also, if VI_XLOCK is
          * set, don't release the lock as we won't be able to regain it.           * set, don't release the lock as we won't be able to regain it.
          */           */
         if (!(flags1 & FNONBLOCK))          if (!(flags1 & FNONBLOCK))
                 VOP_UNLOCK(vp, 0);                  VOP_UNLOCK(vp, 0);
   
         if (vp->v_type == VBLK)          if (vp->v_type == VBLK)
                 error = bdev_close(dev, flags1, mode, ap->a_l);                  error = bdev_close(dev, flags1, mode, curlwp);
         else          else
                 error = cdev_close(dev, flags1, mode, ap->a_l);                  error = cdev_close(dev, flags1, mode, curlwp);
   
         if (!(flags1 & FNONBLOCK))          if (!(flags1 & FNONBLOCK))
                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);                  vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);

Legend:
Removed from v.1.104  
changed lines
  Added in v.1.104.2.5

CVSweb <webmaster@jp.NetBSD.org>