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

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

Diff for /src/sys/miscfs/genfs/genfs_vnops.c between version 1.80.2.11 and 1.81

version 1.80.2.11, 2005/12/11 10:29:18 version 1.81, 2003/08/07 16:32:35
Line 33 
Line 33 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
 #if defined(_KERNEL_OPT)  
 #include "opt_nfsserver.h"  #include "opt_nfsserver.h"
 #endif  
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
Line 70  static void filt_genfsdetach(struct knot
Line 68  static void filt_genfsdetach(struct knot
 static int filt_genfsread(struct knote *, long);  static int filt_genfsread(struct knote *, long);
 static int filt_genfsvnode(struct knote *, long);  static int filt_genfsvnode(struct knote *, long);
   
 #define MAX_READ_PAGES  16      /* XXXUBC 16 */  
   #define MAX_READ_AHEAD  16      /* XXXUBC 16 */
   int genfs_rapages = MAX_READ_AHEAD; /* # of pages in each chunk of readahead */
   int genfs_racount = 2;          /* # of page chunks to readahead */
   int genfs_raskip = 2;           /* # of busy page chunks allowed to skip */
   
 int  int
 genfs_poll(void *v)  genfs_poll(void *v)
Line 78  genfs_poll(void *v)
Line 80  genfs_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;                  struct proc *a_p;
         } */ *ap = v;          } */ *ap = v;
   
         return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));          return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
 }  }
   
 int  int
   genfs_fsync(void *v)
   {
           struct vop_fsync_args /* {
                   struct vnode *a_vp;
                   struct ucred *a_cred;
                   int a_flags;
                   off_t offlo;
                   off_t offhi;
                   struct proc *a_p;
           } */ *ap = v;
           struct vnode *vp = ap->a_vp;
           int wait;
   
           wait = (ap->a_flags & FSYNC_WAIT) != 0;
           vflushbuf(vp, wait);
           if ((ap->a_flags & FSYNC_DATAONLY) != 0)
                   return (0);
           else
                   return (VOP_UPDATE(vp, NULL, NULL, wait ? UPDATE_WAIT : 0));
   }
   
   int
 genfs_seek(void *v)  genfs_seek(void *v)
 {  {
         struct vop_seek_args /* {          struct vop_seek_args /* {
Line 122  genfs_fcntl(void *v)
Line 146  genfs_fcntl(void *v)
                 caddr_t a_data;                  caddr_t a_data;
                 int a_fflag;                  int a_fflag;
                 struct ucred *a_cred;                  struct ucred *a_cred;
                 struct lwp *a_l;                  struct proc *a_p;
         } */ *ap = v;          } */ *ap = v;
   
         if (ap->a_command == F_SETFL)          if (ap->a_command == F_SETFL)
Line 233  genfs_revoke(void *v)
Line 257  genfs_revoke(void *v)
                 int a_flags;                  int a_flags;
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp, *vq;          struct vnode *vp, *vq;
         struct lwp *l = curlwp;         /* XXX */          struct proc *p = curproc;       /* XXX */
   
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if ((ap->a_flags & REVOKEALL) == 0)          if ((ap->a_flags & REVOKEALL) == 0)
Line 250  genfs_revoke(void *v)
Line 274  genfs_revoke(void *v)
                  */                   */
                 if (vp->v_flag & VXLOCK) {                  if (vp->v_flag & VXLOCK) {
                         vp->v_flag |= VXWANT;                          vp->v_flag |= VXWANT;
                         ltsleep(vp, PINOD|PNORELOCK, "vop_revokeall", 0,                          simple_unlock(&vp->v_interlock);
                                 &vp->v_interlock);                          tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
                         return (0);                          return (0);
                 }                  }
                 /*                  /*
Line 281  genfs_revoke(void *v)
Line 305  genfs_revoke(void *v)
                 simple_lock(&vp->v_interlock);                  simple_lock(&vp->v_interlock);
                 vp->v_flag &= ~VXLOCK;                  vp->v_flag &= ~VXLOCK;
         }          }
         vgonel(vp, l);          vgonel(vp, p);
         return (0);          return (0);
 }  }
   
Line 297  genfs_lock(void *v)
Line 321  genfs_lock(void *v)
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
   
         return (lockmgr(vp->v_vnlock, ap->a_flags, &vp->v_interlock));          return (lockmgr(&vp->v_lock, ap->a_flags, &vp->v_interlock));
 }  }
   
 /*  /*
Line 312  genfs_unlock(void *v)
Line 336  genfs_unlock(void *v)
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
   
         return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE,          return (lockmgr(&vp->v_lock, ap->a_flags | LK_RELEASE,
             &vp->v_interlock));              &vp->v_interlock));
 }  }
   
Line 327  genfs_islocked(void *v)
Line 351  genfs_islocked(void *v)
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
   
         return (lockstatus(vp->v_vnlock));          return (lockstatus(&vp->v_lock));
 }  }
   
 /*  /*
Line 339  genfs_nolock(void *v)
Line 363  genfs_nolock(void *v)
         struct vop_lock_args /* {          struct vop_lock_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 int a_flags;                  int a_flags;
                 struct lwp *a_l;                  struct proc *a_p;
         } */ *ap = v;          } */ *ap = v;
   
         /*          /*
Line 376  genfs_lease_check(void *v)
Line 400  genfs_lease_check(void *v)
 #ifdef NFSSERVER  #ifdef NFSSERVER
         struct vop_lease_args /* {          struct vop_lease_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                 struct lwp *a_l;                  struct proc *a_p;
                 struct ucred *a_cred;                  struct ucred *a_cred;
                 int a_flag;                  int a_flag;
         } */ *ap = v;          } */ *ap = v;
Line 385  genfs_lease_check(void *v)
Line 409  genfs_lease_check(void *v)
         u_quad_t frev;          u_quad_t frev;
   
         (void) nqsrv_getlease(ap->a_vp, &duration, ND_CHECK | ap->a_flag,          (void) nqsrv_getlease(ap->a_vp, &duration, ND_CHECK | ap->a_flag,
             NQLOCALSLP, ap->a_l, (struct mbuf *)0, &cache, &frev, ap->a_cred);              NQLOCALSLP, ap->a_p, (struct mbuf *)0, &cache, &frev, ap->a_cred);
         return (0);          return (0);
 #else  #else
         return (0);          return (0);
Line 451  genfs_getpages(void *v)
Line 475  genfs_getpages(void *v)
         struct vnode *devvp;          struct vnode *devvp;
         struct genfs_node *gp = VTOG(vp);          struct genfs_node *gp = VTOG(vp);
         struct uvm_object *uobj = &vp->v_uobj;          struct uvm_object *uobj = &vp->v_uobj;
         struct vm_page *pg, **pgs, *pgs_onstack[MAX_READ_PAGES];          struct vm_page *pg, **pgs, *pgs_onstack[MAX_READ_AHEAD];
         int pgs_size;          int pgs_size;
         struct ucred *cred = curproc->p_ucred;          /* XXXUBC curlwp */          struct ucred *cred = curproc->p_ucred;          /* XXXUBC curlwp */
         boolean_t async = (flags & PGO_SYNCIO) == 0;          boolean_t async = (flags & PGO_SYNCIO) == 0;
         boolean_t write = (ap->a_access_type & VM_PROT_WRITE) != 0;          boolean_t write = (ap->a_access_type & VM_PROT_WRITE) != 0;
         boolean_t sawhole = FALSE;          boolean_t sawhole = FALSE;
         boolean_t overwrite = (flags & PGO_OVERWRITE) != 0;          boolean_t overwrite = (flags & PGO_OVERWRITE) != 0;
         boolean_t blockalloc = write && (flags & PGO_NOBLOCKALLOC) == 0;  
         UVMHIST_FUNC("genfs_getpages"); UVMHIST_CALLED(ubchist);          UVMHIST_FUNC("genfs_getpages"); UVMHIST_CALLED(ubchist);
   
         UVMHIST_LOG(ubchist, "vp %p off 0x%x/%x count %d",          UVMHIST_LOG(ubchist, "vp %p off 0x%x/%x count %d",
             vp, ap->a_offset >> 32, ap->a_offset, *ap->a_count);              vp, ap->a_offset >> 32, ap->a_offset, *ap->a_count);
   
         KASSERT(vp->v_type == VREG || vp->v_type == VBLK);  
   
         /* XXXUBC temp limit */          /* XXXUBC temp limit */
         if (*ap->a_count > MAX_READ_PAGES) {          if (*ap->a_count > MAX_READ_AHEAD) {
                 panic("genfs_getpages: too many pages");                  panic("genfs_getpages: too many pages");
         }          }
   
Line 478  genfs_getpages(void *v)
Line 499  genfs_getpages(void *v)
         if (flags & PGO_PASTEOF) {          if (flags & PGO_PASTEOF) {
                 newsize = MAX(vp->v_size,                  newsize = MAX(vp->v_size,
                     origoffset + (orignpages << PAGE_SHIFT));                      origoffset + (orignpages << PAGE_SHIFT));
                 GOP_SIZE(vp, newsize, &memeof, GOP_SIZE_READ|GOP_SIZE_MEM);                  GOP_SIZE(vp, newsize, &memeof, GOP_SIZE_READ);
         } else {          } else {
                 GOP_SIZE(vp, vp->v_size, &memeof, GOP_SIZE_READ|GOP_SIZE_MEM);                  memeof = diskeof;
         }          }
         KASSERT(ap->a_centeridx >= 0 || ap->a_centeridx <= orignpages);          KASSERT(ap->a_centeridx >= 0 || ap->a_centeridx <= orignpages);
         KASSERT((origoffset & (PAGE_SIZE - 1)) == 0 && origoffset >= 0);          KASSERT((origoffset & (PAGE_SIZE - 1)) == 0 && origoffset >= 0);
Line 499  genfs_getpages(void *v)
Line 520  genfs_getpages(void *v)
                 return (EINVAL);                  return (EINVAL);
         }          }
   
         /* uobj is locked */  
   
         if ((flags & PGO_NOTIMESTAMP) == 0 &&  
             (vp->v_type == VREG ||  
             (vp->v_mount->mnt_flag & MNT_NODEVMTIME) == 0)) {  
                 int updflags = 0;  
   
                 if ((vp->v_mount->mnt_flag & MNT_NOATIME) == 0) {  
                         updflags = GOP_UPDATE_ACCESSED;  
                 }  
                 if (write) {  
                         updflags |= GOP_UPDATE_MODIFIED;  
                 }  
                 if (updflags != 0) {  
                         GOP_MARKUPDATE(vp, updflags);  
                 }  
         }  
   
         if (write) {  
                 gp->g_dirtygen++;  
                 if ((vp->v_flag & VONWORKLST) == 0) {  
                         vn_syncer_add_to_worklist(vp, filedelay);  
                 }  
                 if ((vp->v_flag & (VWRITEMAP|VWRITEMAPDIRTY)) == VWRITEMAP) {  
                         vp->v_flag |= VWRITEMAPDIRTY;  
                 }  
         }  
   
         /*          /*
          * For PGO_LOCKED requests, just return whatever's in memory.           * For PGO_LOCKED requests, just return whatever's in memory.
          */           */
Line 538  genfs_getpages(void *v)
Line 531  genfs_getpages(void *v)
                 return (ap->a_m[ap->a_centeridx] == NULL ? EBUSY : 0);                  return (ap->a_m[ap->a_centeridx] == NULL ? EBUSY : 0);
         }          }
   
           /* vnode is VOP_LOCKed, uobj is locked */
   
           if (write && (vp->v_flag & VONWORKLST) == 0) {
                   vn_syncer_add_to_worklist(vp, filedelay);
           }
   
         /*          /*
          * find the requested pages and make some simple checks.           * find the requested pages and make some simple checks.
          * leave space in the page array for a whole block.           * leave space in the page array for a whole block.
Line 590  genfs_getpages(void *v)
Line 589  genfs_getpages(void *v)
          */           */
   
         for (i = 0; i < npages; i++) {          for (i = 0; i < npages; i++) {
                 struct vm_page *pg1 = pgs[ridx + i];                  struct vm_page *pg = pgs[ridx + i];
   
                 if ((pg1->flags & PG_FAKE) ||                  if ((pg->flags & PG_FAKE) ||
                     (blockalloc && (pg1->flags & PG_RDONLY))) {                      (write && (pg->flags & PG_RDONLY))) {
                         break;                          break;
                 }                  }
         }          }
Line 601  genfs_getpages(void *v)
Line 600  genfs_getpages(void *v)
                 UVMHIST_LOG(ubchist, "returning cached pages", 0,0,0,0);                  UVMHIST_LOG(ubchist, "returning cached pages", 0,0,0,0);
                 raoffset = origoffset + (orignpages << PAGE_SHIFT);                  raoffset = origoffset + (orignpages << PAGE_SHIFT);
                 npages += ridx;                  npages += ridx;
                 goto out;                  goto raout;
         }          }
   
         /*          /*
Line 612  genfs_getpages(void *v)
Line 611  genfs_getpages(void *v)
                 UVMHIST_LOG(ubchist, "PGO_OVERWRITE",0,0,0,0);                  UVMHIST_LOG(ubchist, "PGO_OVERWRITE",0,0,0,0);
   
                 for (i = 0; i < npages; i++) {                  for (i = 0; i < npages; i++) {
                         struct vm_page *pg1 = pgs[ridx + i];                          struct vm_page *pg = pgs[ridx + i];
   
                         pg1->flags &= ~(PG_RDONLY|PG_CLEAN);                          pg->flags &= ~(PG_RDONLY|PG_CLEAN);
                 }                  }
                 npages += ridx;                  npages += ridx;
                 goto out;                  goto out;
Line 698  genfs_getpages(void *v)
Line 697  genfs_getpages(void *v)
          * now loop over the pages, reading as needed.           * now loop over the pages, reading as needed.
          */           */
   
         if (blockalloc) {          if (write) {
                 lockmgr(&gp->g_glock, LK_EXCLUSIVE, NULL);                  lockmgr(&gp->g_glock, LK_EXCLUSIVE, NULL);
         } else {          } else {
                 lockmgr(&gp->g_glock, LK_SHARED, NULL);                  lockmgr(&gp->g_glock, LK_SHARED, NULL);
Line 714  genfs_getpages(void *v)
Line 713  genfs_getpages(void *v)
                  */                   */
   
                 pidx = (offset - startoffset) >> PAGE_SHIFT;                  pidx = (offset - startoffset) >> PAGE_SHIFT;
                 while ((pgs[pidx]->flags & PG_FAKE) == 0) {                  while ((pgs[pidx]->flags & (PG_FAKE|PG_RDONLY)) == 0) {
                         size_t b;                          size_t b;
   
                         KASSERT((offset & (PAGE_SIZE - 1)) == 0);                          KASSERT((offset & (PAGE_SIZE - 1)) == 0);
                         if ((pgs[pidx]->flags & PG_RDONLY)) {  
                                 sawhole = TRUE;  
                         }  
                         b = MIN(PAGE_SIZE, bytes);                          b = MIN(PAGE_SIZE, bytes);
                         offset += b;                          offset += b;
                         bytes -= b;                          bytes -= b;
Line 768  genfs_getpages(void *v)
Line 764  genfs_getpages(void *v)
   
                 /*                  /*
                  * if this block isn't allocated, zero it instead of                   * if this block isn't allocated, zero it instead of
                  * reading it.  unless we are going to allocate blocks,                   * reading it.  if this is a read access, mark the
                  * mark the pages we zeroed PG_RDONLY.                   * pages we zeroed PG_RDONLY.
                  */                   */
   
                 if (blkno < 0) {                  if (blkno < 0) {
Line 785  genfs_getpages(void *v)
Line 781  genfs_getpages(void *v)
                         for (i = 0; i < holepages; i++) {                          for (i = 0; i < holepages; i++) {
                                 if (write) {                                  if (write) {
                                         pgs[pidx + i]->flags &= ~PG_CLEAN;                                          pgs[pidx + i]->flags &= ~PG_CLEAN;
                                 }                                  } else {
                                 if (!blockalloc) {  
                                         pgs[pidx + i]->flags |= PG_RDONLY;                                          pgs[pidx + i]->flags |= PG_RDONLY;
                                 }                                  }
                         }                          }
Line 815  genfs_getpages(void *v)
Line 810  genfs_getpages(void *v)
                 }                  }
                 bp->b_lblkno = 0;                  bp->b_lblkno = 0;
                 bp->b_private = mbp;                  bp->b_private = mbp;
                   if (devvp->v_type == VBLK) {
                           bp->b_dev = devvp->v_rdev;
                   }
   
                 /* adjust physical blkno for partial blocks */                  /* adjust physical blkno for partial blocks */
                 bp->b_blkno = blkno + ((offset - ((off_t)lbn << fs_bshift)) >>                  bp->b_blkno = blkno + ((offset - ((off_t)lbn << fs_bshift)) >>
Line 824  genfs_getpages(void *v)
Line 822  genfs_getpages(void *v)
                     "bp %p offset 0x%x bcount 0x%x blkno 0x%x",                      "bp %p offset 0x%x bcount 0x%x blkno 0x%x",
                     bp, offset, iobytes, bp->b_blkno);                      bp, offset, iobytes, bp->b_blkno);
   
                 if (async)                  VOP_STRATEGY(bp);
                         BIO_SETPRIO(bp, BPRIO_TIMELIMITED);  
                 else  
                         BIO_SETPRIO(bp, BPRIO_TIMECRITICAL);  
   
                 VOP_STRATEGY(devvp, bp);  
         }          }
   
 loopdone:  loopdone:
Line 870  loopdone:
Line 863  loopdone:
          * the page is completely allocated while the pages are locked.           * the page is completely allocated while the pages are locked.
          */           */
   
         if (!error && sawhole && blockalloc) {          if (!error && sawhole && write) {
                   for (i = 0; i < npages; i++) {
                           if (pgs[i] == NULL) {
                                   continue;
                           }
                           pgs[i]->flags &= ~PG_CLEAN;
                           UVMHIST_LOG(ubchist, "mark dirty pg %p", pgs[i],0,0,0);
                   }
                 error = GOP_ALLOC(vp, startoffset, npages << PAGE_SHIFT, 0,                  error = GOP_ALLOC(vp, startoffset, npages << PAGE_SHIFT, 0,
                     cred);                      cred);
                 UVMHIST_LOG(ubchist, "gop_alloc off 0x%x/0x%x -> %d",                  UVMHIST_LOG(ubchist, "gop_alloc off 0x%x/0x%x -> %d",
                     startoffset, npages << PAGE_SHIFT, error,0);                      startoffset, npages << PAGE_SHIFT, error,0);
                 if (!error) {  
                         for (i = 0; i < npages; i++) {  
                                 if (pgs[i] == NULL) {  
                                         continue;  
                                 }  
                                 pgs[i]->flags &= ~(PG_CLEAN|PG_RDONLY);  
                                 UVMHIST_LOG(ubchist, "mark dirty pg %p",  
                                     pgs[i],0,0,0);  
                         }  
                 }  
         }          }
         lockmgr(&gp->g_glock, LK_RELEASE, NULL);          lockmgr(&gp->g_glock, LK_RELEASE, NULL);
         simple_lock(&uobj->vmobjlock);          simple_lock(&uobj->vmobjlock);
   
         /*          /*
            * see if we want to start any readahead.
            * XXXUBC for now, just read the next 128k on 64k boundaries.
            * this is pretty nonsensical, but it is 50% faster than reading
            * just the next 64k.
            */
   
   raout:
           if (!error && !async && !write && ((int)raoffset & 0xffff) == 0 &&
               PAGE_SHIFT <= 16) {
                   off_t rasize;
                   int rapages, err, i, skipped;
   
                   /* XXXUBC temp limit, from above */
                   rapages = MIN(MIN(1 << (16 - PAGE_SHIFT), MAX_READ_AHEAD),
                       genfs_rapages);
                   rasize = rapages << PAGE_SHIFT;
                   for (i = skipped = 0; i < genfs_racount; i++) {
                           err = VOP_GETPAGES(vp, raoffset, NULL, &rapages, 0,
                               VM_PROT_READ, 0, 0);
                           simple_lock(&uobj->vmobjlock);
                           if (err) {
                                   if (err != EBUSY ||
                                       skipped++ == genfs_raskip)
                                           break;
                           }
                           raoffset += rasize;
                           rapages = rasize >> PAGE_SHIFT;
                   }
           }
   
           /*
          * we're almost done!  release the pages...           * we're almost done!  release the pages...
          * for errors, we free the pages.           * for errors, we free the pages.
          * otherwise we activate them and mark them as valid and clean.           * otherwise we activate them and mark them as valid and clean.
Line 931  out:
Line 952  out:
                         pg->flags &= ~(PG_FAKE);                          pg->flags &= ~(PG_FAKE);
                         pmap_clear_modify(pgs[i]);                          pmap_clear_modify(pgs[i]);
                 }                  }
                 KASSERT(!write || !blockalloc || (pg->flags & PG_RDONLY) == 0);                  if (write) {
                           pg->flags &= ~(PG_RDONLY);
                   }
                 if (i < ridx || i >= ridx + orignpages || async) {                  if (i < ridx || i >= ridx + orignpages || async) {
                         UVMHIST_LOG(ubchist, "unbusy pg %p offset 0x%x",                          UVMHIST_LOG(ubchist, "unbusy pg %p offset 0x%x",
                             pg, pg->offset,0,0);                              pg, pg->offset,0,0);
Line 1034  genfs_putpages(void *v)
Line 1057  genfs_putpages(void *v)
         int i, s, error, npages, nback;          int i, s, error, npages, nback;
         int freeflag;          int freeflag;
         struct vm_page *pgs[maxpages], *pg, *nextpg, *tpg, curmp, endmp;          struct vm_page *pgs[maxpages], *pg, *nextpg, *tpg, curmp, endmp;
         boolean_t wasclean, by_list, needs_clean, yld;          boolean_t wasclean, by_list, needs_clean, yield;
         boolean_t async = (flags & PGO_SYNCIO) == 0;          boolean_t async = (flags & PGO_SYNCIO) == 0;
         boolean_t pagedaemon = curproc == uvm.pagedaemon_proc;          boolean_t pagedaemon = curproc == uvm.pagedaemon_proc;
         struct lwp *l = curlwp ? curlwp : &lwp0;          struct lwp *l = curlwp ? curlwp : &lwp0;
         struct genfs_node *gp = VTOG(vp);  
         int dirtygen;  
         boolean_t modified = FALSE;  
         boolean_t cleanall;  
   
         UVMHIST_FUNC("genfs_putpages"); UVMHIST_CALLED(ubchist);          UVMHIST_FUNC("genfs_putpages"); UVMHIST_CALLED(ubchist);
   
Line 1051  genfs_putpages(void *v)
Line 1070  genfs_putpages(void *v)
   
         UVMHIST_LOG(ubchist, "vp %p pages %d off 0x%x len 0x%x",          UVMHIST_LOG(ubchist, "vp %p pages %d off 0x%x len 0x%x",
             vp, uobj->uo_npages, startoff, endoff - startoff);              vp, uobj->uo_npages, startoff, endoff - startoff);
   
         KASSERT((vp->v_flag & VONWORKLST) != 0 ||  
             (vp->v_flag & VWRITEMAPDIRTY) == 0);  
         if (uobj->uo_npages == 0) {          if (uobj->uo_npages == 0) {
                 s = splbio();                  s = splbio();
                 if (vp->v_flag & VONWORKLST) {                  if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL &&
                         vp->v_flag &= ~VWRITEMAPDIRTY;                      (vp->v_flag & VONWORKLST)) {
                         if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {                          vp->v_flag &= ~VONWORKLST;
                                 vp->v_flag &= ~VONWORKLST;                          LIST_REMOVE(vp, v_synclist);
                                 LIST_REMOVE(vp, v_synclist);  
                         }  
                 }                  }
                 splx(s);                  splx(s);
                 simple_unlock(slock);                  simple_unlock(slock);
Line 1085  genfs_putpages(void *v)
Line 1099  genfs_putpages(void *v)
         by_list = (uobj->uo_npages <=          by_list = (uobj->uo_npages <=
             ((endoff - startoff) >> PAGE_SHIFT) * UVM_PAGE_HASH_PENALTY);              ((endoff - startoff) >> PAGE_SHIFT) * UVM_PAGE_HASH_PENALTY);
   
 #if !defined(DEBUG)  
         /*  
          * if this vnode is known not to have dirty pages,  
          * don't bother to clean it out.  
          */  
   
         if ((vp->v_flag & VONWORKLST) == 0) {  
                 if ((flags & (PGO_FREE|PGO_DEACTIVATE)) == 0) {  
                         goto skip_scan;  
                 }  
                 flags &= ~PGO_CLEANIT;  
         }  
 #endif /* !defined(DEBUG) */  
   
         /*          /*
          * start the loop.  when scanning by list, hold the last page           * start the loop.  when scanning by list, hold the last page
          * in the list before we start.  pages allocated after we start           * in the list before we start.  pages allocated after we start
Line 1106  genfs_putpages(void *v)
Line 1106  genfs_putpages(void *v)
          * current last page.           * current last page.
          */           */
   
         cleanall = (flags & PGO_CLEANIT) != 0 && wasclean &&  
             startoff == 0 && endoff == trunc_page(LLONG_MAX) &&  
             (vp->v_flag & VONWORKLST) != 0;  
         dirtygen = gp->g_dirtygen;  
         freeflag = pagedaemon ? PG_PAGEOUT : PG_RELEASED;          freeflag = pagedaemon ? PG_PAGEOUT : PG_RELEASED;
           curmp.uobject = uobj;
           curmp.offset = (voff_t)-1;
           curmp.flags = PG_BUSY;
           endmp.uobject = uobj;
           endmp.offset = (voff_t)-1;
           endmp.flags = PG_BUSY;
         if (by_list) {          if (by_list) {
                 curmp.uobject = uobj;  
                 curmp.offset = (voff_t)-1;  
                 curmp.flags = PG_BUSY;  
                 endmp.uobject = uobj;  
                 endmp.offset = (voff_t)-1;  
                 endmp.flags = PG_BUSY;  
                 pg = TAILQ_FIRST(&uobj->memq);                  pg = TAILQ_FIRST(&uobj->memq);
                 TAILQ_INSERT_TAIL(&uobj->memq, &endmp, listq);                  TAILQ_INSERT_TAIL(&uobj->memq, &endmp, listq);
                 PHOLD(l);                  PHOLD(l);
Line 1141  genfs_putpages(void *v)
Line 1137  genfs_putpages(void *v)
                         }                          }
                         if (pg->offset < startoff || pg->offset >= endoff ||                          if (pg->offset < startoff || pg->offset >= endoff ||
                             pg->flags & (PG_RELEASED|PG_PAGEOUT)) {                              pg->flags & (PG_RELEASED|PG_PAGEOUT)) {
                                 if (pg->flags & (PG_RELEASED|PG_PAGEOUT)) {  
                                         wasclean = FALSE;  
                                 }  
                                 pg = TAILQ_NEXT(pg, listq);                                  pg = TAILQ_NEXT(pg, listq);
                                 continue;                                  continue;
                         }                          }
                         off = pg->offset;                          off = pg->offset;
                 } else if (pg == NULL || pg->flags & (PG_RELEASED|PG_PAGEOUT)) {                  } else if (pg == NULL ||
                         if (pg != NULL) {                      pg->flags & (PG_RELEASED|PG_PAGEOUT)) {
                                 wasclean = FALSE;  
                         }  
                         off += PAGE_SIZE;                          off += PAGE_SIZE;
                         if (off < endoff) {                          if (off < endoff) {
                                 pg = uvm_pagelookup(uobj, off);                                  pg = uvm_pagelookup(uobj, off);
Line 1164  genfs_putpages(void *v)
Line 1155  genfs_putpages(void *v)
                  * wait for it to become unbusy.                   * wait for it to become unbusy.
                  */                   */
   
                 yld = (l->l_cpu->ci_schedstate.spc_flags &                  yield = (l->l_cpu->ci_schedstate.spc_flags &
                     SPCF_SHOULDYIELD) && !pagedaemon;                      SPCF_SHOULDYIELD) && !pagedaemon;
                 if (pg->flags & PG_BUSY || yld) {                  if (pg->flags & PG_BUSY || yield) {
                         UVMHIST_LOG(ubchist, "busy %p", pg,0,0,0);                          UVMHIST_LOG(ubchist, "busy %p", pg,0,0,0);
                         if (flags & PGO_BUSYFAIL && pg->flags & PG_BUSY) {                          if (flags & PGO_BUSYFAIL && pg->flags & PG_BUSY) {
                                 UVMHIST_LOG(ubchist, "busyfail %p", pg, 0,0,0);                                  UVMHIST_LOG(ubchist, "busyfail %p", pg, 0,0,0);
Line 1179  genfs_putpages(void *v)
Line 1170  genfs_putpages(void *v)
                                 UVMHIST_LOG(ubchist, "curmp next %p",                                  UVMHIST_LOG(ubchist, "curmp next %p",
                                     TAILQ_NEXT(&curmp, listq), 0,0,0);                                      TAILQ_NEXT(&curmp, listq), 0,0,0);
                         }                          }
                         if (yld) {                          if (yield) {
                                 simple_unlock(slock);                                  simple_unlock(slock);
                                 preempt(1);                                  preempt(1);
                                 simple_lock(slock);                                  simple_lock(slock);
Line 1206  genfs_putpages(void *v)
Line 1197  genfs_putpages(void *v)
   
                 if (flags & PGO_FREE) {                  if (flags & PGO_FREE) {
                         pmap_page_protect(pg, VM_PROT_NONE);                          pmap_page_protect(pg, VM_PROT_NONE);
                 } else if (flags & PGO_CLEANIT) {  
   
                         /*  
                          * if we still have some hope to pull this vnode off  
                          * from the syncer queue, write-protect the page.  
                          */  
   
                         if (cleanall && wasclean &&  
                             gp->g_dirtygen == dirtygen) {  
   
                                 /*  
                                  * uobj pages get wired only by uvm_fault  
                                  * where uobj is locked.  
                                  */  
   
                                 if (pg->wire_count == 0) {  
                                         pmap_page_protect(pg,  
                                             VM_PROT_READ|VM_PROT_EXECUTE);  
                                 } else {  
                                         cleanall = FALSE;  
                                 }  
                         }  
                 }                  }
   
                 if (flags & PGO_CLEANIT) {                  if (flags & PGO_CLEANIT) {
                         needs_clean = pmap_clear_modify(pg) ||                          needs_clean = pmap_clear_modify(pg) ||
                             (pg->flags & PG_CLEAN) == 0;                              (pg->flags & PG_CLEAN) == 0;
Line 1246  genfs_putpages(void *v)
Line 1214  genfs_putpages(void *v)
                  */                   */
   
                 if (needs_clean) {                  if (needs_clean) {
                         KDASSERT((vp->v_flag & VONWORKLST));  
                         wasclean = FALSE;                          wasclean = FALSE;
                         memset(pgs, 0, sizeof(pgs));                          memset(pgs, 0, sizeof(pgs));
                         pg->flags |= PG_BUSY;                          pg->flags |= PG_BUSY;
Line 1330  genfs_putpages(void *v)
Line 1297  genfs_putpages(void *v)
   
                                         nextpg = TAILQ_NEXT(tpg, listq);                                          nextpg = TAILQ_NEXT(tpg, listq);
                                         uvm_pagefree(tpg);                                          uvm_pagefree(tpg);
                                         if (pagedaemon)  
                                                 uvmexp.pdfreed++;  
                                 }                                  }
                         }                          }
                 }                  }
Line 1339  genfs_putpages(void *v)
Line 1304  genfs_putpages(void *v)
                         uvm_unlock_pageq();                          uvm_unlock_pageq();
                 }                  }
                 if (needs_clean) {                  if (needs_clean) {
                         modified = TRUE;  
   
                         /*                          /*
                          * start the i/o.  if we're traversing by list,                           * start the i/o.  if we're traversing by list,
Line 1388  genfs_putpages(void *v)
Line 1352  genfs_putpages(void *v)
                 PRELE(l);                  PRELE(l);
         }          }
   
         if (modified && (vp->v_flag & VWRITEMAPDIRTY) != 0 &&  
             (vp->v_type == VREG ||  
             (vp->v_mount->mnt_flag & MNT_NODEVMTIME) == 0)) {  
                 GOP_MARKUPDATE(vp, GOP_UPDATE_MODIFIED);  
         }  
   
         /*          /*
          * if we're cleaning and there was nothing to clean,           * if we're cleaning and there was nothing to clean,
          * take us off the syncer list.  if we started any i/o           * take us off the syncer list.  if we started any i/o
Line 1401  genfs_putpages(void *v)
Line 1359  genfs_putpages(void *v)
          */           */
   
         s = splbio();          s = splbio();
         if (cleanall && wasclean && gp->g_dirtygen == dirtygen &&          if ((flags & PGO_CLEANIT) && wasclean &&
             (vp->v_flag & VONWORKLST) != 0) {              startoff == 0 && endoff == trunc_page(LLONG_MAX) &&
                 vp->v_flag &= ~VWRITEMAPDIRTY;              LIST_FIRST(&vp->v_dirtyblkhd) == NULL &&
                 if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {              (vp->v_flag & VONWORKLST)) {
                         vp->v_flag &= ~VONWORKLST;                  vp->v_flag &= ~VONWORKLST;
                         LIST_REMOVE(vp, v_synclist);                  LIST_REMOVE(vp, v_synclist);
                 }  
         }          }
         splx(s);          splx(s);
   
 #if !defined(DEBUG)  
 skip_scan:  
 #endif /* !defined(DEBUG) */  
         if (!wasclean && !async) {          if (!wasclean && !async) {
                 s = splbio();                  s = splbio();
                 /*                  /*
Line 1526  genfs_gop_write(struct vnode *vp, struct
Line 1479  genfs_gop_write(struct vnode *vp, struct
                 }                  }
                 bp->b_lblkno = 0;                  bp->b_lblkno = 0;
                 bp->b_private = mbp;                  bp->b_private = mbp;
                   if (devvp->v_type == VBLK) {
                           bp->b_dev = devvp->v_rdev;
                   }
   
                 /* adjust physical blkno for partial blocks */                  /* adjust physical blkno for partial blocks */
                 bp->b_blkno = blkno + ((offset - ((off_t)lbn << fs_bshift)) >>                  bp->b_blkno = blkno + ((offset - ((off_t)lbn << fs_bshift)) >>
Line 1533  genfs_gop_write(struct vnode *vp, struct
Line 1489  genfs_gop_write(struct vnode *vp, struct
                 UVMHIST_LOG(ubchist,                  UVMHIST_LOG(ubchist,
                     "vp %p offset 0x%x bcount 0x%x blkno 0x%x",                      "vp %p offset 0x%x bcount 0x%x blkno 0x%x",
                     vp, offset, bp->b_bcount, bp->b_blkno);                      vp, offset, bp->b_bcount, bp->b_blkno);
                 if (curproc == uvm.pagedaemon_proc)                  VOP_STRATEGY(bp);
                         BIO_SETPRIO(bp, BPRIO_TIMELIMITED);  
                 else if (async)  
                         BIO_SETPRIO(bp, BPRIO_TIMENONCRITICAL);  
                 else  
                         BIO_SETPRIO(bp, BPRIO_TIMECRITICAL);  
   
                 VOP_STRATEGY(devvp, bp);  
         }          }
         if (skipbytes) {          if (skipbytes) {
                 UVMHIST_LOG(ubchist, "skipbytes %d", skipbytes, 0,0,0);                  UVMHIST_LOG(ubchist, "skipbytes %d", skipbytes, 0,0,0);
Line 1587  genfs_null_putpages(void *v)
Line 1536  genfs_null_putpages(void *v)
 }  }
   
 void  void
 genfs_node_init(struct vnode *vp, const struct genfs_ops *ops)  genfs_node_init(struct vnode *vp, struct genfs_ops *ops)
 {  {
         struct genfs_node *gp = VTOG(vp);          struct genfs_node *gp = VTOG(vp);
   
Line 1647  genfs_compat_getpages(void *v)
Line 1596  genfs_compat_getpages(void *v)
                 simple_unlock(&uobj->vmobjlock);                  simple_unlock(&uobj->vmobjlock);
                 return (EINVAL);                  return (EINVAL);
         }          }
         if ((ap->a_flags & PGO_SYNCIO) == 0) {  
                 return 0;  
         }  
         npages = orignpages;          npages = orignpages;
         uvn_findpages(uobj, origoffset, &npages, pgs, UFP_ALL);          uvn_findpages(uobj, origoffset, &npages, pgs, UFP_ALL);
         simple_unlock(&uobj->vmobjlock);          simple_unlock(&uobj->vmobjlock);
Line 1668  genfs_compat_getpages(void *v)
Line 1614  genfs_compat_getpages(void *v)
                 uio.uio_segflg = UIO_SYSSPACE;                  uio.uio_segflg = UIO_SYSSPACE;
                 uio.uio_rw = UIO_READ;                  uio.uio_rw = UIO_READ;
                 uio.uio_resid = PAGE_SIZE;                  uio.uio_resid = PAGE_SIZE;
                 uio.uio_lwp = NULL;                  uio.uio_procp = curproc;
                 /* XXX vn_lock */  
                 error = VOP_READ(vp, &uio, 0, cred);                  error = VOP_READ(vp, &uio, 0, cred);
                 if (error) {                  if (error) {
                         break;                          break;
Line 1722  genfs_compat_gop_write(struct vnode *vp,
Line 1667  genfs_compat_gop_write(struct vnode *vp,
         uio.uio_segflg = UIO_SYSSPACE;          uio.uio_segflg = UIO_SYSSPACE;
         uio.uio_rw = UIO_WRITE;          uio.uio_rw = UIO_WRITE;
         uio.uio_resid = npages << PAGE_SHIFT;          uio.uio_resid = npages << PAGE_SHIFT;
         uio.uio_lwp = NULL;          uio.uio_procp = curproc;
         /* XXX vn_lock */  
         error = VOP_WRITE(vp, &uio, 0, cred);          error = VOP_WRITE(vp, &uio, 0, cred);
   
         s = splbio();          s = splbio();
Line 1788  filt_genfsvnode(struct knote *kn, long h
Line 1732  filt_genfsvnode(struct knote *kn, long h
         return (kn->kn_fflags != 0);          return (kn->kn_fflags != 0);
 }  }
   
 static const struct filterops genfsread_filtops =  static const struct filterops genfsread_filtops =
         { 1, NULL, filt_genfsdetach, filt_genfsread };          { 1, NULL, filt_genfsdetach, filt_genfsread };
 static const struct filterops genfsvnode_filtops =  static const struct filterops genfsvnode_filtops =
         { 1, NULL, filt_genfsdetach, filt_genfsvnode };          { 1, NULL, filt_genfsdetach, filt_genfsvnode };
   
 int  int

Legend:
Removed from v.1.80.2.11  
changed lines
  Added in v.1.81

CVSweb <webmaster@jp.NetBSD.org>