[haiku-commits] haiku: hrev49558 - in src: apps/debuganalyzer/model_loader system/kernel/fs apps/debuganalyzer/gui/main_window apps/debuganalyzer/gui/thread_window apps/debuganalyzer/gui/chart

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 20 Aug 2015 21:50:10 +0200 (CEST)

hrev49558 adds 3 changesets to branch 'master'
old head: 36ab52c74eb0e51bc6540dfc3f1dd5a26bd779f0
new head: 44b69ccbdb65be0ee0f6ececa9279397f8908d84
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=44b69ccbdb65+%5E36ab52c74eb0

----------------------------------------------------------------------------

883b3e1d5cd6: DebugAnalyzer: Fix 64 bit build.

efb0a3a85355: EntryCache: Add entry_cache_add_missing() for negative caching.

It provides a way for filesystems to cache a lookup failure and
therefore prevents repeated lookups of missing entries. This is a
common scenario for example in command lookup and compiling, where
each directory in PATH or each include directory is searched for the
given entry.

44b69ccbdb65: bfs: Use negative caching on directory lookup failures.

[ Michael Lotz <mmlr@xxxxxxxx> ]

----------------------------------------------------------------------------

21 files changed, 109 insertions(+), 56 deletions(-)
headers/os/drivers/fs_cache.h | 2 +
headers/private/fs_shell/fssh_api_wrapper.h | 1 +
headers/private/fs_shell/fssh_fs_cache.h | 2 +
.../kernel/file_systems/bfs/kernel_interface.cpp | 3 ++
.../userlandfs/server/haiku/entry_cache.cpp | 7 ++++
src/apps/debuganalyzer/DebugAnalyzer.cpp | 8 ++--
.../gui/chart/BigtimeChartAxisLegendSource.cpp | 2 +-
.../debuganalyzer/gui/chart/LegendChartAxis.cpp | 2 +-
.../gui/chart/NanotimeChartAxisLegendSource.cpp | 2 +-
.../gui/main_window/GeneralPage.cpp | 4 +-
.../gui/main_window/SchedulingPage.cpp | 17 +++++----
.../gui/main_window/ThreadsPage.cpp | 4 +-
.../gui/thread_window/GeneralPage.cpp | 10 ++---
.../gui/thread_window/ThreadWindow.cpp | 4 +-
src/apps/debuganalyzer/model/Model.cpp | 6 +--
.../debuganalyzer/model_loader/ModelLoader.cpp | 39 +++++++++++---------
.../model_loader/ThreadModelLoader.cpp | 4 +-
src/system/kernel/fs/EntryCache.cpp | 10 ++++-
src/system/kernel/fs/EntryCache.h | 5 ++-
src/system/kernel/fs/vfs.cpp | 24 ++++++++++--
src/tools/fs_shell/vfs.cpp | 9 +++++

############################################################################

Commit: 883b3e1d5cd632bb1a86def5d39a3eebf32ace13
URL: http://cgit.haiku-os.org/haiku/commit/?id=883b3e1d5cd6
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Mon Aug 17 19:51:30 2015 UTC

DebugAnalyzer: Fix 64 bit build.

----------------------------------------------------------------------------

diff --git a/src/apps/debuganalyzer/DebugAnalyzer.cpp
b/src/apps/debuganalyzer/DebugAnalyzer.cpp
index d800cfb..d319604 100644
--- a/src/apps/debuganalyzer/DebugAnalyzer.cpp
+++ b/src/apps/debuganalyzer/DebugAnalyzer.cpp
@@ -38,11 +38,11 @@ printf("ReadyToRun()\n");
PostMessage(B_QUIT_REQUESTED);
}

- virtual void ArgvReceived(int32 argc, char** argv)
+ virtual void ArgvReceived(int32 argc, char** argv)
{
-printf("ArgvReceived()\n");
-for (int32 i = 0; i < argc; i++)
-printf(" arg %ld: \"%s\"\n", i, argv[i]);
+ printf("ArgvReceived()\n");
+ for (int32 i = 0; i < argc; i++)
+ printf(" arg %" B_PRId32 ": \"%s\"\n", i, argv[i]);

for (int32 i = 1; i < argc; i++) {
PathDataSource* dataSource = new(std::nothrow)
PathDataSource;
diff --git a/src/apps/debuganalyzer/gui/chart/BigtimeChartAxisLegendSource.cpp
b/src/apps/debuganalyzer/gui/chart/BigtimeChartAxisLegendSource.cpp
index 2a58e07..364c50e 100644
--- a/src/apps/debuganalyzer/gui/chart/BigtimeChartAxisLegendSource.cpp
+++ b/src/apps/debuganalyzer/gui/chart/BigtimeChartAxisLegendSource.cpp
@@ -59,7 +59,7 @@ BigtimeChartAxisLegendSource::GetAxisLegends(const
ChartDataRange& range,
decomposed_bigtime decomposed;
decompose_time(time, decomposed);
char buffer[128];
- snprintf(buffer, sizeof(buffer), "%02lld:%02d:%02d.%06d",
+ snprintf(buffer, sizeof(buffer), "%02" B_PRIu64
":%02d:%02d.%06d",
decomposed.hours, decomposed.minutes,
decomposed.seconds,
decomposed.micros);
// TODO: Drop superfluous micro seconds digits, or even microseconds and
seconds
diff --git a/src/apps/debuganalyzer/gui/chart/LegendChartAxis.cpp
b/src/apps/debuganalyzer/gui/chart/LegendChartAxis.cpp
index 035f3d1..c8bbc34 100644
--- a/src/apps/debuganalyzer/gui/chart/LegendChartAxis.cpp
+++ b/src/apps/debuganalyzer/gui/chart/LegendChartAxis.cpp
@@ -89,7 +89,7 @@ LegendChartAxis::_FilterLegends(int32 totalSize, int32
spacing,
// Filter out all higher level legends colliding with lower level or
// preceeding same-level legends. We iterate backwards from the lower to
// the higher levels
- for (int32 level = std::max(minLevel, 0L); level <= maxLevel;) {
+ for (int32 level = std::max(minLevel, (int32)0); level <= maxLevel;) {
legendCount = fLegends.CountItems();

// get the first legend position/end
diff --git a/src/apps/debuganalyzer/gui/chart/NanotimeChartAxisLegendSource.cpp
b/src/apps/debuganalyzer/gui/chart/NanotimeChartAxisLegendSource.cpp
index 49ebd4a..1e234b0 100644
--- a/src/apps/debuganalyzer/gui/chart/NanotimeChartAxisLegendSource.cpp
+++ b/src/apps/debuganalyzer/gui/chart/NanotimeChartAxisLegendSource.cpp
@@ -60,7 +60,7 @@ NanotimeChartAxisLegendSource::GetAxisLegends(const
ChartDataRange& range,
decomposed_nanotime decomposed;
decompose_time(time, decomposed);
char buffer[128];
- snprintf(buffer, sizeof(buffer), "%02lld:%02d:%02d.%09d",
+ snprintf(buffer, sizeof(buffer), "%02" B_PRId64
":%02d:%02d.%09d",
decomposed.hours, decomposed.minutes,
decomposed.seconds,
decomposed.nanos);
// TODO: Drop superfluous nanoseconds digits, or even nanoseconds and seconds
diff --git a/src/apps/debuganalyzer/gui/main_window/GeneralPage.cpp
b/src/apps/debuganalyzer/gui/main_window/GeneralPage.cpp
index b1df7de..6511319 100644
--- a/src/apps/debuganalyzer/gui/main_window/GeneralPage.cpp
+++ b/src/apps/debuganalyzer/gui/main_window/GeneralPage.cpp
@@ -68,11 +68,11 @@ MainWindow::GeneralPage::SetModel(Model* model)
fIdleTimeView->SetText(buffer);

// team count
- snprintf(buffer, sizeof(buffer), "%ld", fModel->CountTeams());
+ snprintf(buffer, sizeof(buffer), "%" B_PRId32,
fModel->CountTeams());
fTeamCountView->SetText(buffer);

// threads
- snprintf(buffer, sizeof(buffer), "%ld", fModel->CountThreads());
+ snprintf(buffer, sizeof(buffer), "%" B_PRId32,
fModel->CountThreads());
fThreadCountView->SetText(buffer);
} else {
fDataSourceView->SetText("");
diff --git a/src/apps/debuganalyzer/gui/main_window/SchedulingPage.cpp
b/src/apps/debuganalyzer/gui/main_window/SchedulingPage.cpp
index 49a798b..5def814 100644
--- a/src/apps/debuganalyzer/gui/main_window/SchedulingPage.cpp
+++ b/src/apps/debuganalyzer/gui/main_window/SchedulingPage.cpp
@@ -318,7 +318,7 @@ protected:
int32 lineHeight = (int32)fFontInfo.lineHeight;
minLine = (int32)rect.top / lineHeight;
maxLine = ((int32)ceilf(rect.bottom) + lineHeight - 1) /
lineHeight;
- minLine = std::max(minLine, 0L);
+ minLine = std::max(minLine, (int32)0);
maxLine = std::min(maxLine, CountLines() - 1);
}

@@ -1449,7 +1449,8 @@ printf("failed to read event!\n");
Model::ThreadSchedulingState* thread = fState.LookupThread(
event->thread);
if (thread == NULL) {
- printf("Schedule event for unknown thread: %ld\n",
event->thread);
+ printf("Schedule event for unknown thread: %" B_PRId32
"\n",
+ event->thread);
return;
}

@@ -1464,8 +1465,8 @@ printf("failed to read event!\n");

thread = fState.LookupThread(event->previous_thread);
if (thread == NULL) {
- printf("Schedule event for unknown previous thread:
%ld\n",
- event->previous_thread);
+ printf("Schedule event for unknown previous thread: %"
B_PRId32
+ "\n", event->previous_thread);
return;
}

@@ -1529,8 +1530,8 @@ printf("failed to read event!\n");
Model::ThreadSchedulingState* thread = fState.LookupThread(
event->thread);
if (thread == NULL) {
- printf("Enqueued in run queue event for unknown thread:
%ld\n",
- event->thread);
+ printf("Enqueued in run queue event for unknown thread:
%" B_PRId32
+ "\n", event->thread);
return;
}

@@ -1559,8 +1560,8 @@ printf("failed to read event!\n");
Model::ThreadSchedulingState* thread = fState.LookupThread(
event->thread);
if (thread == NULL) {
- printf("Removed from run queue event for unknown
thread: %ld\n",
- event->thread);
+ printf("Removed from run queue event for unknown
thread: %" B_PRId32
+ "\n", event->thread);
return;
}

diff --git a/src/apps/debuganalyzer/gui/main_window/ThreadsPage.cpp
b/src/apps/debuganalyzer/gui/main_window/ThreadsPage.cpp
index 88e9965..80e9180 100644
--- a/src/apps/debuganalyzer/gui/main_window/ThreadsPage.cpp
+++ b/src/apps/debuganalyzer/gui/main_window/ThreadsPage.cpp
@@ -51,8 +51,8 @@ public:
{
char buffer[128];
Model::Team* team = thread->GetTeam();
- snprintf(buffer, sizeof(buffer), "%s (%ld)",
team->Name(),
- team->ID());
+ snprintf(buffer, sizeof(buffer), "%s (%"
B_PRId32 ")",
+ team->Name(), team->ID());
value.SetTo(buffer);
return true;
}
diff --git a/src/apps/debuganalyzer/gui/thread_window/GeneralPage.cpp
b/src/apps/debuganalyzer/gui/thread_window/GeneralPage.cpp
index a0d17eb..017afe7 100644
--- a/src/apps/debuganalyzer/gui/thread_window/GeneralPage.cpp
+++ b/src/apps/debuganalyzer/gui/thread_window/GeneralPage.cpp
@@ -55,7 +55,7 @@ ThreadWindow::GeneralPage::SetModel(Model* model,
Model::Thread* thread)

// ID
char buffer[128];
- snprintf(buffer, sizeof(buffer), "%ld", fThread->ID());
+ snprintf(buffer, sizeof(buffer), "%" B_PRId32, fThread->ID());
fThreadIDView->SetText(buffer);

// team
@@ -65,28 +65,28 @@ ThreadWindow::GeneralPage::SetModel(Model* model,
Model::Thread* thread)
char timeBuffer[64];
format_nanotime(fThread->TotalRunTime(), timeBuffer,
sizeof(timeBuffer));
- snprintf(buffer, sizeof(buffer), "%s (%lld)", timeBuffer,
+ snprintf(buffer, sizeof(buffer), "%s (%" B_PRId64 ")",
timeBuffer,
fThread->Runs());
fRunTimeView->SetText(buffer);

// wait time
format_nanotime(fThread->TotalWaitTime(), timeBuffer,
sizeof(timeBuffer));
- snprintf(buffer, sizeof(buffer), "%s (%lld)", timeBuffer,
+ snprintf(buffer, sizeof(buffer), "%s (%" B_PRId64 ")",
timeBuffer,
fThread->Waits());
fWaitTimeView->SetText(buffer);

// latencies
format_nanotime(fThread->TotalLatency(), timeBuffer,
sizeof(timeBuffer));
- snprintf(buffer, sizeof(buffer), "%s (%lld)", timeBuffer,
+ snprintf(buffer, sizeof(buffer), "%s (%" B_PRId64 ")",
timeBuffer,
fThread->Latencies());
fLatencyView->SetText(buffer);

// preemptions
format_nanotime(fThread->TotalRerunTime(), timeBuffer,
sizeof(timeBuffer));
- snprintf(buffer, sizeof(buffer), "%s (%lld)", timeBuffer,
+ snprintf(buffer, sizeof(buffer), "%s (%" B_PRId64 ")",
timeBuffer,
fThread->Preemptions());
fPreemptionView->SetText(buffer);

diff --git a/src/apps/debuganalyzer/gui/thread_window/ThreadWindow.cpp
b/src/apps/debuganalyzer/gui/thread_window/ThreadWindow.cpp
index a3bba76..491b5b8 100644
--- a/src/apps/debuganalyzer/gui/thread_window/ThreadWindow.cpp
+++ b/src/apps/debuganalyzer/gui/thread_window/ThreadWindow.cpp
@@ -27,8 +27,8 @@ static BString
get_window_name(Model::Thread* thread)
{
char buffer[1024];
- snprintf(buffer, sizeof(buffer), "Thread: %s (%ld)", thread->Name(),
- thread->ID());
+ snprintf(buffer, sizeof(buffer), "Thread: %s (%" B_PRId32 ")",
+ thread->Name(), thread->ID());
return BString(buffer);
}

diff --git a/src/apps/debuganalyzer/model/Model.cpp
b/src/apps/debuganalyzer/model/Model.cpp
index f1e1f64..fe1119a 100644
--- a/src/apps/debuganalyzer/model/Model.cpp
+++ b/src/apps/debuganalyzer/model/Model.cpp
@@ -785,7 +785,7 @@ Model::AddTeam(const system_profiler_team_added* event,
nanotime_t time)
{
Team* team = TeamByID(event->team);
if (team != NULL) {
- fprintf(stderr, "Duplicate team: %ld\n", event->team);
+ fprintf(stderr, "Duplicate team: %" B_PRId32 "\n", event->team);
// TODO: User feedback!
return team;
}
@@ -830,7 +830,7 @@ Model::AddThread(const system_profiler_thread_added* event,
nanotime_t time)
// check whether we do already know the thread
Thread* thread = ThreadByID(event->thread);
if (thread != NULL) {
- fprintf(stderr, "Duplicate thread: %ld\n", event->thread);
+ fprintf(stderr, "Duplicate thread: %" B_PRId32 "\n",
event->thread);
// TODO: User feedback!
return thread;
}
@@ -838,7 +838,7 @@ Model::AddThread(const system_profiler_thread_added* event,
nanotime_t time)
// get its team
Team* team = TeamByID(event->team);
if (team == NULL) {
- fprintf(stderr, "No team for thread: %ld\n", event->thread);
+ fprintf(stderr, "No team for thread: %" B_PRId32 "\n",
event->thread);
return NULL;
}

diff --git a/src/apps/debuganalyzer/model_loader/ModelLoader.cpp
b/src/apps/debuganalyzer/model_loader/ModelLoader.cpp
index e8acbbf..7b75f2c 100644
--- a/src/apps/debuganalyzer/model_loader/ModelLoader.cpp
+++ b/src/apps/debuganalyzer/model_loader/ModelLoader.cpp
@@ -721,9 +721,9 @@ ModelLoader::_ProcessEvent(uint32 event, uint32 cpu, const
void* buffer,
break;

default:
-printf("unsupported event type %lu, size: %lu\n", event, size);
-return B_BAD_DATA;
- break;
+ printf("unsupported event type %" B_PRIu32 ", size: %"
B_PRIuSIZE
+ "\n", event, size);
+ return B_BAD_DATA;
}

return B_OK;
@@ -889,8 +889,10 @@
ModelLoader::_HandleTeamRemoved(system_profiler_team_removed* event)
{
if (Model::Team* team = fModel->TeamByID(event->team))
team->SetDeletionTime(fState->LastEventTime());
- else
- printf("Warning: Removed event for unknown team: %ld\n",
event->team);
+ else {
+ printf("Warning: Removed event for unknown team: %" B_PRId32
"\n",
+ event->team);
+ }
}


@@ -913,7 +915,7 @@
ModelLoader::_HandleThreadRemoved(system_profiler_thread_removed* event)
{
ExtendedThreadSchedulingState* thread =
fState->LookupThread(event->thread);
if (thread == NULL) {
- printf("Warning: Removed event for unknown thread: %ld\n",
+ printf("Warning: Removed event for unknown thread: %" B_PRId32
"\n",
event->thread);
thread = _AddUnknownThread(event->thread);
}
@@ -931,7 +933,7 @@ ModelLoader::_HandleThreadScheduled(uint32 cpu,

ExtendedThreadSchedulingState* thread =
fState->LookupThread(event->thread);
if (thread == NULL) {
- printf("Warning: Schedule event for unknown thread: %ld\n",
+ printf("Warning: Schedule event for unknown thread: %" B_PRId32
"\n",
event->thread);
thread = _AddUnknownThread(event->thread);
return;
@@ -966,8 +968,8 @@ ModelLoader::_HandleThreadScheduled(uint32 cpu,

thread = fState->LookupThread(event->previous_thread);
if (thread == NULL) {
- printf("Warning: Schedule event for unknown previous thread:
%ld\n",
- event->previous_thread);
+ printf("Warning: Schedule event for unknown previous thread: %"
B_PRId32
+ "\n", event->previous_thread);
thread = _AddUnknownThread(event->previous_thread);
}

@@ -1035,8 +1037,8 @@ ModelLoader::_HandleThreadEnqueuedInRunQueue(

ExtendedThreadSchedulingState* thread =
fState->LookupThread(event->thread);
if (thread == NULL) {
- printf("Warning: Enqueued in run queue event for unknown
thread: %ld\n",
- event->thread);
+ printf("Warning: Enqueued in run queue event for unknown
thread: %"
+ B_PRId32 "\n", event->thread);
thread = _AddUnknownThread(event->thread);
}

@@ -1073,7 +1075,7 @@ ModelLoader::_HandleThreadRemovedFromRunQueue(uint32 cpu,
ExtendedThreadSchedulingState* thread =
fState->LookupThread(event->thread);
if (thread == NULL) {
printf("Warning: Removed from run queue event for unknown
thread: "
- "%ld\n", event->thread);
+ "%" B_PRId32 "\n", event->thread);
thread = _AddUnknownThread(event->thread);
}

@@ -1112,8 +1114,8 @@
ModelLoader::_HandleIOSchedulerAdded(system_profiler_io_scheduler_added* event)
{
Model::IOScheduler* scheduler =
fModel->IOSchedulerByID(event->scheduler);
if (scheduler != NULL) {
- printf("Warning: Duplicate added event for I/O scheduler %ld\n",
- event->scheduler);
+ printf("Warning: Duplicate added event for I/O scheduler %"
B_PRId32
+ "\n", event->scheduler);
return;
}

@@ -1134,12 +1136,13 @@
ModelLoader::_HandleIORequestScheduled(io_request_scheduled* event)

ExtendedThreadSchedulingState* thread =
fState->LookupThread(event->thread);
if (thread == NULL) {
- printf("Warning: I/O request for unknown thread %ld\n",
event->thread);
+ printf("Warning: I/O request for unknown thread %" B_PRId32
"\n",
+ event->thread);
thread = _AddUnknownThread(event->thread);
}

if (fModel->IOSchedulerByID(event->scheduler) == NULL) {
- printf("Warning: I/O requests for unknown scheduler %ld\n",
+ printf("Warning: I/O requests for unknown scheduler %" B_PRId32
"\n",
event->scheduler);
// TODO: Add state for unknown scheduler, as we do for threads.
return;
@@ -1307,8 +1310,8 @@
ModelLoader::_AddThreadWaitObject(ExtendedThreadSchedulingState* thread,
= fModel->WaitObjectGroupFor(type, object);
if (waitObjectGroup == NULL) {
// The algorithm should prevent this case.
-printf("ModelLoader::_AddThreadWaitObject(): Unknown wait object: type: %lu, "
-"object: %#lx\n", type, object);
+ printf("ModelLoader::_AddThreadWaitObject(): Unknown wait
object: type:"
+ " %" B_PRIu32 ", " "object: %#" B_PRIxADDR "\n", type,
object);
return;
}

diff --git a/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp
b/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp
index 192abfd..3ff9a47 100644
--- a/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp
+++ b/src/apps/debuganalyzer/model_loader/ThreadModelLoader.cpp
@@ -114,9 +114,9 @@ ThreadModelLoader::_Load()

// create the groups
int32 waitObjectCount = waitObjects.CountItems();
-printf("%ld wait objects\n", waitObjectCount);
+ printf("%" B_PRId32 " wait objects\n", waitObjectCount);
for (int32 i = 0; i < waitObjectCount;) {
-printf("new wait object group at %ld\n", i);
+ printf("new wait object group at %" B_PRId32 "\n", i);
// collect the objects for this group
Model::ThreadWaitObject* firstObject = waitObjects.ItemAt(i);
int32 k = i + 1;

############################################################################

Commit: efb0a3a853557e69ecf2bc88adc9a69ed08d1514
URL: http://cgit.haiku-os.org/haiku/commit/?id=efb0a3a85355
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Mon Aug 17 20:13:59 2015 UTC

EntryCache: Add entry_cache_add_missing() for negative caching.

It provides a way for filesystems to cache a lookup failure and
therefore prevents repeated lookups of missing entries. This is a
common scenario for example in command lookup and compiling, where
each directory in PATH or each include directory is searched for the
given entry.

----------------------------------------------------------------------------

diff --git a/headers/os/drivers/fs_cache.h b/headers/os/drivers/fs_cache.h
index 6466769..9a71a5b 100644
--- a/headers/os/drivers/fs_cache.h
+++ b/headers/os/drivers/fs_cache.h
@@ -104,6 +104,8 @@ extern status_t file_map_translate(void *map, off_t offset,
size_t size,
/* entry cache */
extern status_t entry_cache_add(dev_t mountID, ino_t dirID, const char* name,
ino_t nodeID);
+extern status_t entry_cache_add_missing(dev_t mountID, ino_t dirID,
+ const char* name);
extern status_t entry_cache_remove(dev_t mountID, ino_t dirID,
const char* name);

diff --git a/headers/private/fs_shell/fssh_api_wrapper.h
b/headers/private/fs_shell/fssh_api_wrapper.h
index 337648f..1651b2a 100644
--- a/headers/private/fs_shell/fssh_api_wrapper.h
+++ b/headers/private/fs_shell/fssh_api_wrapper.h
@@ -871,6 +871,7 @@

/* entry cache */
#define entry_cache_add
fssh_entry_cache_add
+#define entry_cache_add_missing
fssh_entry_cache_add_missing
#define entry_cache_remove fssh_entry_cache_remove


////////////////////////////////////////////////////////////////////////////////
diff --git a/headers/private/fs_shell/fssh_fs_cache.h
b/headers/private/fs_shell/fssh_fs_cache.h
index 87eef13..88cc9a3 100644
--- a/headers/private/fs_shell/fssh_fs_cache.h
+++ b/headers/private/fs_shell/fssh_fs_cache.h
@@ -126,6 +126,8 @@ extern fssh_status_t fssh_file_map_translate(void
*_map, fssh_off_t offset,
extern fssh_status_t fssh_entry_cache_add(fssh_dev_t mountID,
fssh_ino_t dirID, const
char* name,
fssh_ino_t nodeID);
+extern fssh_status_t fssh_entry_cache_add_missing(fssh_dev_t mountID,
+ fssh_ino_t dirID, const
char* name);
extern fssh_status_t fssh_entry_cache_remove(fssh_dev_t mountID,
fssh_ino_t dirID, const
char* name);

diff --git
a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/entry_cache.cpp
b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/entry_cache.cpp
index 8ea12b8..7aa60ac 100644
--- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/entry_cache.cpp
+++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/entry_cache.cpp
@@ -18,6 +18,13 @@ entry_cache_add(dev_t mountID, ino_t dirID, const char*
name, ino_t nodeID)


status_t
+entry_cache_add_missing(dev_t mountID, ino_t dirID, const char* name)
+{
+ return B_OK;
+}
+
+
+status_t
entry_cache_remove(dev_t mountID, ino_t dirID, const char* name)
{
return B_OK;
diff --git a/src/system/kernel/fs/EntryCache.cpp
b/src/system/kernel/fs/EntryCache.cpp
index e9a6a14..63743b8 100644
--- a/src/system/kernel/fs/EntryCache.cpp
+++ b/src/system/kernel/fs/EntryCache.cpp
@@ -90,7 +90,7 @@ EntryCache::Init()


status_t
-EntryCache::Add(ino_t dirID, const char* name, ino_t nodeID)
+EntryCache::Add(ino_t dirID, const char* name, ino_t nodeID, bool missing)
{
EntryCacheKey key(dirID, name);

@@ -99,6 +99,7 @@ EntryCache::Add(ino_t dirID, const char* name, ino_t nodeID)
EntryCacheEntry* entry = fEntries.Lookup(key);
if (entry != NULL) {
entry->node_id = nodeID;
+ entry->missing = missing;
if (entry->generation != fCurrentGeneration) {
if (entry->index >= 0) {

fGenerations[entry->generation].entries[entry->index] = NULL;
@@ -114,6 +115,7 @@ EntryCache::Add(ino_t dirID, const char* name, ino_t nodeID)

entry->node_id = nodeID;
entry->dir_id = dirID;
+ entry->missing = missing;
entry->generation = fCurrentGeneration;
entry->index = kEntryNotInArray;
strcpy(entry->name, name);
@@ -155,7 +157,8 @@ EntryCache::Remove(ino_t dirID, const char* name)


bool
-EntryCache::Lookup(ino_t dirID, const char* name, ino_t& _nodeID)
+EntryCache::Lookup(ino_t dirID, const char* name, ino_t& _nodeID,
+ bool& _missing)
{
EntryCacheKey key(dirID, name);

@@ -171,6 +174,7 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t&
_nodeID)
// The entry is already in the current generation or is being
moved to
// it by another thread.
_nodeID = entry->node_id;
+ _missing = entry->missing;
return true;
}

@@ -184,6 +188,7 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t&
_nodeID)
fGenerations[fCurrentGeneration].entries[index] = entry;
entry->index = index;
_nodeID = entry->node_id;
+ _missing = entry->missing;
return true;
}

@@ -201,6 +206,7 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t&
_nodeID)
_AddEntryToCurrentGeneration(entry);

_nodeID = entry->node_id;
+ _missing = entry->missing;
return true;
}

diff --git a/src/system/kernel/fs/EntryCache.h
b/src/system/kernel/fs/EntryCache.h
index 79a8df0..4cbf865 100644
--- a/src/system/kernel/fs/EntryCache.h
+++ b/src/system/kernel/fs/EntryCache.h
@@ -36,6 +36,7 @@ struct EntryCacheEntry {
ino_t dir_id;
int32 generation;
int32 index;
+ bool missing;
char name[1];
};

@@ -87,12 +88,12 @@ public:
status_t Init();

status_t Add(ino_t dirID, const
char* name,
- ino_t
nodeID);
+ ino_t
nodeID, bool missing);

status_t Remove(ino_t dirID,
const char* name);

bool Lookup(ino_t dirID,
const char* name,
- ino_t&
nodeID);
+ ino_t&
nodeID, bool& missing);

const char*
DebugReverseLookup(ino_t nodeID, ino_t& _dirID);

diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp
index 6e98ac4..68f58c6 100644
--- a/src/system/kernel/fs/vfs.cpp
+++ b/src/system/kernel/fs/vfs.cpp
@@ -2089,9 +2089,12 @@ static status_t
lookup_dir_entry(struct vnode* dir, const char* name, struct vnode** _vnode)
{
ino_t id;
+ bool missing;

- if (dir->mount->entry_cache.Lookup(dir->id, name, id))
- return get_vnode(dir->device, id, _vnode, true, false);
+ if (dir->mount->entry_cache.Lookup(dir->id, name, id, missing)) {
+ return missing ? B_ENTRY_NOT_FOUND
+ : get_vnode(dir->device, id, _vnode, true, false);
+ }

status_t status = FS_CALL(dir, lookup, name, &id);
if (status != B_OK)
@@ -4011,7 +4014,22 @@ entry_cache_add(dev_t mountID, ino_t dirID, const char*
name, ino_t nodeID)
return B_BAD_VALUE;
locker.Unlock();

- return mount->entry_cache.Add(dirID, name, nodeID);
+ return mount->entry_cache.Add(dirID, name, nodeID, false);
+}
+
+
+extern "C" status_t
+entry_cache_add_missing(dev_t mountID, ino_t dirID, const char* name)
+{
+ // lookup mount -- the caller is required to make sure that the mount
+ // won't go away
+ MutexLocker locker(sMountMutex);
+ struct fs_mount* mount = find_mount(mountID);
+ if (mount == NULL)
+ return B_BAD_VALUE;
+ locker.Unlock();
+
+ return mount->entry_cache.Add(dirID, name, -1, true);
}


diff --git a/src/tools/fs_shell/vfs.cpp b/src/tools/fs_shell/vfs.cpp
index 9308a35..5137ddd 100644
--- a/src/tools/fs_shell/vfs.cpp
+++ b/src/tools/fs_shell/vfs.cpp
@@ -2278,6 +2278,15 @@ fssh_entry_cache_add(fssh_dev_t mountID, fssh_ino_t
dirID, const char* name,


extern "C" fssh_status_t
+fssh_entry_cache_add_missing(fssh_dev_t mountID, fssh_ino_t dirID,
+ const char* name)
+{
+ // We don't implement an entry cache in the FS shell.
+ return FSSH_B_OK;
+}
+
+
+extern "C" fssh_status_t
fssh_entry_cache_remove(fssh_dev_t mountID, fssh_ino_t dirID, const char* name)
{
// We don't implement an entry cache in the FS shell.

############################################################################

Revision: hrev49558
Commit: 44b69ccbdb65be0ee0f6ececa9279397f8908d84
URL: http://cgit.haiku-os.org/haiku/commit/?id=44b69ccbdb65
Author: Michael Lotz <mmlr@xxxxxxxx>
Date: Mon Aug 17 20:25:44 2015 UTC

bfs: Use negative caching on directory lookup failures.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
index c6c0f03..fe2478a 100644
--- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
@@ -587,6 +587,9 @@ bfs_lookup(fs_volume* _volume, fs_vnode* _directory, const
char* file,
status = tree->Find((uint8*)file, (uint16)strlen(file), _vnodeID);
if (status != B_OK) {
//PRINT(("bfs_walk() could not find %Ld:\"%s\": %s\n",
directory->BlockNumber(), file, strerror(status)));
+ if (status == B_ENTRY_NOT_FOUND)
+ entry_cache_add_missing(volume->ID(), directory->ID(),
file);
+
return status;
}



Other related posts: