RAMFS: Properly check that the Lockers are actually locked.

They pretty much always will be, but better to be safe. Also
de-indent one level and use an early return for this.
This commit is contained in:
Augustin Cavalier 2024-11-22 18:07:26 -05:00
parent 374d7a1eb1
commit e2e7d84d21

View File

@ -1509,158 +1509,155 @@ private:
}; };
// ramfs_create_attr
static status_t static status_t
ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name, ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
uint32 type, int openMode, void** _cookie) uint32 type, int openMode, void** _cookie)
{ {
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
if (VolumeWriteLocker locker = volume) { VolumeWriteLocker locker(volume);
// try to find the attribute if (!locker.IsLocked())
Attribute *attribute = NULL;
node->FindAttribute(name, &attribute);
// in case the attribute exists we fail if required by the openMode
if (attribute && (openMode & O_EXCL))
RETURN_ERROR(B_FILE_EXISTS);
// creating and truncating require write permission
int accessMode = open_mode_to_access(openMode);
if (!attribute || (openMode & O_TRUNC))
accessMode |= ACCESS_W;
// check required permissions against node permissions
status_t error = node->CheckPermissions(accessMode);
if (error != B_OK)
RETURN_ERROR(error);
// create the cookie
AttributeCookie *cookie = new(nothrow) AttributeCookie();
if (!cookie)
return B_NO_MEMORY;
ObjectDeleter<AttributeCookie> cookieDeleter(cookie);
// init the cookie
error = cookie->Init(name, openMode);
if (error != B_OK)
RETURN_ERROR(error);
// if not existing yet, create the attribute and set its type
if (!attribute) {
error = node->CreateAttribute(name, &attribute);
if (error != B_OK)
RETURN_ERROR(error);
attribute->SetType(type);
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CREATED);
// else truncate if requested
} else if (openMode & O_TRUNC) {
error = attribute->SetSize(0);
if (error != B_OK)
return error;
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CHANGED);
}
NodeMTimeUpdater mTimeUpdater(node);
// success
cookieDeleter.Detach();
*_cookie = cookie;
} else
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
// try to find the attribute
Attribute *attribute = NULL;
node->FindAttribute(name, &attribute);
// in case the attribute exists we fail if required by the openMode
if (attribute && (openMode & O_EXCL))
RETURN_ERROR(B_FILE_EXISTS);
// creating and truncating require write permission
int accessMode = open_mode_to_access(openMode);
if (!attribute || (openMode & O_TRUNC))
accessMode |= ACCESS_W;
// check required permissions against node permissions
status_t error = node->CheckPermissions(accessMode);
if (error != B_OK)
RETURN_ERROR(error);
// create the cookie
AttributeCookie *cookie = new(nothrow) AttributeCookie();
if (!cookie)
return B_NO_MEMORY;
ObjectDeleter<AttributeCookie> cookieDeleter(cookie);
// init the cookie
error = cookie->Init(name, openMode);
if (error != B_OK)
RETURN_ERROR(error);
// if not existing yet, create the attribute and set its type
if (!attribute) {
error = node->CreateAttribute(name, &attribute);
if (error != B_OK)
RETURN_ERROR(error);
attribute->SetType(type);
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CREATED);
// else truncate if requested
} else if (openMode & O_TRUNC) {
error = attribute->SetSize(0);
if (error != B_OK)
return error;
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CHANGED);
}
NodeMTimeUpdater mTimeUpdater(node);
// success
cookieDeleter.Detach();
*_cookie = cookie;
return B_OK; return B_OK;
} }
// ramfs_open_attr
static status_t static status_t
ramfs_open_attr(fs_volume* _volume, fs_vnode* _node, const char *name, ramfs_open_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
int openMode, void** _cookie) int openMode, void** _cookie)
{ {
// FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
FUNCTION(("node: %lld\n", node->GetID())); FUNCTION(("node: %lld\n", node->GetID()));
status_t error = B_OK; status_t error = B_OK;
if (VolumeWriteLocker locker = volume) { VolumeWriteLocker locker(volume);
// find the attribute if (!locker.IsLocked())
Attribute *attribute = NULL; RETURN_ERROR(B_ERROR);
if (error == B_OK)
error = node->FindAttribute(name, &attribute);
// truncating requires write permission // find the attribute
int accessMode = open_mode_to_access(openMode); Attribute *attribute = NULL;
if (error == B_OK && (openMode & O_TRUNC)) if (error == B_OK)
accessMode |= ACCESS_W; error = node->FindAttribute(name, &attribute);
// check open mode against permissions // truncating requires write permission
if (error == B_OK) int accessMode = open_mode_to_access(openMode);
error = node->CheckPermissions(accessMode); if (error == B_OK && (openMode & O_TRUNC))
accessMode |= ACCESS_W;
// check open mode against permissions
if (error == B_OK)
error = node->CheckPermissions(accessMode);
// create the cookie
AttributeCookie *cookie = NULL;
if (error == B_OK) {
cookie = new(nothrow) AttributeCookie();
if (cookie) {
SET_ERROR(error, cookie->Init(name, openMode));
} else {
SET_ERROR(error, B_NO_MEMORY);
}
}
// truncate if requested
if (error == B_OK && (openMode & O_TRUNC)) {
error = attribute->SetSize(0);
// create the cookie
AttributeCookie *cookie = NULL;
if (error == B_OK) { if (error == B_OK) {
cookie = new(nothrow) AttributeCookie(); notify_attribute_changed(volume->GetID(), -1, node->GetID(),
if (cookie) { name, B_ATTR_CHANGED);
SET_ERROR(error, cookie->Init(name, openMode));
} else {
SET_ERROR(error, B_NO_MEMORY);
}
} }
}
NodeMTimeUpdater mTimeUpdater(node);
// truncate if requested // set result / cleanup on failure
if (error == B_OK && (openMode & O_TRUNC)) { if (error == B_OK)
error = attribute->SetSize(0); *_cookie = cookie;
else if (cookie)
delete cookie;
if (error == B_OK) {
notify_attribute_changed(volume->GetID(), -1, node->GetID(),
name, B_ATTR_CHANGED);
}
}
NodeMTimeUpdater mTimeUpdater(node);
// set result / cleanup on failure
if (error == B_OK)
*_cookie = cookie;
else if (cookie)
delete cookie;
} else
SET_ERROR(error, B_ERROR);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_close_attr
static status_t static status_t
ramfs_close_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie) ramfs_close_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie)
{ {
// FUNCTION_START(); FUNCTION(("node: %lld\n", node->GetID()));
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
FUNCTION(("node: %lld\n", node->GetID())); VolumeReadLocker locker(volume);
status_t error = B_OK; if (!locker.IsLocked())
RETURN_ERROR(B_ERROR);
// notify listeners // notify listeners
if (VolumeReadLocker locker = volume) { notify_if_stat_changed(volume, node);
notify_if_stat_changed(volume, node); return B_OK;
} else
SET_ERROR(error, B_ERROR);
return error;
} }
// ramfs_free_attr_cookie
static status_t static status_t
ramfs_free_attr_cookie(fs_volume* /*fs*/, fs_vnode* /*_node*/, void* _cookie) ramfs_free_attr_cookie(fs_volume* /*fs*/, fs_vnode* /*_node*/, void* _cookie)
{ {
@ -1671,44 +1668,47 @@ ramfs_free_attr_cookie(fs_volume* /*fs*/, fs_vnode* /*_node*/, void* _cookie)
} }
// ramfs_read_attr
static status_t static status_t
ramfs_read_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos, ramfs_read_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie, off_t pos,
void *buffer, size_t *bufferSize) void *buffer, size_t *bufferSize)
{ {
// FUNCTION_START(); FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
AttributeCookie *cookie = (AttributeCookie*)_cookie; AttributeCookie *cookie = (AttributeCookie*)_cookie;
VolumeReadLocker locker(volume);
if (!locker.IsLocked())
RETURN_ERROR(B_ERROR);
status_t error = B_OK; status_t error = B_OK;
if (VolumeReadLocker locker = volume) {
// find the attribute
Attribute *attribute = NULL;
if (error == B_OK)
error = node->FindAttribute(cookie->GetName(), &attribute);
// check permissions // find the attribute
int accessMode = open_mode_to_access(cookie->GetOpenMode()); Attribute *attribute = NULL;
if (error == B_OK && !(accessMode & ACCESS_R)) if (error == B_OK)
SET_ERROR(error, B_NOT_ALLOWED); error = node->FindAttribute(cookie->GetName(), &attribute);
// check permissions
int accessMode = open_mode_to_access(cookie->GetOpenMode());
if (error == B_OK && !(accessMode & ACCESS_R))
SET_ERROR(error, B_NOT_ALLOWED);
// read
if (error == B_OK)
error = attribute->ReadAt(pos, buffer, *bufferSize, bufferSize);
// read
if (error == B_OK)
error = attribute->ReadAt(pos, buffer, *bufferSize, bufferSize);
} else
SET_ERROR(error, B_ERROR);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_write_attr
static status_t static status_t
ramfs_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie, ramfs_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie,
off_t pos, const void *buffer, size_t *bufferSize) off_t pos, const void *buffer, size_t *bufferSize)
{ {
// FUNCTION_START(); FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
AttributeCookie *cookie = (AttributeCookie*)_cookie; AttributeCookie *cookie = (AttributeCookie*)_cookie;
@ -1717,75 +1717,77 @@ ramfs_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie,
// Don't allow writing the reserved attributes. // Don't allow writing the reserved attributes.
const char *name = cookie->GetName(); const char *name = cookie->GetName();
if (name[0] == '\0' || !strcmp(name, "name") if (name[0] == '\0' || !strcmp(name, "name")
|| !strcmp(name, "last_modified") || !strcmp(name, "size")) { || !strcmp(name, "last_modified") || !strcmp(name, "size")) {
// FUNCTION(("failed: node: %s, attribute: %s\n", // FUNCTION(("failed: node: %s, attribute: %s\n",
// node->GetName(), name)); // node->GetName(), name));
RETURN_ERROR(B_NOT_ALLOWED); RETURN_ERROR(B_NOT_ALLOWED);
} }
if (VolumeWriteLocker locker = volume) { VolumeWriteLocker locker(volume);
NodeMTimeUpdater mTimeUpdater(node); if (!locker.IsLocked())
RETURN_ERROR(B_ERROR);
// find the attribute NodeMTimeUpdater mTimeUpdater(node);
Attribute *attribute = NULL;
if (error == B_OK)
error = node->FindAttribute(cookie->GetName(), &attribute);
// check permissions // find the attribute
int accessMode = open_mode_to_access(cookie->GetOpenMode()); Attribute *attribute = NULL;
if (error == B_OK && !(accessMode & ACCESS_W)) if (error == B_OK)
SET_ERROR(error, B_NOT_ALLOWED); error = node->FindAttribute(cookie->GetName(), &attribute);
// write the data // check permissions
if (error == B_OK) int accessMode = open_mode_to_access(cookie->GetOpenMode());
error = attribute->WriteAt(pos, buffer, *bufferSize, bufferSize); if (error == B_OK && !(accessMode & ACCESS_W))
SET_ERROR(error, B_NOT_ALLOWED);
// notify listeners // write the data
if (error == B_OK) { if (error == B_OK)
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name, error = attribute->WriteAt(pos, buffer, *bufferSize, bufferSize);
B_ATTR_CHANGED);
} // notify listeners
} else if (error == B_OK) {
SET_ERROR(error, B_ERROR); notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_CHANGED);
}
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_read_attr_stat
static status_t static status_t
ramfs_read_attr_stat(fs_volume* _volume, fs_vnode* _node, void* _cookie, ramfs_read_attr_stat(fs_volume* _volume, fs_vnode* _node, void* _cookie,
struct stat *st) struct stat *st)
{ {
// FUNCTION_START(); // FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
AttributeCookie *cookie = (AttributeCookie*)_cookie; AttributeCookie *cookie = (AttributeCookie*)_cookie;
status_t error = B_OK; status_t error = B_OK;
if (VolumeReadLocker locker = volume) { VolumeReadLocker locker(volume);
// find the attribute if (!locker.IsLocked())
Attribute *attribute = NULL; RETURN_ERROR(B_ERROR);
if (error == B_OK)
error = node->FindAttribute(cookie->GetName(), &attribute);
// check permissions // find the attribute
int accessMode = open_mode_to_access(cookie->GetOpenMode()); Attribute *attribute = NULL;
if (error == B_OK && !(accessMode & ACCESS_R)) if (error == B_OK)
SET_ERROR(error, B_NOT_ALLOWED); error = node->FindAttribute(cookie->GetName(), &attribute);
// check permissions
int accessMode = open_mode_to_access(cookie->GetOpenMode());
if (error == B_OK && !(accessMode & ACCESS_R))
SET_ERROR(error, B_NOT_ALLOWED);
// read
if (error == B_OK) {
st->st_type = attribute->GetType();
st->st_size = attribute->GetSize();
}
// read
if (error == B_OK) {
st->st_type = attribute->GetType();
st->st_size = attribute->GetSize();
}
} else
SET_ERROR(error, B_ERROR);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_rename_attr
static status_t static status_t
ramfs_rename_attr(fs_volume* /*fs*/, fs_vnode* /*_fromNode*/, ramfs_rename_attr(fs_volume* /*fs*/, fs_vnode* /*_fromNode*/,
const char */*fromName*/, fs_vnode* /*_toNode*/, const char */*toName*/) const char */*fromName*/, fs_vnode* /*_toNode*/, const char */*toName*/)
@ -1795,7 +1797,6 @@ ramfs_rename_attr(fs_volume* /*fs*/, fs_vnode* /*_fromNode*/,
} }
// ramfs_remove_attr
static status_t static status_t
ramfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char *name) ramfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char *name)
{ {
@ -1804,28 +1805,29 @@ ramfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char *name)
Node* node = (Node*)_node->private_node; Node* node = (Node*)_node->private_node;
status_t error = B_OK; status_t error = B_OK;
if (VolumeWriteLocker locker = volume) { VolumeWriteLocker locker(volume);
NodeMTimeUpdater mTimeUpdater(node); if (!locker.IsLocked())
RETURN_ERROR(B_ERROR);
// check permissions NodeMTimeUpdater mTimeUpdater(node);
error = node->CheckPermissions(ACCESS_W);
// find the attribute // check permissions
Attribute *attribute = NULL; error = node->CheckPermissions(ACCESS_W);
if (error == B_OK)
error = node->FindAttribute(name, &attribute);
// delete it // find the attribute
if (error == B_OK) Attribute *attribute = NULL;
error = node->DeleteAttribute(attribute); if (error == B_OK)
error = node->FindAttribute(name, &attribute);
// notify listeners // delete it
if (error == B_OK) { if (error == B_OK)
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name, error = node->DeleteAttribute(attribute);
B_ATTR_REMOVED);
} // notify listeners
} else if (error == B_OK) {
SET_ERROR(error, B_ERROR); notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
B_ATTR_REMOVED);
}
RETURN_ERROR(error); RETURN_ERROR(error);
} }
@ -1843,30 +1845,31 @@ public:
}; };
// ramfs_open_index_dir
static status_t static status_t
ramfs_open_index_dir(fs_volume* _volume, void** _cookie) ramfs_open_index_dir(fs_volume* _volume, void** _cookie)
{ {
FUNCTION_START(); FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
VolumeReadLocker locker(volume);
if (!locker.IsLocked())
RETURN_ERROR(B_ERROR);
status_t error = B_OK; status_t error = B_OK;
if (VolumeReadLocker locker = volume) { // check whether an index directory exists
// check whether an index directory exists if (volume->GetIndexDirectory()) {
if (volume->GetIndexDirectory()) { IndexDirCookie *cookie = new(nothrow) IndexDirCookie;
IndexDirCookie *cookie = new(nothrow) IndexDirCookie; if (cookie)
if (cookie) *_cookie = cookie;
*_cookie = cookie; else
else SET_ERROR(error, B_NO_MEMORY);
SET_ERROR(error, B_NO_MEMORY);
} else
SET_ERROR(error, B_ENTRY_NOT_FOUND);
} else } else
SET_ERROR(error, B_ERROR); SET_ERROR(error, B_ENTRY_NOT_FOUND);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_close_index_dir
static status_t static status_t
ramfs_close_index_dir(fs_volume* /*fs*/, void* /*_cookie*/) ramfs_close_index_dir(fs_volume* /*fs*/, void* /*_cookie*/)
{ {
@ -1875,7 +1878,6 @@ ramfs_close_index_dir(fs_volume* /*fs*/, void* /*_cookie*/)
} }
// ramfs_free_index_dir_cookie
static status_t static status_t
ramfs_free_index_dir_cookie(fs_volume* /*fs*/, void* _cookie) ramfs_free_index_dir_cookie(fs_volume* /*fs*/, void* _cookie)
{ {
@ -1886,7 +1888,6 @@ ramfs_free_index_dir_cookie(fs_volume* /*fs*/, void* _cookie)
} }
// ramfs_read_index_dir
static status_t static status_t
ramfs_read_index_dir(fs_volume* _volume, void* _cookie, ramfs_read_index_dir(fs_volume* _volume, void* _cookie,
struct dirent *buffer, size_t bufferSize, uint32 *count) struct dirent *buffer, size_t bufferSize, uint32 *count)
@ -1896,36 +1897,36 @@ ramfs_read_index_dir(fs_volume* _volume, void* _cookie,
IndexDirCookie *cookie = (IndexDirCookie*)_cookie; IndexDirCookie *cookie = (IndexDirCookie*)_cookie;
status_t error = B_OK; status_t error = B_OK;
if (VolumeReadLocker locker = volume) { VolumeReadLocker locker(volume);
// get the next index if (!locker.IsLocked())
Index *index = volume->GetIndexDirectory()->IndexAt( RETURN_ERROR(B_ERROR);
cookie->index_index++);
if (index) { // get the next index
const char *name = index->GetName(); Index *index = volume->GetIndexDirectory()->IndexAt(
size_t nameLen = strlen(name); cookie->index_index++);
// check, whether the entry fits into the buffer, if (index) {
// and fill it in const char *name = index->GetName();
size_t length = (buffer->d_name + nameLen + 1) - (char*)buffer; size_t nameLen = strlen(name);
if (length <= bufferSize) { // check, whether the entry fits into the buffer,
buffer->d_dev = volume->GetID(); // and fill it in
buffer->d_ino = -1; // indices don't have a node ID size_t length = (buffer->d_name + nameLen + 1) - (char*)buffer;
memcpy(buffer->d_name, name, nameLen); if (length <= bufferSize) {
buffer->d_name[nameLen] = '\0'; buffer->d_dev = volume->GetID();
buffer->d_reclen = length; buffer->d_ino = -1; // indices don't have a node ID
*count = 1; memcpy(buffer->d_name, name, nameLen);
} else { buffer->d_name[nameLen] = '\0';
SET_ERROR(error, B_BUFFER_OVERFLOW); buffer->d_reclen = length;
} *count = 1;
} else } else {
*count = 0; SET_ERROR(error, B_BUFFER_OVERFLOW);
}
} else } else
SET_ERROR(error, B_ERROR); *count = 0;
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_rewind_index_dir
static status_t static status_t
ramfs_rewind_index_dir(fs_volume* /*fs*/, void* _cookie) ramfs_rewind_index_dir(fs_volume* /*fs*/, void* _cookie)
{ {
@ -1936,7 +1937,6 @@ ramfs_rewind_index_dir(fs_volume* /*fs*/, void* _cookie)
} }
// ramfs_create_index
static status_t static status_t
ramfs_create_index(fs_volume* _volume, const char *name, uint32 type, ramfs_create_index(fs_volume* _volume, const char *name, uint32 type,
uint32 /*flags*/) uint32 /*flags*/)
@ -1946,96 +1946,101 @@ ramfs_create_index(fs_volume* _volume, const char *name, uint32 type,
status_t error = B_OK; status_t error = B_OK;
// only root is allowed to manipulate the indices // only root is allowed to manipulate the indices
if (geteuid() != 0) { if (geteuid() != 0)
SET_ERROR(error, B_NOT_ALLOWED); RETURN_ERROR(B_NOT_ALLOWED);
} else if (VolumeWriteLocker locker = volume) {
// get the index directory VolumeWriteLocker locker(volume);
if (IndexDirectory *indexDir = volume->GetIndexDirectory()) { if (!locker.IsLocked())
// check whether an index with that name does already exist RETURN_ERROR(B_ERROR);
if (indexDir->FindIndex(name)) {
SET_ERROR(error, B_FILE_EXISTS); // get the index directory
} else { if (IndexDirectory *indexDir = volume->GetIndexDirectory()) {
// create the index // check whether an index with that name does already exist
AttributeIndex *index; if (indexDir->FindIndex(name)) {
error = indexDir->CreateIndex(name, type, &index); SET_ERROR(error, B_FILE_EXISTS);
} } else {
} else // create the index
SET_ERROR(error, B_ENTRY_NOT_FOUND); AttributeIndex *index;
error = indexDir->CreateIndex(name, type, &index);
}
} else } else
SET_ERROR(error, B_ERROR); SET_ERROR(error, B_ENTRY_NOT_FOUND);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_remove_index
static status_t static status_t
ramfs_remove_index(fs_volume* _volume, const char *name) ramfs_remove_index(fs_volume* _volume, const char *name)
{ {
FUNCTION_START(); FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
status_t error = B_OK; status_t error = B_OK;
// only root is allowed to manipulate the indices // only root is allowed to manipulate the indices
if (geteuid() != 0) { if (geteuid() != 0)
SET_ERROR(error, B_NOT_ALLOWED); RETURN_ERROR(B_NOT_ALLOWED);
} else if (VolumeWriteLocker locker = volume) {
// get the index directory VolumeWriteLocker locker(volume);
if (IndexDirectory *indexDir = volume->GetIndexDirectory()) { if (!locker.IsLocked())
// check whether an index with that name does exist RETURN_ERROR(B_ERROR);
if (Index *index = indexDir->FindIndex(name)) {
// don't delete a special index // get the index directory
if (indexDir->IsSpecialIndex(index)) { if (IndexDirectory *indexDir = volume->GetIndexDirectory()) {
SET_ERROR(error, B_BAD_VALUE); // check whether an index with that name does exist
} else if (Index *index = indexDir->FindIndex(name)) {
indexDir->DeleteIndex(index); // don't delete a special index
if (indexDir->IsSpecialIndex(index)) {
SET_ERROR(error, B_BAD_VALUE);
} else } else
SET_ERROR(error, B_ENTRY_NOT_FOUND); indexDir->DeleteIndex(index);
} else } else
SET_ERROR(error, B_ENTRY_NOT_FOUND); SET_ERROR(error, B_ENTRY_NOT_FOUND);
} else } else
SET_ERROR(error, B_ERROR); SET_ERROR(error, B_ENTRY_NOT_FOUND);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// ramfs_read_index_stat
static status_t static status_t
ramfs_read_index_stat(fs_volume* _volume, const char *name, struct stat *st) ramfs_read_index_stat(fs_volume* _volume, const char *name, struct stat *st)
{ {
FUNCTION_START(); FUNCTION_START();
Volume* volume = (Volume*)_volume->private_volume; Volume* volume = (Volume*)_volume->private_volume;
status_t error = B_OK; status_t error = B_OK;
if (VolumeReadLocker locker = volume) {
// get the index directory VolumeReadLocker locker(volume);
if (IndexDirectory *indexDir = volume->GetIndexDirectory()) { if (!locker.IsLocked())
// find the index RETURN_ERROR(B_ERROR);
if (Index *index = indexDir->FindIndex(name)) {
st->st_type = index->GetType(); // get the index directory
if (index->HasFixedKeyLength()) if (IndexDirectory *indexDir = volume->GetIndexDirectory()) {
st->st_size = index->GetKeyLength(); // find the index
else if (Index *index = indexDir->FindIndex(name)) {
st->st_size = kMaxIndexKeyLength; st->st_type = index->GetType();
st->st_atime = 0; // TODO: index times if (index->HasFixedKeyLength())
st->st_mtime = 0; // ... st->st_size = index->GetKeyLength();
st->st_ctime = 0; // ... else
st->st_crtime = 0; // ... st->st_size = kMaxIndexKeyLength;
st->st_uid = 0; // root owns the indices st->st_atime = 0; // TODO: index times
st->st_gid = 0; // st->st_mtime = 0; // ...
} else st->st_ctime = 0; // ...
SET_ERROR(error, B_ENTRY_NOT_FOUND); st->st_crtime = 0; // ...
st->st_uid = 0; // root owns the indices
st->st_gid = 0; //
} else } else
SET_ERROR(error, B_ENTRY_NOT_FOUND); SET_ERROR(error, B_ENTRY_NOT_FOUND);
} else } else
SET_ERROR(error, B_ERROR); SET_ERROR(error, B_ENTRY_NOT_FOUND);
RETURN_ERROR(error); RETURN_ERROR(error);
} }
// #pragma mark - Queries // #pragma mark - Queries
// Query implementation by Axel Dörfler. Slightly adjusted.
// ramfs_open_query
static status_t static status_t
ramfs_open_query(fs_volume* _volume, const char *queryString, uint32 flags, ramfs_open_query(fs_volume* _volume, const char *queryString, uint32 flags,
port_id port, uint32 token, void** _cookie) port_id port, uint32 token, void** _cookie)
@ -2064,7 +2069,6 @@ ramfs_open_query(fs_volume* _volume, const char *queryString, uint32 flags,
} }
// ramfs_close_query
static status_t static status_t
ramfs_close_query(fs_volume* /*fs*/, void* /*cookie*/) ramfs_close_query(fs_volume* /*fs*/, void* /*cookie*/)
{ {
@ -2073,7 +2077,6 @@ ramfs_close_query(fs_volume* /*fs*/, void* /*cookie*/)
} }
// ramfs_free_query_cookie
static status_t static status_t
ramfs_free_query_cookie(fs_volume* _volume, void* _cookie) ramfs_free_query_cookie(fs_volume* _volume, void* _cookie)
{ {
@ -2093,7 +2096,6 @@ ramfs_free_query_cookie(fs_volume* _volume, void* _cookie)
} }
// ramfs_read_query
static status_t static status_t
ramfs_read_query(fs_volume* _volume, void* _cookie, struct dirent *buffer, ramfs_read_query(fs_volume* _volume, void* _cookie, struct dirent *buffer,
size_t bufferSize, uint32 *count) size_t bufferSize, uint32 *count)