#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <libburn/libburn.h>
#include <libisofs/libisofs.h>
#include "isoburn.h"

Go to the source code of this file.
Data Structures | |
| struct | isoburn_cache_tile |
| struct | isoburn_cached_drive |
Defines | |
| #define | Libisoburn_tile_blockS 32 |
| #define | Libisoburn_cache_tileS 32 |
| #define | Libisoburn_max_agE 2000000000 |
Functions | |
| static int | ds_inc_age (struct isoburn_cached_drive *icd, int idx, int flag) |
| int | ds_read_block (IsoDataSource *src, uint32_t lba, uint8_t *buffer) |
| static int | ds_open (IsoDataSource *src) |
| static int | ds_close (IsoDataSource *src) |
| static void | ds_free_data (IsoDataSource *src) |
| int | isoburn_data_source_shutdown (IsoDataSource *src, int flag) |
| Disable read capabilities of a data source which was originally created by isoburn_data_source_new(). | |
| IsoDataSource * | isoburn_data_source_new (struct burn_drive *d) |
| Get a data source suitable for read from a drive using burn_read_data() function. | |
| #define Libisoburn_cache_tileS 32 |
Definition at line 41 of file data_source.c.
Referenced by ds_inc_age(), ds_read_block(), and isoburn_data_source_new().
| #define Libisoburn_max_agE 2000000000 |
| #define Libisoburn_tile_blockS 32 |
| static int ds_close | ( | IsoDataSource * | src | ) | [static] |
| static void ds_free_data | ( | IsoDataSource * | src | ) | [static] |
Definition at line 197 of file data_source.c.
Referenced by isoburn_data_source_new().
00198 { 00199 /* nothing to do */; 00200 if(src->data != NULL) 00201 free(src->data); 00202 src->data= NULL; 00203 }
| static int ds_inc_age | ( | struct isoburn_cached_drive * | icd, | |
| int | idx, | |||
| int | flag | |||
| ) | [static] |
Definition at line 249 of file data_source.c.
References isoburn_cached_drive::current_age, Libisoburn_cache_tileS, Libisoburn_max_agE, and isoburn_cached_drive::tiles.
Referenced by ds_read_block().
00250 { 00251 int i; 00252 00253 (icd->current_age)++; 00254 if(icd->current_age>=Libisoburn_max_agE) { /* reset all ages (allow waste) */ 00255 for(i= 0; i<Libisoburn_cache_tileS; i++) 00256 (icd->tiles)[i].age= 0; 00257 icd->current_age= 1; 00258 } 00259 (icd->tiles)[idx].age= icd->current_age; 00260 return(1); 00261 }
| static int ds_open | ( | IsoDataSource * | src | ) | [static] |
| int ds_read_block | ( | IsoDataSource * | src, | |
| uint32_t | lba, | |||
| uint8_t * | buffer | |||
| ) |
Definition at line 69 of file data_source.c.
References isoburn_cache_tile::age, isoburn_cache_tile::cache_data, isoburn_cache_tile::cache_hits, isoburn_cache_tile::cache_lba, isoburn_cached_drive::drive, ds_inc_age(), isoburn_msgs_submit(), isoburn_cache_tile::last_aligned_error_lba, isoburn_cache_tile::last_error_lba, Libisoburn_cache_tileS, Libisoburn_max_agE, Libisoburn_tile_blockS, and isoburn_cached_drive::tiles.
Referenced by isoburn_data_source_new().
00070 { 00071 int ret, i, oldest, oldest_age; 00072 struct burn_drive *d; 00073 off_t count; 00074 uint32_t aligned_lba; 00075 char msg[80]; 00076 struct isoburn_cache_tile *tiles; 00077 struct isoburn_cached_drive *icd; 00078 00079 if(src == NULL || buffer == NULL) 00080 /* It is not required by the specs of libisofs but implicitely assumed 00081 by its current implementation that a data source read result <0 is 00082 a valid libisofs error code. 00083 */ 00084 return ISO_NULL_POINTER; 00085 00086 icd = (struct isoburn_cached_drive *) src->data; 00087 d = (struct burn_drive*) icd->drive; 00088 00089 if(d == NULL) { 00090 /* This would happen if libisoburn saw output data in the fifo and 00091 performed early drive release and afterwards libisofs still tries 00092 to read data. 00093 That would constitute a bad conceptual problem in libisoburn. 00094 */ 00095 isoburn_msgs_submit(NULL, 0x00060000, 00096 "Programming error: Drive released while libisofs still attempts to read", 00097 0, "FATAL", 0); 00098 return ISO_ASSERT_FAILURE; 00099 } 00100 00101 tiles = (struct isoburn_cache_tile *) icd->tiles; 00102 00103 aligned_lba= lba & ~(Libisoburn_tile_blockS - 1); 00104 00105 for(i=0; i<Libisoburn_cache_tileS; i++) { 00106 if(aligned_lba == tiles[i].cache_lba && tiles[i].cache_lba != 0xffffffff) { 00107 (tiles[i].cache_hits)++; 00108 memcpy(buffer, tiles[i].cache_data + (lba - aligned_lba) * 2048, 2048); 00109 count= 2048; 00110 ds_inc_age(icd, i, 0); 00111 return 1; 00112 } 00113 } 00114 00115 /* find oldest tile */ 00116 oldest_age= Libisoburn_max_agE; 00117 oldest= 0; 00118 for(i= 0; i<Libisoburn_cache_tileS; i++) { 00119 if(tiles[i].cache_lba == 0xffffffff) { 00120 oldest= i; 00121 break; 00122 } 00123 if(tiles[i].age<oldest_age) { 00124 oldest_age= tiles[i].age; 00125 oldest= i; 00126 } 00127 } 00128 00129 tiles[oldest].cache_lba= 0xffffffff; /* invalidate cache */ 00130 if(tiles[oldest].last_aligned_error_lba == aligned_lba) { 00131 ret = 0; 00132 } else { 00133 ret = burn_read_data(d, (off_t) aligned_lba * (off_t) 2048, 00134 (char *) tiles[oldest].cache_data, 00135 Libisoburn_tile_blockS * 2048, &count, 2); 00136 } 00137 if (ret <= 0 ) { 00138 tiles[oldest].last_aligned_error_lba = aligned_lba; 00139 00140 /* Read-ahead failure ? Try to read 2048 directly. */ 00141 if(tiles[oldest].last_error_lba == lba) 00142 ret = 0; 00143 else 00144 ret = burn_read_data(d, (off_t) lba * (off_t) 2048, (char *) buffer, 00145 2048, &count, 0); 00146 if (ret > 0) 00147 return 1; 00148 tiles[oldest].last_error_lba = lba; 00149 00150 /* It is not required by the specs of libisofs but implicitely assumed 00151 ... 00152 But it is not possible to ignore FAILURE. 00153 libisofs insists in original error codes, i.e. libisoburn cannot 00154 change severity FAILURE associated with ISO_FILE_READ_ERROR. 00155 So ISO_FILE_READ_ERROR is not an option and libisoburn has to 00156 misuse ISO_FILE_CANT_WRITE, which is actually for image generation 00157 and not for image reading. 00158 This is quite wrong, although the error message text is unclear 00159 enough to make it appear plausible. 00160 */ 00161 ret= ISO_FILE_CANT_WRITE; 00162 if(ret >= 0) 00163 ret = -1; 00164 sprintf(msg, "ds_read_block(%lu) returns %d", (unsigned long) lba, ret); 00165 isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "DEBUG", 0); 00166 return ret; 00167 } 00168 00169 #ifdef Libisoburn_read_cache_reporT 00170 fprintf(stderr, "Tile %2.2d : After %3d hits, new load from %8x , count= %d\n", 00171 oldest, tiles[oldest].cache_hits, aligned_lba, (int) count); 00172 #endif 00173 00174 tiles[oldest].cache_lba= aligned_lba; 00175 tiles[oldest].cache_hits= 1; 00176 ds_inc_age(icd, oldest, 0); 00177 00178 memcpy(buffer, tiles[oldest].cache_data + (lba - aligned_lba) * 2048, 2048); 00179 count= 2048; 00180 00181 return 1; 00182 }
| IsoDataSource* isoburn_data_source_new | ( | struct burn_drive * | d | ) |
Get a data source suitable for read from a drive using burn_read_data() function.
| d | drive to read from. Must be grabbed. |
Definition at line 218 of file data_source.c.
References isoburn_cache_tile::age, isoburn_cache_tile::cache_hits, isoburn_cache_tile::cache_lba, isoburn_cached_drive::current_age, isoburn_cached_drive::drive, ds_close(), ds_free_data(), ds_open(), ds_read_block(), isoburn_cache_tile::last_aligned_error_lba, isoburn_cache_tile::last_error_lba, Libisoburn_cache_tileS, and isoburn_cached_drive::tiles.
Referenced by isoburn_read_image().
00219 { 00220 IsoDataSource *ret; 00221 struct isoburn_cached_drive *icd= NULL; 00222 int i; 00223 00224 if (d==NULL) 00225 return NULL; 00226 ret = malloc(sizeof(IsoDataSource)); 00227 icd = calloc(1,sizeof(struct isoburn_cached_drive)); 00228 if (ret == NULL || icd == NULL) 00229 return NULL; 00230 ret->refcount = 1; 00231 ret->read_block = ds_read_block; 00232 ret->open = ds_open; 00233 ret->close = ds_close; 00234 ret->free_data = ds_free_data; 00235 ret->data = icd; 00236 icd->drive = d; 00237 icd->current_age= 0; 00238 for(i= 0; i<Libisoburn_cache_tileS; i++) { 00239 icd->tiles[i].cache_lba = 0xffffffff; 00240 icd->tiles[i].cache_hits = 0; 00241 icd->tiles[i].last_error_lba = 0xffffffff; 00242 icd->tiles[i].last_aligned_error_lba = 0xffffffff; 00243 icd->tiles[i].age= 0; 00244 } 00245 return ret; 00246 }
| int isoburn_data_source_shutdown | ( | IsoDataSource * | src, | |
| int | flag | |||
| ) |
Disable read capabilities of a data source which was originally created by isoburn_data_source_new().
After this any attempt to read will yield a FATAL programming error event. This is usually done to allow libburn to release the drive while libisofs still holds a reference to the data source object. libisofs is not supposed to use this object for reading any more, nevertheless. The disabled state of the data source is a safety fence around this daring situation.
| src | The data source to be disabled | |
| flag | unused yet |
Definition at line 206 of file data_source.c.
References isoburn_cached_drive::drive.
Referenced by isoburn_prepare_disc_aux().
00207 { 00208 struct isoburn_cached_drive *icd; 00209 00210 if(src==NULL) 00211 return(0); 00212 icd= (struct isoburn_cached_drive *) src->data; 00213 icd->drive= NULL; 00214 return(1); 00215 }
1.5.6