* Added support for symlink and directory creation, as well as entry deletion
(directories and other nodes). * Removed methods we can't possibly implement, since the FUSE interface doesn't provide them and we can't emulate them. * A FUSEEntry does now also own a reference to its parent directory. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29715 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -345,35 +345,23 @@ FUSEFileSystem::_InitCapabilities()
|
|||||||
fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_GET_VNODE, true);
|
fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_GET_VNODE, true);
|
||||||
// emulated
|
// emulated
|
||||||
|
|
||||||
// // index directory & index operations
|
// index directory & index operations
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_OPEN_INDEX_DIR,
|
// missing: FS_VOLUME_CAPABILITY_OPEN_INDEX_DIR
|
||||||
// fFS->ops.open_indexdir);
|
// missing: FS_VOLUME_CAPABILITY_CLOSE_INDEX_DIR
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CLOSE_INDEX_DIR,
|
// missing: FS_VOLUME_CAPABILITY_FREE_INDEX_DIR_COOKIE
|
||||||
// fFS->ops.close_indexdir);
|
// missing: FS_VOLUME_CAPABILITY_READ_INDEX_DIR
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_FREE_INDEX_DIR_COOKIE,
|
// missing: FS_VOLUME_CAPABILITY_REWIND_INDEX_DIR
|
||||||
// fFS->ops.free_indexdircookie);
|
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_INDEX_DIR,
|
// missing: FS_VOLUME_CAPABILITY_CREATE_INDEX
|
||||||
// fFS->ops.read_indexdir);
|
// missing: FS_VOLUME_CAPABILITY_REMOVE_INDEX
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_REWIND_INDEX_DIR,
|
// missing: FS_VOLUME_CAPABILITY_READ_INDEX_STAT
|
||||||
// fFS->ops.rewind_indexdir);
|
|
||||||
//
|
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CREATE_INDEX,
|
|
||||||
// fFS->ops.create_index);
|
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_REMOVE_INDEX,
|
|
||||||
// fFS->ops.remove_index);
|
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_INDEX_STAT,
|
|
||||||
// fFS->ops.stat_index);
|
|
||||||
|
|
||||||
// query operations
|
// query operations
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_OPEN_QUERY,
|
// missing: FS_VOLUME_CAPABILITY_OPEN_QUERY
|
||||||
// fFS->ops.open_query);
|
// missing: FS_VOLUME_CAPABILITY_CLOSE_QUERY
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CLOSE_QUERY,
|
// missing: FS_VOLUME_CAPABILITY_FREE_QUERY_COOKIE
|
||||||
// fFS->ops.close_query);
|
// missing: FS_VOLUME_CAPABILITY_READ_QUERY
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_FREE_QUERY_COOKIE,
|
// missing: FS_VOLUME_CAPABILITY_REWIND_QUERY
|
||||||
// fFS->ops.free_querycookie);
|
|
||||||
// fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_QUERY,
|
|
||||||
// fFS->ops.read_query);
|
|
||||||
// // missing: FS_VOLUME_CAPABILITY_REWIND_QUERY,
|
|
||||||
|
|
||||||
// vnode operations
|
// vnode operations
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LOOKUP, true);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LOOKUP, true);
|
||||||
@@ -386,25 +374,25 @@ FUSEFileSystem::_InitCapabilities()
|
|||||||
// emulated
|
// emulated
|
||||||
|
|
||||||
// VM file access
|
// VM file access
|
||||||
// missing: FS_VNODE_CAPABILITY_CAN_PAGE,
|
// missing: FS_VNODE_CAPABILITY_CAN_PAGE
|
||||||
// missing: FS_VNODE_CAPABILITY_READ_PAGES,
|
// missing: FS_VNODE_CAPABILITY_READ_PAGES
|
||||||
// missing: FS_VNODE_CAPABILITY_WRITE_PAGES,
|
// missing: FS_VNODE_CAPABILITY_WRITE_PAGES
|
||||||
|
|
||||||
// cache file access
|
// cache file access
|
||||||
// missing: FS_VNODE_CAPABILITY_GET_FILE_MAP,
|
// missing: FS_VNODE_CAPABILITY_GET_FILE_MAP
|
||||||
|
|
||||||
// common operations
|
// common operations
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_IOCTL, fFS->ops.ioctl);
|
// missing: FS_VNODE_CAPABILITY_IOCTL
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SET_FLAGS, fFS->ops.setflags);
|
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SET_FLAGS, fFS->ops.setflags);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SELECT, fFS->ops.select);
|
// missing: FS_VNODE_CAPABILITY_SELECT
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_DESELECT, fFS->ops.deselect);
|
// missing: FS_VNODE_CAPABILITY_DESELECT
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FSYNC, fFS->ops.fsync);
|
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FSYNC, fFS->ops.fsync);
|
||||||
|
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_SYMLINK, fFS->ops.readlink);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_SYMLINK, fFS->ops.readlink);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_SYMLINK, fFS->ops.symlink);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_SYMLINK, fFS->ops.symlink);
|
||||||
|
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LINK, fFS->ops.link);
|
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LINK, fFS->ops.link);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_UNLINK, fFS->ops.unlink);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_UNLINK, fFS->ops.unlink);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME, fFS->ops.rename);
|
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME, fFS->ops.rename);
|
||||||
|
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_ACCESS, fFS->ops.access);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_ACCESS, fFS->ops.access);
|
||||||
@@ -420,13 +408,12 @@ FUSEFileSystem::_InitCapabilities()
|
|||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE, fFS->ops.write);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE, fFS->ops.write);
|
||||||
|
|
||||||
// directory operations
|
// directory operations
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_DIR, fFS->ops.mkdir);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_DIR, fFS->ops.mkdir);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_DIR, fFS->ops.rmdir);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_DIR, fFS->ops.rmdir);
|
||||||
bool readDirSupport = fFS->ops.opendir != NULL || fFS->ops.readdir != NULL
|
bool readDirSupport = fFS->ops.opendir != NULL || fFS->ops.readdir != NULL
|
||||||
|| fFS->ops.getdir;
|
|| fFS->ops.getdir;
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_DIR, readDirSupport);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_DIR, readDirSupport);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE_DIR, true);
|
// not needed: FS_VNODE_CAPABILITY_CLOSE_DIR
|
||||||
// not needed
|
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_DIR_COOKIE, readDirSupport);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_DIR_COOKIE, readDirSupport);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_DIR, readDirSupport);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_DIR, readDirSupport);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_DIR, readDirSupport);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_DIR, readDirSupport);
|
||||||
@@ -434,8 +421,7 @@ FUSEFileSystem::_InitCapabilities()
|
|||||||
// attribute directory operations
|
// attribute directory operations
|
||||||
bool hasAttributes = fFS->ops.listxattr != NULL;
|
bool hasAttributes = fFS->ops.listxattr != NULL;
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_ATTR_DIR, hasAttributes);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_ATTR_DIR, hasAttributes);
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE_ATTR_DIR, true);
|
// not needed: FS_VNODE_CAPABILITY_CLOSE_ATTR_DIR
|
||||||
// not needed
|
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_DIR_COOKIE,
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_DIR_COOKIE,
|
||||||
hasAttributes);
|
hasAttributes);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_DIR, hasAttributes);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_DIR, hasAttributes);
|
||||||
|
|||||||
@@ -483,6 +483,7 @@ printf("FUSEVolume::Mount()\n");
|
|||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node->refCount++; // for the entry
|
||||||
node->entries.Add(entry);
|
node->entries.Add(entry);
|
||||||
fRootNode = node;
|
fRootNode = node;
|
||||||
|
|
||||||
@@ -684,15 +685,6 @@ FUSEVolume::IterativeIOFinished(void* cookie, int32 requestID, status_t status,
|
|||||||
// #pragma mark - nodes
|
// #pragma mark - nodes
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::IOCtl(void* node, void* cookie, uint32 command, void *buffer,
|
|
||||||
size_t size)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::SetFlags(void* node, void* cookie, int flags)
|
FUSEVolume::SetFlags(void* node, void* cookie, int flags)
|
||||||
{
|
{
|
||||||
@@ -701,22 +693,6 @@ FUSEVolume::SetFlags(void* node, void* cookie, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::Select(void* node, void* cookie, uint8 event, selectsync* sync)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::Deselect(void* node, void* cookie, uint8 event, selectsync* sync)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::FSync(void* node)
|
FUSEVolume::FSync(void* node)
|
||||||
{
|
{
|
||||||
@@ -764,11 +740,39 @@ FUSEVolume::ReadSymlink(void* _node, char* buffer, size_t bufferSize,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::CreateSymlink(void* dir, const char* name, const char* target,
|
FUSEVolume::CreateSymlink(void* _dir, const char* name, const char* target,
|
||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* dir = (FUSENode*)_dir;
|
||||||
return B_UNSUPPORTED;
|
PRINT(("FUSEVolume::CreateSymlink(%p (%lld), \"%s\" -> \"%s\", %#x)\n", dir,
|
||||||
|
dir->id, name, target, mode));
|
||||||
|
|
||||||
|
// lock the directory
|
||||||
|
NodeWriteLocker nodeLocker(this, dir, false);
|
||||||
|
if (nodeLocker.Status() != B_OK)
|
||||||
|
RETURN_ERROR(nodeLocker.Status());
|
||||||
|
|
||||||
|
AutoLocker<Locker> locker(fLock);
|
||||||
|
|
||||||
|
// get a path for the entry
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
size_t pathLen;
|
||||||
|
status_t error = _BuildPath(dir, name, path, pathLen);
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// create the dir
|
||||||
|
int fuseError = fuse_fs_symlink(fFS, target, path);
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// TODO: Set the mode?!
|
||||||
|
|
||||||
|
// TODO: Node monitoring!
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -781,10 +785,39 @@ FUSEVolume::Link(void* dir, const char* name, void* node)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::Unlink(void* dir, const char* name)
|
FUSEVolume::Unlink(void* _dir, const char* name)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* dir = (FUSENode*)_dir;
|
||||||
return B_UNSUPPORTED;
|
PRINT(("FUSEVolume::Unlink(%p (%lld), \"%s\")\n", dir, dir->id, name));
|
||||||
|
|
||||||
|
// lock the directory
|
||||||
|
NodeWriteLocker nodeLocker(this, dir, false);
|
||||||
|
if (nodeLocker.Status() != B_OK)
|
||||||
|
RETURN_ERROR(nodeLocker.Status());
|
||||||
|
|
||||||
|
AutoLocker<Locker> locker(fLock);
|
||||||
|
|
||||||
|
// get a path for the entry
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
size_t pathLen;
|
||||||
|
status_t error = _BuildPath(dir, name, path, pathLen);
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// unlink
|
||||||
|
int fuseError = fuse_fs_unlink(fFS, path);
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// remove the entry
|
||||||
|
locker.Lock();
|
||||||
|
_RemoveEntry(dir, name);
|
||||||
|
|
||||||
|
// TODO: Node monitoring!
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -904,6 +937,8 @@ openMode, mode));
|
|||||||
if (fuseError != 0)
|
if (fuseError != 0)
|
||||||
RETURN_ERROR(fuseError);
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// TODO: Node monitoring!
|
||||||
|
|
||||||
// get the node
|
// get the node
|
||||||
FUSENode* node;
|
FUSENode* node;
|
||||||
error = _GetNode(dir, name, &node);
|
error = _GetNode(dir, name, &node);
|
||||||
@@ -968,6 +1003,7 @@ PRINT(("FUSEVolume::Open(%p (%lld), %#x)\n", node, node->id, openMode));
|
|||||||
fuse_fs_release(fFS, path, cookie);
|
fuse_fs_release(fFS, path, cookie);
|
||||||
RETURN_ERROR(fuseError);
|
RETURN_ERROR(fuseError);
|
||||||
}
|
}
|
||||||
|
// TODO: Node monitoring!
|
||||||
}
|
}
|
||||||
|
|
||||||
cookieDeleter.Detach();
|
cookieDeleter.Detach();
|
||||||
@@ -1067,7 +1103,6 @@ FUSEVolume::Read(void* _node, void* _cookie, off_t pos, void* buffer,
|
|||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
// read the file
|
// read the file
|
||||||
|
|
||||||
int bytesRead = fuse_fs_read(fFS, path, (char*)buffer, bufferSize, pos,
|
int bytesRead = fuse_fs_read(fFS, path, (char*)buffer, bufferSize, pos,
|
||||||
cookie);
|
cookie);
|
||||||
if (bytesRead < 0)
|
if (bytesRead < 0)
|
||||||
@@ -1103,13 +1138,14 @@ FUSEVolume::Write(void* _node, void* _cookie, off_t pos, const void* buffer,
|
|||||||
|
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
// read the file
|
// write the file
|
||||||
|
|
||||||
int bytesWritten = fuse_fs_write(fFS, path, (const char*)buffer, bufferSize,
|
int bytesWritten = fuse_fs_write(fFS, path, (const char*)buffer, bufferSize,
|
||||||
pos, cookie);
|
pos, cookie);
|
||||||
if (bytesWritten < 0)
|
if (bytesWritten < 0)
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
|
|
||||||
|
// TODO: Node monitoring?
|
||||||
|
|
||||||
*_bytesWritten = bytesWritten;
|
*_bytesWritten = bytesWritten;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -1119,18 +1155,76 @@ FUSEVolume::Write(void* _node, void* _cookie, off_t pos, const void* buffer,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::CreateDir(void* dir, const char* name, int mode, ino_t *newDir)
|
FUSEVolume::CreateDir(void* _dir, const char* name, int mode, ino_t *newDir)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* dir = (FUSENode*)_dir;
|
||||||
return B_UNSUPPORTED;
|
PRINT(("FUSEVolume::CreateDir(%p (%lld), \"%s\", %#x)\n", dir, dir->id, name,
|
||||||
|
mode));
|
||||||
|
|
||||||
|
// lock the directory
|
||||||
|
NodeWriteLocker nodeLocker(this, dir, false);
|
||||||
|
if (nodeLocker.Status() != B_OK)
|
||||||
|
RETURN_ERROR(nodeLocker.Status());
|
||||||
|
|
||||||
|
AutoLocker<Locker> locker(fLock);
|
||||||
|
|
||||||
|
// get a path for the entry
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
size_t pathLen;
|
||||||
|
status_t error = _BuildPath(dir, name, path, pathLen);
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// create the dir
|
||||||
|
int fuseError = fuse_fs_mkdir(fFS, path, mode);
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// TODO: Node monitoring!
|
||||||
|
|
||||||
|
*newDir = 0;
|
||||||
|
// TODO: This is really superfluous!
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::RemoveDir(void* dir, const char* name)
|
FUSEVolume::RemoveDir(void* _dir, const char* name)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* dir = (FUSENode*)_dir;
|
||||||
return B_UNSUPPORTED;
|
PRINT(("FUSEVolume::RemoveDir(%p (%lld), \"%s\")\n", dir, dir->id, name));
|
||||||
|
|
||||||
|
// lock the directory
|
||||||
|
NodeWriteLocker nodeLocker(this, dir, false);
|
||||||
|
if (nodeLocker.Status() != B_OK)
|
||||||
|
RETURN_ERROR(nodeLocker.Status());
|
||||||
|
|
||||||
|
AutoLocker<Locker> locker(fLock);
|
||||||
|
|
||||||
|
// get a path for the entry
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
size_t pathLen;
|
||||||
|
status_t error = _BuildPath(dir, name, path, pathLen);
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// remove the dir
|
||||||
|
int fuseError = fuse_fs_rmdir(fFS, path);
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// remove the entry
|
||||||
|
locker.Lock();
|
||||||
|
_RemoveEntry(dir, name);
|
||||||
|
|
||||||
|
// TODO: Node monitoring!
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1604,6 +1698,9 @@ FUSEVolume::_InternalGetNode(FUSENode* dir, const char* entryName,
|
|||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dir->refCount++;
|
||||||
|
// dir reference for the entry
|
||||||
|
|
||||||
fEntries.Insert(entry);
|
fEntries.Insert(entry);
|
||||||
node->entries.Add(entry);
|
node->entries.Add(entry);
|
||||||
|
|
||||||
@@ -1635,6 +1732,33 @@ FUSEVolume::_PutNodes(FUSENode* const* nodes, int32 count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Volume must be locked. The entry's directory must be write locked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
FUSEVolume::_RemoveEntry(FUSEEntry* entry)
|
||||||
|
{
|
||||||
|
fEntries.Remove(entry);
|
||||||
|
entry->node->entries.Remove(entry);
|
||||||
|
_PutNode(entry->node);
|
||||||
|
_PutNode(entry->parent);
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Volume must be locked. The directory must be write locked.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
FUSEVolume::_RemoveEntry(FUSENode* dir, const char* name)
|
||||||
|
{
|
||||||
|
FUSEEntry* entry = fEntries.Lookup(FUSEEntryRef(dir->id, name));
|
||||||
|
if (entry == NULL)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
_RemoveEntry(entry);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Locks the given node and all of its ancestors up to the root. The given
|
/*! Locks the given node and all of its ancestors up to the root. The given
|
||||||
node is write-locked, if \a writeLock is \c true, read-locked otherwise. All
|
node is write-locked, if \a writeLock is \c true, read-locked otherwise. All
|
||||||
ancestors are always read-locked in either case.
|
ancestors are always read-locked in either case.
|
||||||
@@ -1901,6 +2025,9 @@ PRINT((" -> create node: %p, id: %lld\n", node, nodeID));
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffer->directory->refCount++;
|
||||||
|
// dir reference for the entry
|
||||||
|
|
||||||
fEntries.Insert(entry);
|
fEntries.Insert(entry);
|
||||||
node->entries.Add(entry);
|
node->entries.Add(entry);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -65,14 +65,8 @@ public:
|
|||||||
size_t bytesTransferred);
|
size_t bytesTransferred);
|
||||||
|
|
||||||
// nodes
|
// nodes
|
||||||
virtual status_t IOCtl(void* node, void* cookie,
|
|
||||||
uint32 command, void* buffer, size_t size);
|
|
||||||
virtual status_t SetFlags(void* node, void* cookie,
|
virtual status_t SetFlags(void* node, void* cookie,
|
||||||
int flags);
|
int flags);
|
||||||
virtual status_t Select(void* node, void* cookie,
|
|
||||||
uint8 event, selectsync* sync);
|
|
||||||
virtual status_t Deselect(void* node, void* cookie,
|
|
||||||
uint8 event, selectsync* sync);
|
|
||||||
|
|
||||||
virtual status_t FSync(void* node);
|
virtual status_t FSync(void* node);
|
||||||
|
|
||||||
@@ -157,6 +151,9 @@ private:
|
|||||||
void _PutNode(FUSENode* node);
|
void _PutNode(FUSENode* node);
|
||||||
void _PutNodes(FUSENode* const* nodes, int32 count);
|
void _PutNodes(FUSENode* const* nodes, int32 count);
|
||||||
|
|
||||||
|
void _RemoveEntry(FUSEEntry* entry);
|
||||||
|
status_t _RemoveEntry(FUSENode* dir, const char* name);
|
||||||
|
|
||||||
status_t _LockNodeChain(FUSENode* node, bool parent,
|
status_t _LockNodeChain(FUSENode* node, bool parent,
|
||||||
bool writeLock);
|
bool writeLock);
|
||||||
void _UnlockNodeChain(FUSENode* node, bool parent,
|
void _UnlockNodeChain(FUSENode* node, bool parent,
|
||||||
|
|||||||
Reference in New Issue
Block a user