diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-02-19 13:52:24 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-02-19 13:52:24 +0000 |
commit | 5bad33167fe0e7c696144ae7060eb89b0862f7b0 (patch) | |
tree | 3f4499669fb06ca1d8f1d3f8d6155475ffdfe86c /src | |
parent | 61cf48f3f9caab1c98686e5012fd400853f8fbdd (diff) | |
download | gnunet-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.c | 6 | ||||
-rw-r--r-- | src/fs/fs_download.c | 76 | ||||
-rw-r--r-- | src/fs/fs_search.c | 6 |
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 | */ |
689 | void | 689 | void |
690 | GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, const char *ext, | 690 | GNUNET_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) |