]> git.proxmox.com Git - mirror_zfs-debian.git/blobdiff - module/zfs/dmu_zfetch.c
Imported Upstream version 0.6.5.3
[mirror_zfs-debian.git] / module / zfs / dmu_zfetch.c
index 1763bae5184a6c40f5e72b8da9d9bc52d1998705..8ff2f0509787cf8061960cf77eef166f57145b07 100644 (file)
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ */
+
 #include <sys/zfs_context.h>
 #include <sys/dnode.h>
 #include <sys/dmu_objset.h>
@@ -48,11 +52,11 @@ unsigned int        zfetch_block_cap = 256;
 unsigned long  zfetch_array_rd_sz = 1024 * 1024;
 
 /* forward decls for static routines */
-static int             dmu_zfetch_colinear(zfetch_t *, zstream_t *);
+static boolean_t       dmu_zfetch_colinear(zfetch_t *, zstream_t *);
 static void            dmu_zfetch_dofetch(zfetch_t *, zstream_t *);
 static uint64_t                dmu_zfetch_fetch(dnode_t *, uint64_t, uint64_t);
 static uint64_t                dmu_zfetch_fetchsz(dnode_t *, uint64_t, uint64_t);
-static int             dmu_zfetch_find(zfetch_t *, zstream_t *, int);
+static boolean_t       dmu_zfetch_find(zfetch_t *, zstream_t *, int);
 static int             dmu_zfetch_stream_insert(zfetch_t *, zstream_t *);
 static zstream_t       *dmu_zfetch_stream_reclaim(zfetch_t *);
 static void            dmu_zfetch_stream_remove(zfetch_t *, zstream_t *);
@@ -104,9 +108,9 @@ kstat_t             *zfetch_ksp;
  * last stream, then we are probably in a strided access pattern.  So
  * combine the two sequential streams into a single strided stream.
  *
- * If no co-linear streams are found, return NULL.
+ * Returns whether co-linear streams were found.
  */
-static int
+static boolean_t
 dmu_zfetch_colinear(zfetch_t *zf, zstream_t *zh)
 {
        zstream_t       *z_walk;
@@ -134,7 +138,8 @@ dmu_zfetch_colinear(zfetch_t *zf, zstream_t *zh)
                        diff = z_comp->zst_offset - z_walk->zst_offset;
                        if (z_comp->zst_offset + diff == zh->zst_offset) {
                                z_walk->zst_offset = zh->zst_offset;
-                               z_walk->zst_direction = diff < 0 ? -1 : 1;
+                               z_walk->zst_direction = diff < 0 ?
+                                   ZFETCH_BACKWARD : ZFETCH_FORWARD;
                                z_walk->zst_stride =
                                    diff * z_walk->zst_direction;
                                z_walk->zst_ph_offset =
@@ -152,7 +157,8 @@ dmu_zfetch_colinear(zfetch_t *zf, zstream_t *zh)
                        diff = z_walk->zst_offset - z_comp->zst_offset;
                        if (z_walk->zst_offset + diff == zh->zst_offset) {
                                z_walk->zst_offset = zh->zst_offset;
-                               z_walk->zst_direction = diff < 0 ? -1 : 1;
+                               z_walk->zst_direction = diff < 0 ?
+                                   ZFETCH_BACKWARD : ZFETCH_FORWARD;
                                z_walk->zst_stride =
                                    diff * z_walk->zst_direction;
                                z_walk->zst_ph_offset =
@@ -287,7 +293,7 @@ dmu_zfetch_fetch(dnode_t *dn, uint64_t blkid, uint64_t nblks)
        fetchsz = dmu_zfetch_fetchsz(dn, blkid, nblks);
 
        for (i = 0; i < fetchsz; i++) {
-               dbuf_prefetch(dn, blkid + i);
+               dbuf_prefetch(dn, blkid + i, ZIO_PRIORITY_ASYNC_READ);
        }
 
        return (fetchsz);
@@ -326,7 +332,7 @@ dmu_zfetch_fetchsz(dnode_t *dn, uint64_t blkid, uint64_t nblks)
  * for this block read.  If so, it starts a prefetch for the stream it
  * located and returns true, otherwise it returns false
  */
-static int
+static boolean_t
 dmu_zfetch_find(zfetch_t *zf, zstream_t *zh, int prefetched)
 {
        zstream_t       *zs;
@@ -639,7 +645,7 @@ dmu_zfetch(zfetch_t *zf, uint64_t offset, uint64_t size, int prefetched)
 {
        zstream_t       zst;
        zstream_t       *newstream;
-       int             fetched;
+       boolean_t       fetched;
        int             inserted;
        unsigned int    blkshft;
        uint64_t        blksz;
@@ -699,7 +705,8 @@ dmu_zfetch(zfetch_t *zf, uint64_t offset, uint64_t size, int prefetched)
                        if (cur_streams >= max_streams) {
                                return;
                        }
-                       newstream = kmem_zalloc(sizeof (zstream_t), KM_PUSHPAGE);
+                       newstream =
+                           kmem_zalloc(sizeof (zstream_t), KM_SLEEP);
                }
 
                newstream->zst_offset = zst.zst_offset;
@@ -739,4 +746,3 @@ MODULE_PARM_DESC(zfetch_block_cap, "Max number of blocks to fetch at a time");
 module_param(zfetch_array_rd_sz, ulong, 0644);
 MODULE_PARM_DESC(zfetch_array_rd_sz, "Number of bytes in a array_read");
 #endif
-