Added support for O_TRUNC, file creation, and writing to files.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29689 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -412,12 +412,12 @@ FUSEFileSystem::_InitCapabilities()
|
|||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_STAT, fFS->ops.wstat);
|
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_STAT, fFS->ops.wstat);
|
||||||
|
|
||||||
// file operations
|
// file operations
|
||||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE, fFS->ops.create);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE, fFS->ops.create);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN, fFS->ops.open);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN, fFS->ops.open);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE, fFS->ops.flush);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE, fFS->ops.flush);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_COOKIE, fFS->ops.release);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_COOKIE, fFS->ops.release);
|
||||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ, fFS->ops.read);
|
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ, fFS->ops.read);
|
||||||
// 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);
|
||||||
|
|||||||
@@ -870,11 +870,57 @@ FUSEVolume::WriteStat(void* node, const struct stat *st, uint32 mask)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::Create(void* dir, const char* name, int openMode, int mode,
|
FUSEVolume::Create(void* _dir, const char* name, int openMode, int mode,
|
||||||
void** cookie, ino_t* vnid)
|
void** _cookie, ino_t* _vnid)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* dir = (FUSENode*)_dir;
|
||||||
return B_UNSUPPORTED;
|
PRINT(("FUSEVolume::Create(%p (%lld), \"%s\", %#x, %#x)\n", dir, dir->id, name,
|
||||||
|
openMode, mode));
|
||||||
|
|
||||||
|
// lock the directory
|
||||||
|
NodeWriteLocker nodeLocker(this, dir, false);
|
||||||
|
if (nodeLocker.Status() != B_OK)
|
||||||
|
RETURN_ERROR(nodeLocker.Status());
|
||||||
|
|
||||||
|
// allocate a file cookie
|
||||||
|
FileCookie* cookie = new(std::nothrow) FileCookie(openMode);
|
||||||
|
if (cookie == NULL)
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
ObjectDeleter<FileCookie> cookieDeleter(cookie);
|
||||||
|
|
||||||
|
AutoLocker<Locker> locker(fLock);
|
||||||
|
|
||||||
|
// get a path for the node
|
||||||
|
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 file
|
||||||
|
int fuseError = fuse_fs_create(fFS, path, mode, cookie);
|
||||||
|
if (fuseError != 0)
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// get the node
|
||||||
|
FUSENode* node;
|
||||||
|
error = _GetNode(dir, name, &node);
|
||||||
|
if (error != B_OK) {
|
||||||
|
// This is bad. We've create the file successfully, but couldn't get
|
||||||
|
// the node. Close the file and delete the entry.
|
||||||
|
fuse_fs_flush(fFS, path, cookie);
|
||||||
|
fuse_fs_release(fFS, path, cookie);
|
||||||
|
fuse_fs_unlink(fFS, path);
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
cookieDeleter.Detach();
|
||||||
|
*_cookie = cookie;
|
||||||
|
*_vnid = node->id;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -892,10 +938,6 @@ PRINT(("FUSEVolume::Open(%p (%lld), %#x)\n", node, node->id, openMode));
|
|||||||
bool truncate = (openMode & O_TRUNC) != 0;
|
bool truncate = (openMode & O_TRUNC) != 0;
|
||||||
openMode &= ~O_TRUNC;
|
openMode &= ~O_TRUNC;
|
||||||
|
|
||||||
// TODO: Support truncation!
|
|
||||||
if (truncate)
|
|
||||||
RETURN_ERROR(B_NOT_ALLOWED);
|
|
||||||
|
|
||||||
// allocate a file cookie
|
// allocate a file cookie
|
||||||
FileCookie* cookie = new(std::nothrow) FileCookie(openMode);
|
FileCookie* cookie = new(std::nothrow) FileCookie(openMode);
|
||||||
if (cookie == NULL)
|
if (cookie == NULL)
|
||||||
@@ -916,7 +958,17 @@ PRINT(("FUSEVolume::Open(%p (%lld), %#x)\n", node, node->id, openMode));
|
|||||||
// open the file
|
// open the file
|
||||||
int fuseError = fuse_fs_open(fFS, path, cookie);
|
int fuseError = fuse_fs_open(fFS, path, cookie);
|
||||||
if (fuseError != 0)
|
if (fuseError != 0)
|
||||||
return fuseError;
|
RETURN_ERROR(fuseError);
|
||||||
|
|
||||||
|
// truncate the file, if requested
|
||||||
|
if (truncate) {
|
||||||
|
fuseError = fuse_fs_ftruncate(fFS, path, 0, cookie);
|
||||||
|
if (fuseError != 0) {
|
||||||
|
fuse_fs_flush(fFS, path, cookie);
|
||||||
|
fuse_fs_release(fFS, path, cookie);
|
||||||
|
RETURN_ERROR(fuseError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cookieDeleter.Detach();
|
cookieDeleter.Detach();
|
||||||
*_cookie = cookie;
|
*_cookie = cookie;
|
||||||
@@ -1027,11 +1079,39 @@ FUSEVolume::Read(void* _node, void* _cookie, off_t pos, void* buffer,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FUSEVolume::Write(void* node, void* cookie, off_t pos, const void* buffer,
|
FUSEVolume::Write(void* _node, void* _cookie, off_t pos, const void* buffer,
|
||||||
size_t bufferSize, size_t* bytesWritten)
|
size_t bufferSize, size_t* _bytesWritten)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
FUSENode* node = (FUSENode*)_node;
|
||||||
return B_UNSUPPORTED;
|
FileCookie* cookie = (FileCookie*)_cookie;
|
||||||
|
|
||||||
|
*_bytesWritten = 0;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// read the file
|
||||||
|
|
||||||
|
int bytesWritten = fuse_fs_write(fFS, path, (const char*)buffer, bufferSize,
|
||||||
|
pos, cookie);
|
||||||
|
if (bytesWritten < 0)
|
||||||
|
return bytesWritten;
|
||||||
|
|
||||||
|
*_bytesWritten = bytesWritten;
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user