From d40b43e64967a1a36fdc3ac5f0b81fc15f4c7445 Mon Sep 17 00:00:00 2001 From: Judson Powers Date: Mon, 6 Aug 2012 15:55:02 -0400 Subject: [PATCH 1/5] Modified caching in image reading to ensure all reads go through cache and all reads are block-aligned. --- tsk3/img/img_io.c | 241 ++++++++++++++++++++++++--------------------- tsk3/img/raw.c | 6 ++ tsk3/img/tsk_img.h | 19 ++-- 3 files changed, 148 insertions(+), 118 deletions(-) diff --git a/tsk3/img/img_io.c b/tsk3/img/img_io.c index d90b42da6d..9b4322e1aa 100644 --- a/tsk3/img/img_io.c +++ b/tsk3/img/img_io.c @@ -12,6 +12,84 @@ #include "tsk_img_i.h" +/** + * \ingroup imglib + * XXX + * @param a_img_info Disk image to read from + * @param ent XXX + * @returns XXX + */ +static int +cache_promote(TSK_IMG_INFO * a_img_info, int ent) +{ + if (ent == 0) + return 0; + + struct TSK_IMG_INFO_CACHE_ENTRY temp; + memcpy(&temp, &(a_img_info->cache_info[ent]), sizeof(struct TSK_IMG_INFO_CACHE_ENTRY)); + memmove(&(a_img_info->cache_info[1]), &(a_img_info->cache_info[0]), sizeof(struct TSK_IMG_INFO_CACHE_ENTRY) * ent); + memcpy(&(a_img_info->cache_info[0]), &temp, sizeof(struct TSK_IMG_INFO_CACHE_ENTRY)); + + return 0; +} + +/** + * \ingroup imglib + * XXX + * @param a_img_info Disk image to read from + * @param a_off XXX + * @param a_entry XXX + * @returns 0 on error or 1 on success + */ +static int +get_cache_block(TSK_IMG_INFO * a_img_info, + TSK_OFF_T a_off, struct TSK_IMG_INFO_CACHE_ENTRY ** a_entry) +{ + // we require that we're called with a page-aligned offset + if ( ( a_off & (TSK_IMG_INFO_CACHE_LEN - 1) ) != 0 ) { + fprintf(stderr, "Internal error: request cache page %" PRIuOFF "\n", a_off); + exit(-1); + } + + int ent; + + // find existing cache page + for (ent = 0; ent < a_img_info->cache_used; ent++) { + if (a_img_info->cache_info[ent].offset == a_off) { + ent = cache_promote(a_img_info, ent); + *a_entry = &(a_img_info->cache_info[ent]); + return 1; + } + } + + // did not find existing cache page + + if (a_img_info->cache_used < TSK_IMG_INFO_CACHE_NUM) { + // if we have not yet filled the cache, add a new cache page + ent = (a_img_info->cache_used)++; + a_img_info->cache_info[ent].page = ent; + } + else { + // otherwise, use the last (lowest-priority) cache page + ent = a_img_info->cache_used - 1; + } + + a_img_info->cache_info[ent].offset = a_off; + a_img_info->cache_info[ent].length = a_img_info->read(a_img_info, a_off, + &(a_img_info->cache[a_img_info->cache_info[ent].page * TSK_IMG_INFO_CACHE_LEN]), + TSK_IMG_INFO_CACHE_LEN); + + if (a_img_info->cache_info[ent].length <= 0) { + a_img_info->cache_info[ent].length = 0; + *a_entry = &(a_img_info->cache_info[ent]); + return 0; + } + + ent = cache_promote(a_img_info, ent); + *a_entry = &(a_img_info->cache_info[ent]); + return 1; +} + /** * \ingroup imglib * Reads data from an open disk image @@ -25,11 +103,8 @@ ssize_t tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, char *a_buf, size_t a_len) { -#define CACHE_AGE 1000 - ssize_t retval = 0; - int i; - int cache_next = 0; // index to lowest age cache (to use next) - size_t len2; + + size_t len2; if (a_img_info == NULL) { tsk_error_reset(); @@ -44,13 +119,7 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, */ tsk_take_lock(&(a_img_info->cache_lock)); - // if they ask for more than the cache length, skip the cache - if (a_len > TSK_IMG_INFO_CACHE_LEN) { - ssize_t nbytes = a_img_info->read(a_img_info, a_off, a_buf, a_len); - tsk_release_lock(&(a_img_info->cache_lock)); - return nbytes; - } - + /* Error: read request starts after the end of the image file. */ if (a_off >= a_img_info->size) { tsk_release_lock(&(a_img_info->cache_lock)); tsk_error_reset(); @@ -58,108 +127,58 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, tsk_error_set_errstr("tsk_img_read - %" PRIuOFF, a_off); return -1; } - - /* See if the requested length is going to be too long. - * we'll use this length when checking the cache. */ + + /* See if the requested length is going to be too long. + * we'll use this length when checking the cache. + * In other words, truncate the read request so that it + * does not pass the end of the image file. */ len2 = a_len; if (a_off + len2 > a_img_info->size) len2 = (size_t) (a_img_info->size - a_off); - // check if it is in the cache - for (i = 0; i < TSK_IMG_INFO_CACHE_NUM; i++) { - - // Look into the in-use cache entries - if (a_img_info->cache_len[i] > 0) { - - // the retval check makes sure we don't go back in after data was read - if ((retval == 0) && (a_img_info->cache_off[i] <= a_off) && - (a_img_info->cache_off[i] + a_img_info->cache_len[i] >= - a_off + len2)) { - - /* - if (tsk_verbose) - fprintf(stderr, - "tsk_img_read: Read found in cache %d\n", i); - */ - - // We found it... - memcpy(a_buf, - &a_img_info->cache[i][a_off - - a_img_info->cache_off[i]], len2); - retval = (ssize_t) len2; - - // reset its "age" since it was useful - a_img_info->cache_age[i] = CACHE_AGE; - - // we don't break out of the loop so that we update all ages - } - else { - /* decrease its "age" since it was not useful. - * We don't let used ones go below 1 so that they are not - * confused with entries that have never been used. */ - a_img_info->cache_age[i]--; - - // see if this is the most eligible replacement - if ((a_img_info->cache_len[cache_next] > 0) - && (a_img_info->cache_age[i] < - a_img_info->cache_age[cache_next])) - cache_next = i; - } - } - else { - cache_next = i; - } - } - - // if we didn't find it, then load it into the cache_next entry - if (retval == 0) { - size_t rlen; - - // round the offset down to a sector boundary - a_img_info->cache_off[cache_next] = (a_off / 512) * 512; - - /* - if (tsk_verbose) - fprintf(stderr, - "tsk_img_read: Loading data into cache %d (%" PRIuOFF - ")\n", cache_next, a_img_info->cache_off[cache_next]); - */ - - // figure out the length to read into the cache - rlen = TSK_IMG_INFO_CACHE_LEN; - if (a_img_info->cache_off[cache_next] + rlen > a_img_info->size) { - rlen = - (size_t) (a_img_info->size - - a_img_info->cache_off[cache_next]); - } - - retval = - a_img_info->read(a_img_info, a_img_info->cache_off[cache_next], - a_img_info->cache[cache_next], rlen); - - // if no error, then set the variables and copy the data - if (retval != -1) { - a_img_info->cache_age[cache_next] = CACHE_AGE; - a_img_info->cache_len[cache_next] = retval; - - // update the length we can actually copy (in case we did not get to read all that we wanted) - if (a_off + len2 > a_img_info->cache_off[cache_next] + retval) - len2 = - (size_t) (a_img_info->cache_off[cache_next] + retval - - a_off); - - memcpy(a_buf, - &a_img_info->cache[cache_next][a_off - - a_img_info->cache_off[cache_next]], len2); - retval = (ssize_t) len2; - } - else { - a_img_info->cache_len[cache_next] = 0; - a_img_info->cache_age[cache_next] = 0; - a_img_info->cache_off[cache_next] = 0; - } - } + if (tsk_verbose > 2) + tsk_fprintf(stderr, "tsk_img_read: offset %" PRIuOFF ", length %lx\n", a_off, len2); + + TSK_OFF_T block_addr; // block to read + TSK_OFF_T block_offs; // offset within block + size_t rlen; // remaining bytes to read + size_t clen; // bytes to copy from the current cache block + + struct TSK_IMG_INFO_CACHE_ENTRY * cache_entry; + + rlen = len2; + block_offs = a_off & (TSK_IMG_INFO_CACHE_LEN - 1); + block_addr = a_off & ~(TSK_IMG_INFO_CACHE_LEN - 1); + + while (rlen > 0) { + // get the current block from cache (possibly reading from disk) + if (! get_cache_block(a_img_info, block_addr, & cache_entry)) { + tsk_release_lock(&(a_img_info->cache_lock)); + return len2 - rlen; + } + + // copy into the buffer the lesser of how much the block + // holds and how much data we still need + clen = MIN(MIN(TSK_IMG_INFO_CACHE_LEN, cache_entry->length) - block_offs, rlen); + + memcpy(a_buf, + &(a_img_info->cache[cache_entry->page * TSK_IMG_INFO_CACHE_LEN]) + block_offs, + clen); + a_buf += clen; + rlen -= clen; + + if ( (rlen > 0) && (cache_entry->length < TSK_IMG_INFO_CACHE_LEN) ) { + // cache had a short read, but we requested data beyond this + // return a short read + tsk_release_lock(&(a_img_info->cache_lock)); + return len2 - rlen; + } + + // advance to the next block + block_offs = 0; + block_addr += TSK_IMG_INFO_CACHE_LEN; + } tsk_release_lock(&(a_img_info->cache_lock)); - return retval; -} + return len2; +} diff --git a/tsk3/img/raw.c b/tsk3/img/raw.c index ac3c6b4309..5b769c81dd 100644 --- a/tsk3/img/raw.c +++ b/tsk3/img/raw.c @@ -721,6 +721,9 @@ tsk_img_malloc(size_t a_len) tsk_init_lock(&(imgInfo->cache_lock)); imgInfo->tag = TSK_IMG_INFO_TAG; + // alloc cache + imgInfo->cache = valloc(TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN); + return (void *) imgInfo; } @@ -736,6 +739,9 @@ tsk_img_free(void *a_ptr) //deinit lock tsk_deinit_lock(&(imgInfo->cache_lock)); imgInfo->tag = 0; + + // free cache + free(imgInfo->cache); free(imgInfo); } diff --git a/tsk3/img/tsk_img.h b/tsk3/img/tsk_img.h index bc7e36a8fb..75c24adf07 100644 --- a/tsk3/img/tsk_img.h +++ b/tsk3/img/tsk_img.h @@ -69,12 +69,18 @@ extern "C" { TSK_IMG_TYPE_UNSUPP = 0xffff, ///< Unsupported disk image type } TSK_IMG_TYPE_ENUM; -#define TSK_IMG_INFO_CACHE_NUM 4 -#define TSK_IMG_INFO_CACHE_LEN 65536 +#define TSK_IMG_INFO_CACHE_NUM 256 +#define TSK_IMG_INFO_CACHE_LEN 32768 typedef struct TSK_IMG_INFO TSK_IMG_INFO; #define TSK_IMG_INFO_TAG 0x39204231 + struct TSK_IMG_INFO_CACHE_ENTRY { + int page; ///< offset into cache is page * TSK_IMG_INFO_CACHE_LEN + TSK_OFF_T offset; ///< offset in image from which cached data was obtained + size_t length; ///< amount of data in cached page; required to be less than TSK_IMG_INFO_CACHE_LEN + }; + /** * Created when a disk image has been opened and stores general information and handles. */ @@ -85,12 +91,11 @@ extern "C" { unsigned int sector_size; ///< sector size of device in bytes (typically 512) tsk_lock_t cache_lock; ///< Lock for cache and associated values - char cache[TSK_IMG_INFO_CACHE_NUM][TSK_IMG_INFO_CACHE_LEN]; ///< read cache (r/w shared - lock) - TSK_OFF_T cache_off[TSK_IMG_INFO_CACHE_NUM]; ///< starting byte offset of corresponding cache entry (r/w shared - lock) - int cache_age[TSK_IMG_INFO_CACHE_NUM]; ///< "Age" of corresponding cache entry, higher means more recently used (r/w shared - lock) - size_t cache_len[TSK_IMG_INFO_CACHE_NUM]; ///< Length of cache entry used (0 if never used) (r/w shared - lock) + struct TSK_IMG_INFO_CACHE_ENTRY cache_info[TSK_IMG_INFO_CACHE_NUM]; ///< read cache (r/w shared - lock) + int cache_used; ///< number of entries used in the cache entry array (r/w shared - lock) + char * cache; - ssize_t(*read) (TSK_IMG_INFO * img, TSK_OFF_T off, char *buf, size_t len); ///< \internal External progs should call tsk_img_read() + ssize_t(*read) (TSK_IMG_INFO * img, TSK_OFF_T off, char *buf, size_t len); ///< \internal External progs should call tsk_img_read() void (*close) (TSK_IMG_INFO *); ///< \internal Progs should call tsk_img_close() void (*imgstat) (TSK_IMG_INFO *, FILE *); ///< Pointer to file type specific function }; From 13ab34e32105c1f593b2bf3087978526905eea72 Mon Sep 17 00:00:00 2001 From: Judson Powers Date: Tue, 7 Aug 2012 10:55:13 -0400 Subject: [PATCH 2/5] Improved comments and platform independence of image cache. --- configure.ac | 2 ++ tsk3/img/img_io.c | 18 +++++++++--------- tsk3/img/raw.c | 29 +++++++++++++++++++++++++++-- tsk3/img/tsk_img.h | 2 +- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 51dd1594ad..47112fb7c1 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,8 @@ AX_PTHREAD( [ CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC"],[]) +AC_CHECK_FUNCS(posix_memalign, [AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, [Define to 1 if you have the posix_memalign() function.])]) + # Not all compilers include /usr/local in the include and link path if test -d /usr/local/include; then CFLAGS="$CFLAGS -I/usr/local/include" diff --git a/tsk3/img/img_io.c b/tsk3/img/img_io.c index 9b4322e1aa..7e1cc46f54 100644 --- a/tsk3/img/img_io.c +++ b/tsk3/img/img_io.c @@ -13,14 +13,14 @@ #include "tsk_img_i.h" /** - * \ingroup imglib + * \internal * XXX * @param a_img_info Disk image to read from * @param ent XXX * @returns XXX */ -static int -cache_promote(TSK_IMG_INFO * a_img_info, int ent) +static inline int +tsk_cache_promote(TSK_IMG_INFO * a_img_info, int ent) { if (ent == 0) return 0; @@ -34,15 +34,15 @@ cache_promote(TSK_IMG_INFO * a_img_info, int ent) } /** - * \ingroup imglib + * \internal * XXX * @param a_img_info Disk image to read from * @param a_off XXX * @param a_entry XXX * @returns 0 on error or 1 on success */ -static int -get_cache_block(TSK_IMG_INFO * a_img_info, +static inline int +tsk_get_cache_block(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, struct TSK_IMG_INFO_CACHE_ENTRY ** a_entry) { // we require that we're called with a page-aligned offset @@ -56,7 +56,7 @@ get_cache_block(TSK_IMG_INFO * a_img_info, // find existing cache page for (ent = 0; ent < a_img_info->cache_used; ent++) { if (a_img_info->cache_info[ent].offset == a_off) { - ent = cache_promote(a_img_info, ent); + ent = tsk_cache_promote(a_img_info, ent); *a_entry = &(a_img_info->cache_info[ent]); return 1; } @@ -85,7 +85,7 @@ get_cache_block(TSK_IMG_INFO * a_img_info, return 0; } - ent = cache_promote(a_img_info, ent); + ent = tsk_cache_promote(a_img_info, ent); *a_entry = &(a_img_info->cache_info[ent]); return 1; } @@ -152,7 +152,7 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, while (rlen > 0) { // get the current block from cache (possibly reading from disk) - if (! get_cache_block(a_img_info, block_addr, & cache_entry)) { + if (! tsk_get_cache_block(a_img_info, block_addr, & cache_entry)) { tsk_release_lock(&(a_img_info->cache_lock)); return len2 - rlen; } diff --git a/tsk3/img/raw.c b/tsk3/img/raw.c index 5b769c81dd..720b1dde70 100644 --- a/tsk3/img/raw.c +++ b/tsk3/img/raw.c @@ -721,8 +721,33 @@ tsk_img_malloc(size_t a_len) tsk_init_lock(&(imgInfo->cache_lock)); imgInfo->tag = TSK_IMG_INFO_TAG; - // alloc cache - imgInfo->cache = valloc(TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN); + long cachesz = TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN; + +#ifdef TSK_WIN32 +#else + +// unistd.h + +#ifdef _SC_PAGESIZE + long pagesz = sysconf(_SC_PAGESIZE); +#else +#ifdef _SC_PAGE_SIZE + long pagesz = sysconf(_SC_PAGE_SIZE); +#else + long pagesz = TSK_IMG_INFO_CACHE_LEN; +#endif +#endif // PAGESIZE + +#ifdef HAVE_POSIX_MEMALIGN + int retval; + if ((retval = posix_memalign(&imgInfo->cache, pagesz, cachesz)) != 0) { + tsk_fprintf("tsk_img_malloc: unable to allocate cache (%d)\n", retval); + exit(-1); // XXX fix + } +#else // HAVE_POSIX_MEMALIGN + imgInfo->cache = malloc(TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN); +#endif // HAVE_POSIX_MEMALIGN +#endif return (void *) imgInfo; } diff --git a/tsk3/img/tsk_img.h b/tsk3/img/tsk_img.h index 75c24adf07..02326d8dcb 100644 --- a/tsk3/img/tsk_img.h +++ b/tsk3/img/tsk_img.h @@ -69,7 +69,7 @@ extern "C" { TSK_IMG_TYPE_UNSUPP = 0xffff, ///< Unsupported disk image type } TSK_IMG_TYPE_ENUM; -#define TSK_IMG_INFO_CACHE_NUM 256 +#define TSK_IMG_INFO_CACHE_NUM 32 #define TSK_IMG_INFO_CACHE_LEN 32768 typedef struct TSK_IMG_INFO TSK_IMG_INFO; From 00a9d8da335423518286f029085d58887c1a0dd6 Mon Sep 17 00:00:00 2001 From: Judson Powers Date: Tue, 7 Aug 2012 10:59:26 -0400 Subject: [PATCH 3/5] Further image cache commentary, etc. --- tsk3/img/img_io.c | 22 ++++++++++++++-------- tsk3/img/raw.c | 31 ++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/tsk3/img/img_io.c b/tsk3/img/img_io.c index 7e1cc46f54..38b31b813c 100644 --- a/tsk3/img/img_io.c +++ b/tsk3/img/img_io.c @@ -14,10 +14,11 @@ /** * \internal - * XXX - * @param a_img_info Disk image to read from - * @param ent XXX - * @returns XXX + * Promotes the selected cache entry, since it has been recently requested. + * This must be called while already under the cache lock. + * @param a_img_info Disk image containing cache + * @param ent Index of the cache entry to promote + * @returns New index of the cache entry (currently always zero) */ static inline int tsk_cache_promote(TSK_IMG_INFO * a_img_info, int ent) @@ -35,11 +36,16 @@ tsk_cache_promote(TSK_IMG_INFO * a_img_info, int ent) /** * \internal - * XXX + * Ensures that the disk block at the specified offset is in the cache, + * either by finding the already-cached block or by reading it from disk. + * This must be called while already under the cache lock. * @param a_img_info Disk image to read from - * @param a_off XXX - * @param a_entry XXX - * @returns 0 on error or 1 on success + * @param a_off Byte offset of the disk block; required to be a multiple of + * TSK_IMG_INFO_CACHE_LEN + * @param a_entry Output: address of a pointer to a cache info entry that will + * be set by this function. (Address should not be used if + * the function returns an error.) + * @returns 0 on error or 1 on success */ static inline int tsk_get_cache_block(TSK_IMG_INFO * a_img_info, diff --git a/tsk3/img/raw.c b/tsk3/img/raw.c index 720b1dde70..cd8d0c720c 100644 --- a/tsk3/img/raw.c +++ b/tsk3/img/raw.c @@ -722,11 +722,13 @@ tsk_img_malloc(size_t a_len) imgInfo->tag = TSK_IMG_INFO_TAG; long cachesz = TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN; - + #ifdef TSK_WIN32 -#else + imgInfo->cache = VirtualAlloc(NULL, cachesz, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#else // ! TSK_WIN32 -// unistd.h +#ifdef HAVE_POSIX_MEMALIGN #ifdef _SC_PAGESIZE long pagesz = sysconf(_SC_PAGESIZE); @@ -738,16 +740,21 @@ tsk_img_malloc(size_t a_len) #endif #endif // PAGESIZE -#ifdef HAVE_POSIX_MEMALIGN int retval; if ((retval = posix_memalign(&imgInfo->cache, pagesz, cachesz)) != 0) { - tsk_fprintf("tsk_img_malloc: unable to allocate cache (%d)\n", retval); + tsk_fprintf(stderr, "tsk_img_malloc: unable to allocate cache (%d)\n", retval); + exit(-1); // XXX fix + } + +#else // ! POSIX_MEMALIGN + imgInfo->cache = malloc(cachesz); +#endif // POSIX_MEMALIGN +#endif // TSK_WIN32 + + if (imgInfo->cache == NULL) { + tsk_fprintf(stderr, "tsk_img_malloc: unable to allocate cache\n"); exit(-1); // XXX fix } -#else // HAVE_POSIX_MEMALIGN - imgInfo->cache = malloc(TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN); -#endif // HAVE_POSIX_MEMALIGN -#endif return (void *) imgInfo; } @@ -766,7 +773,13 @@ tsk_img_free(void *a_ptr) imgInfo->tag = 0; // free cache +#ifdef TSK_WIN32 + VirtualFree(imgInfo->cache, + TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN, + MEM_DECOMMIT | MEM_RELEASE); +#else free(imgInfo->cache); +#endif free(imgInfo); } From 5de465b29bb7a3ba1d5e1473b2d14846f2fd4698 Mon Sep 17 00:00:00 2001 From: Judson Powers Date: Tue, 7 Aug 2012 15:35:21 -0400 Subject: [PATCH 4/5] Got rid of exit() in cache alloc. --- tsk3/img/raw.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tsk3/img/raw.c b/tsk3/img/raw.c index cd8d0c720c..c3f15687eb 100644 --- a/tsk3/img/raw.c +++ b/tsk3/img/raw.c @@ -717,8 +717,7 @@ tsk_img_malloc(size_t a_len) TSK_IMG_INFO *imgInfo; if ((imgInfo = (TSK_IMG_INFO *) tsk_malloc(a_len)) == NULL) return NULL; - //init lock - tsk_init_lock(&(imgInfo->cache_lock)); + imgInfo->tag = TSK_IMG_INFO_TAG; long cachesz = TSK_IMG_INFO_CACHE_NUM * TSK_IMG_INFO_CACHE_LEN; @@ -742,8 +741,7 @@ tsk_img_malloc(size_t a_len) int retval; if ((retval = posix_memalign(&imgInfo->cache, pagesz, cachesz)) != 0) { - tsk_fprintf(stderr, "tsk_img_malloc: unable to allocate cache (%d)\n", retval); - exit(-1); // XXX fix + imgInfo->cache = NULL; } #else // ! POSIX_MEMALIGN @@ -753,9 +751,12 @@ tsk_img_malloc(size_t a_len) if (imgInfo->cache == NULL) { tsk_fprintf(stderr, "tsk_img_malloc: unable to allocate cache\n"); - exit(-1); // XXX fix + return NULL; } + //init lock + tsk_init_lock(&(imgInfo->cache_lock)); + return (void *) imgInfo; } From a9c64432f33383daf801c15e60977b6330ed7cdc Mon Sep 17 00:00:00 2001 From: Judson Powers Date: Wed, 8 Aug 2012 14:49:58 -0400 Subject: [PATCH 5/5] Oops -- Windows needs MIN(x,y) defined. --- tsk3/img/img_io.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tsk3/img/img_io.c b/tsk3/img/img_io.c index 38b31b813c..72bcfb9f45 100644 --- a/tsk3/img/img_io.c +++ b/tsk3/img/img_io.c @@ -12,6 +12,8 @@ #include "tsk_img_i.h" +#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) + /** * \internal * Promotes the selected cache entry, since it has been recently requested. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy