Rearranged some functions to better fit in their context.
new_file_fd() is now called get_new_fd(), and can also create fds for other types as well. Furthermore, it lost some memory if it couldn't allocate a new fd. Implemented most of the VFS attribute API (kernel internal only), only remove_attr(), and rename_attr() is missing for now. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1168 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+338
-144
@@ -122,18 +122,25 @@ static status_t vfs_rewind_dir(struct file_descriptor *);
|
||||
static int vfs_read_stat(struct file_descriptor *, struct stat *);
|
||||
static int vfs_close(struct file_descriptor *, int, struct io_context *);
|
||||
|
||||
static int common_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
|
||||
static int common_read_stat(struct file_descriptor *, struct stat *);
|
||||
|
||||
// file descriptor operation prototypes
|
||||
static ssize_t file_read(struct file_descriptor *, off_t pos, void *buffer, size_t *);
|
||||
static ssize_t file_write(struct file_descriptor *, off_t pos, const void *buffer, size_t *);
|
||||
static off_t file_seek(struct file_descriptor *, off_t pos, int seek_type);
|
||||
static status_t dir_read(struct file_descriptor *,struct dirent *buffer,size_t bufferSize,uint32 *_count);
|
||||
static status_t dir_rewind(struct file_descriptor *);
|
||||
static void file_free_fd(struct file_descriptor *);
|
||||
static int file_close(struct file_descriptor *);
|
||||
static status_t dir_read(struct file_descriptor *,struct dirent *buffer,size_t bufferSize,uint32 *_count);
|
||||
static status_t dir_rewind(struct file_descriptor *);
|
||||
static void dir_free_fd(struct file_descriptor *);
|
||||
static int dir_close(struct file_descriptor *);
|
||||
static ssize_t attr_read(struct file_descriptor *, off_t pos, void *buffer, size_t *);
|
||||
static ssize_t attr_write(struct file_descriptor *, off_t pos, const void *buffer, size_t *);
|
||||
static off_t attr_seek(struct file_descriptor *, off_t pos, int seek_type);
|
||||
static void attr_free_fd(struct file_descriptor *);
|
||||
static int attr_close(struct file_descriptor *);
|
||||
static int attr_read_stat(struct file_descriptor *, struct stat *);
|
||||
|
||||
static int common_ioctl(struct file_descriptor *, ulong, void *buf, size_t len);
|
||||
static int common_read_stat(struct file_descriptor *, struct stat *);
|
||||
|
||||
static int vfs_open(char *path, int omode, bool kernel);
|
||||
static int vfs_open_dir(char *path, bool kernel);
|
||||
@@ -168,6 +175,19 @@ struct fd_ops dir_ops = {
|
||||
dir_free_fd
|
||||
};
|
||||
|
||||
struct fd_ops attr_ops = {
|
||||
"attribute",
|
||||
attr_read,
|
||||
attr_write,
|
||||
attr_seek,
|
||||
common_ioctl,
|
||||
NULL,
|
||||
NULL,
|
||||
attr_read_stat,
|
||||
attr_close,
|
||||
attr_free_fd
|
||||
};
|
||||
|
||||
#define VNODE_HASH_TABLE_SIZE 1024
|
||||
static void *vnode_table;
|
||||
static struct vnode *root_vnode;
|
||||
@@ -453,67 +473,6 @@ put_vnode(struct vnode *vnode)
|
||||
}
|
||||
|
||||
|
||||
static struct file_descriptor *
|
||||
get_fd_and_vnode(int fd, struct vnode **_vnode, bool kernel)
|
||||
{
|
||||
struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd);
|
||||
if (descriptor == NULL)
|
||||
return NULL;
|
||||
|
||||
if (descriptor->vnode == NULL) {
|
||||
put_fd(descriptor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*_vnode = descriptor->vnode;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
file_free_fd(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
if (vnode != NULL) {
|
||||
FS_CALL(vnode, free_cookie)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
dec_vnode_ref_count(vnode, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dir_free_fd(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
if (vnode != NULL) {
|
||||
//FS_CALL(vnode, close_dir)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
FS_CALL(vnode, free_dir_cookie)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
dec_vnode_ref_count(vnode, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct vnode *
|
||||
get_vnode_from_fd(struct io_context *ioContext, int fd)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
struct vnode *vnode;
|
||||
|
||||
descriptor = get_fd(ioContext, fd);
|
||||
if (descriptor == NULL)
|
||||
return NULL;
|
||||
|
||||
vnode = descriptor->vnode;
|
||||
if (vnode != NULL)
|
||||
inc_vnode_ref_count(vnode);
|
||||
|
||||
put_fd(descriptor);
|
||||
return vnode;
|
||||
}
|
||||
|
||||
|
||||
static struct fs_container *
|
||||
find_fs(const char *fs_name)
|
||||
{
|
||||
@@ -943,6 +902,42 @@ check_path(char *to)
|
||||
}
|
||||
|
||||
|
||||
static struct file_descriptor *
|
||||
get_fd_and_vnode(int fd, struct vnode **_vnode, bool kernel)
|
||||
{
|
||||
struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd);
|
||||
if (descriptor == NULL)
|
||||
return NULL;
|
||||
|
||||
if (descriptor->vnode == NULL) {
|
||||
put_fd(descriptor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*_vnode = descriptor->vnode;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
static struct vnode *
|
||||
get_vnode_from_fd(struct io_context *ioContext, int fd)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
struct vnode *vnode;
|
||||
|
||||
descriptor = get_fd(ioContext, fd);
|
||||
if (descriptor == NULL)
|
||||
return NULL;
|
||||
|
||||
vnode = descriptor->vnode;
|
||||
if (vnode != NULL)
|
||||
inc_vnode_ref_count(vnode);
|
||||
|
||||
put_fd(descriptor);
|
||||
return vnode;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_vnode, bool kernel)
|
||||
{
|
||||
@@ -951,7 +946,7 @@ fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_
|
||||
if (fd != -1) {
|
||||
struct file_descriptor *descriptor = get_fd_and_vnode(fd, &vnode, kernel);
|
||||
if (descriptor == NULL)
|
||||
return EBADF;
|
||||
return B_FILE_ERROR;
|
||||
|
||||
inc_vnode_ref_count(vnode);
|
||||
put_fd(descriptor);
|
||||
@@ -964,6 +959,46 @@ fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_new_fd(int type, struct vnode *vnode, fs_cookie cookie, int openMode, bool kernel)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
int fd;
|
||||
|
||||
descriptor = alloc_fd();
|
||||
if (!descriptor)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
descriptor->vnode = vnode;
|
||||
descriptor->cookie = cookie;
|
||||
switch (type) {
|
||||
case FDTYPE_FILE:
|
||||
descriptor->ops = &file_ops;
|
||||
break;
|
||||
case FDTYPE_DIR:
|
||||
descriptor->ops = &dir_ops;
|
||||
break;
|
||||
case FDTYPE_ATTR:
|
||||
descriptor->ops = &attr_ops;
|
||||
break;
|
||||
default:
|
||||
// ToDo: perhaps we should better panic here...
|
||||
descriptor->ops = NULL;
|
||||
break;
|
||||
}
|
||||
descriptor->type = type;
|
||||
descriptor->open_mode = openMode;
|
||||
|
||||
fd = new_fd(get_current_io_context(kernel), descriptor);
|
||||
if (fd < 0) {
|
||||
kfree(descriptor);
|
||||
return B_NO_MORE_FDS;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Functions the VFS exports for other parts of the kernel
|
||||
|
||||
@@ -1574,36 +1609,12 @@ vfs_init(kernel_args *ka)
|
||||
// The filetype-dependent implementations (fd_ops + open/create/rename/remove, ...)
|
||||
|
||||
|
||||
static int
|
||||
new_file_fd(struct vnode *vnode, fs_cookie cookie, int openMode, bool kernel)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
int fd;
|
||||
|
||||
descriptor = alloc_fd();
|
||||
if (!descriptor)
|
||||
return ENOMEM;
|
||||
|
||||
descriptor->vnode = vnode;
|
||||
descriptor->cookie = cookie;
|
||||
descriptor->ops = &file_ops;
|
||||
descriptor->type = FDTYPE_FILE;
|
||||
descriptor->open_mode = openMode;
|
||||
|
||||
fd = new_fd(get_current_io_context(kernel), descriptor);
|
||||
if (fd < 0)
|
||||
return ERR_VFS_FD_TABLE_FULL;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
/** Calls fs_open() on the given vnode and returns a new
|
||||
* file descriptor for it
|
||||
*/
|
||||
|
||||
static int
|
||||
create_vnode(struct vnode *directory, const char *name, int omode, int perms, bool kernel)
|
||||
create_vnode(struct vnode *directory, const char *name, int openMode, int perms, bool kernel)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
fs_cookie cookie;
|
||||
@@ -1613,7 +1624,7 @@ create_vnode(struct vnode *directory, const char *name, int omode, int perms, bo
|
||||
if (FS_CALL(directory, create) == NULL)
|
||||
return EROFS;
|
||||
|
||||
status = FS_CALL(directory, create)(directory->mount->cookie, directory->private_node, name, omode, perms, &cookie, &newID);
|
||||
status = FS_CALL(directory, create)(directory->mount->cookie, directory->private_node, name, openMode, perms, &cookie, &newID);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@@ -1626,9 +1637,10 @@ create_vnode(struct vnode *directory, const char *name, int omode, int perms, bo
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ((status = new_file_fd(vnode,cookie,omode,kernel)) >= 0)
|
||||
if ((status = get_new_fd(FDTYPE_FILE, vnode, cookie, openMode, kernel)) >= 0)
|
||||
return status;
|
||||
|
||||
|
||||
err:
|
||||
FS_CALL(vnode, close)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
FS_CALL(vnode, free_cookie)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
put_vnode(vnode);
|
||||
@@ -1653,7 +1665,7 @@ open_vnode(struct vnode *vnode, int omode, bool kernel)
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
status = new_file_fd(vnode, cookie, omode, kernel);
|
||||
status = get_new_fd(FDTYPE_FILE, vnode, cookie, omode, kernel);
|
||||
if (status < 0) {
|
||||
FS_CALL(vnode, close)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
FS_CALL(vnode, free_cookie)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
@@ -1678,24 +1690,10 @@ open_dir_vnode(struct vnode *vnode, bool kernel)
|
||||
return status;
|
||||
|
||||
// file is opened, create a fd
|
||||
descriptor = alloc_fd();
|
||||
if (!descriptor) {
|
||||
status = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
descriptor->vnode = vnode;
|
||||
descriptor->cookie = cookie;
|
||||
descriptor->ops = &dir_ops;
|
||||
descriptor->type = FDTYPE_DIR;
|
||||
|
||||
fd = new_fd(get_current_io_context(kernel), descriptor);
|
||||
fd = get_new_fd(FDTYPE_DIR, vnode, cookie, 0, kernel);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
err1:
|
||||
status = B_NO_MORE_FDS;
|
||||
kfree(descriptor);
|
||||
|
||||
err:
|
||||
FS_CALL(vnode, close_dir)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
FS_CALL(vnode, free_dir_cookie)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
@@ -1725,22 +1723,22 @@ file_create_entry_ref(fs_id fsID, vnode_id directoryID, const char *name, int om
|
||||
|
||||
|
||||
static int
|
||||
file_create(char *path, int omode, int perms, bool kernel)
|
||||
file_create(char *path, int openMode, int perms, bool kernel)
|
||||
{
|
||||
char filename[SYS_MAX_NAME_LEN];
|
||||
struct vnode *directory,*vnode;
|
||||
struct vnode *directory, *vnode;
|
||||
fs_cookie cookie;
|
||||
vnode_id newID;
|
||||
int status;
|
||||
|
||||
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path, omode, perms, kernel));
|
||||
FUNCTION(("file_create: path '%s', omode %x, perms %d, kernel %d\n", path, openMode, perms, kernel));
|
||||
|
||||
// get directory to put the new file in
|
||||
status = path_to_dir_vnode(path, &directory, filename, kernel);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
status = create_vnode(directory,filename,omode,perms,kernel);
|
||||
status = create_vnode(directory, filename, openMode, perms, kernel);
|
||||
put_vnode(directory);
|
||||
|
||||
return status;
|
||||
@@ -1796,15 +1794,27 @@ file_close(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("file_close(descriptor = %p)\n",descriptor));
|
||||
|
||||
FUNCTION(("file_close(descriptor = %p)\n", descriptor));
|
||||
|
||||
if (FS_CALL(vnode, close))
|
||||
return FS_CALL(vnode, close)(vnode->mount->cookie,vnode->private_node,descriptor->cookie);
|
||||
return FS_CALL(vnode, close)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
file_free_fd(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
if (vnode != NULL) {
|
||||
FS_CALL(vnode, free_cookie)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
put_vnode(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
file_read(struct file_descriptor *descriptor, off_t pos, void *buffer, size_t *length)
|
||||
{
|
||||
@@ -1944,6 +1954,32 @@ dir_open(char *path, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dir_close(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("dir_close(descriptor = %p)\n", descriptor));
|
||||
|
||||
if (FS_CALL(vnode, close_dir))
|
||||
return FS_CALL(vnode, close_dir)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dir_free_fd(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
if (vnode != NULL) {
|
||||
FS_CALL(vnode, free_dir_cookie)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
put_vnode(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
dir_read(struct file_descriptor *descriptor, struct dirent *buffer, size_t bufferSize, uint32 *_count)
|
||||
{
|
||||
@@ -1968,20 +2004,6 @@ dir_rewind(struct file_descriptor *descriptor)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dir_close(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("dir_close(descriptor = %p)\n",descriptor));
|
||||
|
||||
if (FS_CALL(vnode, close_dir))
|
||||
return FS_CALL(vnode, close_dir)(vnode->mount->cookie,vnode->private_node,descriptor->cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
dir_remove(char *path, bool kernel)
|
||||
{
|
||||
@@ -2003,16 +2025,6 @@ dir_remove(char *path, bool kernel)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
common_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("common_read_stat: stat 0x%p\n", stat));
|
||||
return FS_CALL(vnode, read_stat)(vnode->mount->cookie, vnode->private_node, stat);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
common_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer, size_t length)
|
||||
{
|
||||
@@ -2234,13 +2246,23 @@ err:
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
common_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("common_read_stat: stat 0x%p\n", stat));
|
||||
return FS_CALL(vnode, read_stat)(vnode->mount->cookie, vnode->private_node, stat);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
common_write_stat(int fd, char *path, bool traverseLeafLink, const struct stat *stat, int statMask, bool kernel)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
int status;
|
||||
|
||||
FUNCTION(("common_write_stat: path '%s', stat 0x%p, stat_mask %d, kernel %d\n", path, stat, statMask, kernel));
|
||||
FUNCTION(("common_write_stat: path '%s', stat %p, stat_mask %d, kernel %d\n", path, stat, statMask, kernel));
|
||||
|
||||
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, kernel);
|
||||
if (status < 0)
|
||||
@@ -2251,7 +2273,179 @@ common_write_stat(int fd, char *path, bool traverseLeafLink, const struct stat *
|
||||
else
|
||||
status = EROFS;
|
||||
|
||||
dec_vnode_ref_count(vnode, false);
|
||||
put_vnode(vnode);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
attr_create(int fd, const char *name, uint32 type, int openMode, bool kernel)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
fs_cookie cookie;
|
||||
int status;
|
||||
|
||||
vnode = get_vnode_from_fd(get_current_io_context(kernel), fd);
|
||||
if (vnode == NULL)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
if (FS_CALL(vnode, create_attr) == NULL) {
|
||||
status = EROFS;
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = FS_CALL(vnode, create_attr)(vnode->mount->cookie, vnode->private_node, name, type, openMode, &cookie);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
if ((status = get_new_fd(FDTYPE_ATTR, vnode, cookie, openMode, kernel)) >= 0)
|
||||
return status;
|
||||
|
||||
err1:
|
||||
FS_CALL(vnode, close_attr)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
FS_CALL(vnode, free_attr_cookie)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
|
||||
FS_CALL(vnode, remove_attr)(vnode->mount->cookie, vnode->private_node, name);
|
||||
|
||||
err:
|
||||
put_vnode(vnode);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
attr_open(int fd, const char *name, int openMode, bool kernel)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
fs_cookie cookie;
|
||||
int status;
|
||||
|
||||
vnode = get_vnode_from_fd(get_current_io_context(kernel), fd);
|
||||
if (vnode == NULL)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
if (FS_CALL(vnode, open_attr) == NULL) {
|
||||
status = EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = FS_CALL(vnode, open_attr)(vnode->mount->cookie, vnode->private_node, name, openMode, &cookie);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
if ((status = get_new_fd(FDTYPE_ATTR, vnode, cookie, openMode, kernel)) >= 0)
|
||||
return status;
|
||||
|
||||
err1:
|
||||
FS_CALL(vnode, close_attr)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
FS_CALL(vnode, free_attr_cookie)(vnode->mount->cookie, vnode->private_node, cookie);
|
||||
|
||||
err:
|
||||
put_vnode(vnode);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
attr_close(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("attr_close(descriptor = %p)\n", descriptor));
|
||||
|
||||
if (FS_CALL(vnode, close_attr))
|
||||
return FS_CALL(vnode, close_attr)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
attr_free_fd(struct file_descriptor *descriptor)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
if (vnode != NULL) {
|
||||
FS_CALL(vnode, free_attr_cookie)(vnode->mount->cookie, vnode->private_node, descriptor->cookie);
|
||||
put_vnode(vnode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
attr_read(struct file_descriptor *descriptor, off_t pos, void *buffer, size_t *length)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("attr_read: buf %p, pos %Ld, len %p = %ld\n", buffer, pos, length, *length));
|
||||
if (!FS_CALL(vnode, read_attr))
|
||||
return EOPNOTSUPP;
|
||||
|
||||
return FS_CALL(vnode, read_attr)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, pos, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
attr_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, size_t *length)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("attr_write: buf %p, pos %Ld, len %p\n", buffer, pos, length));
|
||||
if (!FS_CALL(vnode, write_attr))
|
||||
return EOPNOTSUPP;
|
||||
|
||||
return FS_CALL(vnode, write_attr)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, pos, buffer, length);
|
||||
}
|
||||
|
||||
|
||||
static off_t
|
||||
attr_seek(struct file_descriptor *descriptor, off_t pos, int seekType)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("attr_seek: pos 0x%Ld, seek_type %d\n", pos, seekType));
|
||||
if (!FS_CALL(vnode, seek_attr))
|
||||
return EOPNOTSUPP;
|
||||
|
||||
return FS_CALL(vnode, seek_attr)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, pos, seekType);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
attr_read_stat(struct file_descriptor *descriptor, struct stat *stat)
|
||||
{
|
||||
struct vnode *vnode = descriptor->vnode;
|
||||
|
||||
FUNCTION(("attr_read_stat: stat 0x%p\n", stat));
|
||||
if (!FS_CALL(vnode, read_attr_stat))
|
||||
return EOPNOTSUPP;
|
||||
|
||||
return FS_CALL(vnode, read_attr_stat)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, stat);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
attr_write_stat(int fd, const struct stat *stat, int statMask, bool kernel)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
struct vnode *vnode;
|
||||
int status;
|
||||
|
||||
FUNCTION(("attr_write_stat: fd = %d, stat = %p, statMask %d, kernel %d\n", fd, stat, statMask, kernel));
|
||||
|
||||
descriptor = get_fd_and_vnode(fd, &vnode, kernel);
|
||||
if (descriptor == NULL)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
if (FS_CALL(vnode, write_attr_stat))
|
||||
status = FS_CALL(vnode, write_attr_stat)(vnode->mount->cookie, vnode->private_node, descriptor->cookie, stat, statMask);
|
||||
else
|
||||
status = EROFS;
|
||||
|
||||
put_vnode(vnode);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user