aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_tree.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
commit502af2167f7c218366666ca4944bd7cc54b5b19a (patch)
treea91fec5cc9769d260640bd91c6633cb9cf395524 /src/fs/fs_tree.c
parent03af5a603b7cc53432249d5854cd412aa90dde0d (diff)
downloadgnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.tar.gz
gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.zip
indentation
Diffstat (limited to 'src/fs/fs_tree.c')
-rw-r--r--src/fs/fs_tree.c247
1 files changed, 110 insertions, 137 deletions
diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c
index e22ce8221..5584ad868 100644
--- a/src/fs/fs_tree.c
+++ b/src/fs/fs_tree.c
@@ -40,7 +40,7 @@ struct GNUNET_FS_TreeEncoder
40 * Global FS context. 40 * Global FS context.
41 */ 41 */
42 struct GNUNET_FS_Handle *h; 42 struct GNUNET_FS_Handle *h;
43 43
44 /** 44 /**
45 * Closure for all callbacks. 45 * Closure for all callbacks.
46 */ 46 */
@@ -65,7 +65,7 @@ struct GNUNET_FS_TreeEncoder
65 * Function to call once we're done with processing. 65 * Function to call once we're done with processing.
66 */ 66 */
67 GNUNET_SCHEDULER_Task cont; 67 GNUNET_SCHEDULER_Task cont;
68 68
69 /** 69 /**
70 * Set to an error message (if we had an error). 70 * Set to an error message (if we had an error).
71 */ 71 */
@@ -132,15 +132,15 @@ GNUNET_FS_compute_depth (uint64_t flen)
132 treeDepth = 1; 132 treeDepth = 1;
133 fl = DBLOCK_SIZE; 133 fl = DBLOCK_SIZE;
134 while (fl < flen) 134 while (fl < flen)
135 {
136 treeDepth++;
137 if (fl * CHK_PER_INODE < fl)
135 { 138 {
136 treeDepth++; 139 /* integer overflow, this is a HUGE file... */
137 if (fl * CHK_PER_INODE < fl) 140 return treeDepth;
138 {
139 /* integer overflow, this is a HUGE file... */
140 return treeDepth;
141 }
142 fl = fl * CHK_PER_INODE;
143 } 141 }
142 fl = fl * CHK_PER_INODE;
143 }
144 return treeDepth; 144 return treeDepth;
145} 145}
146 146
@@ -161,7 +161,7 @@ GNUNET_FS_tree_compute_tree_size (unsigned int depth)
161 unsigned int i; 161 unsigned int i;
162 162
163 rsize = DBLOCK_SIZE; 163 rsize = DBLOCK_SIZE;
164 for (i = 0; i<depth; i++) 164 for (i = 0; i < depth; i++)
165 rsize *= CHK_PER_INODE; 165 rsize *= CHK_PER_INODE;
166 return rsize; 166 return rsize;
167} 167}
@@ -181,9 +181,8 @@ GNUNET_FS_tree_compute_tree_size (unsigned int depth)
181 * end of a block). 181 * end of a block).
182 * @return size of the corresponding IBlock 182 * @return size of the corresponding IBlock
183 */ 183 */
184static uint16_t 184static uint16_t
185GNUNET_FS_tree_compute_iblock_size (unsigned int depth, 185GNUNET_FS_tree_compute_iblock_size (unsigned int depth, uint64_t end_offset)
186 uint64_t end_offset)
187{ 186{
188 unsigned int ret; 187 unsigned int ret;
189 uint64_t mod; 188 uint64_t mod;
@@ -194,19 +193,19 @@ GNUNET_FS_tree_compute_iblock_size (unsigned int depth,
194 bds = GNUNET_FS_tree_compute_tree_size (depth); 193 bds = GNUNET_FS_tree_compute_tree_size (depth);
195 mod = end_offset % bds; 194 mod = end_offset % bds;
196 if (0 == mod) 195 if (0 == mod)
197 { 196 {
198 /* we were triggered at the end of a full block */ 197 /* we were triggered at the end of a full block */
199 ret = CHK_PER_INODE; 198 ret = CHK_PER_INODE;
200 } 199 }
201 else 200 else
202 { 201 {
203 /* we were triggered at the end of the file */ 202 /* we were triggered at the end of the file */
204 bds /= CHK_PER_INODE; 203 bds /= CHK_PER_INODE;
205 ret = mod / bds; 204 ret = mod / bds;
206 if (0 != mod % bds) 205 if (0 != mod % bds)
207 ret++; 206 ret++;
208 } 207 }
209 return (uint16_t) (ret * sizeof(struct ContentHashKey)); 208 return (uint16_t) (ret * sizeof (struct ContentHashKey));
210} 209}
211 210
212 211
@@ -223,8 +222,7 @@ GNUNET_FS_tree_compute_iblock_size (unsigned int depth,
223 */ 222 */
224size_t 223size_t
225GNUNET_FS_tree_calculate_block_size (uint64_t fsize, 224GNUNET_FS_tree_calculate_block_size (uint64_t fsize,
226 uint64_t offset, 225 uint64_t offset, unsigned int depth)
227 unsigned int depth)
228{ 226{
229 size_t ret; 227 size_t ret;
230 uint64_t rsize; 228 uint64_t rsize;
@@ -234,18 +232,16 @@ GNUNET_FS_tree_calculate_block_size (uint64_t fsize,
234 GNUNET_assert (fsize > 0); 232 GNUNET_assert (fsize > 0);
235 GNUNET_assert (offset <= fsize); 233 GNUNET_assert (offset <= fsize);
236 if (depth == 0) 234 if (depth == 0)
237 { 235 {
238 ret = DBLOCK_SIZE; 236 ret = DBLOCK_SIZE;
239 if ( (offset + ret > fsize) || 237 if ((offset + ret > fsize) || (offset + ret < offset))
240 (offset + ret < offset) ) 238 ret = (size_t) (fsize - offset);
241 ret = (size_t) (fsize - offset); 239 return ret;
242 return ret; 240 }
243 }
244 241
245 rsize = GNUNET_FS_tree_compute_tree_size (depth - 1); 242 rsize = GNUNET_FS_tree_compute_tree_size (depth - 1);
246 epos = offset + rsize * CHK_PER_INODE; 243 epos = offset + rsize * CHK_PER_INODE;
247 if ( (epos < offset) || 244 if ((epos < offset) || (epos > fsize))
248 (epos > fsize) )
249 epos = fsize; 245 epos = fsize;
250 /* round up when computing #CHKs in our IBlock */ 246 /* round up when computing #CHKs in our IBlock */
251 chks = (epos - offset + rsize - 1) / rsize; 247 chks = (epos - offset + rsize - 1) / rsize;
@@ -273,16 +269,16 @@ GNUNET_FS_tree_calculate_block_size (uint64_t fsize,
273 */ 269 */
274struct GNUNET_FS_TreeEncoder * 270struct GNUNET_FS_TreeEncoder *
275GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, 271GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h,
276 uint64_t size, 272 uint64_t size,
277 void *cls, 273 void *cls,
278 GNUNET_FS_DataReader reader, 274 GNUNET_FS_DataReader reader,
279 GNUNET_FS_TreeBlockProcessor proc, 275 GNUNET_FS_TreeBlockProcessor proc,
280 GNUNET_FS_TreeProgressCallback progress, 276 GNUNET_FS_TreeProgressCallback progress,
281 GNUNET_SCHEDULER_Task cont) 277 GNUNET_SCHEDULER_Task cont)
282{ 278{
283 struct GNUNET_FS_TreeEncoder *te; 279 struct GNUNET_FS_TreeEncoder *te;
284 280
285 te = GNUNET_malloc (sizeof (struct GNUNET_FS_TreeEncoder)); 281 te = GNUNET_malloc (sizeof (struct GNUNET_FS_TreeEncoder));
286 te->h = h; 282 te->h = h;
287 te->size = size; 283 te->size = size;
288 te->cls = cls; 284 te->cls = cls;
@@ -292,8 +288,7 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h,
292 te->cont = cont; 288 te->cont = cont;
293 te->chk_tree_depth = GNUNET_FS_compute_depth (size); 289 te->chk_tree_depth = GNUNET_FS_compute_depth (size);
294 te->chk_tree = GNUNET_malloc (te->chk_tree_depth * 290 te->chk_tree = GNUNET_malloc (te->chk_tree_depth *
295 CHK_PER_INODE * 291 CHK_PER_INODE * sizeof (struct ContentHashKey));
296 sizeof (struct ContentHashKey));
297 return te; 292 return te;
298} 293}
299 294
@@ -310,17 +305,16 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h,
310 * @return (array of CHKs') offset in the above IBlock 305 * @return (array of CHKs') offset in the above IBlock
311 */ 306 */
312static unsigned int 307static unsigned int
313compute_chk_offset (unsigned int depth, 308compute_chk_offset (unsigned int depth, uint64_t end_offset)
314 uint64_t end_offset)
315{ 309{
316 uint64_t bds; 310 uint64_t bds;
317 unsigned int ret; 311 unsigned int ret;
318 312
319 bds = GNUNET_FS_tree_compute_tree_size (depth); 313 bds = GNUNET_FS_tree_compute_tree_size (depth);
320 if (depth > 0) 314 if (depth > 0)
321 end_offset--; /* round down since for depth > 0 offset is at the END of the block */ 315 end_offset--; /* round down since for depth > 0 offset is at the END of the block */
322 ret = end_offset / bds; 316 ret = end_offset / bds;
323 return ret % CHK_PER_INODE; 317 return ret % CHK_PER_INODE;
324} 318}
325 319
326 320
@@ -331,8 +325,8 @@ compute_chk_offset (unsigned int depth,
331 * 325 *
332 * @param te tree encoder to use 326 * @param te tree encoder to use
333 */ 327 */
334void 328void
335GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder * te) 329GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te)
336{ 330{
337 struct ContentHashKey *mychk; 331 struct ContentHashKey *mychk;
338 const void *pt_block; 332 const void *pt_block;
@@ -346,105 +340,85 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder * te)
346 GNUNET_assert (GNUNET_NO == te->in_next); 340 GNUNET_assert (GNUNET_NO == te->in_next);
347 te->in_next = GNUNET_YES; 341 te->in_next = GNUNET_YES;
348 if (te->chk_tree_depth == te->current_depth) 342 if (te->chk_tree_depth == te->current_depth)
349 { 343 {
350 off = CHK_PER_INODE * (te->chk_tree_depth - 1); 344 off = CHK_PER_INODE * (te->chk_tree_depth - 1);
351#if DEBUG_TREE 345#if DEBUG_TREE
352 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
353 "TE done, reading CHK `%s' from %u\n", 347 "TE done, reading CHK `%s' from %u\n",
354 GNUNET_h2s (&te->chk_tree[off].query), 348 GNUNET_h2s (&te->chk_tree[off].query), off);
355 off);
356#endif 349#endif
357 te->uri = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri)); 350 te->uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
358 te->uri->type = chk; 351 te->uri->type = chk;
359 te->uri->data.chk.chk = te->chk_tree[off]; 352 te->uri->data.chk.chk = te->chk_tree[off];
360 te->uri->data.chk.file_length = GNUNET_htonll (te->size); 353 te->uri->data.chk.file_length = GNUNET_htonll (te->size);
361 te->in_next = GNUNET_NO; 354 te->in_next = GNUNET_NO;
362 te->cont (te->cls, NULL); 355 te->cont (te->cls, NULL);
363 return; 356 return;
364 } 357 }
365 if (0 == te->current_depth) 358 if (0 == te->current_depth)
359 {
360 /* read DBLOCK */
361 pt_size = GNUNET_MIN (DBLOCK_SIZE, te->size - te->publish_offset);
362 if (pt_size !=
363 te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg))
366 { 364 {
367 /* read DBLOCK */ 365 GNUNET_SCHEDULER_add_continuation (te->cont,
368 pt_size = GNUNET_MIN(DBLOCK_SIZE, 366 te->cls,
369 te->size - te->publish_offset); 367 GNUNET_SCHEDULER_REASON_TIMEOUT);
370 if (pt_size != 368 te->in_next = GNUNET_NO;
371 te->reader (te->cls, 369 return;
372 te->publish_offset,
373 pt_size,
374 iob,
375 &te->emsg))
376 {
377 GNUNET_SCHEDULER_add_continuation (te->cont,
378 te->cls,
379 GNUNET_SCHEDULER_REASON_TIMEOUT);
380 te->in_next = GNUNET_NO;
381 return;
382 }
383 pt_block = iob;
384 } 370 }
371 pt_block = iob;
372 }
385 else 373 else
386 { 374 {
387 pt_size = GNUNET_FS_tree_compute_iblock_size (te->current_depth, 375 pt_size = GNUNET_FS_tree_compute_iblock_size (te->current_depth,
388 te->publish_offset); 376 te->publish_offset);
389 pt_block = &te->chk_tree[(te->current_depth - 1) * 377 pt_block = &te->chk_tree[(te->current_depth - 1) * CHK_PER_INODE];
390 CHK_PER_INODE]; 378 }
391 } 379 off = compute_chk_offset (te->current_depth, te->publish_offset);
392 off = compute_chk_offset (te->current_depth,
393 te->publish_offset);
394#if DEBUG_TREE 380#if DEBUG_TREE
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
396 "TE is at offset %llu and depth %u with block size %u and target-CHK-offset %u\n", 382 "TE is at offset %llu and depth %u with block size %u and target-CHK-offset %u\n",
397 (unsigned long long) te->publish_offset, 383 (unsigned long long) te->publish_offset,
398 te->current_depth, 384 te->current_depth, (unsigned int) pt_size, (unsigned int) off);
399 (unsigned int) pt_size,
400 (unsigned int) off);
401#endif 385#endif
402 mychk = &te->chk_tree[te->current_depth*CHK_PER_INODE+off]; 386 mychk = &te->chk_tree[te->current_depth * CHK_PER_INODE + off];
403 GNUNET_CRYPTO_hash (pt_block, pt_size, &mychk->key); 387 GNUNET_CRYPTO_hash (pt_block, pt_size, &mychk->key);
404 GNUNET_CRYPTO_hash_to_aes_key (&mychk->key, &sk, &iv); 388 GNUNET_CRYPTO_hash_to_aes_key (&mychk->key, &sk, &iv);
405 GNUNET_CRYPTO_aes_encrypt (pt_block, 389 GNUNET_CRYPTO_aes_encrypt (pt_block, pt_size, &sk, &iv, enc);
406 pt_size,
407 &sk,
408 &iv,
409 enc);
410 GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query); 390 GNUNET_CRYPTO_hash (enc, pt_size, &mychk->query);
411#if DEBUG_TREE 391#if DEBUG_TREE
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "TE calculates query to be `%s', stored at %u\n", 393 "TE calculates query to be `%s', stored at %u\n",
414 GNUNET_h2s (&mychk->query), 394 GNUNET_h2s (&mychk->query),
415 te->current_depth * CHK_PER_INODE + off); 395 te->current_depth * CHK_PER_INODE + off);
416#endif 396#endif
417 if (NULL != te->proc) 397 if (NULL != te->proc)
418 te->proc (te->cls, 398 te->proc (te->cls,
419 mychk, 399 mychk,
420 te->publish_offset, 400 te->publish_offset,
421 te->current_depth, 401 te->current_depth,
422 (0 == te->current_depth) 402 (0 == te->current_depth)
423 ? GNUNET_BLOCK_TYPE_FS_DBLOCK 403 ? GNUNET_BLOCK_TYPE_FS_DBLOCK
424 : GNUNET_BLOCK_TYPE_FS_IBLOCK, 404 : GNUNET_BLOCK_TYPE_FS_IBLOCK, enc, pt_size);
425 enc,
426 pt_size);
427 if (NULL != te->progress) 405 if (NULL != te->progress)
428 te->progress (te->cls, 406 te->progress (te->cls,
429 te->publish_offset, 407 te->publish_offset, pt_block, pt_size, te->current_depth);
430 pt_block, 408 if (0 == te->current_depth)
431 pt_size, 409 {
432 te->current_depth); 410 te->publish_offset += pt_size;
433 if (0 == te->current_depth) 411 if ((te->publish_offset == te->size) ||
434 { 412 (0 == te->publish_offset % (CHK_PER_INODE * DBLOCK_SIZE)))
435 te->publish_offset += pt_size; 413 te->current_depth++;
436 if ( (te->publish_offset == te->size) || 414 }
437 (0 == te->publish_offset % (CHK_PER_INODE * DBLOCK_SIZE) ) )
438 te->current_depth++;
439 }
440 else 415 else
441 { 416 {
442 if ( (off == CHK_PER_INODE) || 417 if ((off == CHK_PER_INODE) || (te->publish_offset == te->size))
443 (te->publish_offset == te->size) ) 418 te->current_depth++;
444 te->current_depth++; 419 else
445 else 420 te->current_depth = 0;
446 te->current_depth = 0; 421 }
447 }
448 te->in_next = GNUNET_NO; 422 te->in_next = GNUNET_NO;
449} 423}
450 424
@@ -460,16 +434,15 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder * te)
460 * prior to completion and prior to an internal error, 434 * prior to completion and prior to an internal error,
461 * both "*uri" and "*emsg" will be set to NULL). 435 * both "*uri" and "*emsg" will be set to NULL).
462 */ 436 */
463void GNUNET_FS_tree_encoder_finish (struct GNUNET_FS_TreeEncoder *te, 437void
464 struct GNUNET_FS_Uri **uri, 438GNUNET_FS_tree_encoder_finish (struct GNUNET_FS_TreeEncoder *te,
465 char **emsg) 439 struct GNUNET_FS_Uri **uri, char **emsg)
466{ 440{
467 GNUNET_assert (GNUNET_NO == te->in_next); 441 GNUNET_assert (GNUNET_NO == te->in_next);
468 if (uri != NULL) 442 if (uri != NULL)
469 *uri = te->uri; 443 *uri = te->uri;
470 else 444 else if (NULL != te->uri)
471 if (NULL != te->uri) 445 GNUNET_FS_uri_destroy (te->uri);
472 GNUNET_FS_uri_destroy (te->uri);
473 if (emsg != NULL) 446 if (emsg != NULL)
474 *emsg = te->emsg; 447 *emsg = te->emsg;
475 else 448 else