Updated filesystem traversal code to skip files/devices that don't

support attributes.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1325 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder
2002-10-01 07:26:11 +00:00
parent ef3fb6465d
commit 09dad369d7
2 changed files with 94 additions and 29 deletions
@@ -14,6 +14,9 @@
#include <RegistrarThread.h> #include <RegistrarThread.h>
#include <SupportDefs.h> #include <SupportDefs.h>
#include <list>
#include <pair.h>
struct entry_ref; struct entry_ref;
class BMessage; class BMessage;
@@ -38,7 +41,11 @@ protected:
const bool fForce; const bool fForce;
BMessage *fReplyee; BMessage *fReplyee;
bool DeviceSupportsAttributes(dev_t device);
private: private:
std::list< std::pair<dev_t, bool> > fAttributeSupportList;
status_t UpdateEntry(const entry_ref *ref); status_t UpdateEntry(const entry_ref *ref);
status_t fStatus; status_t fStatus;
+84 -26
View File
@@ -10,9 +10,11 @@
#include "mime/MimeUpdateThread.h" #include "mime/MimeUpdateThread.h"
#include <Directory.h> #include <Directory.h>
#include <kernel_interface.h>
#include <Message.h> #include <Message.h>
#include <Path.h> #include <Path.h>
#include <RegistrarDefs.h> #include <RegistrarDefs.h>
#include <Volume.h>
#include <stdio.h> #include <stdio.h>
@@ -60,6 +62,7 @@ MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority, BMessenger
*/ */
MimeUpdateThread::~MimeUpdateThread() MimeUpdateThread::~MimeUpdateThread()
{ {
// delete our acquired BMessage
if (InitCheck() == B_OK) if (InitCheck() == B_OK)
delete fReplyee; delete fReplyee;
} }
@@ -110,6 +113,53 @@ MimeUpdateThread::ThreadFunction()
find_thread(NULL), err)); find_thread(NULL), err));
} }
// DeviceSupportsAttributes
/*! \brief Returns true if the given device supports attributes, false
if not (or if an error occurs while determining).
Device numbers and their corresponding support info are cached in
a std::list to save unnecessarily \c statvfs()ing devices that have
already been statvfs()ed (which might otherwise happen quite often
for a device that did in fact support attributes).
\return
- \c true: The device supports attributes
- \c false: The device does not support attributes, or there was an
error while determining
*/
bool
MimeUpdateThread::DeviceSupportsAttributes(dev_t device)
{
// See if an entry for this device already exists
std::list< std::pair<dev_t,bool> >::iterator i;
for (i = fAttributeSupportList.begin();
i != fAttributeSupportList.end();
i++)
{
if (i->first == device)
return i->second;
}
bool result = false;
// If we get here, no such device is yet in our list,
// so we attempt to remedy the situation
BVolume volume;
status_t err = volume.SetTo(device);
if (!err) {
result = volume.KnowsAttr();
// devices supporting attributes are likely to be queried
// again, devices not supporting attributes are not
std::pair<dev_t,bool> p(device, result);
if (result)
fAttributeSupportList.push_front(p);
else
fAttributeSupportList.push_back(p);
}
return result;
}
// UpdateEntry // UpdateEntry
/*! \brief Updates the given entry and then recursively updates all the entry's child /*! \brief Updates the given entry and then recursively updates all the entry's child
entries if the entry is a directory and \c fRecursive is true. entries if the entry is a directory and \c fRecursive is true.
@@ -120,36 +170,44 @@ MimeUpdateThread::UpdateEntry(const entry_ref *ref)
status_t err = ref ? B_OK : B_BAD_VALUE; status_t err = ref ? B_OK : B_BAD_VALUE;
bool entryIsDir = false; bool entryIsDir = false;
// Update this entry
if (!err) {
DoMimeUpdate(ref, &entryIsDir);
// err = DoMimeUpdate(ref, &entryIsDir);
/* BPath path(ref);
printf("Updating '%s'... ", path.Path());
fflush(stdout);
printf("0x%lx\n", DoMimeUpdate(ref, &entryIsDir));
*/
}
// Look to see if we're being terminated // Look to see if we're being terminated
if (!err && fShouldExit) if (!err && fShouldExit)
err = B_CANCELED; err = B_CANCELED;
// If we're recursing and this is a directory, update
// each of the directory's children as well // Before we update, make sure this entry lives on a device that supports
if (!err && fRecursive && entryIsDir) { // attributes. If not, we skip it and any of its children for
BDirectory dir; // updates (we don't signal an error, however).
err = dir.SetTo(ref);
//BPath path(ref);
//printf("Updating '%s' (%s)... \n", path.Path(),
// (DeviceSupportsAttributes(ref->device) ? "yes" : "no"));
if (!err
&& (device_is_root_device(ref->device)
|| DeviceSupportsAttributes(ref->device))) {
// Update this entry
if (!err) { if (!err) {
entry_ref childRef; // R5 appears to ignore whether or not the update succeeds.
while (!err) { DoMimeUpdate(ref, &entryIsDir);
err = dir.GetNextRef(&childRef); }
if (err) { // If we're recursing and this is a directory, update
// If we've come to the end of the directory listing, // each of the directory's children as well
// it's not an error. if (!err && fRecursive && entryIsDir) {
if (err == B_ENTRY_NOT_FOUND) BDirectory dir;
err = B_OK; err = dir.SetTo(ref);
break; if (!err) {
} else { entry_ref childRef;
err = UpdateEntry(&childRef); while (!err) {
err = dir.GetNextRef(&childRef);
if (err) {
// If we've come to the end of the directory listing,
// it's not an error.
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
err = UpdateEntry(&childRef);
}
} }
} }
} }