* 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:
+144
-102
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user