* Removed DirectoryIterator.{h,cpp} and included them in Icp.{h,cpp}

* Porting Icb to new file cache system


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27017 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto
2008-08-18 09:40:42 +00:00
parent e7ada11b55
commit a412472546
5 changed files with 264 additions and 301 deletions
@@ -1,96 +0,0 @@
/*
* Copyright 2003, Tyler Dauwalder, [email protected].
* Distributed under the terms of the MIT License.
*/
/*! \file DirectoryIterator.cpp */
#include "DirectoryIterator.h"
#include "Icb.h"
#include "UdfString.h"
#include "Utils.h"
#include <dirent.h>
#include <stdio.h>
status_t
DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
{
DEBUG_INIT_ETC("DirectoryIterator",
("name: %p, length: %p, id: %p", name, length, id));
if (!id || !name || !length)
return B_BAD_VALUE;
PRINT(("fPosition: %Ld\n", fPosition));
PRINT(("Parent()->Length(): %Ld\n", Parent()->Length()));
status_t error = B_OK;
if (fAtBeginning) {
sprintf(name, ".");
*length = 2;
*id = Parent()->Id();
fAtBeginning = false;
} else {
if (uint64(fPosition) >= Parent()->Length())
RETURN(B_ENTRY_NOT_FOUND);
uint8 data[kMaxFileIdSize];
file_id_descriptor *entry = reinterpret_cast<file_id_descriptor*>(data);
uint32 block = 0;
off_t offset = fPosition;
size_t entryLength = kMaxFileIdSize;
// First read in the static portion of the file id descriptor,
// then, based on the information therein, read in the variable
// length tail portion as well.
error = Parent()->Read(offset, entry, &entryLength, &block);
if (!error && entryLength >= sizeof(file_id_descriptor)
&& entry->tag().init_check(block) == B_OK) {
PDUMP(entry);
offset += entry->total_length();
if (entry->is_parent()) {
sprintf(name, "..");
*length = 3;
} else {
UdfString string(entry->id(), entry->id_length());
PRINT(("id == `%s'\n", string.Utf8()));
DUMP(entry->icb());
sprintf(name, "%s", string.Utf8());
*length = string.Utf8Length();
}
*id = to_vnode_id(entry->icb());
}
if (!error)
fPosition = offset;
}
RETURN(error);
}
/* \brief Rewinds the iterator to point to the first entry in the directory. */
void
DirectoryIterator::Rewind()
{
fAtBeginning = true;
fPosition = 0;
}
// #pragma - Private methods
DirectoryIterator::DirectoryIterator(Icb *parent)
:
fAtBeginning(true),
fParent(parent),
fPosition(0)
{
}
@@ -1,40 +0,0 @@
/*
* Copyright 2003, Tyler Dauwalder, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _UDF_DIRECTORY_ITERATOR_H
#define _UDF_DIRECTORY_ITERATOR_H
/*! \file DirectoryIterator.h */
#include "UdfDebug.h"
#include <util/kernel_cpp.h>
class Icb;
class DirectoryIterator {
public:
status_t GetNextEntry(char *name, uint32 *length,
ino_t *id);
Icb *Parent() { return fParent; }
const Icb *Parent() const { return fParent; }
void Rewind();
private:
friend class Icb;
/* The following is called by Icb::GetDirectoryIterator() */
DirectoryIterator(Icb *parent);
/* The following is called by Icb::~Icb() */
void _Invalidate() { fParent = NULL; }
bool fAtBeginning;
Icb *fParent;
off_t fPosition;
};
#endif // _UDF_DIRECTORY_ITERATOR_H
+115 -31
View File
@@ -9,19 +9,98 @@
#include "time.h" #include "time.h"
#include "AllocationDescriptorList.h" #include "AllocationDescriptorList.h"
#include "DirectoryIterator.h"
#include "Utils.h" #include "Utils.h"
#include "Volume.h" #include "Volume.h"
using namespace Udf;
status_t
DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id)
{
DEBUG_INIT_ETC("DirectoryIterator",
("name: %p, length: %p, id: %p", name, length, id));
if (!id || !name || !length)
return B_BAD_VALUE;
PRINT(("fPosition: %Ld\n", fPosition));
PRINT(("Parent()->Length(): %Ld\n", Parent()->Length()));
status_t error = B_OK;
if (fAtBeginning) {
sprintf(name, ".");
*length = 2;
*id = Parent()->Id();
fAtBeginning = false;
} else {
if (uint64(fPosition) >= Parent()->Length())
RETURN(B_ENTRY_NOT_FOUND);
uint8 data[kMaxFileIdSize];
file_id_descriptor *entry = reinterpret_cast<file_id_descriptor*>(data);
uint32 block = 0;
off_t offset = fPosition;
size_t entryLength = kMaxFileIdSize;
// First read in the static portion of the file id descriptor,
// then, based on the information therein, read in the variable
// length tail portion as well.
error = Parent()->Read(offset, entry, &entryLength, &block);
if (!error && entryLength >= sizeof(file_id_descriptor)
&& entry->tag().init_check(block) == B_OK) {
PDUMP(entry);
offset += entry->total_length();
if (entry->is_parent()) {
sprintf(name, "..");
*length = 3;
} else {
UdfString string(entry->id(), entry->id_length());
PRINT(("id == `%s'\n", string.Utf8()));
DUMP(entry->icb());
sprintf(name, "%s", string.Utf8());
*length = string.Utf8Length();
}
*id = to_vnode_id(entry->icb());
}
if (!error)
fPosition = offset;
}
RETURN(error);
}
/* \brief Rewinds the iterator to point to the first entry in the directory. */
void
DirectoryIterator::Rewind()
{
fAtBeginning = true;
fPosition = 0;
}
// #pragma - Private methods
DirectoryIterator::DirectoryIterator(Icb *parent)
:
fAtBeginning(true),
fParent(parent),
fPosition(0)
{
}
Icb::Icb(Volume *volume, long_address address) Icb::Icb(Volume *volume, long_address address)
: fVolume(volume) :
, fData(volume) fVolume(volume),
, fInitStatus(B_NO_INIT) fData(volume),
, fId(to_vnode_id(address)) fInitStatus(B_NO_INIT),
, fFileEntry(&fData) fId(to_vnode_id(address)),
, fExtendedEntry(&fData) fFileEntry(&fData),
fExtendedEntry(&fData)
{ {
DEBUG_INIT_ETC("Icb", ("volume: %p, address(block: %ld, " DEBUG_INIT_ETC("Icb", ("volume: %p, address(block: %ld, "
"partition: %d, length: %ld)", volume, address.block(), "partition: %d, length: %ld)", volume, address.block(),
@@ -31,7 +110,7 @@ Icb::Icb(Volume *volume, long_address address)
off_t block; off_t block;
error = fVolume->MapBlock(address, &block); error = fVolume->MapBlock(address, &block);
if (!error) { if (!error) {
icb_header *header = reinterpret_cast<icb_header*>(fData.SetTo(block)); icb_header *header = (icb_header *)fData.SetTo(block);
if (header->tag().id() == TAGID_FILE_ENTRY) { if (header->tag().id() == TAGID_FILE_ENTRY) {
file_icb_entry *entry = reinterpret_cast<file_icb_entry*>(header); file_icb_entry *entry = reinterpret_cast<file_icb_entry*>(header);
PDUMP(entry); PDUMP(entry);
@@ -49,25 +128,46 @@ Icb::Icb(Volume *volume, long_address address)
fInitStatus = error; fInitStatus = error;
PRINT(("result: 0x%lx, `%s'\n", error, strerror(error))); PRINT(("result: 0x%lx, `%s'\n", error, strerror(error)));
} }
status_t
Icb::GetDirectoryIterator(DirectoryIterator **iterator)
{
status_t error = iterator ? B_OK : B_BAD_VALUE;
if (!error) {
*iterator = new(std::nothrow) DirectoryIterator(this);
if (*iterator)
fIteratorList.Add(*iterator);
else
error = B_NO_MEMORY;
}
return error;
}
status_t status_t
Icb::InitCheck() Icb::InitCheck()
{ {
return fInitStatus; return fInitStatus;
} }
time_t time_t
Icb::AccessTime() Icb::AccessTime()
{ {
return make_time(FileEntry()->access_date_and_time()); return make_time(_FileEntry()->access_date_and_time());
} }
time_t time_t
Icb::ModificationTime() Icb::ModificationTime()
{ {
return make_time(FileEntry()->modification_date_and_time()); return make_time(_FileEntry()->modification_date_and_time());
} }
status_t status_t
Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block) Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
{ {
@@ -82,7 +182,7 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
return B_OK; return B_OK;
} }
switch (IcbTag().descriptor_flags()) { switch (_IcbTag().descriptor_flags()) {
case ICB_DESCRIPTOR_TYPE_SHORT: { case ICB_DESCRIPTOR_TYPE_SHORT: {
PRINT(("descriptor type: short\n")); PRINT(("descriptor type: short\n"));
AllocationDescriptorList<ShortDescriptorAccessor> list(this, ShortDescriptorAccessor(0)); AllocationDescriptorList<ShortDescriptorAccessor> list(this, ShortDescriptorAccessor(0));
@@ -96,7 +196,7 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
RETURN(_Read(list, pos, buffer, length, block)); RETURN(_Read(list, pos, buffer, length, block));
break; break;
} }
case ICB_DESCRIPTOR_TYPE_EXTENDED: { case ICB_DESCRIPTOR_TYPE_EXTENDED: {
PRINT(("descriptor type: extended\n")); PRINT(("descriptor type: extended\n"));
// AllocationDescriptorList<ExtendedDescriptorAccessor> list(this, ExtendedDescriptorAccessor(0)); // AllocationDescriptorList<ExtendedDescriptorAccessor> list(this, ExtendedDescriptorAccessor(0));
@@ -112,28 +212,12 @@ Icb::Read(off_t pos, void *buffer, size_t *length, uint32 *block)
} }
default: default:
PRINT(("Invalid icb descriptor flags! (flags = %d)\n", IcbTag().descriptor_flags())); PRINT(("Invalid icb descriptor flags! (flags = %d)\n", _IcbTag().descriptor_flags()));
RETURN(B_BAD_VALUE); RETURN(B_BAD_VALUE);
break; break;
} }
} }
status_t
Icb::GetDirectoryIterator(DirectoryIterator **iterator)
{
status_t error = iterator ? B_OK : B_BAD_VALUE;
if (!error) {
*iterator = new(nothrow) DirectoryIterator(this);
if (*iterator) {
error = fIteratorList.PushBack(*iterator);
} else {
error = B_NO_MEMORY;
}
}
return error;
}
status_t status_t
Icb::Find(const char *filename, ino_t *id) Icb::Find(const char *filename, ino_t *id)
+149 -133
View File
@@ -1,41 +1,27 @@
//---------------------------------------------------------------------- /*
// This software is part of the Haiku distribution and is covered * Copyright 2008, Salvatore Benedetto, [email protected].
// by the MIT license. * Copyright 2003, Tyler Dauwalder, [email protected].
// * Distributed under the terms of the MIT License.
// Copyright (c) 2003 Tyler Dauwalder, [email protected] */
//---------------------------------------------------------------------
#ifndef _UDF_ICB_H #ifndef _UDF_ICB_H
#define _UDF_ICB_H #define _UDF_ICB_H
/*! \file Icb.h /*! \file Icb.h */
*/
#ifndef _IMPEXP_KERNEL #include "UdfStructures.h"
# define _IMPEXP_KERNEL
#endif
#ifdef COMPILE_FOR_R5
extern "C" {
#endif
#include "fsproto.h"
#ifdef COMPILE_FOR_R5
}
#endif
#include "kernel_cpp.h" #include <util/kernel_cpp.h>
#include "UdfDebug.h" #include <util/SinglyLinkedList.h>
#include "CachedBlock.h" #include "CachedBlock.h"
#include "UdfStructures.h"
#include "SinglyLinkedList.h"
namespace Udf {
class DirectoryIterator; class DirectoryIterator;
class Icb;
class Volume; class Volume;
/*! \brief Abstract interface to file entry structure members /*! \brief Abstract interface to file entry structure members
that are not commonly accessible through file_icb_entry(). that are not commonly accessible through file_icb_entry().
This is necessary, since we can't use virtual functions in This is necessary, since we can't use virtual functions in
the disk structure structs themselves, since we generally the disk structure structs themselves, since we generally
don't create disk structure objects by calling new, but don't create disk structure objects by calling new, but
@@ -46,86 +32,110 @@ class Volume;
*/ */
class AbstractFileEntry { class AbstractFileEntry {
public: public:
virtual uint8* AllocationDescriptors() = 0; virtual uint8* AllocationDescriptors() = 0;
virtual uint32 AllocationDescriptorsLength() = 0; virtual uint32 AllocationDescriptorsLength() = 0;
}; };
template <class Descriptor> template <class Descriptor>
class FileEntry : public AbstractFileEntry { class FileEntry : public AbstractFileEntry {
public: public:
FileEntry(CachedBlock *descriptorBlock = NULL); FileEntry(CachedBlock *descriptorBlock = NULL);
void SetTo(CachedBlock *descriptorBlock); void SetTo(CachedBlock *descriptorBlock);
virtual uint8* AllocationDescriptors(); virtual uint8* AllocationDescriptors();
virtual uint32 AllocationDescriptorsLength(); virtual uint32 AllocationDescriptorsLength();
private: private:
Descriptor* _Descriptor(); Descriptor *_Descriptor();
CachedBlock *fDescriptorBlock;
CachedBlock *fDescriptorBlock;
}; };
class DirectoryIterator : public SinglyLinkedListLinkImpl<DirectoryIterator> {
public:
status_t GetNextEntry(char *name, uint32 *length,
ino_t *id);
Icb *Parent() { return fParent; }
const Icb *Parent() const { return fParent; }
void Rewind();
private:
friend class Icb;
/* The following is called by Icb::GetDirectoryIterator() */
DirectoryIterator(Icb *parent);
/* The following is called by Icb::~Icb() */
void _Invalidate() { fParent = NULL; }
bool fAtBeginning;
Icb *fParent;
off_t fPosition;
};
class Icb { class Icb {
public: public:
Icb(Volume *volume, long_address address); Icb(Volume *volume, long_address address);
status_t InitCheck(); status_t InitCheck();
ino_t Id() { return fId; } ino_t Id() { return fId; }
// categorization // categorization
uint8 Type() { return IcbTag().file_type(); } uint8 Type() { return _IcbTag().file_type(); }
bool IsFile() { return InitCheck() == B_OK && Type() == ICB_TYPE_REGULAR_FILE; } bool IsFile() { return Type() == ICB_TYPE_REGULAR_FILE; }
bool IsDirectory() { return InitCheck() == B_OK bool IsDirectory() { return (Type() == ICB_TYPE_DIRECTORY
&& (Type() == ICB_TYPE_DIRECTORY || Type() == ICB_TYPE_STREAM_DIRECTORY); } || Type() == ICB_TYPE_STREAM_DIRECTORY); }
uint32 Uid() { return 0; }//FileEntry()->uid(); } uint32 Uid() { return _FileEntry()->uid(); }
uint32 Gid() { return 0; } uint32 Gid() { return 0; }
uint16 FileLinkCount() { return FileEntry()->file_link_count(); } uint16 FileLinkCount() { return _FileEntry()->file_link_count(); }
uint64 Length() { return FileEntry()->information_length(); } uint64 Length() { return _FileEntry()->information_length(); }
mode_t Mode() { return (IsDirectory() ? S_IFDIR : S_IFREG) | S_IRUSR | S_IRGRP | S_IROTH; } mode_t Mode() { return (IsDirectory() ? S_IFDIR : S_IFREG)
time_t AccessTime(); | S_IRUSR | S_IRGRP | S_IROTH; }
time_t ModificationTime(); time_t AccessTime();
time_t ModificationTime();
uint8 *AllocationDescriptors() { return AbstractEntry()->AllocationDescriptors(); }
uint32 AllocationDescriptorsSize() { return AbstractEntry()->AllocationDescriptorsLength(); } uint8 *AllocationDescriptors()
{ return _AbstractEntry()->AllocationDescriptors(); }
status_t Read(off_t pos, void *buffer, size_t *length, uint32 *block = NULL); uint32 AllocationDescriptorsSize()
{ return _AbstractEntry()->AllocationDescriptorsLength(); }
status_t Read(off_t pos, void *buffer, size_t *length,
uint32 *block = NULL);
// for directories only // for directories only
status_t GetDirectoryIterator(DirectoryIterator **iterator); status_t GetDirectoryIterator(DirectoryIterator **iterator);
status_t Find(const char *filename, ino_t *id); status_t Find(const char *filename, ino_t *id);
Volume* GetVolume() const { return fVolume; } Volume *GetVolume() const { return fVolume; }
private: private:
Icb(); // unimplemented AbstractFileEntry *_AbstractEntry() { return (_Tag().id()
== TAGID_EXTENDED_FILE_ENTRY)
descriptor_tag & Tag() { return (reinterpret_cast<icb_header*>(fData.Block()))->tag(); } ? &fExtendedEntry : &fFileEntry; }
icb_entry_tag& IcbTag() { return (reinterpret_cast<icb_header*>(fData.Block()))->icb_tag(); }
AbstractFileEntry* AbstractEntry() { descriptor_tag &_Tag() { return ((icb_header *)fData.Block())->tag(); }
DEBUG_INIT("Icb"); icb_entry_tag &_IcbTag() { return ((icb_header *)fData.Block())->icb_tag(); }
return (Tag().id() == TAGID_EXTENDED_FILE_ENTRY) file_icb_entry *_FileEntry() { return (file_icb_entry *)fData.Block(); }
// ? reinterpret_cast<extended_file_icb_entry*>(fData.Block()) extended_file_icb_entry &_ExtendedEntry() { return *(extended_file_icb_entry *)fData.Block(); }
// : reinterpret_cast<file_icb_entry*>(fData.Block()));
? &fExtendedEntry
: &fFileEntry;
}
file_icb_entry* FileEntry() { return (reinterpret_cast<file_icb_entry*>(fData.Block())); }
extended_file_icb_entry& ExtendedEntry() { return *(reinterpret_cast<extended_file_icb_entry*>(fData.Block())); }
template <class DescriptorList> template <class DescriptorList>
status_t _Read(DescriptorList &list, off_t pos, void *buffer, size_t *length, uint32 *block); status_t _Read(DescriptorList &list, off_t pos,
void *buffer, size_t *length, uint32 *block);
private: private:
Volume *fVolume; Volume *fVolume;
CachedBlock fData; CachedBlock fData;
status_t fInitStatus; status_t fInitStatus;
ino_t fId; ino_t fId;
SinglyLinkedList<DirectoryIterator*> fIteratorList; SinglyLinkedList<DirectoryIterator> fIteratorList;
/* [zooey]: gcc-2.95.3 requires the explicit namespace here, otherwise FileEntry<file_icb_entry> fFileEntry;
it complains about a syntax error(!). This is most probably a bug. */ FileEntry<extended_file_icb_entry> fExtendedEntry;
Udf::FileEntry<file_icb_entry> fFileEntry;
Udf::FileEntry<extended_file_icb_entry> fExtendedEntry;
}; };
/*! \brief Does the dirty work of reading using the given DescriptorList object /*! \brief Does the dirty work of reading using the given DescriptorList object
to access the allocation descriptors properly. to access the allocation descriptors properly.
*/ */
@@ -133,48 +143,47 @@ template <class DescriptorList>
status_t status_t
Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint32 *block) Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint32 *block)
{ {
DEBUG_INIT_ETC("Icb", ("list: %p, pos: %Ld, buffer: %p, length: (%p)->%ld", TRACE(("Icb::_Read(): list: %p, pos: %Ld, buffer: %p, length: (%p)->%ld",
&list, pos, _buffer, length, (length ? *length : 0))); &list, pos, _buffer, length, (length ? *length : 0)));
if (!_buffer || !length)
RETURN(B_BAD_VALUE);
uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos; uint64 bytesLeftInFile = uint64(pos) > Length() ? 0 : Length() - pos;
size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length; size_t bytesLeft = (*length >= bytesLeftInFile) ? bytesLeftInFile : *length;
size_t bytesRead = 0; size_t bytesRead = 0;
Volume *volume = GetVolume(); Volume *volume = GetVolume();
status_t error = B_OK; status_t error = B_OK;
uint8 *buffer = reinterpret_cast<uint8*>(_buffer); uint8 *buffer = (uint8 *)_buffer;
bool isFirstBlock = true; bool isFirstBlock = true;
while (bytesLeft > 0 && !error) { while (bytesLeft > 0 && !error) {
PRINT(("pos: %Ld\n", pos)); TRACE(("Icb::_Read(): pos: %Ld\n, bytesLeft: %ld\n", pos, bytesLeft));
PRINT(("bytesLeft: %ld\n", bytesLeft));
long_address extent; long_address extent;
bool isEmpty = false; bool isEmpty = false;
error = list.FindExtent(pos, &extent, &isEmpty); error = list.FindExtent(pos, &extent, &isEmpty);
if (!error) { if (!error) {
PRINT(("found extent for offset %Ld: (block: %ld, partition: %d, length: %ld, type: %d)\n", TRACE(("Icb::_Read(): found extent for offset %Ld: (block: %ld, "
pos, extent.block(), extent.partition(), extent.length(), extent.type())); "partition: %d, length: %ld, type: %d)\n", pos, extent.block(),
extent.partition(), extent.length(), extent.type()));
switch (extent.type()) { switch (extent.type()) {
case EXTENT_TYPE_RECORDED: case EXTENT_TYPE_RECORDED:
isEmpty = false; isEmpty = false;
break; break;
case EXTENT_TYPE_ALLOCATED: case EXTENT_TYPE_ALLOCATED:
case EXTENT_TYPE_UNALLOCATED: case EXTENT_TYPE_UNALLOCATED:
isEmpty = true; isEmpty = true;
break; break;
default: default:
PRINT(("Invalid extent type found: %d\n", extent.type())); TRACE_ERROR(("Icb::_Read(): Invalid extent type "
"found: %d\n", extent.type()));
error = B_ERROR; error = B_ERROR;
break; break;
} }
if (!error) { if (!error) {
// Note the unmapped first block of the total read in // Note the unmapped first block of the total read in
// the block output parameter if provided // the block output parameter if provided
@@ -183,37 +192,40 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
if (block) if (block)
*block = extent.block(); *block = extent.block();
} }
off_t blockOffset = pos - off_t((pos >> volume->BlockShift()) << volume->BlockShift()); off_t blockOffset = pos - off_t((pos >> volume->BlockShift())
<< volume->BlockShift());
size_t fullBlocksLeft = bytesLeft >> volume->BlockShift(); size_t fullBlocksLeft = bytesLeft >> volume->BlockShift();
if (fullBlocksLeft > 0 && blockOffset == 0) { if (fullBlocksLeft > 0 && blockOffset == 0) {
PRINT(("reading full block (or more)\n")); TRACE(("Icb::_Read(): reading full block (or more)\n"));
// Block aligned and at least one full block left. Read in using // Block aligned and at least one full block left. Read
// cached_read() calls. // in using cached_read() calls.
off_t diskBlock; off_t diskBlock;
error = volume->MapBlock(extent, &diskBlock); error = volume->MapBlock(extent, &diskBlock);
if (!error) { if (!error) {
size_t fullBlockBytesLeft = fullBlocksLeft << volume->BlockShift(); size_t fullBlockBytesLeft =
fullBlocksLeft << volume->BlockShift();
size_t readLength = fullBlockBytesLeft < extent.length() size_t readLength = fullBlockBytesLeft < extent.length()
? fullBlockBytesLeft ? fullBlockBytesLeft : extent.length();
: extent.length();
if (isEmpty) { if (isEmpty) {
PRINT(("reading %ld empty bytes as zeros\n", readLength)); TRACE(("Icb::_Read(): reading %ld empty bytes "
"as zeros\n", readLength));
memset(buffer, 0, readLength); memset(buffer, 0, readLength);
} else { } else {
off_t diskBlock; off_t diskBlock;
error = volume->MapBlock(extent, &diskBlock); error = volume->MapBlock(extent, &diskBlock);
if (!error) { if (!error) {
PRINT(("reading %ld bytes from disk block %Ld using cached_read()\n", TRACE(("Icb::_Read(): reading %ld bytes from "
readLength, diskBlock)); "disk block %Ld using cached_read()\n",
error = cached_read(volume->Device(), diskBlock, buffer, readLength, diskBlock));
readLength >> volume->BlockShift(), size_t length = readLength >> volume->BlockShift();
volume->BlockSize()); error = file_cache_read(volume->BlockCache(),
} NULL, pos, buffer, &length);
}
} }
if (!error) { if (!error) {
bytesLeft -= readLength; bytesLeft -= readLength;
bytesRead += readLength; bytesRead += readLength;
@@ -221,7 +233,7 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
buffer += readLength; buffer += readLength;
} }
} }
} else { } else {
PRINT(("partial block\n")); PRINT(("partial block\n"));
off_t partialOffset; off_t partialOffset;
@@ -251,15 +263,15 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
if (!error) { if (!error) {
PRINT(("reading %ld bytes from disk block %Ld using get_block()\n", PRINT(("reading %ld bytes from disk block %Ld using get_block()\n",
partialLength, diskBlock)); partialLength, diskBlock));
uint8 *data = (uint8*)get_block(volume->Device(), diskBlock, volume->BlockSize()); uint8 *data = (uint8*)block_cache_get_etc((void*)volume->BlockCache(), diskBlock, 0, partialLength);
error = data ? B_OK : B_BAD_DATA; error = data ? B_OK : B_BAD_DATA;
if (!error) { if (!error) {
memcpy(buffer, data+partialOffset, partialLength); memcpy(buffer, data+partialOffset, partialLength);
release_block(volume->Device(), diskBlock); block_cache_put(volume->BlockCache(), diskBlock);
} }
} }
} }
if (!error) { if (!error) {
bytesLeft -= partialLength; bytesLeft -= partialLength;
bytesRead += partialLength; bytesRead += partialLength;
@@ -280,12 +292,14 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
RETURN(error); RETURN(error);
} }
template <class Descriptor> template <class Descriptor>
FileEntry<Descriptor>::FileEntry(CachedBlock *descriptorBlock) FileEntry<Descriptor>::FileEntry(CachedBlock *descriptorBlock)
: fDescriptorBlock(descriptorBlock) : fDescriptorBlock(descriptorBlock)
{ {
} }
template <class Descriptor> template <class Descriptor>
void void
FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock) FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock)
@@ -293,6 +307,7 @@ FileEntry<Descriptor>::SetTo(CachedBlock *descriptorBlock)
fDescriptorBlock = descriptorBlock; fDescriptorBlock = descriptorBlock;
} }
template <class Descriptor> template <class Descriptor>
uint8* uint8*
FileEntry<Descriptor>::AllocationDescriptors() FileEntry<Descriptor>::AllocationDescriptors()
@@ -301,6 +316,7 @@ FileEntry<Descriptor>::AllocationDescriptors()
return descriptor ? descriptor->allocation_descriptors() : NULL; return descriptor ? descriptor->allocation_descriptors() : NULL;
} }
template <class Descriptor> template <class Descriptor>
uint32 uint32
FileEntry<Descriptor>::AllocationDescriptorsLength() FileEntry<Descriptor>::AllocationDescriptorsLength()
@@ -309,13 +325,13 @@ FileEntry<Descriptor>::AllocationDescriptorsLength()
return descriptor ? descriptor->allocation_descriptors_length() : 0; return descriptor ? descriptor->allocation_descriptors_length() : 0;
} }
template <class Descriptor> template <class Descriptor>
Descriptor* Descriptor*
FileEntry<Descriptor>::_Descriptor() FileEntry<Descriptor>::_Descriptor()
{ {
return fDescriptorBlock ? reinterpret_cast<Descriptor*>(fDescriptorBlock->Block()) : NULL; return fDescriptorBlock
? (Descriptor *)fDescriptorBlock->Block() : NULL;
} }
}; // namespace Udf
#endif // _UDF_ICB_H #endif // _UDF_ICB_H
@@ -16,7 +16,6 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include "DirectoryIterator.h"
#include "Icb.h" #include "Icb.h"
#include "Recognition.h" #include "Recognition.h"
#include "Utils.h" #include "Utils.h"