*sigh* svn really messed it up. I supposed one should make sure to run

update on the directory to be copied before doing it, even if it is up
to date.

Anyway: Ported RamFS to Haiku's FS interface. Change set apparently merged
with older changes.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20346 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-03-07 06:40:25 +00:00
parent 224e7c4269
commit c7a7242307
20 changed files with 1284 additions and 1132 deletions
@@ -30,10 +30,14 @@
#include <new>
#include <stdio.h>
#include <OS.h>
#include "Misc.h"
using std::nothrow;
// maximal height of a tree
static const int kMaxAVLTreeHeight = 32;
@@ -25,11 +25,11 @@
// dealings in this Software without prior written authorization of the
// copyright holder.
#include <algobase.h>
#include <OS.h>
#include "AreaUtils.h"
#include "Debug.h"
#include "Misc.h"
#ifndef USE_STANDARD_FUNCTIONS
#define USE_STANDARD_FUNCTIONS 0
@@ -47,6 +47,21 @@ Attribute::SetType(uint32 type)
}
}
// SetSize
status_t
Attribute::SetSize(off_t newSize)
{
status_t error = B_OK;
off_t oldSize = DataContainer::GetSize();
if (newSize != oldSize) {
if (fNode)
fNode->MarkModified(B_STAT_MODIFICATION_TIME);
error = DataContainer::Resize(newSize);
}
return error;
}
// WriteAt
status_t
Attribute::WriteAt(off_t offset, const void *buffer, size_t size,
@@ -74,7 +89,7 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size,
// node has been changed
if (fNode && size > 0)
fNode->MarkModified();
fNode->MarkModified(B_STAT_MODIFICATION_TIME);
return error;
}
@@ -28,6 +28,9 @@ public:
void SetType(uint32 type);
uint32 GetType() const { return fType; }
status_t SetSize(off_t newSize);
off_t GetSize() const { return DataContainer::GetSize(); }
virtual status_t WriteAt(off_t offset, const void *buffer, size_t size,
size_t *bytesWritten);
@@ -33,4 +33,4 @@ bucket_containing_min_size(size_t size)
{ return (size ? bucket_containing_size(size - 1) + 1 : 0); }
#endif BLOCK_ALLOCATOR_MISC_H
#endif // BLOCK_ALLOCATOR_MISC_H
@@ -108,7 +108,7 @@ Directory::CreateFile(const char *name, File **file)
status_t
Directory::CreateSymLink(const char *name, const char *path, SymLink **symLink)
{
status_t error = (name && symlink ? B_OK : B_BAD_VALUE);
status_t error = (name && symLink ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
// create symlink
if (SymLink *node = new(nothrow) SymLink(GetVolume())) {
@@ -136,7 +136,7 @@ Directory::AddEntry(Entry *entry)
entry->SetParent(this);
error = GetVolume()->EntryAdded(GetID(), entry);
if (error == B_OK) {
MarkModified();
MarkModified(B_STAT_MODIFICATION_TIME);
} else {
fEntries.Remove(entry);
entry->SetParent(NULL);
@@ -213,7 +213,7 @@ Directory::RemoveEntry(Entry *entry)
if (error == B_OK) {
fEntries.Remove(entry);
entry->SetParent(NULL);
MarkModified();
MarkModified(B_STAT_MODIFICATION_TIME);
}
}
}
@@ -68,10 +68,7 @@ Entry::SetName(const char *newName)
{
status_t error = (newName ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
if (fName.SetTo(newName)) {
// if (fNode)
// fNode->MarkModified();
} else
if (!fName.SetTo(newName))
SET_ERROR(error, B_NO_MEMORY);
}
return error;
@@ -3,10 +3,10 @@
#ifndef ENTRY_H
#define ENTRY_H
#include <fs_interface.h>
#include <SupportDefs.h>
#include "DLList.h"
#include "fsproto.h"
#include "String.h"
class AllocationInfo;
@@ -34,9 +34,12 @@ File::WriteAt(off_t offset, const void *buffer, size_t size,
off_t oldSize = DataContainer::GetSize();
status_t error = DataContainer::WriteAt(offset, buffer, size,
bytesWritten);
MarkModified();
MarkModified(B_STAT_MODIFICATION_TIME);
// update the size index, if our size has changed
if (oldSize != DataContainer::GetSize()) {
MarkModified(B_STAT_SIZE);
if (SizeIndex *index = GetVolume()->GetSizeIndex())
index->Changed(this, oldSize);
}
@@ -51,7 +54,7 @@ File::SetSize(off_t newSize)
off_t oldSize = DataContainer::GetSize();
if (newSize != oldSize) {
error = DataContainer::Resize(newSize);
MarkModified();
MarkModified(B_STAT_SIZE);
// update the size index
if (SizeIndex *index = GetVolume()->GetSizeIndex())
index->Changed(this, oldSize);
+6 -6
View File
@@ -101,7 +101,7 @@ private:
// sDefaultItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t
typename List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t
List<ITEM, DEFAULT_ITEM_SUPPLIER>::sDefaultItem(
DEFAULT_ITEM_SUPPLIER::GetItem());
@@ -129,7 +129,7 @@ List<ITEM, DEFAULT_ITEM_SUPPLIER>::~List()
// GetDefaultItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
inline
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
const typename List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem() const
{
return sDefaultItem;
@@ -138,7 +138,7 @@ List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem() const
// GetDefaultItem
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
inline
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
typename List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::GetDefaultItem()
{
return sDefaultItem;
@@ -310,7 +310,7 @@ List<ITEM, DEFAULT_ITEM_SUPPLIER>::IsEmpty() const
// ItemAt
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
const typename List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index) const
{
if (index >= 0 && index < fItemCount)
@@ -320,7 +320,7 @@ List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index) const
// ItemAt
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
typename List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t &
List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index)
{
if (index >= 0 && index < fItemCount)
@@ -330,7 +330,7 @@ List<ITEM, DEFAULT_ITEM_SUPPLIER>::ItemAt(int32 index)
// Items
template<typename ITEM, typename DEFAULT_ITEM_SUPPLIER>
const List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t *
const typename List<ITEM, DEFAULT_ITEM_SUPPLIER>::item_t *
List<ITEM, DEFAULT_ITEM_SUPPLIER>::Items() const
{
return fItems;
@@ -11,4 +11,4 @@ class Volume;
typedef AutoLocker<Volume, AutoLockerReadLocking<Volume> > VolumeReadLocker;
typedef AutoLocker<Volume, AutoLockerWriteLocking<Volume> > VolumeWriteLocker;
#endif LOCKING_H
#endif // LOCKING_H
@@ -37,7 +37,7 @@ Node::Node(Volume *volume, uint8 type)
fMTime(0),
fCTime(0),
fCrTime(0),
fModified(false),
fModified(0),
fIsKnownToVFS(false),
// attribute management
fAttributes(),
@@ -85,7 +85,7 @@ status_t
Node::AddReference()
{
if (++fRefCount == 1) {
status_t error = GetVolume()->NewVNode(this);
status_t error = GetVolume()->PublishVNode(this);
if (error != B_OK) {
fRefCount--;
return error;
@@ -217,7 +217,7 @@ Node::AddAttribute(Attribute *attribute)
if (error == B_OK) {
fAttributes.Insert(attribute);
attribute->SetNode(this);
MarkModified();
MarkModified(B_STAT_MODIFICATION_TIME);
}
}
return error;
@@ -258,7 +258,7 @@ Node::RemoveAttribute(Attribute *attribute)
if (error == B_OK) {
fAttributes.Remove(attribute);
attribute->SetNode(NULL);
MarkModified();
MarkModified(B_STAT_MODIFICATION_TIME);
}
}
}
+12 -11
View File
@@ -3,11 +3,11 @@
#ifndef NODE_H
#define NODE_H
#include <SupportDefs.h>
#include <fs_interface.h>
#include <NodeMonitor.h>
#include "Attribute.h"
#include "Entry.h"
#include "fsproto.h"
#include "String.h"
class AllocationInfo;
@@ -61,10 +61,10 @@ public:
{ fMode = fMode & ~S_IUMSK | mode & S_IUMSK; }
inline mode_t GetMode() const { return fMode; }
inline void SetUID(uid_t uid) { fUID = uid; }
inline void SetUID(uid_t uid) { fUID = uid; MarkModified(B_STAT_UID); }
inline uid_t GetUID() const { return fUID; }
inline void SetGID(uid_t gid) { fGID = gid; }
inline void SetGID(uid_t gid) { fGID = gid; MarkModified(B_STAT_GID); }
inline uid_t GetGID() const { return fGID; }
inline void SetATime(time_t aTime) { fATime = aTime; }
@@ -79,9 +79,8 @@ public:
inline void SetCrTime(time_t crTime) { fCrTime = crTime; }
inline time_t GetCrTime() const { return fCrTime; }
inline void MarkModified() { fModified = true; }
inline void MarkUnmodified();
inline void SetModified(bool modified) { fModified = modified; }
inline void MarkModified(uint32 flags) { fModified |= flags; }
inline uint32 MarkUnmodified();
inline bool IsModified() const { return fModified; }
status_t CheckPermissions(int mode) const;
@@ -118,7 +117,7 @@ private:
time_t fMTime;
time_t fCTime;
time_t fCrTime;
bool fModified;
uint32 fModified;
bool fIsKnownToVFS;
// attribute management
@@ -131,14 +130,16 @@ protected:
// MarkUnmodified
inline
void
uint32
Node::MarkUnmodified()
{
if (fModified) {
uint32 modified = fModified;
if (modified) {
fCTime = time(NULL);
SetMTime(fCTime);
fModified = false;
fModified = 0;
}
return modified;
}
// open_mode_to_access
@@ -224,7 +224,7 @@ NodeChildTable<ParentNode, NodeChild>::GetNodeChild(vnode_id id,
// _FindElement
template<typename ParentNode, typename NodeChild>
NodeChildTable<ParentNode, NodeChild>::Element *
typename NodeChildTable<ParentNode, NodeChild>::Element *
NodeChildTable<ParentNode, NodeChild>::_FindElement(vnode_id id,
const char *name) const
{
+30 -18
View File
@@ -1449,13 +1449,13 @@ Expression::ParseEquation(char **expr)
{
skipWhitespace(expr);
bool not = false;
bool nott = false; // note: not is a C++ keyword
if (**expr == '!') {
skipWhitespace(expr, 1);
if (**expr != '(')
return NULL;
not = true;
nott = true;
}
if (**expr == ')') {
@@ -1475,7 +1475,7 @@ Expression::ParseEquation(char **expr)
// If the term is negated, we just complement the tree, to get
// rid of the not, a.k.a. DeMorgan's Law.
if (not)
if (nott)
term->Complement();
skipWhitespace(expr, 1);
@@ -1686,6 +1686,22 @@ Query::SetLiveMode(port_id port, int32 token)
}
static void
send_entry_notification(port_id port, int32 token, Volume* volume, Entry* entry,
bool created)
{
if (created) {
notify_query_entry_created(port, token, volume->GetID(),
entry->GetParent()->GetID(), entry->GetName(),
entry->GetNode()->GetID());
} else {
notify_query_entry_removed(port, token, volume->GetID(),
entry->GetParent()->GetID(), entry->GetName(),
entry->GetNode()->GetID());
}
}
void
Query::LiveUpdate(Entry *entry, Node* node, const char *attribute, int32 type,
const uint8 *oldKey, size_t oldLength, const uint8 *newKey,
@@ -1717,7 +1733,7 @@ this, entry, node, attribute, type, oldKey, oldLength, newKey, newLength));
type, newKey, newLength);
PRINT((" oldStatus: 0x%lx, newStatus: 0x%lx\n", oldStatus, newStatus));
int32 op;
bool created;
if (oldStatus == MATCH_OK && newStatus == MATCH_OK) {
// only send out a notification if the name was changed
if (oldKey == NULL || strcmp(attribute,"name"))
@@ -1726,33 +1742,29 @@ PRINT((" oldStatus: 0x%lx, newStatus: 0x%lx\n", oldStatus, newStatus));
if (entry) {
// entry should actually always be given, when the changed
// attribute is the entry name
PRINT(("send_notification(): old: B_ENTRY_REMOVED\n"));
send_notification(fPort, fToken, B_QUERY_UPDATE, B_ENTRY_REMOVED,
fVolume->GetID(), 0, entry->GetParent()->GetID(), 0,
entry->GetNode()->GetID(), (const char *)oldKey);
PRINT(("notification: old: removed\n"));
notify_query_entry_removed(fPort, fToken, fVolume->GetID(),
entry->GetParent()->GetID(), (const char *)oldKey,
entry->GetNode()->GetID());
}
op = B_ENTRY_CREATED;
created = true;
} else if (oldStatus != MATCH_OK && newStatus != MATCH_OK) {
// nothing has changed
return;
} else if (oldStatus == MATCH_OK && newStatus != MATCH_OK)
op = B_ENTRY_REMOVED;
created = false;
else
op = B_ENTRY_CREATED;
created = true;
// We send a notification for the given entry, if any, or otherwise for
// all entries referring to the node;
if (entry) {
PRINT(("send_notification(): new: %s\n", (op == B_ENTRY_REMOVED ? "B_ENTRY_REMOVED" : "B_ENTRY_CREATED")));
send_notification(fPort, fToken, B_QUERY_UPDATE, op, fVolume->GetID(),
0, entry->GetParent()->GetID(), 0, entry->GetNode()->GetID(),
entry->GetName());
PRINT(("notification: new: %s\n", (created ? "created" : "removed")));
send_entry_notification(fPort, fToken, fVolume, entry, created);
} else {
entry = node->GetFirstReferrer();
while (entry) {
send_notification(fPort, fToken, B_QUERY_UPDATE, op,
fVolume->GetID(), 0, entry->GetParent()->GetID(), 0,
entry->GetNode()->GetID(), entry->GetName());
send_entry_notification(fPort, fToken, fVolume, entry, created);
entry = node->GetNextReferrer(entry);
}
}
@@ -28,7 +28,7 @@ SymLink::SetSize(off_t newSize)
int32 oldSize = GetLinkedPathLength();
if (error == B_OK && newSize < oldSize) {
fLinkedPath.Truncate(newSize);
MarkModified();
MarkModified(B_STAT_SIZE);
// update the size index
if (SizeIndex *index = GetVolume()->GetSizeIndex())
index->Changed(this, oldSize);
@@ -50,9 +50,11 @@ SymLink::SetLinkedPath(const char *path)
int32 oldLen = GetLinkedPathLength();
int32 len = strnlen(path, PATH_MAX - 1);
if (fLinkedPath.SetTo(path, len)) {
MarkModified();
MarkModified(B_STAT_MODIFICATION_TIME);
// update the size index, if necessary
if (len != oldLen) {
MarkModified(B_STAT_SIZE);
if (SizeIndex *index = GetVolume()->GetSizeIndex())
index->Changed(this, oldLen);
}
@@ -141,6 +141,8 @@ private:
GetKey;
typedef AVLTree<Value, Key, Node, KeyCompare, GetKey, NodeAllocator,
GetValue> BaseClass;
public:
typedef typename BaseClass::Iterator Iterator;
public:
TwoKeyAVLTree();
@@ -210,7 +212,7 @@ Value *
TWO_KEY_AVL_TREE_CLASS_NAME::FindFirst(const PrimaryKey &key,
Iterator *iterator)
{
Node *node = fRoot;
Node *node = BaseClass::fRoot;
while (node) {
int cmp = fPrimaryKeyCompare(key, fGetPrimaryKey(fGetValue(node)));
if (cmp == 0) {
@@ -237,7 +239,7 @@ Value *
TWO_KEY_AVL_TREE_CLASS_NAME::FindLast(const PrimaryKey &key,
Iterator *iterator)
{
Node *node = fRoot;
Node *node = BaseClass::fRoot;
while (node) {
int cmp = fPrimaryKeyCompare(key, fGetPrimaryKey(fGetValue(node)));
if (cmp == 0) {
@@ -164,7 +164,7 @@ Volume::~Volume()
// Mount
status_t
Volume::Mount(nspace_id id)
Volume::Mount(mount_id id)
{
Unmount();
@@ -354,6 +354,19 @@ Volume::NewVNode(Node *node)
return error;
}
// PublishVNode
status_t
Volume::PublishVNode(Node *node)
{
status_t error = NodeAdded(node);
if (error == B_OK) {
error = publish_vnode(GetID(), node->GetID(), node);
if (error != B_OK)
NodeRemoved(node);
}
return error;
}
// GetVNode
status_t
Volume::GetVNode(vnode_id id, Node **node)
@@ -22,7 +22,7 @@
#ifndef VOLUME_H
#define VOLUME_H
#include <fsproto.h>
#include <fs_interface.h>
#include <SupportDefs.h>
#include "DLList.h"
@@ -93,10 +93,10 @@ public:
Volume();
~Volume();
status_t Mount(nspace_id nsid);
status_t Mount(mount_id nsid);
status_t Unmount();
nspace_id GetID() const { return fID; }
mount_id GetID() const { return fID; }
off_t GetBlockSize() const;
off_t CountBlocks() const;
@@ -108,6 +108,7 @@ public:
Directory *GetRootDirectory() const { return fRootDirectory; }
status_t NewVNode(Node *node);
status_t PublishVNode(Node *node);
status_t GetVNode(vnode_id id, Node **node);
status_t GetVNode(Node *node);
status_t PutVNode(vnode_id id);
@@ -175,7 +176,7 @@ public:
private:
typedef DLList<Query> QueryList;
nspace_id fID;
mount_id fID;
vnode_id fNextNodeID;
NodeTable *fNodeTable;
DirectoryEntryTable *fDirectoryEntryTable;
File diff suppressed because it is too large Load Diff