* 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
+113 -29
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);
@@ -50,24 +129,45 @@ Icb::Icb(Volume *volume, long_address address)
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));
@@ -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)
+98 -82
View File
@@ -1,36 +1,22 @@
//---------------------------------------------------------------------- /*
// 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
@@ -50,6 +36,7 @@ public:
virtual uint32 AllocationDescriptorsLength() = 0; virtual uint32 AllocationDescriptorsLength() = 0;
}; };
template <class Descriptor> template <class Descriptor>
class FileEntry : public AbstractFileEntry { class FileEntry : public AbstractFileEntry {
public: public:
@@ -57,12 +44,38 @@ public:
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);
@@ -70,23 +83,27 @@ public:
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)
| S_IRUSR | S_IRGRP | S_IROTH; }
time_t AccessTime(); time_t AccessTime();
time_t ModificationTime(); time_t ModificationTime();
uint8 *AllocationDescriptors() { return AbstractEntry()->AllocationDescriptors(); } uint8 *AllocationDescriptors()
uint32 AllocationDescriptorsSize() { return AbstractEntry()->AllocationDescriptorsLength(); } { return _AbstractEntry()->AllocationDescriptors(); }
uint32 AllocationDescriptorsSize()
{ return _AbstractEntry()->AllocationDescriptorsLength(); }
status_t Read(off_t pos, void *buffer, size_t *length, uint32 *block = NULL); 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);
@@ -95,37 +112,30 @@ public:
Volume *GetVolume() const { return fVolume; } Volume *GetVolume() const { return fVolume; }
private: private:
Icb(); // unimplemented AbstractFileEntry *_AbstractEntry() { return (_Tag().id()
== TAGID_EXTENDED_FILE_ENTRY)
? &fExtendedEntry : &fFileEntry; }
descriptor_tag & Tag() { return (reinterpret_cast<icb_header*>(fData.Block()))->tag(); } descriptor_tag &_Tag() { return ((icb_header *)fData.Block())->tag(); }
icb_entry_tag& IcbTag() { return (reinterpret_cast<icb_header*>(fData.Block()))->icb_tag(); } icb_entry_tag &_IcbTag() { return ((icb_header *)fData.Block())->icb_tag(); }
AbstractFileEntry* AbstractEntry() { file_icb_entry *_FileEntry() { return (file_icb_entry *)fData.Block(); }
DEBUG_INIT("Icb"); extended_file_icb_entry &_ExtendedEntry() { return *(extended_file_icb_entry *)fData.Block(); }
return (Tag().id() == TAGID_EXTENDED_FILE_ENTRY)
// ? reinterpret_cast<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,10 +143,8 @@ 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;
@@ -144,20 +152,20 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
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:
@@ -170,7 +178,8 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
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;
} }
@@ -184,33 +193,36 @@ Icb::_Read(DescriptorList &list, off_t pos, void *_buffer, size_t *length, uint3
*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 "
"disk block %Ld using cached_read()\n",
readLength, diskBlock)); readLength, diskBlock));
error = cached_read(volume->Device(), diskBlock, buffer, size_t length = readLength >> volume->BlockShift();
readLength >> volume->BlockShift(), error = file_cache_read(volume->BlockCache(),
volume->BlockSize()); NULL, pos, buffer, &length);
} }
} }
@@ -251,11 +263,11 @@ 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);
} }
} }
} }
@@ -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"