[BACK]Return to deblock_media.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / dist / pdisk

File: [cvs.NetBSD.org] / src / dist / pdisk / Attic / deblock_media.c (download)

Revision 1.1.1.1 (vendor branch), Tue Jul 9 05:49:06 2002 UTC (21 years, 9 months ago) by dbj
Branch: ERYK_VERSHEN
CVS Tags: yamt-pf42-baseX, yamt-pf42-base4, yamt-pf42-base3, yamt-pf42-base2, yamt-pf42-base, yamt-pf42, wrstuden-revivesa-base-3, wrstuden-revivesa-base-2, wrstuden-revivesa-base-1, wrstuden-revivesa-base, wrstuden-revivesa, wrstuden-fixsa-newbase, wrstuden-fixsa-base-1, wrstuden-fixsa-base, wrstuden-fixsa, pdisk-0_8a2, netbsd-5-base, netbsd-5-2-RELEASE, netbsd-5-2-RC1, netbsd-5-2-3-RELEASE, netbsd-5-2-2-RELEASE, netbsd-5-2-1-RELEASE, netbsd-5-2, netbsd-5-1-RELEASE, netbsd-5-1-RC4, netbsd-5-1-RC3, netbsd-5-1-RC2, netbsd-5-1-RC1, netbsd-5-1-5-RELEASE, netbsd-5-1-4-RELEASE, netbsd-5-1-3-RELEASE, netbsd-5-1-2-RELEASE, netbsd-5-1-1-RELEASE, netbsd-5-1, netbsd-5-0-RELEASE, netbsd-5-0-RC4, netbsd-5-0-RC3, netbsd-5-0-RC2, netbsd-5-0-RC1, netbsd-5-0-2-RELEASE, netbsd-5-0-1-RELEASE, netbsd-5-0, netbsd-5, netbsd-4-base, netbsd-4-0-RELEASE, netbsd-4-0-RC5, netbsd-4-0-RC4, netbsd-4-0-RC3, netbsd-4-0-RC2, netbsd-4-0-RC1, netbsd-4-0-1-RELEASE, netbsd-4-0, netbsd-4, netbsd-3-base, netbsd-3-1-RELEASE, netbsd-3-1-RC4, netbsd-3-1-RC3, netbsd-3-1-RC2, netbsd-3-1-RC1, netbsd-3-1-1-RELEASE, netbsd-3-1, netbsd-3-0-RELEASE, netbsd-3-0-RC6, netbsd-3-0-RC5, netbsd-3-0-RC4, netbsd-3-0-RC3, netbsd-3-0-RC2, netbsd-3-0-RC1, netbsd-3-0-3-RELEASE, netbsd-3-0-2-RELEASE, netbsd-3-0-1-RELEASE, netbsd-3-0, netbsd-3, netbsd-2-base, netbsd-2-1-RELEASE, netbsd-2-1-RC6, netbsd-2-1-RC5, netbsd-2-1-RC4, netbsd-2-1-RC3, netbsd-2-1-RC2, netbsd-2-1-RC1, netbsd-2-1, netbsd-2-0-base, netbsd-2-0-RELEASE, netbsd-2-0-RC5, netbsd-2-0-RC4, netbsd-2-0-RC3, netbsd-2-0-RC2, netbsd-2-0-RC1, netbsd-2-0-3-RELEASE, netbsd-2-0-2-RELEASE, netbsd-2-0-1-RELEASE, netbsd-2-0, netbsd-2, mjf-devfs2-base, mjf-devfs2, matt-nb5-pq3-base, matt-nb5-pq3, matt-nb5-mips64-u2-k2-k4-k7-k8-k9, matt-nb5-mips64-u1-k1-k5, matt-nb5-mips64-premerge-20101231, matt-nb5-mips64-premerge-20091211, matt-nb5-mips64-k15, matt-nb5-mips64, matt-nb4-mips64-k7-u2a-k9b, matt-mips64-base2, matt-mips64-base, matt-mips64, matt-armv6-prevmlocking, matt-armv6-nbase, matt-armv6-base, matt-armv6, keiichi-mipv6-base, keiichi-mipv6, hpcarm-cleanup-nbase, hpcarm-cleanup-base, hpcarm-cleanup, fvdl_fs64_base, cube-autoconf-base, cube-autoconf, abandoned-netbsd-4-base, abandoned-netbsd-4
Branch point for: jym-xensuspend
Changes since 1.1: +0 -0 lines

import pdisk utility from Eryk Vershen:
  http://cantaforda.com/cfcl/eryk/linux/pdisk/index.html
this is the utility provided by mklinux and osX to manipulate
the Apple Partition map.

/*
 * deblock_media.c -
 *
 * Written by Eryk Vershen
 */

/*
 * Copyright 1997,1998 by Apple Computer, Inc.
 *              All Rights Reserved 
 *  
 * Permission to use, copy, modify, and distribute this software and 
 * its documentation for any purpose and without fee is hereby granted, 
 * provided that the above copyright notice appears in all copies and 
 * that both the copyright notice and this permission notice appear in 
 * supporting documentation. 
 *  
 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 * FOR A PARTICULAR PURPOSE. 
 *  
 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 */


// for malloc() & free()
#include <stdlib.h>
// for memcpy()
#include <string.h>

#include "deblock_media.h"


/*
 * Defines
 */


/*
 * Types
 */
typedef struct deblock_media *DEBLOCK_MEDIA;

struct deblock_media {
    struct media    m;
    long            need_filtering;
    MEDIA           next_media;
    unsigned long   next_block_size;
    unsigned char   *buffer;
};

struct deblock_globals {
    long        exists;
    long        kind;
};


/*
 * Global Constants
 */


/*
 * Global Variables
 */
static long deblock_inited = 0;
static struct deblock_globals deblock_info;

/*
 * Forward declarations
 */
void deblock_init(void);
DEBLOCK_MEDIA new_deblock_media(void);
long read_deblock_media(MEDIA m, long long offset, unsigned long count, void *address);
long write_deblock_media(MEDIA m, long long offset, unsigned long count, void *address);
long close_deblock_media(MEDIA m);
long os_reload_deblock_media(MEDIA m);


/*
 * Routines
 */
void
deblock_init(void)
{
    if (deblock_inited != 0) {
	return;
    }
    deblock_inited = 1;
    
    deblock_info.kind = allocate_media_kind();
}


DEBLOCK_MEDIA
new_deblock_media(void)
{
    return (DEBLOCK_MEDIA) new_media(sizeof(struct deblock_media));
}


MEDIA
open_deblock_media(long new_block_size, MEDIA m)
{
    DEBLOCK_MEDIA   a;
    unsigned long   block_size;
    
    if (deblock_inited == 0) {
	deblock_init();
    }
    
    a = 0;
    if (m != 0) {
	block_size = media_granularity(m);

	if (new_block_size == block_size) {
	    return m;

	} else if (new_block_size > block_size) {
	    if ((new_block_size % block_size) == 0) {
		/* no filtering necessary */
		a = new_deblock_media();
		if (a != 0) {
		    a->need_filtering = 0;
		    a->next_block_size = block_size;
		    a->buffer = 0;
		}
	    } else {
		/* too hard to bother with */
	    }
	} else /* new_block_size < block_size */ {
	    if ((block_size % new_block_size) == 0) {
		/* block & unblock */
		a = new_deblock_media();
		if (a != 0) {
		    a->need_filtering = 1;
		    a->next_block_size = block_size;
		    a->buffer = malloc(block_size);
		}
	    } else {
		/* too hard to bother with */
	    }
	}
	if (a != 0) {
	    a->m.kind = deblock_info.kind;
	    a->m.grain = new_block_size;
	    a->m.size_in_bytes = media_total_size(m);
	    a->m.do_read = read_deblock_media;
	    a->m.do_write = write_deblock_media;
	    a->m.do_close = close_deblock_media;
	    a->m.do_os_reload = os_reload_deblock_media;
	    a->next_media = m;
	}
    }
    return (MEDIA) a;
}


long
read_deblock_media(MEDIA m, long long offset, unsigned long count, void *address)
{
    DEBLOCK_MEDIA a;
    long rtn_value;
    unsigned long next_size;
    unsigned long partial_offset;
    unsigned long partial_count;
    long long cur_offset;
    unsigned long remainder;
    unsigned char *addr;

    a = (DEBLOCK_MEDIA) m;
    rtn_value = 0;
    if (a == 0) {
	/* no media */
    } else if (a->m.kind != deblock_info.kind) {
	/* wrong kind - XXX need to error here - this is an internal problem */
    } else if (count <= 0 || count % a->m.grain != 0) {
	/* can't handle size */
    } else if (offset < 0 || offset % a->m.grain != 0) {
	/* can't handle offset */
    } else if (a->need_filtering == 0) {
	rtn_value = read_media(a->next_media, offset, count, address);
    } else {
	next_size = a->next_block_size;
	addr = address;
	cur_offset = offset;
	remainder = count;
	rtn_value = 1;

	/* read partial */
	partial_offset = cur_offset % next_size;
	if (partial_offset != 0) {
	    partial_count = next_size - partial_offset;
	    if (partial_count > remainder) {
		partial_count = remainder;
	    }
	    rtn_value = read_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer);
	    if (rtn_value != 0) {
		memcpy (addr, a->buffer + partial_offset, partial_count);
		addr += partial_count;
		cur_offset += partial_count;
		remainder -= partial_count;
	    }
	}
	/* read fulls as long as needed */
	if (rtn_value != 0 && remainder > next_size) {
	    partial_count = remainder - (remainder % next_size);
	    rtn_value = read_media(a->next_media, cur_offset, partial_count, addr);
	    addr += partial_count;
	    cur_offset += partial_count;
	    remainder -= partial_count;
	}
	/* read partial */
	if (rtn_value != 0 && remainder > 0) {
	    partial_count = remainder;
	    rtn_value = read_media(a->next_media, cur_offset, next_size, a->buffer);
	    if (rtn_value != 0) {
		memcpy (addr, a->buffer, partial_count);
	    }
	}
    }
    return rtn_value;
}


long
write_deblock_media(MEDIA m, long long offset, unsigned long count, void *address)
{
    DEBLOCK_MEDIA a;
    long rtn_value;
    unsigned long next_size;
    unsigned long partial_offset;
    unsigned long partial_count;
    long long cur_offset;
    unsigned long remainder;
    unsigned char *addr;
    
    a = (DEBLOCK_MEDIA) m;
    rtn_value = 0;
    if (a == 0) {
	/* no media */
    } else if (a->m.kind != deblock_info.kind) {
	/* wrong kind - XXX need to error here - this is an internal problem */
    } else if (count <= 0 || count % a->m.grain != 0) {
	/* can't handle size */
    } else if (offset < 0 || offset % a->m.grain != 0) {
	/* can't handle offset */
    } else if (a->need_filtering == 0) {
	rtn_value = write_media(a->next_media, offset, count, address);
    } else {
	next_size = a->next_block_size;
	addr = address;
	cur_offset = offset;
	remainder = count;
	rtn_value = 1;

	/* write partial */
	partial_offset = cur_offset % next_size;
	if (partial_offset != 0) {
	    partial_count = next_size - partial_offset;
	    if (partial_count > remainder) {
		partial_count = remainder;
	    }
	    rtn_value = read_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer);
	    if (rtn_value != 0) {
		memcpy (a->buffer + partial_offset, addr, partial_count);
		rtn_value = write_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer);
		addr += partial_count;
		cur_offset += partial_count;
		remainder -= partial_count;
	    }
	}
	/* write fulls as long as needed */
	if (rtn_value != 0 && remainder > next_size) {
	    partial_count = remainder - (remainder % next_size);
	    rtn_value = write_media(a->next_media, cur_offset, partial_count, addr);
	    addr += partial_count;
	    cur_offset += partial_count;
	    remainder -= partial_count;
	}
	/* write partial */
	if (rtn_value != 0 && remainder > 0) {
	    partial_count = remainder;
	    rtn_value = read_media(a->next_media, cur_offset, next_size, a->buffer);
	    if (rtn_value != 0) {
		memcpy (a->buffer, addr, partial_count);
		rtn_value = write_media(a->next_media, cur_offset, next_size, a->buffer);
	    }
	}
    }
    /* recompute size to handle file media */
    a->m.size_in_bytes = media_total_size(a->next_media);
    return rtn_value;
}


long
close_deblock_media(MEDIA m)
{
    DEBLOCK_MEDIA a;
    
    a = (DEBLOCK_MEDIA) m;
    if (a == 0) {
	return 0;
    } else if (a->m.kind != deblock_info.kind) {
	/* XXX need to error here - this is an internal problem */
	return 0;
    }
    
    close_media(a->next_media);
    free(a->buffer);
    return 1;
}


long
os_reload_deblock_media(MEDIA m)
{
    DEBLOCK_MEDIA a;
    
    a = (DEBLOCK_MEDIA) m;
    if (a == 0) {
	return 0;
    } else if (a->m.kind != deblock_info.kind) {
	/* XXX need to error here - this is an internal problem */
	return 0;
    }
    
    os_reload_media(a->next_media);
    return 1;
}