aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-02-19 13:52:24 +0000
committerChristian Grothoff <christian@grothoff.org>2014-02-19 13:52:24 +0000
commit5bad33167fe0e7c696144ae7060eb89b0862f7b0 (patch)
tree3f4499669fb06ca1d8f1d3f8d6155475ffdfe86c /src
parent61cf48f3f9caab1c98686e5012fd400853f8fbdd (diff)
downloadgnunet-5bad33167fe0e7c696144ae7060eb89b0862f7b0.tar.gz
gnunet-5bad33167fe0e7c696144ae7060eb89b0862f7b0.zip
handle case where partial download prevents proper bottom-up reconstruction as not all child-nodes are even attempted; handle case where probe returns results immediately while being created (do not break on that)
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs_api.c6
-rw-r--r--src/fs/fs_download.c76
-rw-r--r--src/fs/fs_search.c6
3 files changed, 50 insertions, 38 deletions
diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c
index 3b8d125ad..148ec4bb9 100644
--- a/src/fs/fs_api.c
+++ b/src/fs/fs_api.c
@@ -687,7 +687,8 @@ get_write_handle_in_dir (struct GNUNET_FS_Handle *h, const char *ext,
687 * @param ent entity identifier 687 * @param ent entity identifier
688 */ 688 */
689void 689void
690GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, const char *ext, 690GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h,
691 const char *ext,
691 const char *ent) 692 const char *ent)
692{ 693{
693 char *filename; 694 char *filename;
@@ -700,7 +701,8 @@ GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, const char *ext,
700 filename = get_serialization_file_name (h, ext, ent); 701 filename = get_serialization_file_name (h, ext, ent);
701 if (NULL != filename) 702 if (NULL != filename)
702 { 703 {
703 if (0 != UNLINK (filename)) 704 if ( (0 != UNLINK (filename)) &&
705 (ENOENT != errno) )
704 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); 706 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
705 GNUNET_free (filename); 707 GNUNET_free (filename);
706 } 708 }
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index 5d4c6d899..f8933bb9d 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -450,6 +450,18 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc,
450 return; 450 return;
451 if (dr->depth > 0) 451 if (dr->depth > 0)
452 { 452 {
453 if ( (dc->offset > 0) ||
454 (dc->length < GNUNET_ntohll (dc->uri->data.chk.file_length)) )
455 {
456 /* NOTE: this test is not tight, but should suffice; the issue
457 here is that 'dr->num_children' may inherently only specify a
458 smaller range than what is in the original file;
459 thus, reconstruction of (some) inner blocks will fail.
460 FIXME: we might eventually want to write a tighter test to
461 maximize the circumstances under which we do succeed with
462 IBlock reconstruction. (need good tests though). */
463 return;
464 }
453 complete = GNUNET_YES; 465 complete = GNUNET_YES;
454 for (i = 0; i < dr->num_children; i++) 466 for (i = 0; i < dr->num_children; i++)
455 { 467 {
@@ -494,39 +506,43 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc,
494 } 506 }
495 /* write block to disk */ 507 /* write block to disk */
496 fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename; 508 fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
497 fh = GNUNET_DISK_file_open (fn, 509 if (NULL != fn)
498 GNUNET_DISK_OPEN_READWRITE |
499 GNUNET_DISK_OPEN_CREATE |
500 GNUNET_DISK_OPEN_TRUNCATE,
501 GNUNET_DISK_PERM_USER_READ |
502 GNUNET_DISK_PERM_USER_WRITE |
503 GNUNET_DISK_PERM_GROUP_READ |
504 GNUNET_DISK_PERM_OTHER_READ);
505 if (NULL == fh)
506 { 510 {
507 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn); 511 fh = GNUNET_DISK_file_open (fn,
508 GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"), 512 GNUNET_DISK_OPEN_READWRITE |
509 fn); 513 GNUNET_DISK_OPEN_CREATE |
510 GNUNET_DISK_file_close (fh); 514 GNUNET_DISK_OPEN_TRUNCATE,
511 dr->state = BRS_ERROR; 515 GNUNET_DISK_PERM_USER_READ |
512 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR; 516 GNUNET_DISK_PERM_USER_WRITE |
513 pi.value.download.specifics.error.message = dc->emsg; 517 GNUNET_DISK_PERM_GROUP_READ |
514 GNUNET_FS_download_make_status_ (&pi, dc); 518 GNUNET_DISK_PERM_OTHER_READ);
515 return; 519 if (NULL == fh)
516 } 520 {
517 if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len)) 521 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
518 { 522 GNUNET_asprintf (&dc->emsg,
519 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); 523 _("Failed to open file `%s' for writing"),
520 GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"), 524 fn);
521 fn); 525 GNUNET_DISK_file_close (fh);
526 dr->state = BRS_ERROR;
527 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
528 pi.value.download.specifics.error.message = dc->emsg;
529 GNUNET_FS_download_make_status_ (&pi, dc);
530 return;
531 }
532 if (data_len != GNUNET_DISK_file_write (fh, odata, odata_len))
533 {
534 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn);
535 GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"),
536 fn);
537 GNUNET_DISK_file_close (fh);
538 dr->state = BRS_ERROR;
539 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
540 pi.value.download.specifics.error.message = dc->emsg;
541 GNUNET_FS_download_make_status_ (&pi, dc);
542 return;
543 }
522 GNUNET_DISK_file_close (fh); 544 GNUNET_DISK_file_close (fh);
523 dr->state = BRS_ERROR;
524 pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
525 pi.value.download.specifics.error.message = dc->emsg;
526 GNUNET_FS_download_make_status_ (&pi, dc);
527 return;
528 } 545 }
529 GNUNET_DISK_file_close (fh);
530 /* signal success */ 546 /* signal success */
531 dr->state = BRS_DOWNLOAD_UP; 547 dr->state = BRS_DOWNLOAD_UP;
532 dc->completed = dc->length; 548 dc->completed = dc->length;
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 90b5eb215..57c3816b7 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -341,12 +341,6 @@ GNUNET_FS_search_probe_progress_ (void *cls,
341 GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time, 341 GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time,
342 &probe_failure_handler, sr); 342 &probe_failure_handler, sr);
343 } 343 }
344 else
345 {
346 /* should only happen if the cancel task was already
347 created on 'DOWNLOAD_INACTIVE' as we were out of time */
348 GNUNET_break (0 == sr->remaining_probe_time.rel_value_us);
349 }
350 break; 344 break;
351 case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: 345 case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
352 if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) 346 if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)