usr/src/uts/common/fs/zfs/vdev_cache.c
changeset 8632 36ef517870a3
parent 7837 001de5627df3
child 11066 cebb50cbe4f9
equal deleted inserted replaced
8631:f693eaa7ed4a 8632:36ef517870a3
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    18  *
    18  *
    19  * CDDL HEADER END
    19  * CDDL HEADER END
    20  */
    20  */
    21 /*
    21 /*
    22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
    22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
    23  * Use is subject to license terms.
    23  * Use is subject to license terms.
    24  */
    24  */
    25 
    25 
    26 #include <sys/zfs_context.h>
    26 #include <sys/zfs_context.h>
    27 #include <sys/spa.h>
    27 #include <sys/spa.h>
   201 
   201 
   202 /*
   202 /*
   203  * Fill a previously allocated cache entry with data.
   203  * Fill a previously allocated cache entry with data.
   204  */
   204  */
   205 static void
   205 static void
   206 vdev_cache_fill(zio_t *zio)
   206 vdev_cache_fill(zio_t *fio)
   207 {
   207 {
   208 	vdev_t *vd = zio->io_vd;
   208 	vdev_t *vd = fio->io_vd;
   209 	vdev_cache_t *vc = &vd->vdev_cache;
   209 	vdev_cache_t *vc = &vd->vdev_cache;
   210 	vdev_cache_entry_t *ve = zio->io_private;
   210 	vdev_cache_entry_t *ve = fio->io_private;
   211 	zio_t *dio;
   211 	zio_t *pio;
   212 
   212 
   213 	ASSERT(zio->io_size == VCBS);
   213 	ASSERT(fio->io_size == VCBS);
   214 
   214 
   215 	/*
   215 	/*
   216 	 * Add data to the cache.
   216 	 * Add data to the cache.
   217 	 */
   217 	 */
   218 	mutex_enter(&vc->vc_lock);
   218 	mutex_enter(&vc->vc_lock);
   219 
   219 
   220 	ASSERT(ve->ve_fill_io == zio);
   220 	ASSERT(ve->ve_fill_io == fio);
   221 	ASSERT(ve->ve_offset == zio->io_offset);
   221 	ASSERT(ve->ve_offset == fio->io_offset);
   222 	ASSERT(ve->ve_data == zio->io_data);
   222 	ASSERT(ve->ve_data == fio->io_data);
   223 
   223 
   224 	ve->ve_fill_io = NULL;
   224 	ve->ve_fill_io = NULL;
   225 
   225 
   226 	/*
   226 	/*
   227 	 * Even if this cache line was invalidated by a missed write update,
   227 	 * Even if this cache line was invalidated by a missed write update,
   228 	 * any reads that were queued up before the missed update are still
   228 	 * any reads that were queued up before the missed update are still
   229 	 * valid, so we can satisfy them from this line before we evict it.
   229 	 * valid, so we can satisfy them from this line before we evict it.
   230 	 */
   230 	 */
   231 	for (dio = zio->io_delegate_list; dio; dio = dio->io_delegate_next)
   231 	while ((pio = zio_walk_parents(fio)) != NULL)
   232 		vdev_cache_hit(vc, ve, dio);
   232 		vdev_cache_hit(vc, ve, pio);
   233 
   233 
   234 	if (zio->io_error || ve->ve_missed_update)
   234 	if (fio->io_error || ve->ve_missed_update)
   235 		vdev_cache_evict(vc, ve);
   235 		vdev_cache_evict(vc, ve);
   236 
   236 
   237 	mutex_exit(&vc->vc_lock);
   237 	mutex_exit(&vc->vc_lock);
   238 
       
   239 	while ((dio = zio->io_delegate_list) != NULL) {
       
   240 		zio->io_delegate_list = dio->io_delegate_next;
       
   241 		dio->io_delegate_next = NULL;
       
   242 		dio->io_error = zio->io_error;
       
   243 		zio_execute(dio);
       
   244 	}
       
   245 }
   238 }
   246 
   239 
   247 /*
   240 /*
   248  * Read data from the cache.  Returns 0 on cache hit, errno on a miss.
   241  * Read data from the cache.  Returns 0 on cache hit, errno on a miss.
   249  */
   242  */
   282 			mutex_exit(&vc->vc_lock);
   275 			mutex_exit(&vc->vc_lock);
   283 			return (ESTALE);
   276 			return (ESTALE);
   284 		}
   277 		}
   285 
   278 
   286 		if ((fio = ve->ve_fill_io) != NULL) {
   279 		if ((fio = ve->ve_fill_io) != NULL) {
   287 			zio->io_delegate_next = fio->io_delegate_list;
       
   288 			fio->io_delegate_list = zio;
       
   289 			zio_vdev_io_bypass(zio);
   280 			zio_vdev_io_bypass(zio);
       
   281 			zio_add_child(zio, fio);
   290 			mutex_exit(&vc->vc_lock);
   282 			mutex_exit(&vc->vc_lock);
   291 			VDCSTAT_BUMP(vdc_stat_delegations);
   283 			VDCSTAT_BUMP(vdc_stat_delegations);
   292 			return (0);
   284 			return (0);
   293 		}
   285 		}
   294 
   286 
   295 		vdev_cache_hit(vc, ve, zio);
   287 		vdev_cache_hit(vc, ve, zio);
   296 		zio_vdev_io_bypass(zio);
   288 		zio_vdev_io_bypass(zio);
   297 
   289 
   298 		mutex_exit(&vc->vc_lock);
   290 		mutex_exit(&vc->vc_lock);
   299 		zio_execute(zio);
       
   300 		VDCSTAT_BUMP(vdc_stat_hits);
   291 		VDCSTAT_BUMP(vdc_stat_hits);
   301 		return (0);
   292 		return (0);
   302 	}
   293 	}
   303 
   294 
   304 	ve = vdev_cache_allocate(zio);
   295 	ve = vdev_cache_allocate(zio);
   311 	fio = zio_vdev_delegated_io(zio->io_vd, cache_offset,
   302 	fio = zio_vdev_delegated_io(zio->io_vd, cache_offset,
   312 	    ve->ve_data, VCBS, ZIO_TYPE_READ, ZIO_PRIORITY_CACHE_FILL,
   303 	    ve->ve_data, VCBS, ZIO_TYPE_READ, ZIO_PRIORITY_CACHE_FILL,
   313 	    ZIO_FLAG_DONT_CACHE, vdev_cache_fill, ve);
   304 	    ZIO_FLAG_DONT_CACHE, vdev_cache_fill, ve);
   314 
   305 
   315 	ve->ve_fill_io = fio;
   306 	ve->ve_fill_io = fio;
   316 	fio->io_delegate_list = zio;
       
   317 	zio_vdev_io_bypass(zio);
   307 	zio_vdev_io_bypass(zio);
       
   308 	zio_add_child(zio, fio);
   318 
   309 
   319 	mutex_exit(&vc->vc_lock);
   310 	mutex_exit(&vc->vc_lock);
   320 	zio_nowait(fio);
   311 	zio_nowait(fio);
   321 	VDCSTAT_BUMP(vdc_stat_misses);
   312 	VDCSTAT_BUMP(vdc_stat_misses);
   322 
   313