Skip to content

Commit

Permalink
summarize: Ignore stat errors during summarisation, increment a count…
Browse files Browse the repository at this point in the history
…er instead.
  • Loading branch information
ned14 committed Dec 14, 2021
1 parent fba45d6 commit 2a4b255
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 12 deletions.
6 changes: 3 additions & 3 deletions include/llfio/revision.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
#define LLFIO_PREVIOUS_COMMIT_REF 713b9dc878eeaf457e990386414466b8c4e334d5
#define LLFIO_PREVIOUS_COMMIT_DATE "2021-12-01 11:52:21 +00:00"
#define LLFIO_PREVIOUS_COMMIT_UNIQUE 713b9dc8
#define LLFIO_PREVIOUS_COMMIT_REF fba45d6bacbdc7710e257a0b3d229fe3ef3a1f5d
#define LLFIO_PREVIOUS_COMMIT_DATE "2021-12-14 16:26:38 +00:00"
#define LLFIO_PREVIOUS_COMMIT_UNIQUE fba45d6b
44 changes: 35 additions & 9 deletions include/llfio/v2.0/algorithm/summarize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace algorithm
}
template <class T> using map_type = std::unordered_map<T, size_t>;
spinlock _lock;
size_t stats_failed{0}; //!< The number of handle stat's which failed.
size_t directory_opens_failed{0}; //!< The number of directories which could not be opened.

stat_t::want want{stat_t::want::none}; //!< The summary items desired
Expand Down Expand Up @@ -151,21 +152,43 @@ namespace algorithm
*/
struct summarize_visitor : public traverse_visitor
{
static result<void> accumulate(traversal_summary &acc, traversal_summary *state, const directory_handle *dirh, directory_entry &entry,
stat_t::want already_have_metadata)
static void accumulate(traversal_summary &acc, traversal_summary *state, const directory_handle *dirh, directory_entry &entry,
stat_t::want already_have_metadata)
{
if((state->want & already_have_metadata) != state->want)
{
// Fetch any missing metadata
if(entry.stat.st_type == filesystem::file_type::directory)
{
OUTCOME_TRY(auto &&fh, directory_handle::directory(*dirh, entry.leafname, file_handle::mode::attr_read));
OUTCOME_TRY(entry.stat.fill(fh, state->want & ~already_have_metadata));
if(auto fh = directory_handle::directory(*dirh, entry.leafname, file_handle::mode::attr_read))
{
if(!entry.stat.fill(fh.assume_value(), state->want & ~already_have_metadata))
{
acc.stats_failed++;
return;
}
}
else
{
acc.stats_failed++;
return;
}
}
else
{
OUTCOME_TRY(auto &&fh, file_handle::file(*dirh, entry.leafname, file_handle::mode::attr_read));
OUTCOME_TRY(entry.stat.fill(fh, state->want & ~already_have_metadata));
if(auto fh = file_handle::file(*dirh, entry.leafname, file_handle::mode::attr_read))
{
if(!entry.stat.fill(fh.assume_value(), state->want & ~already_have_metadata))
{
acc.stats_failed++;
return;
}
}
else
{
acc.stats_failed++;
return;
}
}
}
if(state->want & stat_t::want::dev)
Expand Down Expand Up @@ -195,7 +218,6 @@ namespace algorithm
acc.file_blocks += entry.stat.st_blocks;
}
}
return success();
}

//! This override ignores failures to traverse into the directory.
Expand All @@ -221,7 +243,7 @@ namespace algorithm
acc.max_depth = depth;
for(auto &entry : contents)
{
OUTCOME_TRY(accumulate(acc, state, &dirh, entry, contents.metadata()));
accumulate(acc, state, &dirh, entry, contents.metadata());
}
state->operator+=(acc);
return success();
Expand All @@ -241,6 +263,9 @@ namespace algorithm
what metadata `directory_handle::read()` returns, performance will be considerably
better. The default summarises all possible metadata.
Most errors during summary are accumulated into `stats_failed` and `directory_opens_failed`,
rather than failing the summary.
This is a trivial implementation on top of `algorithm::traverse()`, indeed it is
implemented entirely as header code. You should review the documentation for
`algorithm::traverse()`, as this algorithm is entirely implemented using that algorithm.
Expand All @@ -263,8 +288,9 @@ namespace algorithm
OUTCOME_TRY(_dirh, directory_handle::directory(topdirh, {}));
}
const path_handle &dirh = _dirh.is_valid() ? _dirh : topdirh;
// We should fail here if we can't stat topdirh
OUTCOME_TRY(entry.stat.fill(dirh, want));
OUTCOME_TRY(summarize_visitor::accumulate(state.assume_value(), &state.assume_value(), nullptr, entry, want));
summarize_visitor::accumulate(state.assume_value(), &state.assume_value(), nullptr, entry, want);
OUTCOME_TRY(traverse(dirh, visitor, threads, &state.assume_value(), force_slow_path));
return state;
}
Expand Down

0 comments on commit 2a4b255

Please sign in to comment.