Added query support - it's more or less the same as found in R5 for now.
Later on (but before R1), we should find a better balance between what the FS has to implement, and what the kernel delivers to them. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10399 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
62ceb50f43
commit
f6743bd145
@ -208,6 +208,10 @@ static status_t index_dir_read(struct file_descriptor *, struct dirent *buffer,
|
|||||||
static status_t index_dir_rewind(struct file_descriptor *);
|
static status_t index_dir_rewind(struct file_descriptor *);
|
||||||
static void index_dir_free_fd(struct file_descriptor *);
|
static void index_dir_free_fd(struct file_descriptor *);
|
||||||
static status_t index_dir_close(struct file_descriptor *);
|
static status_t index_dir_close(struct file_descriptor *);
|
||||||
|
static status_t query_read(struct file_descriptor *, struct dirent *buffer, size_t bufferSize, uint32 *_count);
|
||||||
|
static status_t query_rewind(struct file_descriptor *);
|
||||||
|
static void query_free_fd(struct file_descriptor *);
|
||||||
|
static status_t query_close(struct file_descriptor *);
|
||||||
|
|
||||||
static status_t common_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
|
static status_t common_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
|
||||||
static status_t common_read_stat(struct file_descriptor *, struct stat *);
|
static status_t common_read_stat(struct file_descriptor *, struct stat *);
|
||||||
@ -314,6 +318,21 @@ static struct fd_ops sIndexOps = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static struct fd_ops sQueryOps = {
|
||||||
|
NULL, // read()
|
||||||
|
NULL, // write()
|
||||||
|
NULL, // seek()
|
||||||
|
NULL, // ioctl()
|
||||||
|
NULL, // select()
|
||||||
|
NULL, // deselect()
|
||||||
|
query_read,
|
||||||
|
query_rewind,
|
||||||
|
NULL, // read_stat()
|
||||||
|
NULL, // write_stat()
|
||||||
|
query_close,
|
||||||
|
query_free_fd
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// VNodePutter
|
// VNodePutter
|
||||||
class VNodePutter {
|
class VNodePutter {
|
||||||
@ -1536,6 +1555,9 @@ get_new_fd(int type, struct vnode *vnode, fs_cookie cookie, int openMode, bool k
|
|||||||
case FDTYPE_INDEX_DIR:
|
case FDTYPE_INDEX_DIR:
|
||||||
descriptor->ops = &sIndexDirectoryOps;
|
descriptor->ops = &sIndexDirectoryOps;
|
||||||
break;
|
break;
|
||||||
|
case FDTYPE_QUERY:
|
||||||
|
descriptor->ops = &sQueryOps;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
panic("get_new_fd() called with unknown type %d\n", type);
|
panic("get_new_fd() called with unknown type %d\n", type);
|
||||||
break;
|
break;
|
||||||
@ -1549,7 +1571,10 @@ get_new_fd(int type, struct vnode *vnode, fs_cookie cookie, int openMode, bool k
|
|||||||
return B_NO_MORE_FDS;
|
return B_NO_MORE_FDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_node_opened(vnode->cache, vnode->device, vnode->id);
|
// index directories and queries don't have a vnode but a mount structure attached
|
||||||
|
if (type != FDTYPE_INDEX_DIR && type != FDTYPE_QUERY)
|
||||||
|
cache_node_opened(vnode->cache, vnode->device, vnode->id);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3703,7 +3728,7 @@ index_dir_close(struct file_descriptor *descriptor)
|
|||||||
{
|
{
|
||||||
struct fs_mount *mount = descriptor->u.mount;
|
struct fs_mount *mount = descriptor->u.mount;
|
||||||
|
|
||||||
FUNCTION(("dir_close(descriptor = %p)\n", descriptor));
|
FUNCTION(("index_dir_close(descriptor = %p)\n", descriptor));
|
||||||
|
|
||||||
if (FS_MOUNT_CALL(mount, close_index_dir))
|
if (FS_MOUNT_CALL(mount, close_index_dir))
|
||||||
return FS_MOUNT_CALL(mount, close_index_dir)(mount->cookie, descriptor->cookie);
|
return FS_MOUNT_CALL(mount, close_index_dir)(mount->cookie, descriptor->cookie);
|
||||||
@ -3853,6 +3878,101 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** ToDo: the query FS API is still the pretty much the same as in R5.
|
||||||
|
* It would be nice if the FS would find some more kernel support
|
||||||
|
* for them.
|
||||||
|
* For example, query parsing should be moved into the kernel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
query_open(dev_t device, const char *query, uint32 flags,
|
||||||
|
port_id port, int32 token, bool kernel)
|
||||||
|
{
|
||||||
|
struct fs_mount *mount;
|
||||||
|
fs_cookie cookie;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
FUNCTION(("query_open(device = %ld, query = \"%s\", kernel = %d)\n", mountID, query, kernel));
|
||||||
|
|
||||||
|
mount = get_mount(device);
|
||||||
|
if (mount == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (FS_MOUNT_CALL(mount, open_query) == NULL) {
|
||||||
|
status = EOPNOTSUPP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = FS_MOUNT_CALL(mount, open_query)(mount->cookie, query, flags, port, token, &cookie);
|
||||||
|
if (status < B_OK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
// get fd for the index directory
|
||||||
|
status = get_new_fd(FDTYPE_QUERY, (struct vnode *)mount, cookie, 0, kernel);
|
||||||
|
if (status >= 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
// something went wrong
|
||||||
|
FS_MOUNT_CALL(mount, close_query)(mount->cookie, cookie);
|
||||||
|
FS_MOUNT_CALL(mount, free_query_cookie)(mount->cookie, cookie);
|
||||||
|
|
||||||
|
out:
|
||||||
|
put_mount(mount);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
query_close(struct file_descriptor *descriptor)
|
||||||
|
{
|
||||||
|
struct fs_mount *mount = descriptor->u.mount;
|
||||||
|
|
||||||
|
FUNCTION(("query_close(descriptor = %p)\n", descriptor));
|
||||||
|
|
||||||
|
if (FS_MOUNT_CALL(mount, close_query))
|
||||||
|
return FS_MOUNT_CALL(mount, close_query)(mount->cookie, descriptor->cookie);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
query_free_fd(struct file_descriptor *descriptor)
|
||||||
|
{
|
||||||
|
struct fs_mount *mount = descriptor->u.mount;
|
||||||
|
|
||||||
|
if (mount != NULL) {
|
||||||
|
FS_MOUNT_CALL(mount, free_query_cookie)(mount->cookie, descriptor->cookie);
|
||||||
|
// ToDo: find a replacement ref_count object - perhaps the root dir?
|
||||||
|
//put_vnode(vnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
query_read(struct file_descriptor *descriptor, struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
||||||
|
{
|
||||||
|
struct fs_mount *mount = descriptor->u.mount;
|
||||||
|
|
||||||
|
if (FS_MOUNT_CALL(mount, read_query))
|
||||||
|
return FS_MOUNT_CALL(mount, read_query)(mount->cookie, descriptor->cookie, buffer, bufferSize, _count);
|
||||||
|
|
||||||
|
return EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
query_rewind(struct file_descriptor *descriptor)
|
||||||
|
{
|
||||||
|
struct fs_mount *mount = descriptor->u.mount;
|
||||||
|
|
||||||
|
if (FS_MOUNT_CALL(mount, rewind_query))
|
||||||
|
return FS_MOUNT_CALL(mount, rewind_query)(mount->cookie, descriptor->cookie);
|
||||||
|
|
||||||
|
return EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
// General File System functions
|
// General File System functions
|
||||||
|
|
||||||
@ -4260,13 +4380,9 @@ fs_read_info(dev_t device, struct fs_info *info)
|
|||||||
struct fs_mount *mount;
|
struct fs_mount *mount;
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
|
|
||||||
mutex_lock(&sMountMutex);
|
mount = get_mount(device);
|
||||||
|
if (mount == NULL)
|
||||||
mount = find_mount(device);
|
return B_BAD_VALUE;
|
||||||
if (mount == NULL) {
|
|
||||||
status = B_BAD_VALUE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill in info the file system doesn't (have to) know about
|
// fill in info the file system doesn't (have to) know about
|
||||||
memset(info, 0, sizeof(struct fs_info));
|
memset(info, 0, sizeof(struct fs_info));
|
||||||
@ -4282,8 +4398,7 @@ fs_read_info(dev_t device, struct fs_info *info)
|
|||||||
// if the call is not supported by the file system, there are still
|
// if the call is not supported by the file system, there are still
|
||||||
// the parts that we filled out ourselves
|
// the parts that we filled out ourselves
|
||||||
|
|
||||||
out:
|
put_mount(mount);
|
||||||
mutex_unlock(&sMountMutex);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4292,23 +4407,18 @@ static status_t
|
|||||||
fs_write_info(dev_t device, const struct fs_info *info, int mask)
|
fs_write_info(dev_t device, const struct fs_info *info, int mask)
|
||||||
{
|
{
|
||||||
struct fs_mount *mount;
|
struct fs_mount *mount;
|
||||||
int status;
|
status_t status;
|
||||||
|
|
||||||
mutex_lock(&sMountMutex);
|
mount = get_mount(device);
|
||||||
|
if (mount == NULL)
|
||||||
mount = find_mount(device);
|
return B_BAD_VALUE;
|
||||||
if (mount == NULL) {
|
|
||||||
status = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FS_MOUNT_CALL(mount, write_fs_info))
|
if (FS_MOUNT_CALL(mount, write_fs_info))
|
||||||
status = FS_MOUNT_CALL(mount, write_fs_info)(mount->cookie, info, mask);
|
status = FS_MOUNT_CALL(mount, write_fs_info)(mount->cookie, info, mask);
|
||||||
else
|
else
|
||||||
status = EROFS;
|
status = EROFS;
|
||||||
|
|
||||||
out:
|
put_mount(mount);
|
||||||
mutex_unlock(&sMountMutex);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5935,9 +6045,24 @@ _user_setcwd(int fd, const char *userPath)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_user_open_query(dev_t device, const char *query, uint32 flags, port_id port,
|
_user_open_query(dev_t device, const char *userQuery, size_t queryLength,
|
||||||
int32 token)
|
uint32 flags, port_id port, int32 token)
|
||||||
{
|
{
|
||||||
// TODO: Implement!
|
char *query;
|
||||||
return B_ERROR;
|
|
||||||
|
if (device < 0 || userQuery == NULL || queryLength == 0 || queryLength >= 65536)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
query = (char *)malloc(queryLength + 1);
|
||||||
|
if (query == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
if (user_strlcpy(query, userQuery, queryLength + 1) < B_OK) {
|
||||||
|
free(query);
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = query_open(device, query, flags, port, token, false);
|
||||||
|
|
||||||
|
free(query);
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user