* Removed the asynchronous I/O methods. We won't implement them for the time
being. * Introduced locking for FileCookie. * Implemented SetFlags() and FSync(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29736 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -383,10 +383,11 @@ FUSEFileSystem::_InitCapabilities()
|
|||||||
|
|
||||||
// common operations
|
// common operations
|
||||||
// missing: FS_VNODE_CAPABILITY_IOCTL
|
// missing: FS_VNODE_CAPABILITY_IOCTL
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SET_FLAGS, fFS->ops.setflags);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SET_FLAGS, true);
|
||||||
|
// emulated
|
||||||
// missing: FS_VNODE_CAPABILITY_SELECT
|
// missing: FS_VNODE_CAPABILITY_SELECT
|
||||||
// missing: FS_VNODE_CAPABILITY_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);
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ struct FUSEVolume::DirCookie : fuse_file_info, RWLockable {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FUSEVolume::FileCookie : fuse_file_info {
|
struct FUSEVolume::FileCookie : fuse_file_info, RWLockable {
|
||||||
FileCookie(int openMode)
|
FileCookie(int openMode)
|
||||||
{
|
{
|
||||||
flags = openMode;
|
flags = openMode;
|
||||||
@@ -298,6 +298,41 @@ struct FUSEVolume::ReadDirBuffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct FUSEVolume::RWLockableReadLocking {
|
||||||
|
RWLockableReadLocking(FUSEVolume* volume)
|
||||||
|
:
|
||||||
|
fLockManager(volume != NULL ? &volume->fLockManager : NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RWLockableReadLocking(RWLockManager* lockManager)
|
||||||
|
:
|
||||||
|
fLockManager(lockManager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RWLockableReadLocking(const RWLockableReadLocking& other)
|
||||||
|
:
|
||||||
|
fLockManager(other.fLockManager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Lock(RWLockable* lockable)
|
||||||
|
{
|
||||||
|
return fLockManager != NULL && fLockManager->ReadLock(lockable);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Unlock(RWLockable* lockable)
|
||||||
|
{
|
||||||
|
if (fLockManager != NULL)
|
||||||
|
fLockManager->ReadUnlock(lockable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RWLockManager* fLockManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FUSEVolume::RWLockableWriteLocking {
|
struct FUSEVolume::RWLockableWriteLocking {
|
||||||
RWLockableWriteLocking(FUSEVolume* volume)
|
RWLockableWriteLocking(FUSEVolume* volume)
|
||||||
:
|
:
|
||||||
@@ -333,6 +368,19 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct FUSEVolume::RWLockableReadLocker
|
||||||
|
: public AutoLocker<RWLockable, RWLockableReadLocking> {
|
||||||
|
|
||||||
|
RWLockableReadLocker(FUSEVolume* volume, RWLockable* lockable)
|
||||||
|
:
|
||||||
|
AutoLocker<RWLockable, RWLockableReadLocking>(
|
||||||
|
RWLockableReadLocking(volume))
|
||||||
|
{
|
||||||
|
SetTo(lockable, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FUSEVolume::RWLockableWriteLocker
|
struct FUSEVolume::RWLockableWriteLocker
|
||||||
: public AutoLocker<RWLockable, RWLockableWriteLocking> {
|
: public AutoLocker<RWLockable, RWLockableWriteLocking> {
|
||||||
|
|
||||||
@@ -646,59 +694,61 @@ FUSEVolume::RemoveVNode(void* node, bool reenter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - asynchronous I/O
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::DoIO(void* node, void* cookie, const IORequestInfo& requestInfo)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::CancelIO(void* node, void* cookie, int32 ioRequestID)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::IterativeIOGetVecs(void* cookie, int32 requestID, off_t offset,
|
|
||||||
size_t size, struct file_io_vec* vecs, size_t* _count)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
FUSEVolume::IterativeIOFinished(void* cookie, int32 requestID, status_t status,
|
|
||||||
bool partialTransfer, size_t bytesTransferred)
|
|
||||||
{
|
|
||||||
// TODO: Implement!
|
|
||||||
return B_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - nodes
|
// #pragma mark - nodes
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::SetFlags(void* node, void* cookie, int flags)
|
FUSEVolume::SetFlags(void* _node, void* _cookie, int flags)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FileCookie* cookie = (FileCookie*)_cookie;
|
||||||
return B_UNSUPPORTED;
|
|
||||||
|
RWLockableWriteLocker cookieLocker(this, cookie);
|
||||||
|
|
||||||
|
const int settableFlags = O_APPEND | O_NONBLOCK | O_SYNC | O_RSYNC
|
||||||
|
| O_DSYNC | O_DIRECT;
|
||||||
|
|
||||||
|
cookie->flags = (cookie->flags & ~settableFlags) | (flags & settableFlags);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::FSync(void* node)
|
FUSEVolume::FSync(void* _node)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* node = (FUSENode*)_node;
|
||||||
return B_UNSUPPORTED;
|
|
||||||
|
// lock the directory
|
||||||
|
NodeReadLocker nodeLocker(this, node, true);
|
||||||
|
if (nodeLocker.Status() != B_OK)
|
||||||
|
RETURN_ERROR(nodeLocker.Status());
|
||||||
|
|
||||||
|
AutoLocker<Locker> locker(fLock);
|
||||||
|
|
||||||
|
// get a path for the node
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
size_t pathLen;
|
||||||
|
status_t error = _BuildPath(node, path, pathLen);
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// open, sync, and close the node
|
||||||
|
FileCookie cookie(O_RDONLY);
|
||||||
|
int fuseError = fuse_fs_open(fFS, path, &cookie);
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
fuseError = fuse_fs_fsync(fFS, path, 0, &cookie);
|
||||||
|
// full sync, not only data
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
fuse_fs_flush(fFS, path, &cookie);
|
||||||
|
fuse_fs_release(fFS, path, &cookie);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1092,6 +1142,8 @@ FUSEVolume::Close(void* _node, void* _cookie)
|
|||||||
FUSENode* node = (FUSENode*)_node;
|
FUSENode* node = (FUSENode*)_node;
|
||||||
FileCookie* cookie = (FileCookie*)_cookie;
|
FileCookie* cookie = (FileCookie*)_cookie;
|
||||||
|
|
||||||
|
RWLockableReadLocker cookieLocker(this, cookie);
|
||||||
|
|
||||||
// lock the directory
|
// lock the directory
|
||||||
NodeReadLocker nodeLocker(this, node, true);
|
NodeReadLocker nodeLocker(this, node, true);
|
||||||
if (nodeLocker.Status() != B_OK)
|
if (nodeLocker.Status() != B_OK)
|
||||||
@@ -1123,6 +1175,8 @@ FUSEVolume::FreeCookie(void* _node, void* _cookie)
|
|||||||
FUSENode* node = (FUSENode*)_node;
|
FUSENode* node = (FUSENode*)_node;
|
||||||
FileCookie* cookie = (FileCookie*)_cookie;
|
FileCookie* cookie = (FileCookie*)_cookie;
|
||||||
|
|
||||||
|
// no need to lock the cookie here, as no-one else uses it anymore
|
||||||
|
|
||||||
// lock the directory
|
// lock the directory
|
||||||
NodeReadLocker nodeLocker(this, node, true);
|
NodeReadLocker nodeLocker(this, node, true);
|
||||||
if (nodeLocker.Status() != B_OK)
|
if (nodeLocker.Status() != B_OK)
|
||||||
@@ -1157,6 +1211,8 @@ FUSEVolume::Read(void* _node, void* _cookie, off_t pos, void* buffer,
|
|||||||
FUSENode* node = (FUSENode*)_node;
|
FUSENode* node = (FUSENode*)_node;
|
||||||
FileCookie* cookie = (FileCookie*)_cookie;
|
FileCookie* cookie = (FileCookie*)_cookie;
|
||||||
|
|
||||||
|
RWLockableReadLocker cookieLocker(this, cookie);
|
||||||
|
|
||||||
*_bytesRead = 0;
|
*_bytesRead = 0;
|
||||||
|
|
||||||
// lock the directory
|
// lock the directory
|
||||||
@@ -1193,6 +1249,8 @@ FUSEVolume::Write(void* _node, void* _cookie, off_t pos, const void* buffer,
|
|||||||
FUSENode* node = (FUSENode*)_node;
|
FUSENode* node = (FUSENode*)_node;
|
||||||
FileCookie* cookie = (FileCookie*)_cookie;
|
FileCookie* cookie = (FileCookie*)_cookie;
|
||||||
|
|
||||||
|
RWLockableReadLocker cookieLocker(this, cookie);
|
||||||
|
|
||||||
*_bytesWritten = 0;
|
*_bytesWritten = 0;
|
||||||
|
|
||||||
// lock the directory
|
// lock the directory
|
||||||
|
|||||||
@@ -51,19 +51,6 @@ public:
|
|||||||
virtual status_t WriteVNode(void* node, bool reenter);
|
virtual status_t WriteVNode(void* node, bool reenter);
|
||||||
virtual status_t RemoveVNode(void* node, bool reenter);
|
virtual status_t RemoveVNode(void* node, bool reenter);
|
||||||
|
|
||||||
// asynchronous I/O
|
|
||||||
virtual status_t DoIO(void* node, void* cookie,
|
|
||||||
const IORequestInfo& requestInfo);
|
|
||||||
virtual status_t CancelIO(void* node, void* cookie,
|
|
||||||
int32 ioRequestID);
|
|
||||||
virtual status_t IterativeIOGetVecs(void* cookie,
|
|
||||||
int32 requestID, off_t offset, size_t size,
|
|
||||||
struct file_io_vec* vecs, size_t* _count);
|
|
||||||
virtual status_t IterativeIOFinished(void* cookie,
|
|
||||||
int32 requestID, status_t status,
|
|
||||||
bool partialTransfer,
|
|
||||||
size_t bytesTransferred);
|
|
||||||
|
|
||||||
// nodes
|
// nodes
|
||||||
virtual status_t SetFlags(void* node, void* cookie,
|
virtual status_t SetFlags(void* node, void* cookie,
|
||||||
int flags);
|
int flags);
|
||||||
@@ -129,12 +116,15 @@ private:
|
|||||||
struct FileCookie;
|
struct FileCookie;
|
||||||
struct AttrDirCookie;
|
struct AttrDirCookie;
|
||||||
struct ReadDirBuffer;
|
struct ReadDirBuffer;
|
||||||
|
struct RWLockableReadLocking;
|
||||||
struct RWLockableWriteLocking;
|
struct RWLockableWriteLocking;
|
||||||
|
struct RWLockableReadLocker;
|
||||||
struct RWLockableWriteLocker;
|
struct RWLockableWriteLocker;
|
||||||
struct NodeLocker;
|
struct NodeLocker;
|
||||||
struct NodeReadLocker;
|
struct NodeReadLocker;
|
||||||
struct NodeWriteLocker;
|
struct NodeWriteLocker;
|
||||||
|
|
||||||
|
friend struct RWLockableReadLocking;
|
||||||
friend struct RWLockableWriteLocking;
|
friend struct RWLockableWriteLocking;
|
||||||
friend struct NodeLocker;
|
friend struct NodeLocker;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user