clang-format
This commit is contained in:
@@ -48,30 +48,24 @@
|
||||
*
|
||||
* We reject O_APPEND.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_eachopen(struct vnode *v, int flags)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
static int dev_eachopen(struct vnode *v, int flags) {
|
||||
struct device *d = v->vn_data;
|
||||
|
||||
if (flags & (O_CREAT | O_TRUNC | O_EXCL | O_APPEND)) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (flags & (O_CREAT | O_TRUNC | O_EXCL | O_APPEND)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return DEVOP_EACHOPEN(d, flags);
|
||||
return DEVOP_EACHOPEN(d, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when the vnode refcount reaches zero.
|
||||
* Do nothing; devices are permanent.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_reclaim(struct vnode *v)
|
||||
{
|
||||
(void)v;
|
||||
/* nothing - device continues to exist even when not in use */
|
||||
return 0;
|
||||
static int dev_reclaim(struct vnode *v) {
|
||||
(void)v;
|
||||
/* nothing - device continues to exist even when not in use */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,73 +75,60 @@ dev_reclaim(struct vnode *v)
|
||||
* For character devices, we should prohibit seeking entirely, but
|
||||
* for the moment we need to accept any position. (XXX)
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_tryseek(struct device *d, off_t pos)
|
||||
{
|
||||
if (d->d_blocks > 0) {
|
||||
if ((pos % d->d_blocksize)!=0) {
|
||||
/* not block-aligned */
|
||||
return EINVAL;
|
||||
}
|
||||
if (pos / d->d_blocksize >= d->d_blocks) {
|
||||
/* off the end */
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//return ESPIPE;
|
||||
}
|
||||
return 0;
|
||||
static int dev_tryseek(struct device *d, off_t pos) {
|
||||
if (d->d_blocks > 0) {
|
||||
if ((pos % d->d_blocksize) != 0) {
|
||||
/* not block-aligned */
|
||||
return EINVAL;
|
||||
}
|
||||
if (pos / d->d_blocksize >= d->d_blocks) {
|
||||
/* off the end */
|
||||
return EINVAL;
|
||||
}
|
||||
} else {
|
||||
// return ESPIPE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for read. Hand off to DEVOP_IO.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_read(struct vnode *v, struct uio *uio)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
int result;
|
||||
static int dev_read(struct vnode *v, struct uio *uio) {
|
||||
struct device *d = v->vn_data;
|
||||
int result;
|
||||
|
||||
result = dev_tryseek(d, uio->uio_offset);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = dev_tryseek(d, uio->uio_offset);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
KASSERT(uio->uio_rw == UIO_READ);
|
||||
return DEVOP_IO(d, uio);
|
||||
KASSERT(uio->uio_rw == UIO_READ);
|
||||
return DEVOP_IO(d, uio);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for write. Hand off to DEVOP_IO.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_write(struct vnode *v, struct uio *uio)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
int result;
|
||||
static int dev_write(struct vnode *v, struct uio *uio) {
|
||||
struct device *d = v->vn_data;
|
||||
int result;
|
||||
|
||||
result = dev_tryseek(d, uio->uio_offset);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = dev_tryseek(d, uio->uio_offset);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
KASSERT(uio->uio_rw == UIO_WRITE);
|
||||
return DEVOP_IO(d, uio);
|
||||
KASSERT(uio->uio_rw == UIO_WRITE);
|
||||
return DEVOP_IO(d, uio);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for ioctl(). Just pass through.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_ioctl(struct vnode *v, int op, userptr_t data)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
return DEVOP_IOCTL(d, op, data);
|
||||
static int dev_ioctl(struct vnode *v, int op, userptr_t data) {
|
||||
struct device *d = v->vn_data;
|
||||
return DEVOP_IOCTL(d, op, data);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -155,40 +136,36 @@ dev_ioctl(struct vnode *v, int op, userptr_t data)
|
||||
* Set the type and the size (block devices only).
|
||||
* The link count for a device is always 1.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_stat(struct vnode *v, struct stat *statbuf)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
int result;
|
||||
static int dev_stat(struct vnode *v, struct stat *statbuf) {
|
||||
struct device *d = v->vn_data;
|
||||
int result;
|
||||
|
||||
bzero(statbuf, sizeof(struct stat));
|
||||
bzero(statbuf, sizeof(struct stat));
|
||||
|
||||
if (d->d_blocks > 0) {
|
||||
statbuf->st_size = d->d_blocks * d->d_blocksize;
|
||||
statbuf->st_blksize = d->d_blocksize;
|
||||
}
|
||||
else {
|
||||
statbuf->st_size = 0;
|
||||
}
|
||||
if (d->d_blocks > 0) {
|
||||
statbuf->st_size = d->d_blocks * d->d_blocksize;
|
||||
statbuf->st_blksize = d->d_blocksize;
|
||||
} else {
|
||||
statbuf->st_size = 0;
|
||||
}
|
||||
|
||||
result = VOP_GETTYPE(v, &statbuf->st_mode);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
/* Make up some plausible default permissions. */
|
||||
statbuf->st_mode |= 0600;
|
||||
result = VOP_GETTYPE(v, &statbuf->st_mode);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
/* Make up some plausible default permissions. */
|
||||
statbuf->st_mode |= 0600;
|
||||
|
||||
statbuf->st_nlink = 1;
|
||||
statbuf->st_blocks = d->d_blocks;
|
||||
statbuf->st_nlink = 1;
|
||||
statbuf->st_blocks = d->d_blocks;
|
||||
|
||||
/* The device number this device sits on (in OS/161, it doesn't) */
|
||||
statbuf->st_dev = 0;
|
||||
/* The device number this device sits on (in OS/161, it doesn't) */
|
||||
statbuf->st_dev = 0;
|
||||
|
||||
/* The device number this device *is* */
|
||||
statbuf->st_rdev = d->d_devnumber;
|
||||
/* The device number this device *is* */
|
||||
statbuf->st_rdev = d->d_devnumber;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -196,75 +173,59 @@ dev_stat(struct vnode *v, struct stat *statbuf)
|
||||
* length. A device that generates data in a stream is a "character
|
||||
* device".
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_gettype(struct vnode *v, mode_t *ret)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
if (d->d_blocks > 0) {
|
||||
*ret = S_IFBLK;
|
||||
}
|
||||
else {
|
||||
*ret = S_IFCHR;
|
||||
}
|
||||
return 0;
|
||||
static int dev_gettype(struct vnode *v, mode_t *ret) {
|
||||
struct device *d = v->vn_data;
|
||||
if (d->d_blocks > 0) {
|
||||
*ret = S_IFBLK;
|
||||
} else {
|
||||
*ret = S_IFCHR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if seeking is allowed.
|
||||
*/
|
||||
static
|
||||
bool
|
||||
dev_isseekable(struct vnode *v)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
static bool dev_isseekable(struct vnode *v) {
|
||||
struct device *d = v->vn_data;
|
||||
|
||||
if (d->d_blocks == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (d->d_blocks == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* For fsync() - meaningless, do nothing.
|
||||
*/
|
||||
static
|
||||
int
|
||||
null_fsync(struct vnode *v)
|
||||
{
|
||||
(void)v;
|
||||
return 0;
|
||||
static int null_fsync(struct vnode *v) {
|
||||
(void)v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* For mmap. If you want this to do anything, you have to write it
|
||||
* yourself. Some devices may not make sense to map. Others do.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_mmap(struct vnode *v /* add stuff as needed */)
|
||||
{
|
||||
(void)v;
|
||||
return ENOSYS;
|
||||
static int dev_mmap(struct vnode *v /* add stuff as needed */) {
|
||||
(void)v;
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
/*
|
||||
* For ftruncate().
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_truncate(struct vnode *v, off_t len)
|
||||
{
|
||||
struct device *d = v->vn_data;
|
||||
static int dev_truncate(struct vnode *v, off_t len) {
|
||||
struct device *d = v->vn_data;
|
||||
|
||||
/*
|
||||
* Allow truncating to the object's own size, if it has one.
|
||||
*/
|
||||
if (d->d_blocks > 0 && (off_t)(d->d_blocks*d->d_blocksize) == len) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Allow truncating to the object's own size, if it has one.
|
||||
*/
|
||||
if (d->d_blocks > 0 && (off_t)(d->d_blocks * d->d_blocksize) == len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -273,20 +234,17 @@ dev_truncate(struct vnode *v, off_t len)
|
||||
* This should never be reached, as it's not possible to chdir to a
|
||||
* device vnode.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_namefile(struct vnode *v, struct uio *uio)
|
||||
{
|
||||
/*
|
||||
* The name of a device is always just "device:". The VFS
|
||||
* layer puts in the device name for us, so we don't need to
|
||||
* do anything further.
|
||||
*/
|
||||
static int dev_namefile(struct vnode *v, struct uio *uio) {
|
||||
/*
|
||||
* The name of a device is always just "device:". The VFS
|
||||
* layer puts in the device name for us, so we don't need to
|
||||
* do anything further.
|
||||
*/
|
||||
|
||||
(void)v;
|
||||
(void)uio;
|
||||
(void)v;
|
||||
(void)uio;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -301,76 +259,71 @@ dev_namefile(struct vnode *v, struct uio *uio)
|
||||
*
|
||||
* However, we have no support for this in the base system.
|
||||
*/
|
||||
static
|
||||
int
|
||||
dev_lookup(struct vnode *dir,
|
||||
char *pathname, struct vnode **result)
|
||||
{
|
||||
/*
|
||||
* If the path was "device:", we get "". For that, return self.
|
||||
* Anything else is an error.
|
||||
* Increment the ref count of the vnode before returning it.
|
||||
*/
|
||||
if (strlen(pathname)>0) {
|
||||
return ENOENT;
|
||||
}
|
||||
VOP_INCREF(dir);
|
||||
*result = dir;
|
||||
return 0;
|
||||
static int dev_lookup(struct vnode *dir, char *pathname,
|
||||
struct vnode **result) {
|
||||
/*
|
||||
* If the path was "device:", we get "". For that, return self.
|
||||
* Anything else is an error.
|
||||
* Increment the ref count of the vnode before returning it.
|
||||
*/
|
||||
if (strlen(pathname) > 0) {
|
||||
return ENOENT;
|
||||
}
|
||||
VOP_INCREF(dir);
|
||||
*result = dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function table for device vnodes.
|
||||
*/
|
||||
static const struct vnode_ops dev_vnode_ops = {
|
||||
.vop_magic = VOP_MAGIC,
|
||||
.vop_magic = VOP_MAGIC,
|
||||
|
||||
.vop_eachopen = dev_eachopen,
|
||||
.vop_reclaim = dev_reclaim,
|
||||
.vop_read = dev_read,
|
||||
.vop_readlink = vopfail_uio_inval,
|
||||
.vop_getdirentry = vopfail_uio_notdir,
|
||||
.vop_write = dev_write,
|
||||
.vop_ioctl = dev_ioctl,
|
||||
.vop_stat = dev_stat,
|
||||
.vop_gettype = dev_gettype,
|
||||
.vop_isseekable = dev_isseekable,
|
||||
.vop_fsync = null_fsync,
|
||||
.vop_mmap = dev_mmap,
|
||||
.vop_truncate = dev_truncate,
|
||||
.vop_namefile = dev_namefile,
|
||||
.vop_creat = vopfail_creat_notdir,
|
||||
.vop_symlink = vopfail_symlink_notdir,
|
||||
.vop_mkdir = vopfail_mkdir_notdir,
|
||||
.vop_link = vopfail_link_notdir,
|
||||
.vop_remove = vopfail_string_notdir,
|
||||
.vop_rmdir = vopfail_string_notdir,
|
||||
.vop_rename = vopfail_rename_notdir,
|
||||
.vop_lookup = dev_lookup,
|
||||
.vop_lookparent = vopfail_lookparent_notdir,
|
||||
.vop_eachopen = dev_eachopen,
|
||||
.vop_reclaim = dev_reclaim,
|
||||
.vop_read = dev_read,
|
||||
.vop_readlink = vopfail_uio_inval,
|
||||
.vop_getdirentry = vopfail_uio_notdir,
|
||||
.vop_write = dev_write,
|
||||
.vop_ioctl = dev_ioctl,
|
||||
.vop_stat = dev_stat,
|
||||
.vop_gettype = dev_gettype,
|
||||
.vop_isseekable = dev_isseekable,
|
||||
.vop_fsync = null_fsync,
|
||||
.vop_mmap = dev_mmap,
|
||||
.vop_truncate = dev_truncate,
|
||||
.vop_namefile = dev_namefile,
|
||||
.vop_creat = vopfail_creat_notdir,
|
||||
.vop_symlink = vopfail_symlink_notdir,
|
||||
.vop_mkdir = vopfail_mkdir_notdir,
|
||||
.vop_link = vopfail_link_notdir,
|
||||
.vop_remove = vopfail_string_notdir,
|
||||
.vop_rmdir = vopfail_string_notdir,
|
||||
.vop_rename = vopfail_rename_notdir,
|
||||
.vop_lookup = dev_lookup,
|
||||
.vop_lookparent = vopfail_lookparent_notdir,
|
||||
};
|
||||
|
||||
/*
|
||||
* Function to create a vnode for a VFS device.
|
||||
*/
|
||||
struct vnode *
|
||||
dev_create_vnode(struct device *dev)
|
||||
{
|
||||
int result;
|
||||
struct vnode *v;
|
||||
struct vnode *dev_create_vnode(struct device *dev) {
|
||||
int result;
|
||||
struct vnode *v;
|
||||
|
||||
v = kmalloc(sizeof(struct vnode));
|
||||
if (v==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
v = kmalloc(sizeof(struct vnode));
|
||||
if (v == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = vnode_init(v, &dev_vnode_ops, NULL, dev);
|
||||
if (result != 0) {
|
||||
panic("While creating vnode for device: vnode_init: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
result = vnode_init(v, &dev_vnode_ops, NULL, dev);
|
||||
if (result != 0) {
|
||||
panic("While creating vnode for device: vnode_init: %s\n",
|
||||
strerror(result));
|
||||
}
|
||||
|
||||
return v;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -379,10 +332,8 @@ dev_create_vnode(struct device *dev)
|
||||
* Note: this is only used in failure paths; we don't support
|
||||
* hotpluggable devices, so once a device is attached it's permanent.
|
||||
*/
|
||||
void
|
||||
dev_uncreate_vnode(struct vnode *vn)
|
||||
{
|
||||
KASSERT(vn->vn_ops == &dev_vnode_ops);
|
||||
vnode_cleanup(vn);
|
||||
kfree(vn);
|
||||
void dev_uncreate_vnode(struct vnode *vn) {
|
||||
KASSERT(vn->vn_ops == &dev_vnode_ops);
|
||||
vnode_cleanup(vn);
|
||||
kfree(vn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user