aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_download.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-03-07 20:31:26 +0000
committerChristian Grothoff <christian@grothoff.org>2012-03-07 20:31:26 +0000
commit40ec47829d2eeca9d8b5a1e3302d11681f2f5f91 (patch)
tree01ab3d2e5c628824dc3f93dfd3b820eefbfc241d /src/fs/fs_download.c
parentcc5f193706781f4c55d7616429f413c3b190284d (diff)
downloadgnunet-40ec47829d2eeca9d8b5a1e3302d11681f2f5f91.tar.gz
gnunet-40ec47829d2eeca9d8b5a1e3302d11681f2f5f91.zip
-misc major bugfixes in download code wrt reconstruction and chk index calculations
Diffstat (limited to 'src/fs/fs_download.c')
-rw-r--r--src/fs/fs_download.c100
1 files changed, 72 insertions, 28 deletions
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index 189afd146..11f5db5b2 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -243,7 +243,8 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc,
243 return GNUNET_SYSERR; 243 return GNUNET_SYSERR;
244 } 244 }
245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
246 "Matching block for `%s' at offset %llu already present, no need for download!\n", 246 "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n",
247 (unsigned int) len,
247 dc->filename, (unsigned long long) dr->offset); 248 dc->filename, (unsigned long long) dr->offset);
248 /* already got it! */ 249 /* already got it! */
249 prc.dc = dc; 250 prc.dc = dc;
@@ -386,6 +387,16 @@ check_completed (struct GNUNET_FS_DownloadContext *dc)
386 GNUNET_FS_dequeue_ (dc->job_queue); 387 GNUNET_FS_dequeue_ (dc->job_queue);
387 dc->job_queue = NULL; 388 dc->job_queue = NULL;
388 } 389 }
390 if (GNUNET_SCHEDULER_NO_TASK != dc->task)
391 {
392 GNUNET_SCHEDULER_cancel (dc->task);
393 dc->task = GNUNET_SCHEDULER_NO_TASK;
394 }
395 if (dc->rfh != NULL)
396 {
397 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh));
398 dc->rfh = NULL;
399 }
389 GNUNET_FS_download_sync_ (dc); 400 GNUNET_FS_download_sync_ (dc);
390 401
391 /* signal completion */ 402 /* signal completion */
@@ -520,6 +531,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc,
520 pi.value.download.specifics.progress.data_len = dlen; 531 pi.value.download.specifics.progress.data_len = dlen;
521 pi.value.download.specifics.progress.depth = 0; 532 pi.value.download.specifics.progress.depth = 0;
522 pi.value.download.specifics.progress.trust_offered = 0; 533 pi.value.download.specifics.progress.trust_offered = 0;
534 pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO;
523 GNUNET_FS_download_make_status_ (&pi, dc); 535 GNUNET_FS_download_make_status_ (&pi, dc);
524 if ((NULL != dc->filename) && 536 if ((NULL != dc->filename) &&
525 (0 != 537 (0 !=
@@ -621,7 +633,6 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc,
621 uint64_t total; 633 uint64_t total;
622 size_t len; 634 size_t len;
623 unsigned int i; 635 unsigned int i;
624 unsigned int chk_off;
625 struct DownloadRequest *drc; 636 struct DownloadRequest *drc;
626 uint64_t child_block_size; 637 uint64_t child_block_size;
627 const struct ContentHashKey *chks; 638 const struct ContentHashKey *chks;
@@ -673,12 +684,11 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc,
673 drc = dr->children[i]; 684 drc = dr->children[i];
674 GNUNET_assert (drc->offset >= dr->offset); 685 GNUNET_assert (drc->offset >= dr->offset);
675 child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth); 686 child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth);
676 GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size); 687 GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
677 chk_off = (drc->offset - dr->offset) / child_block_size;
678 if (drc->state == BRS_INIT) 688 if (drc->state == BRS_INIT)
679 { 689 {
680 drc->state = BRS_CHK_SET; 690 drc->state = BRS_CHK_SET;
681 drc->chk = chks[chk_off]; 691 drc->chk = chks[drc->chk_idx];
682 try_top_down_reconstruction (dc, drc); 692 try_top_down_reconstruction (dc, drc);
683 } 693 }
684 if (drc->state != BRS_DOWNLOAD_UP) 694 if (drc->state != BRS_DOWNLOAD_UP)
@@ -1113,9 +1123,10 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
1113 switch (drc->state) 1123 switch (drc->state)
1114 { 1124 {
1115 case BRS_INIT: 1125 case BRS_INIT:
1116 drc->chk = chkarr[dr->chk_idx]; 1126 drc->chk = chkarr[drc->chk_idx];
1117 drc->state = BRS_CHK_SET; 1127 drc->state = BRS_CHK_SET;
1118 schedule_block_download (dc, drc); 1128 if (GNUNET_YES == dc->issue_requests)
1129 schedule_block_download (dc, drc);
1119 break; 1130 break;
1120 case BRS_RECONSTRUCT_DOWN: 1131 case BRS_RECONSTRUCT_DOWN:
1121 GNUNET_assert (0); 1132 GNUNET_assert (0);
@@ -1527,6 +1538,11 @@ create_download_request (struct DownloadRequest *parent,
1527 if (dr->num_children * child_block_size < 1538 if (dr->num_children * child_block_size <
1528 file_start_offset + desired_length) 1539 file_start_offset + desired_length)
1529 dr->num_children++; /* round up */ 1540 dr->num_children++; /* round up */
1541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1542 "Block at offset %llu and depth %u has %u children\n",
1543 (unsigned long long) dr_offset,
1544 depth,
1545 dr->num_children);
1530 1546
1531 /* now we can get the total number of children for this block */ 1547 /* now we can get the total number of children for this block */
1532 dr->num_children -= head_skip; 1548 dr->num_children -= head_skip;
@@ -1560,12 +1576,7 @@ reconstruct_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1560{ 1576{
1561 struct GNUNET_FS_DownloadContext *dc = cls; 1577 struct GNUNET_FS_DownloadContext *dc = cls;
1562 1578
1563 /* clean up state from tree encoder */ 1579 /* clean up state from tree encoder */
1564 if (dc->te != NULL)
1565 {
1566 GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL);
1567 dc->te = NULL;
1568 }
1569 if (dc->task != GNUNET_SCHEDULER_NO_TASK) 1580 if (dc->task != GNUNET_SCHEDULER_NO_TASK)
1570 { 1581 {
1571 GNUNET_SCHEDULER_cancel (dc->task); 1582 GNUNET_SCHEDULER_cancel (dc->task);
@@ -1577,6 +1588,9 @@ reconstruct_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1577 dc->rfh = NULL; 1588 dc->rfh = NULL;
1578 } 1589 }
1579 /* start "normal" download */ 1590 /* start "normal" download */
1591 dc->issue_requests = GNUNET_YES;
1592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1593 "Starting normal download\n");
1580 schedule_block_download (dc, dc->top_request); 1594 schedule_block_download (dc, dc->top_request);
1581} 1595}
1582 1596
@@ -1630,11 +1644,34 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
1630 dr = dc->top_request; 1644 dr = dc->top_request;
1631 while (dr->depth > depth) 1645 while (dr->depth > depth)
1632 { 1646 {
1633 blen = GNUNET_FS_tree_compute_tree_size (dr->depth); 1647 GNUNET_assert (dr->num_children > 0);
1648 blen = GNUNET_FS_tree_compute_tree_size (dr->depth - 1);
1634 chld = (offset - dr->offset) / blen; 1649 chld = (offset - dr->offset) / blen;
1635 GNUNET_assert (chld < dr->num_children); 1650 if (chld < dr->children[0]->chk_idx)
1636 dr = dr->children[chld]; 1651 {
1652 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1653 "Block %u < %u irrelevant for our range\n",
1654 chld,
1655 dr->children[dr->num_children-1]->chk_idx);
1656 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1657 return; /* irrelevant block */
1658 }
1659 if (chld > dr->children[dr->num_children-1]->chk_idx)
1660 {
1661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1662 "Block %u > %u irrelevant for our range\n",
1663 chld,
1664 dr->children[dr->num_children-1]->chk_idx);
1665 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1666 return; /* irrelevant block */
1667 }
1668 dr = dr->children[chld - dr->children[0]->chk_idx];
1637 } 1669 }
1670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1671 "Matched TE block with request at offset %llu and depth %u in state %d\n",
1672 (unsigned long long) dr->offset,
1673 dr->depth,
1674 dr->state);
1638 /* FIXME: this code needs more testing and might 1675 /* FIXME: this code needs more testing and might
1639 need to handle more states... */ 1676 need to handle more states... */
1640 switch (dr->state) 1677 switch (dr->state)
@@ -1650,11 +1687,14 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
1650 case BRS_CHK_SET: 1687 case BRS_CHK_SET:
1651 if (0 == memcmp (chk, &dr->chk, sizeof (struct ContentHashKey))) 1688 if (0 == memcmp (chk, &dr->chk, sizeof (struct ContentHashKey)))
1652 { 1689 {
1690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1691 "Reconstruction succeeded, can use block at offset %llu, depth %u\n",
1692 (unsigned long long) offset,
1693 depth);
1653 /* block matches, hence tree below matches; 1694 /* block matches, hence tree below matches;
1654 * this request is done! */ 1695 * this request is done! */
1655 dr->state = BRS_DOWNLOAD_UP; 1696 dr->state = BRS_DOWNLOAD_UP;
1656 GNUNET_break (GNUNET_NO == 1697 (void) GNUNET_CONTAINER_multihashmap_remove (dc->active, &dr->chk.query, dr);
1657 GNUNET_CONTAINER_multihashmap_remove (dc->active, &dr->chk.query, dr));
1658 if (GNUNET_YES == dr->is_pending) 1698 if (GNUNET_YES == dr->is_pending)
1659 { 1699 {
1660 GNUNET_break (0); /* how did we get here? */ 1700 GNUNET_break (0); /* how did we get here? */
@@ -1674,6 +1714,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
1674 pi.value.download.specifics.progress.data_len = 0; 1714 pi.value.download.specifics.progress.data_len = 0;
1675 pi.value.download.specifics.progress.depth = 0; 1715 pi.value.download.specifics.progress.depth = 0;
1676 pi.value.download.specifics.progress.trust_offered = 0; 1716 pi.value.download.specifics.progress.trust_offered = 0;
1717 pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO;
1677 GNUNET_FS_download_make_status_ (&pi, dc); 1718 GNUNET_FS_download_make_status_ (&pi, dc);
1678 /* FIXME: duplicated code from 'process_result_with_request - refactor */ 1719 /* FIXME: duplicated code from 'process_result_with_request - refactor */
1679 if (dc->completed == dc->length) 1720 if (dc->completed == dc->length)
@@ -1694,6 +1735,11 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
1694 } 1735 }
1695 } 1736 }
1696 } 1737 }
1738 else
1739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1740 "Reconstruction failed, need to download block at offset %llu, depth %u\n",
1741 (unsigned long long) offset,
1742 depth);
1697 break; 1743 break;
1698 case BRS_DOWNLOAD_DOWN: 1744 case BRS_DOWNLOAD_DOWN:
1699 break; 1745 break;
@@ -1705,12 +1751,9 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
1705 GNUNET_assert (0); 1751 GNUNET_assert (0);
1706 break; 1752 break;
1707 } 1753 }
1754 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1708 if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP)) 1755 if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP))
1709 {
1710 check_completed (dc); 1756 check_completed (dc);
1711 return;
1712 }
1713 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1714} 1757}
1715 1758
1716 1759
@@ -1876,18 +1919,21 @@ GNUNET_FS_download_start_task_ (void *cls,
1876 } 1919 }
1877 if (dc->rfh != NULL) 1920 if (dc->rfh != NULL)
1878 { 1921 {
1879 /* finally, try bottom-up */ 1922 /* finally, actually run bottom-up */
1880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1881 "Trying bottom-up reconstruction of file `%s'\n", dc->filename); 1924 "Trying bottom-up reconstruction of file `%s'\n", dc->filename);
1882 dc->te = 1925 dc->te =
1883 GNUNET_FS_tree_encoder_create (dc->h, dc->old_file_size, dc, &fh_reader, 1926 GNUNET_FS_tree_encoder_create (dc->h,
1884 &reconstruct_cb, NULL, 1927 GNUNET_FS_uri_chk_get_file_size (dc->uri),
1885 &reconstruct_cont); 1928 dc, &fh_reader,
1929 &reconstruct_cb, NULL,
1930 &reconstruct_cont);
1886 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc); 1931 dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
1887 } 1932 }
1888 else 1933 else
1889 { 1934 {
1890 /* simple, top-level download */ 1935 /* simple, top-level download */
1936 dc->issue_requests = GNUNET_YES;
1891 schedule_block_download (dc, dc->top_request); 1937 schedule_block_download (dc, dc->top_request);
1892 } 1938 }
1893 if (dc->top_request->state == BRS_DOWNLOAD_UP) 1939 if (dc->top_request->state == BRS_DOWNLOAD_UP)
@@ -2194,8 +2240,6 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete)
2194 2240
2195 if (dc->top != NULL) 2241 if (dc->top != NULL)
2196 GNUNET_FS_end_top (dc->h, dc->top); 2242 GNUNET_FS_end_top (dc->h, dc->top);
2197
2198
2199 if (dc->task != GNUNET_SCHEDULER_NO_TASK) 2243 if (dc->task != GNUNET_SCHEDULER_NO_TASK)
2200 { 2244 {
2201 GNUNET_SCHEDULER_cancel (dc->task); 2245 GNUNET_SCHEDULER_cancel (dc->task);