* 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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user