The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/buf.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: buf.h,v 1.113 2022/09/01 05:24:51 jsg Exp $   */
    2 /*      $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1982, 1986, 1989, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)buf.h       8.7 (Berkeley) 1/21/94
   38  */
   39 
   40 #ifndef _SYS_BUF_H_
   41 #define _SYS_BUF_H_
   42 #include <sys/queue.h>
   43 #include <sys/tree.h>
   44 #include <sys/mutex.h>
   45 #include <uvm/uvm_extern.h>
   46 
   47 #define NOLIST ((struct buf *)0x87654321)
   48 
   49 struct buf;
   50 struct vnode;
   51 
   52 LIST_HEAD(bufhead, buf);
   53 
   54 /*
   55  * To avoid including <ufs/ffs/softdep.h>
   56  */
   57 
   58 LIST_HEAD(workhead, worklist);
   59 
   60 /*
   61  * Buffer queues
   62  */
   63 #define BUFQ_NSCAN_N    128
   64 #define BUFQ_FIFO       0
   65 #define BUFQ_NSCAN      1
   66 #define BUFQ_DEFAULT    BUFQ_NSCAN
   67 #define BUFQ_HOWMANY    2
   68 
   69 /*
   70  * Write limits for bufq - defines high and low water marks for how
   71  * many kva slots are allowed to be consumed to parallelize writes from
   72  * the buffer cache from any individual bufq.
   73  */
   74 #define BUFQ_HI         128
   75 #define BUFQ_LOW        64
   76 
   77 struct bufq_impl;
   78 
   79 struct bufq {
   80         SLIST_ENTRY(bufq)        bufq_entries;
   81         struct mutex             bufq_mtx;
   82         void                    *bufq_data;
   83         u_int                    bufq_outstanding;
   84         u_int                    bufq_hi;
   85         u_int                    bufq_low;
   86         int                      bufq_waiting;
   87         int                      bufq_stop;
   88         int                      bufq_type;
   89         const struct bufq_impl  *bufq_impl;
   90 };
   91 
   92 int              bufq_init(struct bufq *, int);
   93 int              bufq_switch(struct bufq *, int);
   94 void             bufq_destroy(struct bufq *);
   95 
   96 void             bufq_queue(struct bufq *, struct buf *);
   97 struct buf      *bufq_dequeue(struct bufq *);
   98 void             bufq_requeue(struct bufq *, struct buf *);
   99 int              bufq_peek(struct bufq *);
  100 void             bufq_drain(struct bufq *);
  101 
  102 void             bufq_wait(struct bufq *);
  103 void             bufq_done(struct bufq *, struct buf *);
  104 void             bufq_quiesce(void);
  105 void             bufq_restart(void);
  106 
  107 /* fifo */
  108 SIMPLEQ_HEAD(bufq_fifo_head, buf);
  109 struct bufq_fifo {
  110         SIMPLEQ_ENTRY(buf)      bqf_entries;
  111 };
  112 
  113 /* nscan */
  114 SIMPLEQ_HEAD(bufq_nscan_head, buf);
  115 struct bufq_nscan {
  116         SIMPLEQ_ENTRY(buf)      bqf_entries;
  117 };
  118 
  119 /* bufq link in struct buf */
  120 union bufq_data {
  121         struct bufq_fifo        bufq_data_fifo;
  122         struct bufq_nscan       bufq_data_nscan;
  123 };
  124 
  125 /*
  126  * These are currently used only by the soft dependency code, hence
  127  * are stored once in a global variable. If other subsystems wanted
  128  * to use these hooks, a pointer to a set of bio_ops could be added
  129  * to each buffer.
  130  */
  131 extern struct bio_ops {
  132         void    (*io_start)(struct buf *);
  133         void    (*io_complete)(struct buf *);
  134         void    (*io_deallocate)(struct buf *);
  135         void    (*io_movedeps)(struct buf *, struct buf *);
  136         int     (*io_countdeps)(struct buf *, int, int);
  137 } bioops;
  138 
  139 /* The buffer header describes an I/O operation in the kernel. */
  140 struct buf {
  141         RBT_ENTRY(buf) b_rbbufs;        /* vnode "hash" tree */
  142         LIST_ENTRY(buf) b_list;         /* All allocated buffers. */
  143         LIST_ENTRY(buf) b_vnbufs;       /* Buffer's associated vnode. */
  144         TAILQ_ENTRY(buf) b_freelist;    /* Free list position if not active. */
  145         int cache;                      /* which cache are we in */
  146         struct  proc *b_proc;           /* Associated proc; NULL if kernel. */
  147         volatile long   b_flags;        /* B_* flags. */
  148         long    b_bufsize;              /* Allocated buffer size. */
  149         long    b_bcount;               /* Valid bytes in buffer. */
  150         size_t  b_resid;                /* Remaining I/O. */
  151         int     b_error;                /* Errno value. */
  152         dev_t   b_dev;                  /* Device associated with buffer. */
  153         caddr_t b_data;                 /* associated data */
  154         void    *b_saveaddr;            /* Original b_data for physio. */
  155 
  156         TAILQ_ENTRY(buf) b_valist;      /* LRU of va to reuse. */
  157 
  158         union   bufq_data b_bufq;
  159         struct  bufq      *b_bq;        /* What bufq this buf is on */
  160 
  161         struct uvm_object *b_pobj;
  162         struct uvm_object b_uobj;       /* Object containing the pages */
  163         off_t   b_poffs;                /* Offset within object */
  164 
  165         daddr_t b_lblkno;               /* Logical block number. */
  166         daddr_t b_blkno;                /* Underlying physical block number. */
  167                                         /* Function to call upon completion.
  168                                          * Will be called at splbio(). */
  169         void    (*b_iodone)(struct buf *);
  170         struct  vnode *b_vp;            /* Device vnode. */
  171         int     b_dirtyoff;             /* Offset in buffer of dirty region. */
  172         int     b_dirtyend;             /* Offset of end of dirty region. */
  173         int     b_validoff;             /* Offset in buffer of valid region. */
  174         int     b_validend;             /* Offset of end of valid region. */
  175         struct  workhead b_dep;         /* List of filesystem dependencies. */
  176 };
  177 
  178 TAILQ_HEAD(bufqueue, buf);
  179 
  180 struct bufcache {
  181         int64_t hotbufpages;
  182         int64_t warmbufpages;
  183         int64_t cachepages;
  184         struct bufqueue hotqueue;
  185         struct bufqueue coldqueue;
  186         struct bufqueue warmqueue;
  187 };
  188 
  189 /* Device driver compatibility definitions. */
  190 #define b_active b_bcount               /* Driver queue head: drive active. */
  191 
  192 /*
  193  * These flags are kept in b_flags.
  194  */
  195 #define B_WRITE         0x00000000      /* Write buffer (pseudo flag). */
  196 #define B_AGE           0x00000001      /* Move to age queue when I/O done. */
  197 #define B_NEEDCOMMIT    0x00000002      /* Needs committing to stable storage */
  198 #define B_ASYNC         0x00000004      /* Start I/O, do not wait. */
  199 #define B_BAD           0x00000008      /* Bad block revectoring in progress. */
  200 #define B_BUSY          0x00000010      /* I/O in progress. */
  201 #define B_CACHE         0x00000020      /* Bread found us in the cache. */
  202 #define B_CALL          0x00000040      /* Call b_iodone from biodone. */
  203 #define B_DELWRI        0x00000080      /* Delay I/O until buffer reused. */
  204 #define B_DONE          0x00000100      /* I/O completed. */
  205 #define B_EINTR         0x00000200      /* I/O was interrupted */
  206 #define B_ERROR         0x00000400      /* I/O error occurred. */
  207 #define B_INVAL         0x00000800      /* Does not contain valid info. */
  208 #define B_NOCACHE       0x00001000      /* Do not cache block after use. */
  209 #define B_PHYS          0x00002000      /* I/O to user memory. */
  210 #define B_RAW           0x00004000      /* Set by physio for raw transfers. */
  211 #define B_READ          0x00008000      /* Read buffer. */
  212 #define B_WANTED        0x00010000      /* Process wants this buffer. */
  213 #define B_WRITEINPROG   0x00020000      /* Write in progress. */
  214 #define B_XXX           0x00040000      /* Debugging flag. */
  215 #define B_DEFERRED      0x00080000      /* Skipped over for cleaning */
  216 #define B_SCANNED       0x00100000      /* Block already pushed during sync */
  217 #define B_PDAEMON       0x00200000      /* I/O started by pagedaemon */
  218 #define B_RELEASED      0x00400000      /* free this buffer after its kvm */
  219 #define B_WARM          0x00800000      /* buffer is or has been on the warm queue */
  220 #define B_COLD          0x01000000      /* buffer is on the cold queue */
  221 #define B_BC            0x02000000      /* buffer is managed by the cache */
  222 #define B_DMA           0x04000000      /* buffer is DMA reachable */
  223 
  224 #define B_BITS  "\2\001AGE\002NEEDCOMMIT\003ASYNC\004BAD\005BUSY" \
  225     "\006CACHE\007CALL\010DELWRI\011DONE\012EINTR\013ERROR" \
  226     "\014INVAL\015NOCACHE\016PHYS\017RAW\020READ" \
  227     "\021WANTED\022WRITEINPROG\023XXX(FORMAT)\024DEFERRED" \
  228     "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA"
  229 
  230 /*
  231  * Zero out the buffer's data area.
  232  */
  233 #define clrbuf(bp) {                                                    \
  234         bzero((bp)->b_data, (bp)->b_bcount);                            \
  235         (bp)->b_resid = 0;                                              \
  236 }
  237 
  238 
  239 /* Flags to low-level allocation routines. */
  240 #define B_CLRBUF        0x01    /* Request allocated buffer be cleared. */
  241 #define B_SYNC          0x02    /* Do all allocations synchronously. */
  242 
  243 struct cluster_info {
  244         daddr_t ci_lastr;       /* last read (read-ahead) */
  245         daddr_t ci_lastw;       /* last write (write cluster) */
  246         daddr_t ci_cstart;      /* start block of cluster */
  247         daddr_t ci_lasta;       /* last allocation */
  248         int     ci_clen;        /* length of current cluster */
  249         int     ci_ralen;       /* Read-ahead length */
  250         daddr_t ci_maxra;       /* last readahead block */
  251 };
  252 
  253 #ifdef _KERNEL
  254 __BEGIN_DECLS
  255 /* Kva slots (of size MAXPHYS) reserved for syncer and cleaner. */
  256 #define RESERVE_SLOTS 4
  257 /* Buffer cache pages reserved for syncer and cleaner. */
  258 #define RESERVE_PAGES (RESERVE_SLOTS * MAXPHYS / PAGE_SIZE)
  259 /* Minimum size of the buffer cache, in pages. */
  260 #define BCACHE_MIN (RESERVE_PAGES * 2)
  261 #define UNCLEAN_PAGES (bcstats.numbufpages - bcstats.numcleanpages)
  262 
  263 extern struct proc *cleanerproc;
  264 extern long bufpages;           /* Max number of pages for buffers' data */
  265 extern struct pool bufpool;
  266 extern struct bufhead bufhead;
  267 
  268 void    bawrite(struct buf *);
  269 void    bdwrite(struct buf *);
  270 void    biodone(struct buf *);
  271 int     biowait(struct buf *);
  272 int bread(struct vnode *, daddr_t, int, struct buf **);
  273 int breadn(struct vnode *, daddr_t, int, daddr_t *, int *, int,
  274     struct buf **);
  275 void    brelse(struct buf *);
  276 #define bremfree bufcache_take
  277 void    bufinit(void);
  278 void    buf_dirty(struct buf *);
  279 void    buf_undirty(struct buf *);
  280 void    buf_adjcnt(struct buf *, long);
  281 int     bwrite(struct buf *);
  282 struct buf *getblk(struct vnode *, daddr_t, int, int, uint64_t);
  283 struct buf *geteblk(size_t);
  284 struct buf *incore(struct vnode *, daddr_t);
  285 
  286 /*
  287  * bufcache functions
  288  */
  289 void bufcache_take(struct buf *);
  290 void bufcache_release(struct buf *);
  291 
  292 int buf_flip_high(struct buf *);
  293 void buf_flip_dma(struct buf *);
  294 struct buf *bufcache_getcleanbuf(int, int);
  295 struct buf *bufcache_getdirtybuf(void);
  296 
  297 /*
  298  * buf_kvm_init initializes the kvm handling for buffers.
  299  * buf_acquire sets the B_BUSY flag and ensures that the buffer is
  300  * mapped in the kvm.
  301  * buf_release clears the B_BUSY flag and allows the buffer to become
  302  * unmapped.
  303  * buf_unmap is for internal use only. Unmaps the buffer from kvm.
  304  */
  305 void    buf_mem_init(vsize_t);
  306 void    buf_acquire(struct buf *);
  307 void    buf_acquire_nomap(struct buf *);
  308 void    buf_map(struct buf *);
  309 void    buf_release(struct buf *);
  310 int     buf_dealloc_mem(struct buf *);
  311 void    buf_fix_mapping(struct buf *, vsize_t);
  312 void    buf_alloc_pages(struct buf *, vsize_t);
  313 void    buf_free_pages(struct buf *);
  314 
  315 void    minphys(struct buf *bp);
  316 int     physio(void (*strategy)(struct buf *), dev_t dev, int flags,
  317             void (*minphys)(struct buf *), struct uio *uio);
  318 void  brelvp(struct buf *);
  319 void  reassignbuf(struct buf *);
  320 void  bgetvp(struct vnode *, struct buf *);
  321 
  322 void  buf_replacevnode(struct buf *, struct vnode *);
  323 void  buf_daemon(void *);
  324 void  buf_replacevnode(struct buf *, struct vnode *);
  325 int bread_cluster(struct vnode *, daddr_t, int, struct buf **);
  326 
  327 static __inline void
  328 buf_start(struct buf *bp)
  329 {
  330         if (bioops.io_start)
  331                 (*bioops.io_start)(bp);
  332 }
  333 
  334 static __inline void
  335 buf_complete(struct buf *bp)
  336 {
  337         if (bioops.io_complete)
  338                 (*bioops.io_complete)(bp);
  339 }
  340 
  341 static __inline void
  342 buf_deallocate(struct buf *bp)
  343 {
  344         if (bioops.io_deallocate)
  345                 (*bioops.io_deallocate)(bp);
  346 }
  347 
  348 static __inline void
  349 buf_movedeps(struct buf *bp, struct buf *bp2)
  350 {
  351         if (bioops.io_movedeps)
  352                 (*bioops.io_movedeps)(bp, bp2);
  353 }
  354 
  355 static __inline int
  356 buf_countdeps(struct buf *bp, int i, int islocked)
  357 {
  358         if (bioops.io_countdeps)
  359                 return ((*bioops.io_countdeps)(bp, i, islocked));
  360         else
  361                 return (0);
  362 }
  363 
  364 __END_DECLS
  365 #endif /* _KERNEL */
  366 #endif /* !_SYS_BUF_H_ */

Cache object: 065478a7b0722499cd97ad3e676a2bbf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.