* Reverted r21199 (and therefore r21254) - it actually did work correctly initially,

see bug #1248.
* Closing a pipe now also removes it from the public namespace and marks it for
  deletion, and thus, there are no more left-overs after using a pipe.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21261 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-05-28 14:12:43 +00:00
parent a046c487d0
commit aac3ed8c03
+144 -102
View File
@@ -25,7 +25,6 @@
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
// TODO: pipefs entries aren't deleted automatically after usage yet!
//#define TRACE_PIPEFS //#define TRACE_PIPEFS
#ifdef TRACE_PIPEFS #ifdef TRACE_PIPEFS
@@ -107,9 +106,11 @@ class Volume {
Inode *Lookup(vnode_id id); Inode *Lookup(vnode_id id);
Inode *Lookup(const char *name); Inode *Lookup(const char *name);
Inode *CreateNode(Inode *parent, const char *name, int32 type); Inode *CreateNode(Inode *parent, const char *name,
int32 type);
status_t DeleteNode(Inode *inode, bool forceDelete = false); status_t DeleteNode(Inode *inode, bool forceDelete = false);
status_t RemoveNode(Inode *directory, const char *name); status_t RemoveNode(Inode *directory, const char *name);
status_t RemoveNode(Inode *inode);
vnode_id GetNextNodeID() { return fNextNodeID++; } vnode_id GetNextNodeID() { return fNextNodeID++; }
@@ -117,13 +118,13 @@ class Volume {
dir_cookie *FirstDirCookie() const { return fFirstDirCookie; } dir_cookie *FirstDirCookie() const { return fFirstDirCookie; }
void InsertCookie(dir_cookie *cookie); void InsertCookie(dir_cookie *cookie);
void RemoveCookie(dir_cookie *cookie);
private: private:
void RemoveCookie(dir_cookie *cookie); void _UpdateDirCookies(Inode *inode);
void UpdateDirCookies(Inode *inode);
status_t RemoveNode(Inode *inode); status_t _RemoveNode(Inode *inode);
status_t InsertNode(Inode *inode); status_t _InsertNode(Inode *inode);
mutex fLock; mutex fLock;
mount_id fID; mount_id fID;
@@ -148,15 +149,18 @@ class Inode {
const char *Name() const { return fName; } const char *Name() const { return fName; }
int32 Type() const { return fType; } int32 Type() const { return fType; }
void SetMode(mode_t mode) { fType = (fType & ~S_IUMSK) | (mode & S_IUMSK); } void SetMode(mode_t mode)
{ fType = (fType & ~S_IUMSK) | (mode & S_IUMSK); }
gid_t GroupID() const { return fGroupID; } gid_t GroupID() const { return fGroupID; }
void SetGroupID(gid_t gid) { fGroupID = gid; } void SetGroupID(gid_t gid) { fGroupID = gid; }
uid_t UserID() const { return fUserID; } uid_t UserID() const { return fUserID; }
void SetUserID(uid_t uid) { fUserID = uid; } void SetUserID(uid_t uid) { fUserID = uid; }
time_t CreationTime() const { return fCreationTime; } time_t CreationTime() const { return fCreationTime; }
void SetCreationTime(time_t creationTime) { fCreationTime = creationTime; } void SetCreationTime(time_t creationTime)
{ fCreationTime = creationTime; }
time_t ModificationTime() const { return fModificationTime; } time_t ModificationTime() const { return fModificationTime; }
void SetModificationTime(time_t modificationTime) { fModificationTime = modificationTime; } void SetModificationTime(time_t modificationTime)
{ fModificationTime = modificationTime; }
Inode *Next() const { return fNext; } Inode *Next() const { return fNext; }
void SetNext(Inode *inode) { fNext = inode; } void SetNext(Inode *inode) { fNext = inode; }
@@ -164,11 +168,13 @@ class Inode {
benaphore *RequestLock() { return &fRequestLock; } benaphore *RequestLock() { return &fRequestLock; }
RequestList &Requests() { return fRequests; } RequestList &Requests() { return fRequests; }
status_t WriteDataToBuffer(const void **_data, size_t *_bytesLeft, bool nonBlocking); status_t WriteDataToBuffer(const void **_data, size_t *_bytesLeft,
bool nonBlocking);
size_t BytesAvailable() const { return fBuffer.Readable(); } size_t BytesAvailable() const { return fBuffer.Readable(); }
void MayReleaseWriter(); void MayReleaseWriter();
void FillPendingRequests(const void **_buffer, size_t *_bytesLeft); void FillPendingRequests(const void **_buffer,
size_t *_bytesLeft);
void FillPendingRequests(); void FillPendingRequests();
status_t AddRequest(ReadRequest &request); status_t AddRequest(ReadRequest &request);
status_t RemoveRequest(ReadRequest &request); status_t RemoveRequest(ReadRequest &request);
@@ -182,12 +188,13 @@ class Inode {
status_t Deselect(uint8 event, selectsync *sync); status_t Deselect(uint8 event, selectsync *sync);
static int32 NameHashNextOffset(); static int32 NameHashNextOffset();
static uint32 name_hash_func(void *_node, const void *_key, uint32 range); static uint32 name_hash_func(void *_node, const void *_key,
static int name_compare_func(void *_node, const void *_key); uint32 range);
static int name_compare_func(void *_node, const void *_key);
static int32 HashNextOffset(); static int32 HashNextOffset();
static uint32 hash_func(void *_node, const void *_key, uint32 range); static uint32 hash_func(void *_node, const void *_key, uint32 range);
static int compare_func(void *_node, const void *_key); static int compare_func(void *_node, const void *_key);
private: private:
Inode *fNext; Inode *fNext;
@@ -322,8 +329,6 @@ Volume::Volume(mount_id id)
fRootNode = CreateNode(NULL, "", S_IFDIR | 0777); fRootNode = CreateNode(NULL, "", S_IFDIR | 0777);
if (fRootNode == NULL) if (fRootNode == NULL)
return; return;
publish_vnode(ID(), fRootNode->ID(), fRootNode);
} }
@@ -392,10 +397,11 @@ Volume::CreateNode(Inode *parent, const char *name, int32 type)
} }
if (S_ISFIFO(type)) if (S_ISFIFO(type))
InsertNode(inode); _InsertNode(inode);
hash_insert(fNodeHash, inode); hash_insert(fNodeHash, inode);
hash_insert(fNameHash, inode); hash_insert(fNameHash, inode);
publish_vnode(ID(), inode->ID(), inode);
if (fRootNode != NULL) if (fRootNode != NULL)
fRootNode->SetModificationTime(time(NULL)); fRootNode->SetModificationTime(time(NULL));
@@ -446,7 +452,7 @@ Volume::RemoveCookie(dir_cookie *cookie)
/*! Makes sure none of the dircookies point to the vnode passed in */ /*! Makes sure none of the dircookies point to the vnode passed in */
void void
Volume::UpdateDirCookies(Inode *inode) Volume::_UpdateDirCookies(Inode *inode)
{ {
dir_cookie *cookie; dir_cookie *cookie;
@@ -476,7 +482,7 @@ Volume::Lookup(const char *name)
status_t status_t
Volume::InsertNode(Inode *inode) Volume::_InsertNode(Inode *inode)
{ {
inode->SetNext(fFirstEntry); inode->SetNext(fFirstEntry);
fFirstEntry = inode; fFirstEntry = inode;
@@ -486,14 +492,15 @@ Volume::InsertNode(Inode *inode)
status_t status_t
Volume::RemoveNode(Inode *findNode) Volume::_RemoveNode(Inode *findNode)
{ {
Inode *inode, *last; Inode *inode, *last;
for (inode = fFirstEntry, last = NULL; inode; last = inode, inode = inode->Next()) { for (inode = fFirstEntry, last = NULL; inode; last = inode,
inode = inode->Next()) {
if (inode == findNode) { if (inode == findNode) {
// make sure no dir cookies point to this node // make sure no dir cookies point to this node
UpdateDirCookies(inode); _UpdateDirCookies(inode);
if (last) if (last)
last->SetNext(inode->Next()); last->SetNext(inode->Next());
@@ -508,6 +515,21 @@ Volume::RemoveNode(Inode *findNode)
} }
status_t
Volume::RemoveNode(Inode *inode)
{
// schedule this vnode to be removed when it's ref goes to zero
status_t status = remove_vnode(ID(), inode->ID());
if (status < B_OK)
return status;
_RemoveNode(inode);
notify_entry_removed(ID(), fRootNode->ID(), inode->Name(), inode->ID());
return B_OK;
}
status_t status_t
Volume::RemoveNode(Inode *directory, const char *name) Volume::RemoveNode(Inode *directory, const char *name)
{ {
@@ -521,18 +543,9 @@ Volume::RemoveNode(Inode *directory, const char *name)
else if (S_ISDIR(inode->Type())) else if (S_ISDIR(inode->Type()))
status = B_NOT_ALLOWED; status = B_NOT_ALLOWED;
if (status < B_OK) if (status == B_OK)
goto err; status = RemoveNode(inode);
// schedule this vnode to be removed when it's ref goes to zero
status = remove_vnode(ID(), inode->ID());
if (status < B_OK)
goto err;
RemoveNode(inode);
notify_entry_removed(ID(), directory->ID(), name, inode->ID());
err:
Unlock(); Unlock();
return status; return status;
@@ -591,21 +604,23 @@ Inode::InitCheck()
} }
/** Writes the specified data bytes to the inode's ring buffer. The /*!
* Inode::WriteLock() must be held when calling this method. Writes the specified data bytes to the inode's ring buffer. The
* Releases the reader sem if necessary, so that blocking Inode::WriteLock() must be held when calling this method.
* readers will get started. Releases the reader sem if necessary, so that blocking
* Returns B_OK for success, B_BAD_ADDRESS if copying from the buffer failed, readers will get started.
* and various semaphore errors (like B_WOULD_BLOCK in non-blocking mode). Returns B_OK for success, B_BAD_ADDRESS if copying from the buffer failed,
*/ and various semaphore errors (like B_WOULD_BLOCK in non-blocking mode).
*/
status_t status_t
Inode::WriteDataToBuffer(const void **_data, size_t *_bytesLeft, bool nonBlocking) Inode::WriteDataToBuffer(const void **_data, size_t *_bytesLeft,
bool nonBlocking)
{ {
const void *data = *_data; const void *data = *_data;
size_t dataSize = *_bytesLeft; size_t dataSize = *_bytesLeft;
TRACE(("Inode::WriteDataToBuffer(data = %p, bytes = %lu)\n", data, dataSize)); TRACE(("Inode::WriteDataToBuffer(data = %p, bytes = %lu)\n",
data, dataSize));
// if this is a blocking call, we need to make sure that data can // if this is a blocking call, we need to make sure that data can
// still come in and we don't block the whole inode data transfer // still come in and we don't block the whole inode data transfer
@@ -614,8 +629,8 @@ Inode::WriteDataToBuffer(const void **_data, size_t *_bytesLeft, bool nonBlockin
if (!nonBlocking) if (!nonBlocking)
benaphore_unlock(&fRequestLock); benaphore_unlock(&fRequestLock);
status_t status = acquire_sem_etc(fWriteLock, 1, (nonBlocking ? B_TIMEOUT : 0) status_t status = acquire_sem_etc(fWriteLock, 1,
| B_CAN_INTERRUPT, 0); (nonBlocking ? B_TIMEOUT : 0) | B_CAN_INTERRUPT, 0);
if (!nonBlocking) if (!nonBlocking)
benaphore_lock(&fRequestLock); benaphore_lock(&fRequestLock);
@@ -656,12 +671,12 @@ Inode::MayReleaseWriter()
} }
/** This functions fills pending requests out of the ring buffer. /*!
* It either stops when there are no more requests to satisfy, or This functions fills pending requests out of the ring buffer.
* the ring buffer is empty, whatever comes first. It either stops when there are no more requests to satisfy, or
* You must hold the request lock when calling this function. the ring buffer is empty, whatever comes first.
*/ You must hold the request lock when calling this function.
*/
void void
Inode::FillPendingRequests() Inode::FillPendingRequests()
{ {
@@ -691,20 +706,21 @@ Inode::FillPendingRequests()
} }
/** This function feeds the pending read requests using the provided /*!
* buffer directly. It will also make sure that bytes in the ring This function feeds the pending read requests using the provided
* buffer are served first. buffer directly. It will also make sure that bytes in the ring
* It only does something as long as the first request in the queue buffer are served first.
* shares the same team context as the caller (write context). It only does something as long as the first request in the queue
* You must hold the request lock when calling this function. shares the same team context as the caller (write context).
*/ You must hold the request lock when calling this function.
*/
void void
Inode::FillPendingRequests(const void **_data, size_t *_bytesLeft) Inode::FillPendingRequests(const void **_data, size_t *_bytesLeft)
{ {
team_id team = team_get_current_team_id(); team_id team = team_get_current_team_id();
TRACE(("Inode::FillPendingRequests(data = %p, bytes = %lu)\n", *_data, *_bytesLeft)); TRACE(("Inode::FillPendingRequests(data = %p, bytes = %lu)\n",
_data, *_bytesLeft));
ReadRequest *request; ReadRequest *request;
RequestList::Iterator iterator = fRequests.GetIterator(); RequestList::Iterator iterator = fRequests.GetIterator();
@@ -935,7 +951,8 @@ ReadRequest::Wait(bool nonBlocking)
{ {
TRACE(("pipefs: request@%p waits for data (%sblocking), thread 0x%lx\n", TRACE(("pipefs: request@%p waits for data (%sblocking), thread 0x%lx\n",
this, nonBlocking ? "non" : "", find_thread(NULL))); this, nonBlocking ? "non" : "", find_thread(NULL)));
return acquire_sem_etc(fLock, 1, (nonBlocking ? B_TIMEOUT : 0) | B_CAN_INTERRUPT, 0); return acquire_sem_etc(fLock, 1,
(nonBlocking ? B_TIMEOUT : 0) | B_CAN_INTERRUPT, 0);
} }
@@ -961,14 +978,15 @@ ReadRequest::SetQueued(bool queued)
} }
/** Reads the contents of the ring buffer into the requests data buffer /*!
* if any (canceled requests don't have a buffer anymore). Reads the contents of the ring buffer into the requests data buffer
* This function must only be called in the team context that initiated if any (canceled requests don't have a buffer anymore).
* the read request. This function must only be called in the team context that initiated
*/ the read request.
*/
status_t status_t
ReadRequest::PutBuffer(RingBuffer &buffer, size_t *_bytesRead, bool releasePartiallyFilled) ReadRequest::PutBuffer(RingBuffer &buffer, size_t *_bytesRead,
bool releasePartiallyFilled)
{ {
TRACE(("pipefs: ReadRequest::PutBuffer()\n")); TRACE(("pipefs: ReadRequest::PutBuffer()\n"));
@@ -1006,15 +1024,16 @@ ReadRequest::PutBuffer(RingBuffer &buffer, size_t *_bytesRead, bool releaseParti
} }
/** Copies the specified buffer into the request. This function currently /*!
* only works for the local address space (both, sender and receiver must Copies the specified buffer into the request. This function currently
* be in the same address space). only works for the local address space (both, sender and receiver must
*/ be in the same address space).
*/
status_t status_t
ReadRequest::PutData(const void **_buffer, size_t *_bytesLeft) ReadRequest::PutData(const void **_buffer, size_t *_bytesLeft)
{ {
TRACE(("pipefs: ReadRequest::PutData(buffer = %p, size = %lu)\n", *_buffer, *_bytesLeft)); TRACE(("pipefs: ReadRequest::PutData(buffer = %p, size = %lu)\n",
*_buffer, *_bytesLeft));
size_t bytes = *_bytesLeft; size_t bytes = *_bytesLeft;
if (bytes > SpaceLeft()) if (bytes > SpaceLeft())
@@ -1084,7 +1103,8 @@ pipefs_sync(fs_volume fs)
static status_t static status_t
pipefs_lookup(fs_volume _volume, fs_vnode _dir, const char *name, vnode_id *_id, int *_type) pipefs_lookup(fs_volume _volume, fs_vnode _dir, const char *name,
vnode_id *_id, int *_type)
{ {
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
status_t status; status_t status;
@@ -1120,7 +1140,8 @@ err:
static status_t static status_t
pipefs_get_vnode_name(fs_volume _volume, fs_vnode _node, char *buffer, size_t bufferSize) pipefs_get_vnode_name(fs_volume _volume, fs_vnode _node, char *buffer,
size_t bufferSize)
{ {
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
@@ -1132,7 +1153,8 @@ pipefs_get_vnode_name(fs_volume _volume, fs_vnode _node, char *buffer, size_t bu
static status_t static status_t
pipefs_get_vnode(fs_volume _volume, vnode_id id, fs_vnode *_inode, bool reenter) pipefs_get_vnode(fs_volume _volume, vnode_id id, fs_vnode *_inode,
bool reenter)
{ {
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
Inode *inode; Inode *inode;
@@ -1162,12 +1184,10 @@ pipefs_put_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
{ {
#ifdef TRACE_PIPEFS #ifdef TRACE_PIPEFS
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_putvnode: entry on vnode 0x%Lx, r %d\n", inode->ID(), reenter)); TRACE(("pipefs_putvnode: entry on vnode 0x%Lx, r %d\n", inode->ID(),
reenter));
#endif #endif
// ToDo: delete pipe - it isn't needed anymore!
//delete inode;
return B_OK; return B_OK;
} }
@@ -1178,14 +1198,16 @@ pipefs_remove_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_removevnode: remove %p (0x%Lx), r %d\n", inode, inode->ID(), reenter)); TRACE(("pipefs_removevnode: remove %p (0x%Lx), r %d\n", inode, inode->ID(),
reenter));
if (!reenter) if (!reenter)
volume->Lock(); volume->Lock();
if (inode->Next()) { if (inode->Next()) {
// can't remove node if it's linked to the dir // can't remove node if it's linked to the dir
panic("pipefs_remove_vnode(): vnode %p asked to be removed is present in dir\n", inode); panic("pipefs_remove_vnode(): vnode %p asked to be removed is present in dir\n",
inode);
} }
volume->DeleteNode(inode); volume->DeleteNode(inode);
@@ -1198,8 +1220,8 @@ pipefs_remove_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
static status_t static status_t
pipefs_create(fs_volume _volume, fs_vnode _dir, const char *name, int openMode, int mode, pipefs_create(fs_volume _volume, fs_vnode _dir, const char *name, int openMode,
fs_cookie *_cookie, vnode_id *_newVnodeID) int mode, fs_cookie *_cookie, vnode_id *_newVnodeID)
{ {
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
bool wasCreated = true; bool wasCreated = true;
@@ -1231,10 +1253,10 @@ pipefs_create(fs_volume _volume, fs_vnode _dir, const char *name, int openMode,
} }
} else { } else {
// we can just open the pipe again // we can just open the pipe again
void *dummy;
get_vnode(volume->ID(), inode->ID(), &dummy);
wasCreated = false; wasCreated = false;
} }
void *dummy;
get_vnode(volume->ID(), inode->ID(), &dummy);
volume->Unlock(); volume->Unlock();
@@ -1259,7 +1281,8 @@ err:
static status_t static status_t
pipefs_open(fs_volume _volume, fs_vnode _node, int openMode, fs_cookie *_cookie) pipefs_open(fs_volume _volume, fs_vnode _node, int openMode,
fs_cookie *_cookie)
{ {
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
@@ -1283,11 +1306,17 @@ static status_t
pipefs_close(fs_volume _volume, fs_vnode _node, fs_cookie _cookie) pipefs_close(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
{ {
file_cookie *cookie = (file_cookie *)_cookie; file_cookie *cookie = (file_cookie *)_cookie;
Volume *volume = (Volume *)_volume;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_close: entry vnode %p, cookie %p\n", _node, _cookie)); TRACE(("pipefs_close: entry vnode %p, cookie %p\n", _node, _cookie));
inode->Close(cookie->open_mode); inode->Close(cookie->open_mode);
volume->Lock();
volume->RemoveNode(inode);
volume->Unlock();
return B_OK; return B_OK;
} }
@@ -1313,14 +1342,14 @@ pipefs_fsync(fs_volume _volume, fs_vnode _v)
static status_t static status_t
pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie, off_t /*pos*/, pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
void *buffer, size_t *_length) off_t /*pos*/, void *buffer, size_t *_length)
{ {
file_cookie *cookie = (file_cookie *)_cookie; file_cookie *cookie = (file_cookie *)_cookie;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_read(vnode = %p, cookie = %p, length = %lu, mode = %d)\n", _node, cookie, *_length, TRACE(("pipefs_read(vnode = %p, cookie = %p, length = %lu, mode = %d)\n",
cookie->open_mode)); _node, cookie, *_length, cookie->open_mode));
if ((cookie->open_mode & O_RWMASK) != O_RDONLY) if ((cookie->open_mode & O_RWMASK) != O_RDONLY)
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
@@ -1359,13 +1388,14 @@ pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie, off_t /*pos*/,
static status_t static status_t
pipefs_write(fs_volume _volume, fs_vnode _node, fs_cookie _cookie, off_t /*pos*/, pipefs_write(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
const void *buffer, size_t *_length) off_t /*pos*/, const void *buffer, size_t *_length)
{ {
file_cookie *cookie = (file_cookie *)_cookie; file_cookie *cookie = (file_cookie *)_cookie;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_write(vnode = %p, cookie = %p, length = %lu)\n", _node, cookie, *_length)); TRACE(("pipefs_write(vnode = %p, cookie = %p, length = %lu)\n",
_node, cookie, *_length));
if ((cookie->open_mode & O_RWMASK) != O_WRONLY) if ((cookie->open_mode & O_RWMASK) != O_WRONLY)
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
@@ -1387,7 +1417,8 @@ pipefs_write(fs_volume _volume, fs_vnode _node, fs_cookie _cookie, off_t /*pos*/
// we could not place all our data in pending requests, so // we could not place all our data in pending requests, so
// have to put them into a temporary buffer // have to put them into a temporary buffer
status = inode->WriteDataToBuffer(&buffer, &bytesLeft, (cookie->open_mode & O_NONBLOCK) != 0); status = inode->WriteDataToBuffer(&buffer, &bytesLeft,
(cookie->open_mode & O_NONBLOCK) != 0);
if (status == B_OK) { if (status == B_OK) {
inode->FillPendingRequests(); inode->FillPendingRequests();
*_length -= bytesLeft; *_length -= bytesLeft;
@@ -1402,7 +1433,8 @@ pipefs_write(fs_volume _volume, fs_vnode _node, fs_cookie _cookie, off_t /*pos*/
static status_t static status_t
pipefs_create_dir(fs_volume _volume, fs_vnode _dir, const char *name, int perms, vnode_id *_newID) pipefs_create_dir(fs_volume _volume, fs_vnode _dir, const char *name,
int perms, vnode_id *_newID)
{ {
TRACE(("pipefs: create directory \"%s\" requested...\n", name)); TRACE(("pipefs: create directory \"%s\" requested...\n", name));
return B_NOT_SUPPORTED; return B_NOT_SUPPORTED;
@@ -1456,7 +1488,8 @@ pipefs_read_dir(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
status_t status = 0; status_t status = 0;
TRACE(("pipefs_read_dir: vnode %p, cookie %p, buffer = %p, bufferSize = %ld, num = %p\n", _node, _cookie, dirent, bufferSize,_num)); TRACE(("pipefs_read_dir: vnode %p, cookie %p, buffer = %p, bufferSize = %ld, num = %p\n",
_node, _cookie, dirent, bufferSize,_num));
if (_node != &volume->RootNode()) if (_node != &volume->RootNode())
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -1550,9 +1583,14 @@ static status_t
pipefs_free_dir_cookie(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie) pipefs_free_dir_cookie(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie)
{ {
dir_cookie *cookie = (dir_cookie *)_cookie; dir_cookie *cookie = (dir_cookie *)_cookie;
Volume *volume = (Volume *)_volume;
TRACE(("pipefs_freecookie: entry vnode %p, cookie %p\n", _vnode, cookie)); TRACE(("pipefs_freecookie: entry vnode %p, cookie %p\n", _vnode, cookie));
volume->Lock();
volume->RemoveCookie(cookie);
volume->Unlock();
free(cookie); free(cookie);
return 0; return 0;
} }
@@ -1637,7 +1675,8 @@ pipefs_unlink(fs_volume _volume, fs_vnode _dir, const char *name)
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
Inode *directory = (Inode *)_dir; Inode *directory = (Inode *)_dir;
TRACE(("pipefs_unlink: dir %p (0x%Lx), name '%s'\n", _dir, directory->ID(), name)); TRACE(("pipefs_unlink: dir %p (0x%Lx), name '%s'\n",
_dir, directory->ID(), name));
return volume->RemoveNode(directory, name); return volume->RemoveNode(directory, name);
} }
@@ -1649,7 +1688,8 @@ pipefs_read_stat(fs_volume _volume, fs_vnode _node, struct stat *stat)
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_read_stat: vnode %p (0x%Lx), stat %p\n", inode, inode->ID(), stat)); TRACE(("pipefs_read_stat: vnode %p (0x%Lx), stat %p\n",
inode, inode->ID(), stat));
stat->st_dev = volume->ID(); stat->st_dev = volume->ID();
stat->st_ino = inode->ID(); stat->st_ino = inode->ID();
@@ -1674,12 +1714,14 @@ pipefs_read_stat(fs_volume _volume, fs_vnode _node, struct stat *stat)
static status_t static status_t
pipefs_write_stat(fs_volume _volume, fs_vnode _node, const struct stat *stat, uint32 statMask) pipefs_write_stat(fs_volume _volume, fs_vnode _node, const struct stat *stat,
uint32 statMask)
{ {
Volume *volume = (Volume *)_volume; Volume *volume = (Volume *)_volume;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
TRACE(("pipefs_write_stat: vnode %p (0x%Lx), stat %p\n", inode, inode->ID(), stat)); TRACE(("pipefs_write_stat: vnode %p (0x%Lx), stat %p\n",
inode, inode->ID(), stat));
// we cannot change the size of anything // we cannot change the size of anything
if (statMask & B_STAT_SIZE) if (statMask & B_STAT_SIZE)