-
/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2001-2006 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
#include <stdlib.h>
#define my_malloc(a) malloc(a)
#define my_free(a) free(a)
-#else TEST_SHADOW
+#else /* !TEST_SHADOW */
#include <sys/malloc.h>
#define my_malloc(a) _MALLOC(a, M_TEMP, M_WAITOK)
#define my_free(a) FREE(a, M_TEMP)
-#endif TEST_SHADOW
+#include <libkern/libkern.h>
+#endif /* TEST_SHADOW */
#include "shadow.h"
-#define ULONG_ALL_ONES ((u_long)(-1))
+#define UINT32_ALL_ONES ((uint32_t)(-1))
#define USHORT_ALL_ONES ((u_short)(-1))
#define UCHAR_ALL_ONES ((u_char)(-1))
#define BAND_MAX ((band_number_t)65535)
struct shadow_map {
- u_long blocks_per_band;/* size in blocks */
- u_long block_size;
+ uint32_t blocks_per_band;/* size in blocks */
+ uint32_t block_size;
u_char * block_bitmap; /* 1 bit per block; 1=written */
band_number_t * bands; /* band map array */
- u_long file_size_blocks; /* size of file in bands */
- u_long shadow_size_bands; /* size of shadow in bands */
- u_long next_band; /* next free band */
- u_long zeroth_band; /* special-case 0th band */
+ uint32_t file_size_blocks; /* size of file in bands */
+ uint32_t shadow_size_bands; /* size of shadow in bands */
+ uint32_t next_band; /* next free band */
+ uint32_t zeroth_band; /* special-case 0th band */
};
typedef struct {
- u_long byte;
- u_long bit;
+ uint32_t byte;
+ uint32_t bit;
} bitmap_offset_t;
static __inline__ u_char
* units, using longs, then a short, then a byte, then bits.
*/
static void
-bitmap_set(u_char * map, u_long start_bit, u_long bit_count)
+bitmap_set(u_char * map, uint32_t start_bit, uint32_t bit_count)
{
bitmap_offset_t start;
bitmap_offset_t end;
start = bitmap_offset(start_bit);
end = bitmap_offset(start_bit + bit_count);
if (start.byte < end.byte) {
- u_long n_bytes;
+ uint32_t n_bytes;
if (start.bit) {
map[start.byte] |= byte_set_bits(start.bit, NBBY - 1);
n_bytes = end.byte - start.byte;
- while (n_bytes >= (sizeof(u_long))) {
- *((u_long *)(map + start.byte)) = ULONG_ALL_ONES;
- start.byte += sizeof(u_long);
- n_bytes -= sizeof(u_long);
+ while (n_bytes >= (sizeof(uint32_t))) {
+ *((uint32_t *)(map + start.byte)) = UINT32_ALL_ONES;
+ start.byte += sizeof(uint32_t);
+ n_bytes -= sizeof(uint32_t);
}
if (n_bytes >= sizeof(u_short)) {
*((u_short *)(map + start.byte)) = USHORT_ALL_ONES;
* a byte, then any remaining bits to find the bit that is different.
*/
-static u_long
-bitmap_get(u_char * map, u_long start_bit, u_long bit_count,
+static uint32_t
+bitmap_get(u_char * map, uint32_t start_bit, uint32_t bit_count,
boolean_t * ret_is_set)
{
- u_long count;
+ uint32_t count;
int i;
boolean_t is_set;
bitmap_offset_t start;
count = 0;
if (start.byte < end.byte) {
- u_long n_bytes;
+ uint32_t n_bytes;
if (start.bit) { /* try to align to a byte */
for (i = start.bit; i < NBBY; i++) {
n_bytes = end.byte - start.byte;
/* check for 4 bytes of the same bits */
- while (n_bytes >= sizeof(u_long)) {
- u_long * valPtr = (u_long *)(map + start.byte);
- if ((is_set && *valPtr == ULONG_ALL_ONES)
+ while (n_bytes >= sizeof(uint32_t)) {
+ uint32_t * valPtr = (uint32_t *)(map + start.byte);
+ if ((is_set && *valPtr == UINT32_ALL_ONES)
|| (!is_set && *valPtr == 0)) {
count += sizeof(*valPtr) * NBBY;
start.byte += sizeof(*valPtr);
}
end:
- for (i = start.bit; i < end.bit; i++) {
+ for (i = start.bit; i < (int)end.bit; i++) {
boolean_t this_is_set = (map[start.byte] & bit(i)) ? TRUE : FALSE;
if (this_is_set != is_set) {
}
static __inline__ band_number_t
-shadow_map_block_to_band(shadow_map_t * map, unsigned long block)
+shadow_map_block_to_band(shadow_map_t * map, uint32_t block)
{
return (block / map->blocks_per_band);
}
*
* If called with is_write = TRUE, this function will map bands as it goes.
*/
-static u_long
-shadow_map_contiguous(shadow_map_t * map, u_long start_block,
- u_long num_blocks, boolean_t is_write)
+static uint32_t
+shadow_map_contiguous(shadow_map_t * map, uint32_t start_block,
+ uint32_t num_blocks, boolean_t is_write)
{
band_number_t band = shadow_map_block_to_band(map, start_block);
- u_long end_block = start_block + num_blocks;
+ uint32_t end_block = start_block + num_blocks;
boolean_t is_mapped;
band_number_t mapped_band;
- u_long ret_end_block = end_block;
- u_long p;
+ uint32_t ret_end_block = end_block;
+ uint32_t p;
is_mapped = shadow_map_mapped_band(map, band, is_write, &mapped_band);
if (is_write == FALSE && is_mapped == FALSE) {
* particularly since most of the bits will be zero.
* A sparse bitmap would really help in this case.
*/
-static __inline__ u_long
-block_bitmap_size(off_t file_size, u_long block_size)
+static __inline__ uint32_t
+block_bitmap_size(off_t file_size, uint32_t block_size)
{
off_t blocks = howmany(file_size, block_size);
return (howmany(blocks, NBBY));
* should be read.
*/
boolean_t
-shadow_map_read(shadow_map_t * map, u_long block_offset, u_long block_count,
- u_long * incr_block_offset, u_long * incr_block_count)
+shadow_map_read(shadow_map_t * map, uint32_t block_offset, uint32_t block_count,
+ uint32_t * incr_block_offset, uint32_t * incr_block_count)
{
boolean_t written = FALSE;
- u_long n_blocks;
+ uint32_t n_blocks;
if (block_offset >= map->file_size_blocks
|| (block_offset + block_count) > map->file_size_blocks) {
- printf("shadow_map_read: request (%ld, %ld) exceeds file size %ld\n",
+ printf("shadow_map_read: request (%d, %d) exceeds file size %d\n",
block_offset, block_count, map->file_size_blocks);
*incr_block_count = 0;
}
}
else { /* start has been written, and therefore mapped */
band_number_t mapped_band;
- u_long band_limit;
+ uint32_t band_limit;
mapped_band = map->bands[shadow_map_block_to_band(map, block_offset)];
*incr_block_offset = mapped_band * map->blocks_per_band
* TRUE if the shadow file was grown, FALSE otherwise.
*/
boolean_t
-shadow_map_write(shadow_map_t * map, u_long block_offset,
- u_long block_count, u_long * incr_block_offset,
- u_long * incr_block_count)
+shadow_map_write(shadow_map_t * map, uint32_t block_offset,
+ uint32_t block_count, uint32_t * incr_block_offset,
+ uint32_t * incr_block_count)
{
- u_long band_limit;
+ uint32_t band_limit;
band_number_t mapped_band;
boolean_t shadow_grew = FALSE;
if (block_offset >= map->file_size_blocks
|| (block_offset + block_count) > map->file_size_blocks) {
- printf("shadow_map_write: request (%ld, %ld) exceeds file size %ld\n",
+ printf("shadow_map_write: request (%d, %d) exceeds file size %d\n",
block_offset, block_count, map->file_size_blocks);
*incr_block_count = 0;
}
return (shadow_grew);
}
+boolean_t
+shadow_map_is_written(shadow_map_t * map, uint32_t block_offset)
+{
+ bitmap_offset_t b;
+
+ b = bitmap_offset(block_offset);
+ return ((map->block_bitmap[b.byte] & bit(b.bit)) ? TRUE : FALSE);
+}
+
/*
* Function: shadow_map_shadow_size
*
* Purpose:
* To return the size of the shadow file in blocks.
*/
-u_long
+uint32_t
shadow_map_shadow_size(shadow_map_t * map)
{
return (map->shadow_size_bands * map->blocks_per_band);
*/
shadow_map_t *
shadow_map_create(off_t file_size, off_t shadow_size,
- u_long band_size, u_long block_size)
+ uint32_t band_size, uint32_t block_size)
{
- void * block_bitmap = 0;
- u_long bitmap_size;
- band_number_t * bands = 0;
+ void * block_bitmap = NULL;
+ uint32_t bitmap_size;
+ band_number_t * bands = NULL;
shadow_map_t * map;
- u_long n_bands = 0;
+ uint32_t n_bands = 0;
if (band_size == 0) {
band_size = BAND_SIZE_DEFAULT;
n_bands = howmany(file_size, band_size);
if (n_bands > (BAND_MAX + 1)) {
- printf("file is too big: %ld > %d\n",
+ printf("file is too big: %d > %d\n",
n_bands, BAND_MAX);
goto failure;
}
my_free(map->block_bitmap);
if (map->bands)
my_free(map->bands);
- map->block_bitmap = 0;
- map->bands = 0;
+ map->block_bitmap = NULL;
+ map->bands = NULL;
my_free(map);
return;
}
typedef struct {
int type;
- u_long offset;
- u_long count;
+ uint32_t offset;
+ uint32_t count;
} block_request_t;
int
exit(1);
}
for (i = 0; TRUE; i++) {
- u_long offset;
- u_long resid;
+ uint32_t offset;
+ uint32_t resid;
boolean_t shadow_grew;
boolean_t read_shadow;
switch (requests[i].type) {
case WriteRequest:
while (resid > 0) {
- u_long this_offset;
- u_long this_count;
+ uint32_t this_offset;
+ uint32_t this_count;
shadow_grew = shadow_map_write(map, offset,
resid,
break;
case ReadRequest:
while (resid > 0) {
- u_long this_offset;
- u_long this_count;
+ uint32_t this_offset;
+ uint32_t this_count;
read_shadow = shadow_map_read(map, offset,
resid,