* takes into account volume label

* clean up
* directories don't seem to have a valid contiguous flag, fixes directories with many files.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40431 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2011-02-10 19:49:12 +00:00
parent 129e6b943f
commit ce9fdaeae4
4 changed files with 56 additions and 20 deletions
@@ -140,7 +140,8 @@ DirectoryIterator::Rewind()
void void
DirectoryIterator::Iterate(EntryVisitor &visitor) DirectoryIterator::Iterate(EntryVisitor &visitor)
{ {
Rewind(); fOffset = 0;
fCluster = fInode->StartCluster();
while (_NextEntry() != B_ENTRY_NOT_FOUND) { while (_NextEntry() != B_ENTRY_NOT_FOUND) {
switch (fCurrent->type) { switch (fCurrent->type) {
@@ -45,10 +45,9 @@ Inode::Inode(Volume* volume, cluster_t cluster, uint32 offset)
fFileEntry.file.SetAttribs(EXFAT_ENTRY_ATTRIB_SUBDIR); fFileEntry.file.SetAttribs(EXFAT_ENTRY_ATTRIB_SUBDIR);
fFileEntry.file_info.SetStartCluster(Cluster()); fFileEntry.file_info.SetStartCluster(Cluster());
fFileInfoEntry.file_info.SetFlag(0); fFileInfoEntry.file_info.SetFlag(0);
} else } else {
fInitStatus = UpdateNodeFromDisk(); fInitStatus = UpdateNodeFromDisk();
if (fInitStatus == B_OK) { if (fInitStatus == B_OK && !IsDirectory() && !IsSymLink()) {
if (!IsDirectory() && !IsSymLink()) {
fCache = file_cache_create(fVolume->ID(), ID(), Size()); fCache = file_cache_create(fVolume->ID(), ID(), Size());
fMap = file_map_create(fVolume->ID(), ID(), Size()); fMap = file_map_create(fVolume->ID(), ID(), Size());
} }
@@ -76,20 +75,17 @@ Inode::Inode(Volume* volume, ino_t ino)
TRACE("Inode::Inode(%" B_PRIdINO ") cluster %ld\n", ID(), Cluster()); TRACE("Inode::Inode(%" B_PRIdINO ") cluster %ld\n", ID(), Cluster());
_Init(); _Init();
if (fInitStatus == B_OK && ID() != 1) if (fInitStatus == B_OK && ID() != 1) {
fInitStatus = UpdateNodeFromDisk(); fInitStatus = UpdateNodeFromDisk();
else if (fInitStatus == B_OK && ID() == 1) {
fFileEntry.file.SetAttribs(EXFAT_ENTRY_ATTRIB_SUBDIR);
fFileInfoEntry.file_info.SetStartCluster(Cluster());
fFileInfoEntry.file_info.SetFlag(0);
}
if (fInitStatus == B_OK) {
if (!IsDirectory() && !IsSymLink()) { if (!IsDirectory() && !IsSymLink()) {
fCache = file_cache_create(fVolume->ID(), ID(), Size()); fCache = file_cache_create(fVolume->ID(), ID(), Size());
fMap = file_map_create(fVolume->ID(), ID(), Size()); fMap = file_map_create(fVolume->ID(), ID(), Size());
} }
} else if (fInitStatus == B_OK && ID() == 1) {
fFileEntry.file.SetAttribs(EXFAT_ENTRY_ATTRIB_SUBDIR);
fFileInfoEntry.file_info.SetStartCluster(Cluster());
fFileInfoEntry.file_info.SetFlag(0);
} }
TRACE("Inode::Inode(%" B_PRIdINO ") end\n", ID());
} }
@@ -124,7 +120,6 @@ Inode::InitCheck()
status_t status_t
Inode::UpdateNodeFromDisk() Inode::UpdateNodeFromDisk()
{ {
DirectoryIterator iterator(this); DirectoryIterator iterator(this);
iterator.LookupEntry(this); iterator.LookupEntry(this);
return B_OK; return B_OK;
@@ -134,7 +129,7 @@ Inode::UpdateNodeFromDisk()
cluster_t cluster_t
Inode::NextCluster(cluster_t cluster) const Inode::NextCluster(cluster_t cluster) const
{ {
if (!IsContiguous()) if (!IsContiguous() || IsDirectory())
return GetVolume()->NextCluster(cluster); return GetVolume()->NextCluster(cluster);
return cluster + 1; return cluster + 1;
} }
@@ -22,6 +22,7 @@
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include "CachedBlock.h" #include "CachedBlock.h"
#include "encodings.h"
#include "Inode.h" #include "Inode.h"
@@ -198,6 +199,38 @@ DeviceOpener::GetSize(off_t* _size, uint32* _blockSize)
// #pragma mark - // #pragma mark -
class LabelVisitor : public EntryVisitor {
public:
LabelVisitor(Volume* volume);
bool VisitLabel(struct exfat_entry*);
private:
Volume* fVolume;
};
LabelVisitor::LabelVisitor(Volume* volume)
:
fVolume(volume)
{
}
bool
LabelVisitor::VisitLabel(struct exfat_entry* entry)
{
dprintf("LabelVisitor::VisitLabel()\n");
char utfName[30];
size_t utfLength = 30;
unicode_to_utf8((const uchar*)entry->name_label.name,
entry->name_label.length * 2, (uint8*)utfName, &utfLength);
fVolume->SetName(utfName);
return true;
}
// #pragma mark -
bool bool
exfat_super_block::IsValid() exfat_super_block::IsValid()
{ {
@@ -228,6 +261,7 @@ Volume::Volume(fs_volume* volume)
mutex_init(&fLock, "exfat volume"); mutex_init(&fLock, "exfat volume");
fInodesClusterTree = new InodesClusterTree; fInodesClusterTree = new InodesClusterTree;
fInodesInoTree = new InodesInoTree; fInodesInoTree = new InodesInoTree;
memset(fName, 0, sizeof(fName));
} }
@@ -249,7 +283,6 @@ Volume::IsValidSuperBlock()
const char* const char*
Volume::Name() const Volume::Name() const
{ {
/* TODO volume name is in the root directory */
return fName; return fName;
} }
@@ -321,7 +354,11 @@ Volume::Mount(const char* deviceName, uint32 flags)
// all went fine // all went fine
opener.Keep(); opener.Keep();
/*if (!fSuperBlock.label[0]) {*/ DirectoryIterator iterator(fRootNode);
LabelVisitor visitor(this);
iterator.Iterate(visitor);
if (fName[0] == '\0') {
// generate a more or less descriptive volume name // generate a more or less descriptive volume name
off_t divisor = 1ULL << 40; off_t divisor = 1ULL << 40;
char unit = 'T'; char unit = 'T';
@@ -339,7 +376,7 @@ Volume::Mount(const char* deviceName, uint32 flags)
snprintf(fName, sizeof(fName), "%g %cB ExFAT Volume", snprintf(fName, sizeof(fName), "%g %cB ExFAT Volume",
size / 10, unit); size / 10, unit);
//} }
return B_OK; return B_OK;
} }
@@ -8,6 +8,7 @@
#include <lock.h> #include <lock.h>
#include <string.h>
#include "exfat.h" #include "exfat.h"
#include "SplayTree.h" #include "SplayTree.h"
@@ -108,6 +109,8 @@ public:
{ return fFSVolume ? fFSVolume->id : -1; } { return fFSVolume ? fFSVolume->id : -1; }
fs_volume* FSVolume() const { return fFSVolume; } fs_volume* FSVolume() const { return fFSVolume; }
const char* Name() const; const char* Name() const;
void SetName(const char* name)
{ strlcpy(fName, name, sizeof(fName)); }
uint32 BlockSize() const { return fBlockSize; } uint32 BlockSize() const { return fBlockSize; }
uint32 EntriesPerBlock() const uint32 EntriesPerBlock() const
@@ -149,8 +152,8 @@ private:
ino_t fNextId; ino_t fNextId;
void* fBlockCache; void* fBlockCache;
InodesInoTree* fInodesInoTree; InodesInoTree* fInodesInoTree;
InodesClusterTree* fInodesClusterTree; InodesClusterTree* fInodesClusterTree;
NodeTree fNodeTree; NodeTree fNodeTree;
InoTree fInoTree; InoTree fInoTree;
}; };