Пример #1
0
static int
vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, 
	      vfs_context_t ctx)
{
	u_int32_t		blocksize = vn->sc_secsize;
	int 		error = 0;
	off_t		offset;
	user_ssize_t	resid;
	off_t		orig_offset;
	user_ssize_t	orig_resid;

	orig_resid = resid = uio_resid(uio);
	orig_offset = offset = uio_offset(uio);

	while (resid > 0) {
		u_int32_t		remainder;
		u_int32_t		this_block_number;
		u_int32_t		this_block_count;
		off_t		this_offset;
		user_ssize_t	this_resid;
		struct vnode *	vp;

		/* figure out which blocks to read */
		remainder = block_remainder(offset, blocksize);
		if (shadow_map_read(vn->sc_shadow_map,
				    block_truncate(offset, blocksize),
				    block_round(resid + remainder, blocksize),
				    &this_block_number, &this_block_count)) {
			vp = vn->sc_shadow_vp;
		}
		else {
			vp = vn->sc_vp;
		}

		/* read the blocks (or parts thereof) */
		this_offset = (off_t)this_block_number * blocksize + remainder;
		uio_setoffset(uio, this_offset);
		this_resid = this_block_count * blocksize - remainder;
		if (this_resid > resid) {
			this_resid = resid;
		}
		uio_setresid(uio, this_resid);
		error = VNOP_READ(vp, uio, ioflag, ctx);
		if (error) {
			break;
		}

		/* figure out how much we actually read */
		this_resid -= uio_resid(uio);
		if (this_resid == 0) {
			printf("vn device: vnread_shadow zero length read\n");
			break;
		}
		resid -= this_resid;
		offset += this_resid;
	}
	uio_setresid(uio, resid);
	uio_setoffset(uio, offset);
	return (error);
}
Пример #2
0
static int
shadow_read(struct vn_softc * vn, struct buf * bp, char * base,
	vfs_context_t ctx)
{
	u_int32_t		blocksize = vn->sc_secsize;
	int 		error = 0;
	u_int32_t		offset;
	boolean_t	read_shadow;
	u_int32_t		resid;
	u_int32_t		start = 0;

	offset = buf_blkno(bp);
	resid =  buf_resid(bp) / blocksize;
	while (resid > 0) {
		user_ssize_t	temp_resid;
		u_int32_t		this_offset;
		u_int32_t		this_resid;
		struct vnode *	vp;

		read_shadow = shadow_map_read(vn->sc_shadow_map,
					      offset, resid,
					      &this_offset, &this_resid);
		if (read_shadow) {
			vp = vn->sc_shadow_vp;
		}
		else {
			vp = vn->sc_vp;
		}
		error = file_io(vp, ctx, UIO_READ, base + start,
				(off_t)this_offset * blocksize,
				(user_ssize_t)this_resid * blocksize, 
				&temp_resid);
		if (error) {
			break;
		}
		this_resid -= (temp_resid / blocksize);
		if (this_resid == 0) {
			printf("vn device: shadow_read zero length read\n");
			break;
		}
		resid -= this_resid;
		offset += this_resid;
		start += this_resid * blocksize;
	}
	buf_setresid(bp, resid * blocksize);
	return (error);
}
Пример #3
0
int
main()
{
    shadow_map_t *	map;
    int 		i;
    block_request_t 	requests[] = {
	{ WriteRequest, BAND_SIZE_BLOCKS * 2, 1 },
	{ ReadRequest, BAND_SIZE_BLOCKS / 2, BAND_SIZE_BLOCKS * 2 - 2 },
	{ WriteRequest, BAND_SIZE_BLOCKS * 1, 5 * BAND_SIZE_BLOCKS + 3},
	{ ReadRequest, 0, BAND_SIZE_BLOCKS * 10 },
	{ WriteRequest, BAND_SIZE_BLOCKS * (BAND_MAX - 1),
	  BAND_SIZE_BLOCKS * 2},
	{ 0, 0 },
    };
    
    map = shadow_map_create(1024 * 1024 * 1024 * 8ULL, 0, 0, 512);
    if (map == NULL) {
	printf("shadow_map_create failed\n");
	exit(1);
    }
    for (i = 0; TRUE; i++) {
	u_long		offset;
	u_long		resid;
	boolean_t	shadow_grew;
	boolean_t	read_shadow;

    	if (requests[i].count == 0) {
	    break;
	}
	offset = requests[i].offset;
	resid = requests[i].count;
	printf("\n%s REQUEST (%ld, %ld)\n", 
	       requests[i].type == WriteRequest ? "WRITE" : "READ",
	       offset, resid);
	switch (requests[i].type) {
	case WriteRequest:
	    while (resid > 0) {
		u_long this_offset;
		u_long this_count;
		
		shadow_grew = shadow_map_write(map, offset,
					       resid,
					       &this_offset,
					       &this_count);
		printf("\t(%ld, %ld) => (%ld, %ld)",
		       offset, resid, this_offset, this_count);
		resid -= this_count;
		offset += this_count;
		if (shadow_grew) {
		    printf(" shadow grew to %ld", shadow_map_shadow_size(map));
		}
		printf("\n");
	    }
	    break;
	case ReadRequest:
	    while (resid > 0) {
		u_long this_offset;
		u_long this_count;
		
		read_shadow = shadow_map_read(map, offset,
					      resid,
					      &this_offset,
					      &this_count);
		printf("\t(%ld, %ld) => (%ld, %ld)%s\n",
		       offset, resid, this_offset, this_count,
		       read_shadow ? " from shadow" : "");
		if (this_count == 0) {
		    printf("this_count is 0, aborting\n");
		    break;
		}
		resid -= this_count;
		offset += this_count;
	    }
	    break;
	default:
	    break;
	}
    }
    if (map) {
	shadow_map_free(map);
    }
    exit(0);
    return (0);
}