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

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

Diff for /src/sys/kern/vfs_wapbl.c between version 1.51.2.1 and 1.51.2.2

version 1.51.2.1, 2012/05/07 03:01:13 version 1.51.2.2, 2013/01/02 23:23:15
Line 184  struct wapbl {
Line 184  struct wapbl {
   
         SIMPLEQ_HEAD(, wapbl_entry) wl_entries; /* On disk transaction          SIMPLEQ_HEAD(, wapbl_entry) wl_entries; /* On disk transaction
                                                    accounting */                                                     accounting */
   
           u_char *wl_buffer;      /* l:   buffer for wapbl_buffered_write() */
           daddr_t wl_buffer_dblk; /* l:   buffer disk block address */
           size_t wl_buffer_used;  /* l:   buffer current use */
 };  };
   
 #ifdef WAPBL_DEBUG_PRINT  #ifdef WAPBL_DEBUG_PRINT
Line 489  wapbl_start(struct wapbl ** wlp, struct 
Line 493  wapbl_start(struct wapbl ** wlp, struct 
         wl->wl_dealloclens = wapbl_alloc(sizeof(*wl->wl_dealloclens) *          wl->wl_dealloclens = wapbl_alloc(sizeof(*wl->wl_dealloclens) *
             wl->wl_dealloclim);              wl->wl_dealloclim);
   
           wl->wl_buffer = wapbl_alloc(MAXPHYS);
           wl->wl_buffer_used = 0;
   
         wapbl_inodetrk_init(wl, WAPBL_INODETRK_SIZE);          wapbl_inodetrk_init(wl, WAPBL_INODETRK_SIZE);
   
         /* Initialize the commit header */          /* Initialize the commit header */
Line 537  wapbl_start(struct wapbl ** wlp, struct 
Line 544  wapbl_start(struct wapbl ** wlp, struct 
             sizeof(*wl->wl_deallocblks) * wl->wl_dealloclim);              sizeof(*wl->wl_deallocblks) * wl->wl_dealloclim);
         wapbl_free(wl->wl_dealloclens,          wapbl_free(wl->wl_dealloclens,
             sizeof(*wl->wl_dealloclens) * wl->wl_dealloclim);              sizeof(*wl->wl_dealloclens) * wl->wl_dealloclim);
           wapbl_free(wl->wl_buffer, MAXPHYS);
         wapbl_inodetrk_free(wl);          wapbl_inodetrk_free(wl);
         wapbl_free(wl, sizeof(*wl));          wapbl_free(wl, sizeof(*wl));
   
Line 716  wapbl_stop(struct wapbl *wl, int force)
Line 724  wapbl_stop(struct wapbl *wl, int force)
             sizeof(*wl->wl_deallocblks) * wl->wl_dealloclim);              sizeof(*wl->wl_deallocblks) * wl->wl_dealloclim);
         wapbl_free(wl->wl_dealloclens,          wapbl_free(wl->wl_dealloclens,
             sizeof(*wl->wl_dealloclens) * wl->wl_dealloclim);              sizeof(*wl->wl_dealloclens) * wl->wl_dealloclim);
           wapbl_free(wl->wl_buffer, MAXPHYS);
         wapbl_inodetrk_free(wl);          wapbl_inodetrk_free(wl);
   
         cv_destroy(&wl->wl_reclaimable_cv);          cv_destroy(&wl->wl_reclaimable_cv);
Line 791  wapbl_read(void *data, size_t len, struc
Line 800  wapbl_read(void *data, size_t len, struc
 }  }
   
 /*  /*
    * Flush buffered data if any.
    */
   static int
   wapbl_buffered_flush(struct wapbl *wl)
   {
           int error;
   
           if (wl->wl_buffer_used == 0)
                   return 0;
   
           error = wapbl_doio(wl->wl_buffer, wl->wl_buffer_used,
               wl->wl_devvp, wl->wl_buffer_dblk, B_WRITE);
           wl->wl_buffer_used = 0;
   
           return error;
   }
   
   /*
    * Write data to the log.
    * Try to coalesce writes and emit MAXPHYS aligned blocks.
    */
   static int
   wapbl_buffered_write(void *data, size_t len, struct wapbl *wl, daddr_t pbn)
   {
           int error;
           size_t resid;
   
           /*
            * If not adjacent to buffered data flush first.  Disk block
            * address is always valid for non-empty buffer.
            */
           if (wl->wl_buffer_used > 0 &&
               pbn != wl->wl_buffer_dblk + btodb(wl->wl_buffer_used)) {
                   error = wapbl_buffered_flush(wl);
                   if (error)
                           return error;
           }
           /*
            * If this write goes to an empty buffer we have to
            * save the disk block address first.
            */
           if (wl->wl_buffer_used == 0)
                   wl->wl_buffer_dblk = pbn;
           /*
            * Remaining space so this buffer ends on a MAXPHYS boundary.
            *
            * Cannot become less or equal zero as the buffer would have been
            * flushed on the last call then.
            */
           resid = MAXPHYS - dbtob(wl->wl_buffer_dblk % btodb(MAXPHYS)) -
               wl->wl_buffer_used;
           KASSERT(resid > 0);
           KASSERT(dbtob(btodb(resid)) == resid);
           if (len >= resid) {
                   memcpy(wl->wl_buffer + wl->wl_buffer_used, data, resid);
                   wl->wl_buffer_used += resid;
                   error = wapbl_doio(wl->wl_buffer, wl->wl_buffer_used,
                       wl->wl_devvp, wl->wl_buffer_dblk, B_WRITE);
                   data = (uint8_t *)data + resid;
                   len -= resid;
                   wl->wl_buffer_dblk = pbn + btodb(resid);
                   wl->wl_buffer_used = 0;
                   if (error)
                           return error;
           }
           KASSERT(len < MAXPHYS);
           if (len > 0) {
                   memcpy(wl->wl_buffer + wl->wl_buffer_used, data, len);
                   wl->wl_buffer_used += len;
           }
   
           return 0;
   }
   
   /*
  * Off is byte offset returns new offset for next write   * Off is byte offset returns new offset for next write
  * handles log wraparound   * handles log wraparound
  */   */
Line 813  wapbl_circ_write(struct wapbl *wl, void 
Line 897  wapbl_circ_write(struct wapbl *wl, void 
 #ifdef _KERNEL  #ifdef _KERNEL
                 pbn = btodb(pbn << wl->wl_log_dev_bshift);                  pbn = btodb(pbn << wl->wl_log_dev_bshift);
 #endif  #endif
                 error = wapbl_write(data, slen, wl->wl_devvp, pbn);                  error = wapbl_buffered_write(data, slen, wl, pbn);
                 if (error)                  if (error)
                         return error;                          return error;
                 data = (uint8_t *)data + slen;                  data = (uint8_t *)data + slen;
Line 824  wapbl_circ_write(struct wapbl *wl, void 
Line 908  wapbl_circ_write(struct wapbl *wl, void 
 #ifdef _KERNEL  #ifdef _KERNEL
         pbn = btodb(pbn << wl->wl_log_dev_bshift);          pbn = btodb(pbn << wl->wl_log_dev_bshift);
 #endif  #endif
         error = wapbl_write(data, len, wl->wl_devvp, pbn);          error = wapbl_buffered_write(data, len, wl, pbn);
         if (error)          if (error)
                 return error;                  return error;
         off += len;          off += len;
Line 1224  wapbl_biodone(struct buf *bp)
Line 1308  wapbl_biodone(struct buf *bp)
 {  {
         struct wapbl_entry *we = bp->b_private;          struct wapbl_entry *we = bp->b_private;
         struct wapbl *wl = we->we_wapbl;          struct wapbl *wl = we->we_wapbl;
   #ifdef WAPBL_DEBUG_BUFBYTES
           const int bufsize = bp->b_bufsize;
   #endif
   
         /*          /*
          * Handle possible flushing of buffers after log has been           * Handle possible flushing of buffers after log has been
Line 1233  wapbl_biodone(struct buf *bp)
Line 1320  wapbl_biodone(struct buf *bp)
                 KASSERT(we->we_bufcount > 0);                  KASSERT(we->we_bufcount > 0);
                 we->we_bufcount--;                  we->we_bufcount--;
 #ifdef WAPBL_DEBUG_BUFBYTES  #ifdef WAPBL_DEBUG_BUFBYTES
                 KASSERT(we->we_unsynced_bufbytes >= bp->b_bufsize);                  KASSERT(we->we_unsynced_bufbytes >= bufsize);
                 we->we_unsynced_bufbytes -= bp->b_bufsize;                  we->we_unsynced_bufbytes -= bufsize;
 #endif  #endif
   
                 if (we->we_bufcount == 0) {                  if (we->we_bufcount == 0) {
Line 1300  wapbl_biodone(struct buf *bp)
Line 1387  wapbl_biodone(struct buf *bp)
 #endif  #endif
         }          }
   
           /*
            * Release the buffer here. wapbl_flush() may wait for the
            * log to become empty and we better unbusy the buffer before
            * wapbl_flush() returns.
            */
           brelse(bp, 0);
   
         mutex_enter(&wl->wl_mtx);          mutex_enter(&wl->wl_mtx);
   
         KASSERT(we->we_bufcount > 0);          KASSERT(we->we_bufcount > 0);
         we->we_bufcount--;          we->we_bufcount--;
 #ifdef WAPBL_DEBUG_BUFBYTES  #ifdef WAPBL_DEBUG_BUFBYTES
         KASSERT(we->we_unsynced_bufbytes >= bp->b_bufsize);          KASSERT(we->we_unsynced_bufbytes >= bufsize);
         we->we_unsynced_bufbytes -= bp->b_bufsize;          we->we_unsynced_bufbytes -= bufsize;
         KASSERT(wl->wl_unsynced_bufbytes >= bp->b_bufsize);          KASSERT(wl->wl_unsynced_bufbytes >= bufsize);
         wl->wl_unsynced_bufbytes -= bp->b_bufsize;          wl->wl_unsynced_bufbytes -= bufsize;
 #endif  #endif
   
         /*          /*
Line 1345  wapbl_biodone(struct buf *bp)
Line 1439  wapbl_biodone(struct buf *bp)
         }          }
   
         mutex_exit(&wl->wl_mtx);          mutex_exit(&wl->wl_mtx);
         brelse(bp, 0);  
 }  }
   
 /*  /*
Line 1958  wapbl_write_commit(struct wapbl *wl, off
Line 2051  wapbl_write_commit(struct wapbl *wl, off
         int error;          int error;
         daddr_t pbn;          daddr_t pbn;
   
           error = wapbl_buffered_flush(wl);
           if (error)
                   return error;
         /*          /*
          * flush disk cache to ensure that blocks we've written are actually           * flush disk cache to ensure that blocks we've written are actually
          * written to the stable storage before the commit header.           * written to the stable storage before the commit header.
Line 1989  wapbl_write_commit(struct wapbl *wl, off
Line 2085  wapbl_write_commit(struct wapbl *wl, off
 #ifdef _KERNEL  #ifdef _KERNEL
         pbn = btodb(pbn << wc->wc_log_dev_bshift);          pbn = btodb(pbn << wc->wc_log_dev_bshift);
 #endif  #endif
         error = wapbl_write(wc, wc->wc_len, wl->wl_devvp, pbn);          error = wapbl_buffered_write(wc, wc->wc_len, wl, pbn);
           if (error)
                   return error;
           error = wapbl_buffered_flush(wl);
         if (error)          if (error)
                 return error;                  return error;
   

Legend:
Removed from v.1.51.2.1  
changed lines
  Added in v.1.51.2.2

CVSweb <webmaster@jp.NetBSD.org>