[openbeos] Re: Storage Kit

  • From: "Travis Geiselbrecht" <geist@xxxxxxxxxx>
  • To: <openbeos@xxxxxxxxxxxxx>
  • Date: Sat, 3 Nov 2001 18:02:30 -0800

Howdy,

For the most part the final api will be somewhat similar to this, but it
is changing right now, it's just not in the main tree.

The first thing that's changing is I'm removing the concept of multiple
streams, or at least removing the way they're accessed here. Being able
to open a separate file descriptor on different streams of a single file
is a Bad Idea (TM). In the replacement api there is no concept of
attributes, but if/when I get around to implementing it, it will be
similar to the Be way, which involves having a readattr/writeattr/etc
call. I am still keeping the concept of stream types though, and will
probably implement openattrdir/readattrdir/etc by opening a file with a
STREAM_TYPE_ATTRDIR type or something like that.

One thing I am keeping is removing the separate calls for dirs and
files. Same thing will apply, open a dir as STREAM_TYPE_DIR and read()
from it normally, the data returned is as if it was a record-based file.

Another change is the passing of the *len field. The length is now
returned in the return code, which you incorrectly identified here. In
the old api, you pass *len with the length to read in, and it returns
the length read from it. Now the call will return ssize_t with the
err/length read/write encoded in it. I'm not sure what I was thinking
before...

Anyway, inlined here is a copy of the current vfs.h. It's not totally
finished, but I doubt the api will change in any appreciable way. It's
complete in that unlink() and rename() and all that now exists. The api
to the filesystem modules is very much inspired by BeOS.

Vfs.h:----------
/* 
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#ifndef _VFS_H
#define _VFS_H

#include <kernel/kernel.h>
#include <boot/stage2.h>

typedef enum {
        STREAM_TYPE_NULL = 0,
        STREAM_TYPE_FILE,
        STREAM_TYPE_DIR,
        STREAM_TYPE_DEVICE,
        STREAM_TYPE_STRING
} stream_type;

typedef enum {
        SEEK_SET = 0,
        SEEK_CUR,
        SEEK_END
} seek_type;

typedef void * fs_cookie;
typedef void * file_cookie;
typedef void * fs_vnode;

typedef struct iovec {
        void *start;
        size_t len;
} iovec;

typedef struct iovecs {
        size_t num;
        size_t total_len;
        iovec vec[0];
} iovecs;       

struct file_stat {
        char            name[SYS_MAX_NAME_LEN];
        vnode_id        vnid;
        stream_type     type;
        off_t           size;
};

#if 0
// old filesystem api
struct fs_calls {
        int (*fs_mount)(void **fs_cookie, void *flags, void
*covered_vnode, fs_id id, void **priv_vnode_root);
        int (*fs_unmount)(void *fs_cookie);
        int (*fs_register_mountpoint)(void *fs_cookie, void *vnode, void
*redir_vnode);
        int (*fs_unregister_mountpoint)(void *fs_cookie, void *vnode);
        int (*fs_dispose_vnode)(void *fs_cookie, void *vnode);
        int (*fs_open)(void *fs_cookie, void *base_vnode, const char
*path, const char *stream, stream_type stream_type, void **vnode, void
**cookie, struct redir_struct *redir);
        int (*fs_seek)(void *fs_cookie, void *vnode, void *cookie, off_t
pos, seek_type seek_type);
        int (*fs_read)(void *fs_cookie, void *vnode, void *cookie, void
*buf, off_t pos, size_t *len);
        int (*fs_write)(void *fs_cookie, void *vnode, void *cookie,
const void *buf, off_t pos, size_t *len);
        int (*fs_ioctl)(void *fs_cookie, void *vnode, void *cookie, int
op, void *buf, size_t len);
        int (*fs_close)(void *fs_cookie, void *vnode, void *cookie);
        int (*fs_create)(void *fs_cookie, void *base_vnode, const char
*path, const char *stream, stream_type stream_type, struct redir_struct
*redir);
        int (*fs_stat)(void *fs_cookie, void *base_vnode, const char
*path, const char *stream, stream_type stream_type, struct vnode_stat
*stat, struct redir_struct *redir);
};
#endif

struct fs_calls {
        int (*fs_mount)(fs_cookie *fs, fs_id id, void *flags);
        int (*fs_getroot)(fs_cookie *fs, vnode_id *root_id);
        int (*fs_unmount)(fs_cookie fs);
        int (*fs_sync)(fs_cookie fs);

        int (*fs_lookup)(fs_cookie fs, fs_vnode dir, const char *name,
vnode_id *id);

        int (*fs_getvnode)(fs_cookie fs, vnode_id id, fs_vnode *v, int
r);
        int (*fs_putvnode)(fs_cookie fs, fs_vnode v);
        int (*fs_removevnode)(fs_cookie fs, fs_vnode v);

        int (*fs_open)(fs_cookie fs, fs_vnode v, file_cookie *cookie,
int oflags);
        int (*fs_close)(fs_cookie fs, fs_vnode v, file_cookie cookie);
        int (*fs_freecookie)(fs_cookie fs, fs_vnode v, file_cookie
cookie);
        int (*fs_fsync)(fs_cookie fs, fs_vnode v);

        ssize_t (*fs_read)(fs_cookie fs, fs_vnode v, file_cookie cookie,
void *buf, off_t pos, ssize_t len);
        ssize_t (*fs_write)(fs_cookie fs, fs_vnode v, file_cookie
cookie, const void *buf, off_t pos, ssize_t len);
        int (*fs_seek)(fs_cookie fs, fs_vnode v, file_cookie cookie,
off_t pos, seek_type st);
        int (*fs_ioctl)(fs_cookie fs, fs_vnode v, file_cookie cookie,
int op, void *buf, size_t len);

        int (*fs_canpage)(fs_cookie fs, fs_vnode v, file_cookie cookie);
        ssize_t (*fs_readpage)(fs_cookie fs, fs_vnode v, file_cookie
cookie, iovecs *vecs, off_t pos);
        ssize_t (*fs_writepage)(fs_cookie fs, fs_vnode v, file_cookie
cookie, iovecs *vecs, off_t pos);

        int (*fs_create)(fs_cookie fs, fs_vnode dir, const char *name,
stream_type st, void *create_args, vnode_id *new_vnid);
        int (*fs_unlink)(fs_cookie fs, fs_vnode dir, const char *name);
        int (*fs_rename)(fs_cookie fs, fs_vnode olddir, const char
*oldname, fs_vnode newdir, const char *newname);

        int (*fs_rstat)(fs_cookie fs, fs_vnode v, struct file_stat
*stat);
        int (*fs_wstat)(fs_cookie fs, fs_vnode v, struct file_stat
*stat, int stat_mask);
};

int vfs_init(kernel_args *ka);
int vfs_register_filesystem(const char *name, struct fs_calls *calls);
void *vfs_new_ioctx();
int vfs_free_ioctx(void *ioctx);
int vfs_test();

/* calls needed by fs internals */
int vfs_get_vnode(fs_id fsid, vnode_id vnid, fs_vnode *v);
int vfs_put_vnode(fs_id fsid, vnode_id vnid);
int vfs_remove_vnode(fs_id fsid, vnode_id vnid);

/* calls kernel code should make for file I/O */
int sys_mount(const char *path, const char *fs_name);
int sys_unmount(const char *path);
int sys_sync();
int sys_open(const char *path, int omode);
int sys_close(int fd);
int sys_fsync(int fd);
ssize_t sys_read(int fd, void *buf, off_t pos, ssize_t len);
ssize_t sys_write(int fd, const void *buf, off_t pos, ssize_t len);
int sys_seek(int fd, off_t pos, seek_type seek_type);
int sys_ioctl(int fd, int op, void *buf, size_t len);
ssize_t sys_readpage(int fd, iovecs *vecs, off_t pos);
ssize_t sys_writepage(int fd, iovecs *vecs, off_t pos);
int sys_create(const char *path, stream_type stream_type);
int sys_unlink(const char *path, bool kernel);
int sys_rename(const char *oldpath, const char *newpath);
int sys_rstat(const char *path, struct file_stat *stat);
int sys_wstat(const char *path, struct file_stat *stat, int stat_mask);

/* calls the syscall dispatcher should use for user file I/O */
// not finished here yet, but should be pretty much identical to it's
sys_ counterpart
int user_open(const char *path, int omode);
int user_seek(int fd, off_t pos, seek_type seek_type);
ssize_t user_read(int fd, void *buf, off_t pos, ssize_t len);
ssize_t user_write(int fd, const void *buf, off_t pos, ssize_t len);
int user_ioctl(int fd, int op, void *buf, size_t len);
int user_close(int fd);
int user_create(const char *path, stream_type stream_type);
int user_rstat(const char *path, struct file_stat *stat);

#endif

End vfs.h------------

Travis

> -----Original Message-----
> From: openbeos-bounce@xxxxxxxxxxxxx 
> [mailto:openbeos-bounce@xxxxxxxxxxxxx] On Behalf Of Keith Poole
> Sent: Saturday, November 03, 2001 10:07 AM
> To: Brander Lien; openbeos
> Subject: [openbeos] Storage Kit
> 
> 
> I've been looking at the storage kit & the newOS source, and 
> I've come 
> up with what I think is the API used for accessing the 
> underlying file 
> systems - I have written a first stab at documenting this but 
> it needs 
> to be checked. (see attached)
> 
> If this is the correct way to proceed, we could write an emulator to 
> test the storage kit classes against
> 
>         Keith
> 
> 
> -- Attached file included as plaintext by Listar --
> -- File: NewOSAPI
> 
> NewOS API
> 
> This details the API provided by NewOS to access the 
> underlying file systems (taken from vfs.h)
> 
> typedef enum {
>       STREAM_TYPE_NULL = 0,
>       STREAM_TYPE_FILE,
>       STREAM_TYPE_DIR,
>       STREAM_TYPE_DEVICE,
>       STREAM_TYPE_STRING
> } stream_type;
> 
> typedef enum {
>       SEEK_SET = 0,
>       SEEK_CUR,
>       SEEK_END
> } seek_type;
> 
> struct redir_struct {
>       bool redir;
>       void *vnode;
>       const char *path;
> };
> 
> struct vnode_stat {
>       off_t size;
> };
> 
> int user_open(const char *path, const char *stream, 
> stream_type stream_type); Open a stream
> Parameters:
>       path - path to the stream (i.e. "/dev/beosDev/doc")
>       stream - name of stream (i.e. "NewOSAPI")
>       stream_type - One of:
>               STREAM_TYPE_NULL - not sure
>               STREAM_TYPE_FILE - a file
>               STREAM_TYPE_DIR - directory
>               STREAM_TYPE_DEVICE - raw device
>               STREAM_TYPE_STRING - not sure
> Returns:
>       > 0 - file descriptor ?
>       < 0 - error (see sys/errors.h for details)
>               
> int user_seek(int fd, off_t pos, seek_type seek_type);
> Seek to a positon in a stream (a la fseek)
> Parameters:
>       fd - file descriptor
>       pos - position to seek to
>       seek_type - one of:
>               SEEK_SET - position from start
>               SEEK_CUR - position from current pos
>               SEEK_END - position from end
> NB, only user_seek(fd, SEEK_SET, 0) - is allowed for directories.
> Returns:
>       < 0 - error
>       0 - seek ok
>       
> int user_read(int fd, void *buf, off_t pos, size_t *len);
> Read bytes from a stream
> Parameters:
>       fd - file descriptor
>       buf - destination buffer
>       pos - ?
>       len - length to read
> NB, directory reads return the name of the next object in the 
> directory
> Returns:
>       < 0 - error
>       = 0 - end of file
>       > 0 - number of bytes read
> 
> int user_write(int fd, const void *buf, off_t pos, size_t 
> *len); Write bytes to a stream
> Parameters:
>       fd - file descriptor
>       buf - source
>       pos - ?
>       len - length to read
> Returns
>       < 0 - error
>       >= 0 - bytes written
>       
> int user_ioctl(int fd, int op, void *buf, size_t len);
> Perform IOCTL operation
> Paramters:
>       fd - file descriptor
>       op - operation
>       buf - buffer to pass
>       len - length of buffer
> 
> int user_close(int fd);
> Close a stream
> Parameters:
>       fd - file descriptor
> Returns
>       < 0 - error
>       0 - ok
> int user_create(const char *path, const char *stream, 
> stream_type stream_type); Create a stream Parameters
>       path - path to new stream
>       stream - name of stream
>       stream_type - as open
> 
> Returns:
>       < 0 - error
>       = 0 - ok (?) or file descriptor(?)
> 
> int user_stat(const char *path, const char *stream, 
> stream_type stream_type, struct vnode_stat *stat); Get file status
> Parameters:
>       path - path to stream
>       stream - name of stream
>       stream_type - as user_open
>       stat - vnode structure containing status:
>               struct vnode_stat {
>                                off_t size;
>               };                       
> 
> 
> 
> 


Other related posts: