[BACK]Return to ufs_readwrite.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / ufs / ufs

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

Diff for /src/sys/ufs/ufs/ufs_readwrite.c between version 1.76.4.8 and 1.77

version 1.76.4.8, 2007/10/09 13:45:17 version 1.77, 2007/04/19 11:05:14
Line 35 
Line 35 
 __KERNEL_RCSID(1, "$NetBSD$");  __KERNEL_RCSID(1, "$NetBSD$");
   
 #ifdef LFS_READWRITE  #ifdef LFS_READWRITE
   #define BLKSIZE(a, b, c)        blksize(a, b, c)
 #define FS                      struct lfs  #define FS                      struct lfs
 #define I_FS                    i_lfs  #define I_FS                    i_lfs
 #define READ                    lfs_read  #define READ                    lfs_read
Line 44  __KERNEL_RCSID(1, "$NetBSD$");
Line 45  __KERNEL_RCSID(1, "$NetBSD$");
 #define fs_bsize                lfs_bsize  #define fs_bsize                lfs_bsize
 #define fs_bmask                lfs_bmask  #define fs_bmask                lfs_bmask
 #else  #else
   #define BLKSIZE(a, b, c)        blksize(a, b, c)
 #define FS                      struct fs  #define FS                      struct fs
 #define I_FS                    i_fs  #define I_FS                    i_fs
 #define READ                    ffs_read  #define READ                    ffs_read
Line 71  READ(void *v)
Line 73  READ(void *v)
         struct ufsmount *ump;          struct ufsmount *ump;
         struct buf *bp;          struct buf *bp;
         FS *fs;          FS *fs;
           void *win;
         vsize_t bytelen;          vsize_t bytelen;
         daddr_t lbn, nextlbn;          daddr_t lbn, nextlbn;
         off_t bytesinfile;          off_t bytesinfile;
         long size, xfersize, blkoffset;          long size, xfersize, blkoffset;
         int error, ioflag;          int error, flags, ioflag;
         bool usepc = false;          bool usepc = false;
   
         vp = ap->a_vp;          vp = ap->a_vp;
Line 102  READ(void *v)
Line 105  READ(void *v)
         if (uio->uio_resid == 0)          if (uio->uio_resid == 0)
                 return (0);                  return (0);
   
         fstrans_start(vp->v_mount, FSTRANS_SHARED);          if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
                   return error;
   
         if (uio->uio_offset >= ip->i_size)          if (uio->uio_offset >= ip->i_size)
                 goto out;                  goto out;
Line 123  READ(void *v)
Line 127  READ(void *v)
                             uio->uio_resid);                              uio->uio_resid);
                         if (bytelen == 0)                          if (bytelen == 0)
                                 break;                                  break;
                         error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,  
                             UBC_READ | UBC_PARTIALOK |                          win = ubc_alloc(&vp->v_uobj, uio->uio_offset,
                             (UBC_WANT_UNMAP(vp) ? UBC_UNMAP : 0));                              &bytelen, advice, UBC_READ);
                           error = uiomove(win, bytelen, uio);
                           flags = UBC_WANT_UNMAP(vp) ? UBC_UNMAP : 0;
                           ubc_release(win, flags);
                         if (error)                          if (error)
                                 break;                                  break;
                 }                  }
Line 138  READ(void *v)
Line 145  READ(void *v)
                         break;                          break;
                 lbn = lblkno(fs, uio->uio_offset);                  lbn = lblkno(fs, uio->uio_offset);
                 nextlbn = lbn + 1;                  nextlbn = lbn + 1;
                 size = blksize(fs, ip, lbn);                  size = BLKSIZE(fs, ip, lbn);
                 blkoffset = blkoff(fs, uio->uio_offset);                  blkoffset = blkoff(fs, uio->uio_offset);
                 xfersize = MIN(MIN(fs->fs_bsize - blkoffset, uio->uio_resid),                  xfersize = MIN(MIN(fs->fs_bsize - blkoffset, uio->uio_resid),
                     bytesinfile);                      bytesinfile);
Line 146  READ(void *v)
Line 153  READ(void *v)
                 if (lblktosize(fs, nextlbn) >= ip->i_size)                  if (lblktosize(fs, nextlbn) >= ip->i_size)
                         error = bread(vp, lbn, size, NOCRED, &bp);                          error = bread(vp, lbn, size, NOCRED, &bp);
                 else {                  else {
                         int nextsize = blksize(fs, ip, nextlbn);                          int nextsize = BLKSIZE(fs, ip, nextlbn);
                         error = breadn(vp, lbn,                          error = breadn(vp, lbn,
                             size, &nextlbn, &nextsize, 1, NOCRED, &bp);                              size, &nextlbn, &nextsize, 1, NOCRED, &bp);
                 }                  }
Line 169  READ(void *v)
Line 176  READ(void *v)
                 error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio);                  error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio);
                 if (error)                  if (error)
                         break;                          break;
                 brelse(bp, 0);                  brelse(bp);
         }          }
         if (bp != NULL)          if (bp != NULL)
                 brelse(bp, 0);                  brelse(bp);
   
  out:   out:
         if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {          if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
Line 208  WRITE(void *v)
Line 215  WRITE(void *v)
         off_t osize, origoff, oldoff, preallocoff, endallocoff, nsize;          off_t osize, origoff, oldoff, preallocoff, endallocoff, nsize;
         int blkoffset, error, flags, ioflag, resid, size, xfersize;          int blkoffset, error, flags, ioflag, resid, size, xfersize;
         int aflag;          int aflag;
           int ubc_alloc_flags, ubc_release_flags;
         int extended=0;          int extended=0;
           void *win;
         vsize_t bytelen;          vsize_t bytelen;
         bool async;          bool async;
         bool usepc = false;          bool usepc = false;
Line 273  WRITE(void *v)
Line 282  WRITE(void *v)
         if (uio->uio_resid == 0)          if (uio->uio_resid == 0)
                 return (0);                  return (0);
   
         fstrans_start(vp->v_mount, FSTRANS_SHARED);          if ((error = fstrans_start(vp->v_mount, FSTRANS_SHARED)) != 0)
                   return error;
   
         flags = ioflag & IO_SYNC ? B_SYNC : 0;          flags = ioflag & IO_SYNC ? B_SYNC : 0;
         async = vp->v_mount->mnt_flag & MNT_ASYNC;          async = vp->v_mount->mnt_flag & MNT_ASYNC;
Line 306  WRITE(void *v)
Line 316  WRITE(void *v)
                 off_t eob;                  off_t eob;
   
                 eob = blkroundup(fs, osize);                  eob = blkroundup(fs, osize);
                 uvm_vnp_setwritesize(vp, eob);  
                 error = ufs_balloc_range(vp, osize, eob - osize, cred, aflag);                  error = ufs_balloc_range(vp, osize, eob - osize, cred, aflag);
                 if (error)                  if (error)
                         goto out;                          goto out;
                 if (flags & B_SYNC) {                  if (flags & B_SYNC) {
                         mutex_enter(&vp->v_interlock);                          vp->v_size = eob;
                           simple_lock(&vp->v_interlock);
                         VOP_PUTPAGES(vp, trunc_page(osize & fs->fs_bmask),                          VOP_PUTPAGES(vp, trunc_page(osize & fs->fs_bmask),
                             round_page(eob), PGO_CLEANIT | PGO_SYNCIO);                              round_page(eob), PGO_CLEANIT | PGO_SYNCIO);
                 }                  }
         }          }
   
           ubc_alloc_flags = UBC_WRITE;
         while (uio->uio_resid > 0) {          while (uio->uio_resid > 0) {
                 int ubc_flags = UBC_WRITE;                  bool extending; /* if we're extending a whole block */
                 bool overwrite; /* if we're overwrite a whole block */  
                 off_t newoff;                  off_t newoff;
   
                 if (ioflag & IO_DIRECT) {                  if (ioflag & IO_DIRECT) {
Line 340  WRITE(void *v)
Line 350  WRITE(void *v)
                  * since the new blocks will be inaccessible until the write                   * since the new blocks will be inaccessible until the write
                  * is complete.                   * is complete.
                  */                   */
                 overwrite = uio->uio_offset >= preallocoff &&                  extending = uio->uio_offset >= preallocoff &&
                     uio->uio_offset < endallocoff;                      uio->uio_offset < endallocoff;
                 if (!overwrite && (vp->v_vflag & VV_MAPPED) == 0 &&  
                     blkoff(fs, uio->uio_offset) == 0 &&  
                     (uio->uio_offset & PAGE_MASK) == 0) {  
                         vsize_t len;  
   
                         len = trunc_page(bytelen);  
                         len -= blkoff(fs, len);  
                         if (len > 0) {  
                                 overwrite = true;  
                                 bytelen = len;  
                         }  
                 }  
   
                 newoff = oldoff + bytelen;                  if (!extending) {
                 if (vp->v_size < newoff) {  
                         uvm_vnp_setwritesize(vp, newoff);  
                 }  
   
                 if (!overwrite) {  
                         error = ufs_balloc_range(vp, uio->uio_offset, bytelen,                          error = ufs_balloc_range(vp, uio->uio_offset, bytelen,
                             cred, aflag);                              cred, aflag);
                         if (error)                          if (error)
                                 break;                                  break;
                           ubc_alloc_flags &= ~UBC_FAULTBUSY;
                 } else {                  } else {
                         genfs_node_wrlock(vp);                          genfs_node_wrlock(vp);
                         error = GOP_ALLOC(vp, uio->uio_offset, bytelen,                          error = GOP_ALLOC(vp, uio->uio_offset, bytelen,
Line 372  WRITE(void *v)
Line 366  WRITE(void *v)
                         genfs_node_unlock(vp);                          genfs_node_unlock(vp);
                         if (error)                          if (error)
                                 break;                                  break;
                         ubc_flags |= UBC_FAULTBUSY;                          ubc_alloc_flags |= UBC_FAULTBUSY;
                 }                  }
   
                 /*                  /*
                  * copy the data.                   * copy the data.
                  */                   */
   
                 ubc_flags |= UBC_WANT_UNMAP(vp) ? UBC_UNMAP : 0;                  win = ubc_alloc(&vp->v_uobj, uio->uio_offset, &bytelen,
                 error = ubc_uiomove(&vp->v_uobj, uio, bytelen, UVM_ADV_RANDOM,                      UVM_ADV_NORMAL, ubc_alloc_flags);
                     ubc_flags);                  error = uiomove(win, bytelen, uio);
                   if (error && extending) {
                           /*
                            * if we haven't initialized the pages yet,
                            * do it now.  it's safe to use memset here
                            * because we just mapped the pages above.
                            */
                           memset(win, 0, bytelen);
                   }
                   ubc_release_flags = UBC_WANT_UNMAP(vp) ? UBC_UNMAP : 0;
                   ubc_release(win, ubc_release_flags);
   
                 /*                  /*
                  * update UVM's notion of the size now that we've                   * update UVM's notion of the size now that we've
Line 391  WRITE(void *v)
Line 395  WRITE(void *v)
                  * otherwise ffs_truncate can't flush soft update states.                   * otherwise ffs_truncate can't flush soft update states.
                  */                   */
   
                   newoff = oldoff + bytelen;
                 if (vp->v_size < newoff) {                  if (vp->v_size < newoff) {
                         uvm_vnp_setsize(vp, newoff);                          uvm_vnp_setsize(vp, newoff);
                         extended = 1;                          extended = 1;
Line 406  WRITE(void *v)
Line 411  WRITE(void *v)
   
 #ifndef LFS_READWRITE  #ifndef LFS_READWRITE
                 if (!async && oldoff >> 16 != uio->uio_offset >> 16) {                  if (!async && oldoff >> 16 != uio->uio_offset >> 16) {
                         mutex_enter(&vp->v_interlock);                          simple_lock(&vp->v_interlock);
                         error = VOP_PUTPAGES(vp, (oldoff >> 16) << 16,                          error = VOP_PUTPAGES(vp, (oldoff >> 16) << 16,
                             (uio->uio_offset >> 16) << 16, PGO_CLEANIT);                              (uio->uio_offset >> 16) << 16, PGO_CLEANIT);
                         if (error)                          if (error)
Line 415  WRITE(void *v)
Line 420  WRITE(void *v)
 #endif  #endif
         }          }
         if (error == 0 && ioflag & IO_SYNC) {          if (error == 0 && ioflag & IO_SYNC) {
                 mutex_enter(&vp->v_interlock);                  simple_lock(&vp->v_interlock);
                 error = VOP_PUTPAGES(vp, trunc_page(origoff & fs->fs_bmask),                  error = VOP_PUTPAGES(vp, trunc_page(origoff & fs->fs_bmask),
                     round_page(blkroundup(fs, uio->uio_offset)),                      round_page(blkroundup(fs, uio->uio_offset)),
                     PGO_CLEANIT | PGO_SYNCIO);                      PGO_CLEANIT | PGO_SYNCIO);
Line 423  WRITE(void *v)
Line 428  WRITE(void *v)
         goto out;          goto out;
   
  bcache:   bcache:
         mutex_enter(&vp->v_interlock);          simple_lock(&vp->v_interlock);
         VOP_PUTPAGES(vp, trunc_page(origoff), round_page(origoff + resid),          VOP_PUTPAGES(vp, trunc_page(origoff), round_page(origoff + resid),
             PGO_CLEANIT | PGO_FREE | PGO_SYNCIO);              PGO_CLEANIT | PGO_FREE | PGO_SYNCIO);
         while (uio->uio_resid > 0) {          while (uio->uio_resid > 0) {
Line 453  WRITE(void *v)
Line 458  WRITE(void *v)
                         uvm_vnp_setsize(vp, ip->i_size);                          uvm_vnp_setsize(vp, ip->i_size);
                         extended = 1;                          extended = 1;
                 }                  }
                 size = blksize(fs, ip, lbn) - bp->b_resid;                  size = BLKSIZE(fs, ip, lbn) - bp->b_resid;
                 if (xfersize > size)                  if (xfersize > size)
                         xfersize = size;                          xfersize = size;
   
Line 465  WRITE(void *v)
Line 470  WRITE(void *v)
                  * so we need to invalidate it.                   * so we need to invalidate it.
                  */                   */
                 if (error && (flags & B_CLRBUF) == 0) {                  if (error && (flags & B_CLRBUF) == 0) {
                         brelse(bp, BC_INVAL);                          bp->b_flags |= B_INVAL;
                           brelse(bp);
                         break;                          break;
                 }                  }
 #ifdef LFS_READWRITE  #ifdef LFS_READWRITE

Legend:
Removed from v.1.76.4.8  
changed lines
  Added in v.1.77

CVSweb <webmaster@jp.NetBSD.org>