aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-11 14:50:07 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-11 14:50:07 +0000
commitcd67a970afe36e8a2aa99e48cbe103cc4cc26424 (patch)
tree67e5023676f2278485e35a2b71ce246b9933f406 /src
parent3dd666cbad61490c0de1cb891fd1b36c8536c348 (diff)
downloadgnunet-cd67a970afe36e8a2aa99e48cbe103cc4cc26424.tar.gz
gnunet-cd67a970afe36e8a2aa99e48cbe103cc4cc26424.zip
generate progress events when publishing directories (towards fixing #2230)
Diffstat (limited to 'src')
-rw-r--r--src/fs/fs_api.c6
-rw-r--r--src/fs/fs_api.h157
-rw-r--r--src/fs/fs_publish.c57
-rw-r--r--src/fs/fs_test_lib.c2
-rw-r--r--src/fs/gnunet-daemon-fsprofiler.c3
-rw-r--r--src/fs/gnunet-publish.c15
-rw-r--r--src/fs/test_fs_download.c2
-rw-r--r--src/fs/test_fs_download_persistence.c2
-rw-r--r--src/fs/test_fs_list_indexed.c3
-rw-r--r--src/fs/test_fs_publish.c3
-rw-r--r--src/fs/test_fs_publish_persistence.c3
-rw-r--r--src/fs/test_fs_search.c4
-rw-r--r--src/fs/test_fs_search_persistence.c2
-rw-r--r--src/fs/test_fs_search_probes.c2
-rw-r--r--src/fs/test_fs_unindex.c2
-rw-r--r--src/fs/test_fs_unindex_persistence.c2
-rw-r--r--src/include/gnunet_fs_service.h35
17 files changed, 223 insertions, 77 deletions
diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c
index 688bdf282..f076b0991 100644
--- a/src/fs/fs_api.c
+++ b/src/fs/fs_api.c
@@ -284,7 +284,7 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
285 "AD: %u, MP: %u; %d probes and %d downloads to start, will run again in %s\n", 285 "AD: %u, MP: %u; %d probes and %d downloads to start, will run again in %s\n",
286 h->active_downloads, 286 h->active_downloads,
287 h->max_parallel_requests, 287 h->max_parallel_requests,
288 num_probes_change, 288 num_probes_change,
289 num_downloads_change, 289 num_downloads_change,
290 GNUNET_STRINGS_relative_time_to_string (restart_at, GNUNET_YES)); 290 GNUNET_STRINGS_relative_time_to_string (restart_at, GNUNET_YES));
@@ -982,6 +982,8 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h, const char *fn,
982 case 4: /* directory */ 982 case 4: /* directory */
983 ret->is_directory = GNUNET_YES; 983 ret->is_directory = GNUNET_YES;
984 if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dsize)) || 984 if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dsize)) ||
985 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.dir.contents_completed)) ||
986 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.dir.contents_size)) ||
985 (NULL == (ret->data.dir.dir_data = GNUNET_malloc_large (dsize))) || 987 (NULL == (ret->data.dir.dir_data = GNUNET_malloc_large (dsize))) ||
986 (GNUNET_OK != 988 (GNUNET_OK !=
987 GNUNET_BIO_read (rh, "dir-data", ret->data.dir.dir_data, dsize)) || 989 GNUNET_BIO_read (rh, "dir-data", ret->data.dir.dir_data, dsize)) ||
@@ -1335,6 +1337,8 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1335 (NULL == fi->data.dir.entries->serialization) ) 1337 (NULL == fi->data.dir.entries->serialization) )
1336 GNUNET_FS_file_information_sync_ (fi->data.dir.entries); 1338 GNUNET_FS_file_information_sync_ (fi->data.dir.entries);
1337 if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->data.dir.dir_size)) || 1339 if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->data.dir.dir_size)) ||
1340 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.dir.contents_completed)) ||
1341 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.dir.contents_size)) ||
1338 (GNUNET_OK != 1342 (GNUNET_OK !=
1339 GNUNET_BIO_write (wh, fi->data.dir.dir_data, 1343 GNUNET_BIO_write (wh, fi->data.dir.dir_data,
1340 (uint32_t) fi->data.dir.dir_size)) || 1344 (uint32_t) fi->data.dir.dir_size)) ||
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h
index 4b0965f15..77e26e155 100644
--- a/src/fs/fs_api.h
+++ b/src/fs/fs_api.h
@@ -347,7 +347,7 @@ struct GNUNET_FS_FileInformation
347 347
348 /** 348 /**
349 * Has the service confirmed our INDEX_START request? 349 * Has the service confirmed our INDEX_START request?
350 * GNUNET_YES if this step has been completed. 350 * #GNUNET_YES if this step has been completed.
351 */ 351 */
352 int index_start_confirmed; 352 int index_start_confirmed;
353 353
@@ -376,6 +376,16 @@ struct GNUNET_FS_FileInformation
376 */ 376 */
377 void *dir_data; 377 void *dir_data;
378 378
379 /**
380 * How much of the directory have we published (relative to @e contents_size).
381 */
382 uint64_t contents_completed;
383
384 /**
385 * Sum of all of the sizes of all of the files in the directory.
386 */
387 uint64_t contents_size;
388
379 } dir; 389 } dir;
380 390
381 } data; 391 } data;
@@ -416,17 +426,17 @@ typedef void (*GNUNET_FS_QueueStop) (void *cls);
416 * Priorities for the queue. 426 * Priorities for the queue.
417 */ 427 */
418enum GNUNET_FS_QueuePriority 428enum GNUNET_FS_QueuePriority
419 { 429{
420 /** 430 /**
421 * This is a probe (low priority). 431 * This is a probe (low priority).
422 */ 432 */
423 GNUNET_FS_QUEUE_PRIORITY_PROBE, 433 GNUNET_FS_QUEUE_PRIORITY_PROBE,
424 434
425 /** 435 /**
426 * Default priority. 436 * Default priority.
427 */ 437 */
428 GNUNET_FS_QUEUE_PRIORITY_NORMAL 438 GNUNET_FS_QUEUE_PRIORITY_NORMAL
429 }; 439};
430 440
431 441
432/** 442/**
@@ -701,6 +711,7 @@ size_t
701GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf, 711GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf,
702 char **emsg); 712 char **emsg);
703 713
714
704/** 715/**
705 * Notification of FS that a search probe has made progress. 716 * Notification of FS that a search probe has made progress.
706 * This function is used INSTEAD of the client's event handler 717 * This function is used INSTEAD of the client's event handler
@@ -901,6 +912,7 @@ GNUNET_FS_remove_sync_dir_ (struct GNUNET_FS_Handle *h, const char *ext,
901void 912void
902GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *f); 913GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *f);
903 914
915
904/** 916/**
905 * Synchronize this publishing struct with its mirror 917 * Synchronize this publishing struct with its mirror
906 * on disk. Note that all internal FS-operations that change 918 * on disk. Note that all internal FS-operations that change
@@ -912,6 +924,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *f);
912void 924void
913GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc); 925GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc);
914 926
927
915/** 928/**
916 * Synchronize this unindex struct with its mirror 929 * Synchronize this unindex struct with its mirror
917 * on disk. Note that all internal FS-operations that change 930 * on disk. Note that all internal FS-operations that change
@@ -923,6 +936,7 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc);
923void 936void
924GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc); 937GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc);
925 938
939
926/** 940/**
927 * Synchronize this search struct with its mirror 941 * Synchronize this search struct with its mirror
928 * on disk. Note that all internal FS-operations that change 942 * on disk. Note that all internal FS-operations that change
@@ -934,6 +948,7 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc);
934void 948void
935GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc); 949GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc);
936 950
951
937/** 952/**
938 * Synchronize this search result with its mirror 953 * Synchronize this search result with its mirror
939 * on disk. Note that all internal FS-operations that change 954 * on disk. Note that all internal FS-operations that change
@@ -945,6 +960,7 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc);
945void 960void
946GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr); 961GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr);
947 962
963
948/** 964/**
949 * Synchronize this download struct with its mirror 965 * Synchronize this download struct with its mirror
950 * on disk. Note that all internal FS-operations that change 966 * on disk. Note that all internal FS-operations that change
@@ -956,6 +972,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr);
956void 972void
957GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc); 973GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc);
958 974
975
959/** 976/**
960 * Create SUSPEND event for the given publish operation 977 * Create SUSPEND event for the given publish operation
961 * and then clean up our state (without stop signal). 978 * and then clean up our state (without stop signal).
@@ -965,6 +982,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc);
965void 982void
966GNUNET_FS_publish_signal_suspend_ (void *cls); 983GNUNET_FS_publish_signal_suspend_ (void *cls);
967 984
985
968/** 986/**
969 * Create SUSPEND event for the given search operation 987 * Create SUSPEND event for the given search operation
970 * and then clean up our state (without stop signal). 988 * and then clean up our state (without stop signal).
@@ -974,6 +992,7 @@ GNUNET_FS_publish_signal_suspend_ (void *cls);
974void 992void
975GNUNET_FS_search_signal_suspend_ (void *cls); 993GNUNET_FS_search_signal_suspend_ (void *cls);
976 994
995
977/** 996/**
978 * Create SUSPEND event for the given download operation 997 * Create SUSPEND event for the given download operation
979 * and then clean up our state (without stop signal). 998 * and then clean up our state (without stop signal).
@@ -983,6 +1002,7 @@ GNUNET_FS_search_signal_suspend_ (void *cls);
983void 1002void
984GNUNET_FS_download_signal_suspend_ (void *cls); 1003GNUNET_FS_download_signal_suspend_ (void *cls);
985 1004
1005
986/** 1006/**
987 * Create SUSPEND event for the given unindex operation 1007 * Create SUSPEND event for the given unindex operation
988 * and then clean up our state (without stop signal). 1008 * and then clean up our state (without stop signal).
@@ -992,6 +1012,7 @@ GNUNET_FS_download_signal_suspend_ (void *cls);
992void 1012void
993GNUNET_FS_unindex_signal_suspend_ (void *cls); 1013GNUNET_FS_unindex_signal_suspend_ (void *cls);
994 1014
1015
995/** 1016/**
996 * Function signature of the functions that can be called 1017 * Function signature of the functions that can be called
997 * to trigger suspend signals and clean-up for top-level 1018 * to trigger suspend signals and clean-up for top-level
@@ -1034,11 +1055,12 @@ struct TopLevelActivity
1034 * 1055 *
1035 * @param h global fs handle 1056 * @param h global fs handle
1036 * @param ssf suspend signal function to use 1057 * @param ssf suspend signal function to use
1037 * @param ssf_cls closure for ssf 1058 * @param ssf_cls closure for @a ssf
1038 * @return fresh top-level activity handle 1059 * @return fresh top-level activity handle
1039 */ 1060 */
1040struct TopLevelActivity * 1061struct TopLevelActivity *
1041GNUNET_FS_make_top (struct GNUNET_FS_Handle *h, SuspendSignalFunction ssf, 1062GNUNET_FS_make_top (struct GNUNET_FS_Handle *h,
1063 SuspendSignalFunction ssf,
1042 void *ssf_cls); 1064 void *ssf_cls);
1043 1065
1044 1066
@@ -1049,7 +1071,8 @@ GNUNET_FS_make_top (struct GNUNET_FS_Handle *h, SuspendSignalFunction ssf,
1049 * @param top top level activity entry 1071 * @param top top level activity entry
1050 */ 1072 */
1051void 1073void
1052GNUNET_FS_end_top (struct GNUNET_FS_Handle *h, struct TopLevelActivity *top); 1074GNUNET_FS_end_top (struct GNUNET_FS_Handle *h,
1075 struct TopLevelActivity *top);
1053 1076
1054 1077
1055 1078
@@ -1256,13 +1279,13 @@ struct GNUNET_FS_PublishContext
1256 int rid; 1279 int rid;
1257 1280
1258 /** 1281 /**
1259 * Set to GNUNET_YES if all processing has completed. 1282 * Set to #GNUNET_YES if all processing has completed.
1260 */ 1283 */
1261 int all_done; 1284 int all_done;
1262 1285
1263 /** 1286 /**
1264 * Flag set to GNUNET_YES if the next callback from 1287 * Flag set to #GNUNET_YES if the next callback from
1265 * GNUNET_FS_file_information_inspect should be skipped because it 1288 * #GNUNET_FS_file_information_inspect should be skipped because it
1266 * is for the directory which was already processed with the parent. 1289 * is for the directory which was already processed with the parent.
1267 */ 1290 */
1268 int skip_next_fi_callback; 1291 int skip_next_fi_callback;
@@ -1362,7 +1385,7 @@ struct GNUNET_FS_UnindexContext
1362 1385
1363 /** 1386 /**
1364 * Connection to the FS service, only valid during the 1387 * Connection to the FS service, only valid during the
1365 * UNINDEX_STATE_FS_NOTIFY phase. 1388 * #UNINDEX_STATE_FS_NOTIFY phase.
1366 */ 1389 */
1367 struct GNUNET_CLIENT_Connection *client; 1390 struct GNUNET_CLIENT_Connection *client;
1368 1391
@@ -1424,7 +1447,7 @@ struct GNUNET_FS_UnindexContext
1424 uint64_t file_size; 1447 uint64_t file_size;
1425 1448
1426 /** 1449 /**
1427 * Random offset given to 'GNUNET_DATASTORE_get_key'. 1450 * Random offset given to #GNUNET_DATASTORE_get_key.
1428 */ 1451 */
1429 uint64_t roff; 1452 uint64_t roff;
1430 1453
@@ -1561,7 +1584,7 @@ struct GNUNET_FS_SearchContext
1561 /** 1584 /**
1562 * ID of a task that is using this struct and that must be cancelled 1585 * ID of a task that is using this struct and that must be cancelled
1563 * when the search is being stopped (if not 1586 * when the search is being stopped (if not
1564 * GNUNET_SCHEDULER_NO_TASK). Used for the task that adds some 1587 * #GNUNET_SCHEDULER_NO_TASK). Used for the task that adds some
1565 * artificial delay when trying to reconnect to the FS service. 1588 * artificial delay when trying to reconnect to the FS service.
1566 */ 1589 */
1567 GNUNET_SCHEDULER_TaskIdentifier task; 1590 GNUNET_SCHEDULER_TaskIdentifier task;
@@ -1602,65 +1625,65 @@ struct GNUNET_FS_SearchContext
1602 */ 1625 */
1603enum BlockRequestState 1626enum BlockRequestState
1604{ 1627{
1605 /** 1628 /**
1606 * Initial state, block has only been allocated (since it is 1629 * Initial state, block has only been allocated (since it is
1607 * relevant to the overall download request). 1630 * relevant to the overall download request).
1608 */ 1631 */
1609 BRS_INIT = 0, 1632 BRS_INIT = 0,
1610 1633
1611 /** 1634 /**
1612 * We've checked the block on the path down the tree, and the 1635 * We've checked the block on the path down the tree, and the
1613 * content on disk did match the desired CHK, but not all 1636 * content on disk did match the desired CHK, but not all
1614 * the way down, so at the bottom some blocks will still 1637 * the way down, so at the bottom some blocks will still
1615 * need to be reconstructed). 1638 * need to be reconstructed).
1616 */ 1639 */
1617 BRS_RECONSTRUCT_DOWN = 1, 1640 BRS_RECONSTRUCT_DOWN = 1,
1618 1641
1619 /** 1642 /**
1620 * We've calculated the CHK bottom-up based on the meta data. 1643 * We've calculated the CHK bottom-up based on the meta data.
1621 * This may work, but if it did we have to write the meta data to 1644 * This may work, but if it did we have to write the meta data to
1622 * disk at the end (and we still need to check against the 1645 * disk at the end (and we still need to check against the
1623 * CHK set on top). 1646 * CHK set on top).
1624 */ 1647 */
1625 BRS_RECONSTRUCT_META_UP = 2, 1648 BRS_RECONSTRUCT_META_UP = 2,
1626 1649
1627 /** 1650 /**
1628 * We've calculated the CHK bottom-up based on what we have on 1651 * We've calculated the CHK bottom-up based on what we have on
1629 * disk, which may not be what the desired CHK is. If the 1652 * disk, which may not be what the desired CHK is. If the
1630 * reconstructed CHKs match whatever comes from above, we're 1653 * reconstructed CHKs match whatever comes from above, we're
1631 * done with the respective subtree. 1654 * done with the respective subtree.
1632 */ 1655 */
1633 BRS_RECONSTRUCT_UP = 3, 1656 BRS_RECONSTRUCT_UP = 3,
1634 1657
1635 /** 1658 /**
1636 * We've determined the real, desired CHK for this block 1659 * We've determined the real, desired CHK for this block
1637 * (full tree reconstruction failed), request is now pending. 1660 * (full tree reconstruction failed), request is now pending.
1638 * If the CHK that bubbled up through reconstruction did match 1661 * If the CHK that bubbled up through reconstruction did match
1639 * the top-level request, the state machine for the subtree 1662 * the top-level request, the state machine for the subtree
1640 * would have moved to BRS_DOWNLOAD_UP. 1663 * would have moved to BRS_DOWNLOAD_UP.
1641 */ 1664 */
1642 BRS_CHK_SET = 4, 1665 BRS_CHK_SET = 4,
1643 1666
1644 /** 1667 /**
1645 * We've successfully downloaded this block, but the children 1668 * We've successfully downloaded this block, but the children
1646 * still need to be either downloaded or verified (download 1669 * still need to be either downloaded or verified (download
1647 * request propagates down). If the download fails, the 1670 * request propagates down). If the download fails, the
1648 * state machine for this block may move to 1671 * state machine for this block may move to
1649 * BRS_DOWNLOAD_ERROR instead. 1672 * BRS_DOWNLOAD_ERROR instead.
1650 */ 1673 */
1651 BRS_DOWNLOAD_DOWN = 5, 1674 BRS_DOWNLOAD_DOWN = 5,
1652 1675
1653 /** 1676 /**
1654 * This block and all of its children have been downloaded 1677 * This block and all of its children have been downloaded
1655 * successfully (full completion propagates up). 1678 * successfully (full completion propagates up).
1656 */ 1679 */
1657 BRS_DOWNLOAD_UP = 6, 1680 BRS_DOWNLOAD_UP = 6,
1658 1681
1659 /** 1682 /**
1660 * We got a block back that matched the query but did not hash to 1683 * We got a block back that matched the query but did not hash to
1661 * the key (malicious publisher or hash collision); this block 1684 * the key (malicious publisher or hash collision); this block
1662 * can never be downloaded (error propagates up). 1685 * can never be downloaded (error propagates up).
1663 */ 1686 */
1664 BRS_ERROR = 7 1687 BRS_ERROR = 7
1665}; 1688};
1666 1689
@@ -1724,7 +1747,7 @@ struct DownloadRequest
1724 enum BlockRequestState state; 1747 enum BlockRequestState state;
1725 1748
1726 /** 1749 /**
1727 * GNUNET_YES if this entry is in the pending list. 1750 * #GNUNET_YES if this entry is in the pending list.
1728 */ 1751 */
1729 int is_pending; 1752 int is_pending;
1730 1753
@@ -1944,7 +1967,7 @@ struct GNUNET_FS_DownloadContext
1944 1967
1945 /** 1968 /**
1946 * Flag set upon transitive completion (includes child downloads). 1969 * Flag set upon transitive completion (includes child downloads).
1947 * This flag is only set to GNUNET_YES for directories where all 1970 * This flag is only set to #GNUNET_YES for directories where all
1948 * child-downloads have also completed (and signalled completion). 1971 * child-downloads have also completed (and signalled completion).
1949 */ 1972 */
1950 int has_finished; 1973 int has_finished;
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 05645f0ab..2075c5f2b 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -362,7 +362,7 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
362 if (UINT64_MAX == offset) 362 if (UINT64_MAX == offset)
363 { 363 {
364 if (&GNUNET_FS_data_reader_file_ == p->data.file.reader) 364 if (&GNUNET_FS_data_reader_file_ == p->data.file.reader)
365 { 365 {
366 /* force closing the file to avoid keeping too many files open */ 366 /* force closing the file to avoid keeping too many files open */
367 p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL); 367 p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL);
368 } 368 }
@@ -390,7 +390,8 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
390 * @param tc scheduler's task context (not used) 390 * @param tc scheduler's task context (not used)
391 */ 391 */
392static void 392static void
393encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 393encode_cont (void *cls,
394 const struct GNUNET_SCHEDULER_TaskContext *tc)
394{ 395{
395 struct GNUNET_FS_PublishContext *pc = cls; 396 struct GNUNET_FS_PublishContext *pc = cls;
396 struct GNUNET_FS_FileInformation *p; 397 struct GNUNET_FS_FileInformation *p;
@@ -421,7 +422,7 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
421 } 422 }
422 else 423 else
423 { 424 {
424 /* final progress event */ 425 /* final progress event */
425 GNUNET_assert (NULL != p->chk_uri); 426 GNUNET_assert (NULL != p->chk_uri);
426 flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri); 427 flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri);
427 pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS; 428 pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
@@ -454,8 +455,12 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
454 * @param block_size size of @a block (in bytes) 455 * @param block_size size of @a block (in bytes)
455 */ 456 */
456static void 457static void
457block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset, 458block_proc (void *cls,
458 unsigned int depth, enum GNUNET_BLOCK_Type type, const void *block, 459 const struct ContentHashKey *chk,
460 uint64_t offset,
461 unsigned int depth,
462 enum GNUNET_BLOCK_Type type,
463 const void *block,
459 uint16_t block_size) 464 uint16_t block_size)
460{ 465{
461 struct GNUNET_FS_PublishContext *pc = cls; 466 struct GNUNET_FS_PublishContext *pc = cls;
@@ -520,11 +525,14 @@ block_proc (void *cls, const struct ContentHashKey *chk, uint64_t offset,
520 * @param depth depth of the block in the tree, 0 for DBLOCK 525 * @param depth depth of the block in the tree, 0 for DBLOCK
521 */ 526 */
522static void 527static void
523progress_proc (void *cls, uint64_t offset, const void *pt_block, size_t pt_size, 528progress_proc (void *cls, uint64_t offset,
529 const void *pt_block,
530 size_t pt_size,
524 unsigned int depth) 531 unsigned int depth)
525{ 532{
526 struct GNUNET_FS_PublishContext *pc = cls; 533 struct GNUNET_FS_PublishContext *pc = cls;
527 struct GNUNET_FS_FileInformation *p; 534 struct GNUNET_FS_FileInformation *p;
535 struct GNUNET_FS_FileInformation *par;
528 struct GNUNET_FS_ProgressInfo pi; 536 struct GNUNET_FS_ProgressInfo pi;
529 537
530 p = pc->fi_pos; 538 p = pc->fi_pos;
@@ -534,6 +542,23 @@ progress_proc (void *cls, uint64_t offset, const void *pt_block, size_t pt_size,
534 pi.value.publish.specifics.progress.data_len = pt_size; 542 pi.value.publish.specifics.progress.data_len = pt_size;
535 pi.value.publish.specifics.progress.depth = depth; 543 pi.value.publish.specifics.progress.depth = depth;
536 p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, offset); 544 p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, offset);
545 if ( (0 != depth) ||
546 (GNUNET_YES == p->is_directory) )
547 return;
548 while (NULL != (par = p->dir))
549 {
550 p = par;
551 GNUNET_assert (GNUNET_YES == par->is_directory);
552 p->data.dir.contents_completed += pt_size;
553 pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY;
554 pi.value.publish.specifics.progress_directory.completed = p->data.dir.contents_completed;
555 pi.value.publish.specifics.progress_directory.total = p->data.dir.contents_size;
556 pi.value.publish.specifics.progress_directory.eta = GNUNET_TIME_calculate_eta (p->start_time,
557 p->data.dir.contents_completed,
558 p->data.dir.contents_size);
559 p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0);
560
561 }
537} 562}
538 563
539 564
@@ -1137,6 +1162,25 @@ finish_reserve (void *cls, int success,
1137 1162
1138 1163
1139/** 1164/**
1165 * Calculate the total size of all of the files in the directory structure.
1166 *
1167 * @param fi file structure to traverse
1168 */
1169static uint64_t
1170compute_contents_size (struct GNUNET_FS_FileInformation *fi)
1171{
1172 struct GNUNET_FS_FileInformation *ent;
1173
1174 if (GNUNET_YES != fi->is_directory)
1175 return fi->data.file.file_size;
1176 fi->data.dir.contents_size = 0;
1177 for (ent = fi->data.dir.entries; NULL != ent; ent = ent->next)
1178 fi->data.dir.contents_size += compute_contents_size (ent);
1179 return fi->data.dir.contents_size;
1180}
1181
1182
1183/**
1140 * Publish a file or directory. 1184 * Publish a file or directory.
1141 * 1185 *
1142 * @param h handle to the file sharing subsystem 1186 * @param h handle to the file sharing subsystem
@@ -1161,6 +1205,7 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
1161 struct GNUNET_DATASTORE_Handle *dsh; 1205 struct GNUNET_DATASTORE_Handle *dsh;
1162 1206
1163 GNUNET_assert (NULL != h); 1207 GNUNET_assert (NULL != h);
1208 compute_contents_size (fi);
1164 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) 1209 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
1165 { 1210 {
1166 dsh = GNUNET_DATASTORE_connect (h->cfg); 1211 dsh = GNUNET_DATASTORE_connect (h->cfg);
diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c
index 925e36a8e..3898f798e 100644
--- a/src/fs/fs_test_lib.c
+++ b/src/fs/fs_test_lib.c
@@ -253,6 +253,8 @@ publish_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
253 (unsigned long long) info->value.publish.completed, 253 (unsigned long long) info->value.publish.completed,
254 (unsigned long long) info->value.publish.size); 254 (unsigned long long) info->value.publish.size);
255 break; 255 break;
256 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
257 break;
256 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: 258 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
257 if (po->verbose) 259 if (po->verbose)
258 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n", 260 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n",
diff --git a/src/fs/gnunet-daemon-fsprofiler.c b/src/fs/gnunet-daemon-fsprofiler.c
index d4c2b1c02..1549972a1 100644
--- a/src/fs/gnunet-daemon-fsprofiler.c
+++ b/src/fs/gnunet-daemon-fsprofiler.c
@@ -385,6 +385,9 @@ progress_cb (void *cls,
385 case GNUNET_FS_STATUS_PUBLISH_PROGRESS: 385 case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
386 p = info->value.publish.cctx; 386 p = info->value.publish.cctx;
387 return p; 387 return p;
388 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
389 p = info->value.publish.cctx;
390 return p;
388 case GNUNET_FS_STATUS_PUBLISH_ERROR: 391 case GNUNET_FS_STATUS_PUBLISH_ERROR:
389 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 392 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
390 "Publishing failed\n"); 393 "Publishing failed\n");
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index 7f7423ae5..12d9a6084 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -227,12 +227,25 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
227 { 227 {
228 s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.eta, 228 s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.eta,
229 GNUNET_YES); 229 GNUNET_YES);
230 FPRINTF (stdout, _("Publishing `%s' at %llu/%llu (%s remaining)\n"), 230 FPRINTF (stdout,
231 _("Publishing `%s' at %llu/%llu (%s remaining)\n"),
231 info->value.publish.filename, 232 info->value.publish.filename,
232 (unsigned long long) info->value.publish.completed, 233 (unsigned long long) info->value.publish.completed,
233 (unsigned long long) info->value.publish.size, s); 234 (unsigned long long) info->value.publish.size, s);
234 } 235 }
235 break; 236 break;
237 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
238 if (verbose)
239 {
240 s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.specifics.progress_directory.eta,
241 GNUNET_YES);
242 FPRINTF (stdout,
243 _("Publishing `%s' at %llu/%llu (%s remaining)\n"),
244 info->value.publish.filename,
245 (unsigned long long) info->value.publish.specifics.progress_directory.completed,
246 (unsigned long long) info->value.publish.specifics.progress_directory.total, s);
247 }
248 break;
236 case GNUNET_FS_STATUS_PUBLISH_ERROR: 249 case GNUNET_FS_STATUS_PUBLISH_ERROR:
237 FPRINTF (stderr, _("Error publishing: %s.\n"), 250 FPRINTF (stderr, _("Error publishing: %s.\n"),
238 info->value.publish.specifics.error.message); 251 info->value.publish.specifics.error.message);
diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c
index 52652dbd3..51f05192e 100644
--- a/src/fs/test_fs_download.c
+++ b/src/fs/test_fs_download.c
@@ -139,6 +139,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
139 (unsigned long long) event->value.publish.specifics. 139 (unsigned long long) event->value.publish.specifics.
140 progress.offset); 140 progress.offset);
141 break; 141 break;
142 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
143 break;
142 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 144 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
143 fprintf (stdout, 145 fprintf (stdout,
144 "Publishing complete, %llu kb/s.\n", 146 "Publishing complete, %llu kb/s.\n",
diff --git a/src/fs/test_fs_download_persistence.c b/src/fs/test_fs_download_persistence.c
index 7c9c8c227..a9b998013 100644
--- a/src/fs/test_fs_download_persistence.c
+++ b/src/fs/test_fs_download_persistence.c
@@ -162,6 +162,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
162 (unsigned long long) event->value.publish.specifics. 162 (unsigned long long) event->value.publish.specifics.
163 progress.offset); 163 progress.offset);
164 break; 164 break;
165 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
166 break;
165 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 167 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
166 printf ("Publishing complete, %llu kbps.\n", 168 printf ("Publishing complete, %llu kbps.\n",
167 (unsigned long long) (FILESIZE * 1000000LL / 169 (unsigned long long) (FILESIZE * 1000000LL /
diff --git a/src/fs/test_fs_list_indexed.c b/src/fs/test_fs_list_indexed.c
index b505e8a18..e359bd8ed 100644
--- a/src/fs/test_fs_list_indexed.c
+++ b/src/fs/test_fs_list_indexed.c
@@ -115,6 +115,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
115 (unsigned long long) event->value.publish.specifics. 115 (unsigned long long) event->value.publish.specifics.
116 progress.offset); 116 progress.offset);
117 break; 117 break;
118 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
119 ret = event->value.publish.cctx;
120 break;
118 case GNUNET_FS_STATUS_PUBLISH_ERROR: 121 case GNUNET_FS_STATUS_PUBLISH_ERROR:
119 ret = event->value.publish.cctx; 122 ret = event->value.publish.cctx;
120 FPRINTF (stderr, "Error publishing file: %s\n", 123 FPRINTF (stderr, "Error publishing file: %s\n",
diff --git a/src/fs/test_fs_publish.c b/src/fs/test_fs_publish.c
index 41b4abd26..d80d749de 100644
--- a/src/fs/test_fs_publish.c
+++ b/src/fs/test_fs_publish.c
@@ -101,6 +101,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
101 (unsigned long long) event->value.publish.specifics. 101 (unsigned long long) event->value.publish.specifics.
102 progress.offset); 102 progress.offset);
103 break; 103 break;
104 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
105 ret = event->value.publish.cctx;
106 break;
104 case GNUNET_FS_STATUS_PUBLISH_ERROR: 107 case GNUNET_FS_STATUS_PUBLISH_ERROR:
105 ret = event->value.publish.cctx; 108 ret = event->value.publish.cctx;
106 FPRINTF (stderr, "Error publishing file: %s\n", 109 FPRINTF (stderr, "Error publishing file: %s\n",
diff --git a/src/fs/test_fs_publish_persistence.c b/src/fs/test_fs_publish_persistence.c
index 5beb1b7e5..8e5e5f53b 100644
--- a/src/fs/test_fs_publish_persistence.c
+++ b/src/fs/test_fs_publish_persistence.c
@@ -145,6 +145,9 @@ progress_cb (void *cls,
145 (0 == strcmp ("publish-context-dir", event->value.publish.cctx)) ) 145 (0 == strcmp ("publish-context-dir", event->value.publish.cctx)) )
146 GNUNET_SCHEDULER_add_now (&abort_publish_task, NULL); 146 GNUNET_SCHEDULER_add_now (&abort_publish_task, NULL);
147 break; 147 break;
148 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
149 ret = event->value.publish.cctx;
150 return ret;
148 case GNUNET_FS_STATUS_PUBLISH_PROGRESS: 151 case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
149 consider_restart (event->status); 152 consider_restart (event->status);
150 ret = event->value.publish.cctx; 153 ret = event->value.publish.cctx;
diff --git a/src/fs/test_fs_search.c b/src/fs/test_fs_search.c
index faf8727a6..f525fb474 100644
--- a/src/fs/test_fs_search.c
+++ b/src/fs/test_fs_search.c
@@ -59,7 +59,7 @@ static int err;
59 59
60static void 60static void
61abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 61abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
62{ 62{
63 if (NULL != publish) 63 if (NULL != publish)
64 { 64 {
65 GNUNET_FS_publish_stop (publish); 65 GNUNET_FS_publish_stop (publish);
@@ -123,6 +123,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
123 (unsigned long long) event->value.publish.specifics. 123 (unsigned long long) event->value.publish.specifics.
124 progress.offset); 124 progress.offset);
125 break; 125 break;
126 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
127 break;
126 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 128 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
127 kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords); 129 kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords);
128 start = GNUNET_TIME_absolute_get (); 130 start = GNUNET_TIME_absolute_get ();
diff --git a/src/fs/test_fs_search_persistence.c b/src/fs/test_fs_search_persistence.c
index 76308ecb9..34ea04aca 100644
--- a/src/fs/test_fs_search_persistence.c
+++ b/src/fs/test_fs_search_persistence.c
@@ -160,6 +160,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
160 (unsigned long long) event->value.publish.specifics. 160 (unsigned long long) event->value.publish.specifics.
161 progress.offset); 161 progress.offset);
162 break; 162 break;
163 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
164 break;
163 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 165 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
164 kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords); 166 kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords);
165 start = GNUNET_TIME_absolute_get (); 167 start = GNUNET_TIME_absolute_get ();
diff --git a/src/fs/test_fs_search_probes.c b/src/fs/test_fs_search_probes.c
index 969c525c6..beae34763 100644
--- a/src/fs/test_fs_search_probes.c
+++ b/src/fs/test_fs_search_probes.c
@@ -122,6 +122,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
122 (unsigned long long) event->value.publish.specifics. 122 (unsigned long long) event->value.publish.specifics.
123 progress.offset); 123 progress.offset);
124 break; 124 break;
125 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
126 break;
125 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 127 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
126 kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords); 128 kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords);
127 start = GNUNET_TIME_absolute_get (); 129 start = GNUNET_TIME_absolute_get ();
diff --git a/src/fs/test_fs_unindex.c b/src/fs/test_fs_unindex.c
index 033195f0b..b64762ce6 100644
--- a/src/fs/test_fs_unindex.c
+++ b/src/fs/test_fs_unindex.c
@@ -90,6 +90,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
90 (unsigned long long) event->value.publish.specifics. 90 (unsigned long long) event->value.publish.specifics.
91 progress.offset); 91 progress.offset);
92 break; 92 break;
93 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
94 break;
93 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 95 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
94 printf ("Publishing complete, %llu kbps.\n", 96 printf ("Publishing complete, %llu kbps.\n",
95 (unsigned long long) (FILESIZE * 1000000LL / 97 (unsigned long long) (FILESIZE * 1000000LL /
diff --git a/src/fs/test_fs_unindex_persistence.c b/src/fs/test_fs_unindex_persistence.c
index f90a01a79..0da4193dd 100644
--- a/src/fs/test_fs_unindex_persistence.c
+++ b/src/fs/test_fs_unindex_persistence.c
@@ -132,6 +132,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
132 (unsigned long long) event->value.publish.specifics. 132 (unsigned long long) event->value.publish.specifics.
133 progress.offset); 133 progress.offset);
134 break; 134 break;
135 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
136 break;
135 case GNUNET_FS_STATUS_PUBLISH_COMPLETED: 137 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
136 printf ("Publishing complete, %llu kbps.\n", 138 printf ("Publishing complete, %llu kbps.\n",
137 (unsigned long long) (FILESIZE * 1000000LL / 139 (unsigned long long) (FILESIZE * 1000000LL /
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index 3546fdcb7..011087a57 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -685,7 +685,13 @@ enum GNUNET_FS_Status
685 * Notification that the unindexing of this file 685 * Notification that the unindexing of this file
686 * was stopped (final event for this action). 686 * was stopped (final event for this action).
687 */ 687 */
688 GNUNET_FS_STATUS_UNINDEX_STOPPED = 36 688 GNUNET_FS_STATUS_UNINDEX_STOPPED = 36,
689
690 /**
691 * Notification that we are making progress sharing a directory.
692 */
693 GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY = 37
694
689}; 695};
690 696
691 697
@@ -844,6 +850,33 @@ struct GNUNET_FS_ProgressInfo
844 850
845 /** 851 /**
846 * These values are only valid for 852 * These values are only valid for
853 * #GNUNET_FS_STATUS_PUBLISH_DIRECTORY_PROGRESS events.
854 */
855 struct
856 {
857
858 /**
859 * How far are we along in the overall directory?
860 */
861 uint64_t completed;
862
863 /**
864 * How big do we estimate the entire directory to be?
865 */
866 uint64_t total;
867
868 /**
869 * At what time do we expect to finish the upload of the
870 * CONTENTS of the directory. (The direcory itself will take
871 * extra time, indicated with the "eta" member at the
872 * "publish"-level of this struct.)
873 */
874 struct GNUNET_TIME_Relative eta;
875
876 } progress_directory;
877
878 /**
879 * These values are only valid for
847 * #GNUNET_FS_STATUS_PUBLISH_RESUME events. 880 * #GNUNET_FS_STATUS_PUBLISH_RESUME events.
848 */ 881 */
849 struct 882 struct