clang-format

This commit is contained in:
2024-09-10 13:03:02 -04:00
parent 53c617d779
commit d66450e427
381 changed files with 28864 additions and 34170 deletions

View File

@@ -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);
}

View File

@@ -39,86 +39,75 @@
#include <device.h>
/* For open() */
static
int
nullopen(struct device *dev, int openflags)
{
(void)dev;
(void)openflags;
static int nullopen(struct device *dev, int openflags) {
(void)dev;
(void)openflags;
return 0;
return 0;
}
/* For d_io() */
static
int
nullio(struct device *dev, struct uio *uio)
{
/*
* On write, discard everything without looking at it.
* (Notice that you can write to the null device from invalid
* buffer pointers and it will still succeed. This behavior is
* traditional.)
*
* On read, do nothing, generating an immediate EOF.
*/
static int nullio(struct device *dev, struct uio *uio) {
/*
* On write, discard everything without looking at it.
* (Notice that you can write to the null device from invalid
* buffer pointers and it will still succeed. This behavior is
* traditional.)
*
* On read, do nothing, generating an immediate EOF.
*/
(void)dev; // unused
(void)dev; // unused
if (uio->uio_rw == UIO_WRITE) {
uio->uio_resid = 0;
}
if (uio->uio_rw == UIO_WRITE) {
uio->uio_resid = 0;
}
return 0;
return 0;
}
/* For ioctl() */
static
int
nullioctl(struct device *dev, int op, userptr_t data)
{
/*
* No ioctls.
*/
static int nullioctl(struct device *dev, int op, userptr_t data) {
/*
* No ioctls.
*/
(void)dev;
(void)op;
(void)data;
(void)dev;
(void)op;
(void)data;
return EINVAL;
return EINVAL;
}
static const struct device_ops null_devops = {
.devop_eachopen = nullopen,
.devop_io = nullio,
.devop_ioctl = nullioctl,
.devop_eachopen = nullopen,
.devop_io = nullio,
.devop_ioctl = nullioctl,
};
/*
* Function to create and attach null:
*/
void
devnull_create(void)
{
int result;
struct device *dev;
void devnull_create(void) {
int result;
struct device *dev;
dev = kmalloc(sizeof(*dev));
if (dev==NULL) {
panic("Could not add null device: out of memory\n");
}
dev = kmalloc(sizeof(*dev));
if (dev == NULL) {
panic("Could not add null device: out of memory\n");
}
dev->d_ops = &null_devops;
dev->d_ops = &null_devops;
dev->d_blocks = 0;
dev->d_blocksize = 1;
dev->d_blocks = 0;
dev->d_blocksize = 1;
dev->d_devnumber = 0; /* assigned by vfs_adddev */
dev->d_devnumber = 0; /* assigned by vfs_adddev */
dev->d_data = NULL;
dev->d_data = NULL;
result = vfs_adddev("null", dev, 0);
if (result) {
panic("Could not add null device: %s\n", strerror(result));
}
result = vfs_adddev("null", dev, 0);
if (result) {
panic("Could not add null device: %s\n", strerror(result));
}
}

View File

@@ -45,94 +45,85 @@
/*
* Get current directory as a vnode.
*/
int
vfs_getcurdir(struct vnode **ret)
{
int rv = 0;
int vfs_getcurdir(struct vnode **ret) {
int rv = 0;
spinlock_acquire(&curproc->p_lock);
if (curproc->p_cwd!=NULL) {
VOP_INCREF(curproc->p_cwd);
*ret = curproc->p_cwd;
}
else {
rv = ENOENT;
}
spinlock_release(&curproc->p_lock);
spinlock_acquire(&curproc->p_lock);
if (curproc->p_cwd != NULL) {
VOP_INCREF(curproc->p_cwd);
*ret = curproc->p_cwd;
} else {
rv = ENOENT;
}
spinlock_release(&curproc->p_lock);
return rv;
return rv;
}
/*
* Set current directory as a vnode.
* The passed vnode must in fact be a directory.
*/
int
vfs_setcurdir(struct vnode *dir)
{
struct vnode *old;
mode_t vtype;
int result;
int vfs_setcurdir(struct vnode *dir) {
struct vnode *old;
mode_t vtype;
int result;
result = VOP_GETTYPE(dir, &vtype);
if (result) {
return result;
}
if (vtype != S_IFDIR) {
return ENOTDIR;
}
result = VOP_GETTYPE(dir, &vtype);
if (result) {
return result;
}
if (vtype != S_IFDIR) {
return ENOTDIR;
}
VOP_INCREF(dir);
VOP_INCREF(dir);
spinlock_acquire(&curproc->p_lock);
old = curproc->p_cwd;
curproc->p_cwd = dir;
spinlock_release(&curproc->p_lock);
spinlock_acquire(&curproc->p_lock);
old = curproc->p_cwd;
curproc->p_cwd = dir;
spinlock_release(&curproc->p_lock);
if (old!=NULL) {
VOP_DECREF(old);
}
if (old != NULL) {
VOP_DECREF(old);
}
return 0;
return 0;
}
/*
* Set current directory to "none".
*/
int
vfs_clearcurdir(void)
{
struct vnode *old;
int vfs_clearcurdir(void) {
struct vnode *old;
spinlock_acquire(&curproc->p_lock);
old = curproc->p_cwd;
curproc->p_cwd = NULL;
spinlock_release(&curproc->p_lock);
spinlock_acquire(&curproc->p_lock);
old = curproc->p_cwd;
curproc->p_cwd = NULL;
spinlock_release(&curproc->p_lock);
if (old!=NULL) {
VOP_DECREF(old);
}
if (old != NULL) {
VOP_DECREF(old);
}
return 0;
return 0;
}
/*
* Set current directory, as a pathname. Use vfs_lookup to translate
* it to a vnode.
*/
int
vfs_chdir(char *path)
{
struct vnode *vn;
int result;
int vfs_chdir(char *path) {
struct vnode *vn;
int result;
result = vfs_lookup(path, &vn);
if (result) {
return result;
}
result = vfs_setcurdir(vn);
VOP_DECREF(vn);
return result;
result = vfs_lookup(path, &vn);
if (result) {
return result;
}
result = vfs_setcurdir(vn);
VOP_DECREF(vn);
return result;
}
/*
@@ -140,45 +131,43 @@ vfs_chdir(char *path)
* Use VOP_NAMEFILE to get the pathname and FSOP_GETVOLNAME to get the
* volume name.
*/
int
vfs_getcwd(struct uio *uio)
{
struct vnode *cwd;
int result;
const char *name;
char colon=':';
int vfs_getcwd(struct uio *uio) {
struct vnode *cwd;
int result;
const char *name;
char colon = ':';
KASSERT(uio->uio_rw==UIO_READ);
KASSERT(uio->uio_rw == UIO_READ);
result = vfs_getcurdir(&cwd);
if (result) {
return result;
}
result = vfs_getcurdir(&cwd);
if (result) {
return result;
}
/* The current dir must be a directory, and thus it is not a device. */
KASSERT(cwd->vn_fs != NULL);
/* The current dir must be a directory, and thus it is not a device. */
KASSERT(cwd->vn_fs != NULL);
name = FSOP_GETVOLNAME(cwd->vn_fs);
if (name==NULL) {
vfs_biglock_acquire();
name = vfs_getdevname(cwd->vn_fs);
vfs_biglock_release();
}
KASSERT(name != NULL);
name = FSOP_GETVOLNAME(cwd->vn_fs);
if (name == NULL) {
vfs_biglock_acquire();
name = vfs_getdevname(cwd->vn_fs);
vfs_biglock_release();
}
KASSERT(name != NULL);
result = uiomove((char *)name, strlen(name), uio);
if (result) {
goto out;
}
result = uiomove(&colon, 1, uio);
if (result) {
goto out;
}
result = uiomove((char *)name, strlen(name), uio);
if (result) {
goto out;
}
result = uiomove(&colon, 1, uio);
if (result) {
goto out;
}
result = VOP_NAMEFILE(cwd, uio);
result = VOP_NAMEFILE(cwd, uio);
out:
out:
VOP_DECREF(cwd);
return result;
VOP_DECREF(cwd);
return result;
}

View File

@@ -47,218 +47,177 @@
////////////////////////////////////////////////////////////
// uio ops (read, readlink, getdirentry, write, namefile)
int
vopfail_uio_notdir(struct vnode *vn, struct uio *uio)
{
(void)vn;
(void)uio;
return ENOTDIR;
int vopfail_uio_notdir(struct vnode *vn, struct uio *uio) {
(void)vn;
(void)uio;
return ENOTDIR;
}
int
vopfail_uio_isdir(struct vnode *vn, struct uio *uio)
{
(void)vn;
(void)uio;
return EISDIR;
int vopfail_uio_isdir(struct vnode *vn, struct uio *uio) {
(void)vn;
(void)uio;
return EISDIR;
}
int
vopfail_uio_inval(struct vnode *vn, struct uio *uio)
{
(void)vn;
(void)uio;
return EINVAL;
int vopfail_uio_inval(struct vnode *vn, struct uio *uio) {
(void)vn;
(void)uio;
return EINVAL;
}
int
vopfail_uio_nosys(struct vnode *vn, struct uio *uio)
{
(void)vn;
(void)uio;
return ENOSYS;
int vopfail_uio_nosys(struct vnode *vn, struct uio *uio) {
(void)vn;
(void)uio;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// mmap
int
vopfail_mmap_isdir(struct vnode *vn /*add stuff */)
{
(void)vn;
return EISDIR;
int vopfail_mmap_isdir(struct vnode *vn /*add stuff */) {
(void)vn;
return EISDIR;
}
int
vopfail_mmap_perm(struct vnode *vn /*add stuff */)
{
(void)vn;
return EPERM;
int vopfail_mmap_perm(struct vnode *vn /*add stuff */) {
(void)vn;
return EPERM;
}
int
vopfail_mmap_nosys(struct vnode *vn /*add stuff */)
{
(void)vn;
return ENOSYS;
int vopfail_mmap_nosys(struct vnode *vn /*add stuff */) {
(void)vn;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// truncate
int
vopfail_truncate_isdir(struct vnode *vn, off_t pos)
{
(void)vn;
(void)pos;
return EISDIR;
int vopfail_truncate_isdir(struct vnode *vn, off_t pos) {
(void)vn;
(void)pos;
return EISDIR;
}
////////////////////////////////////////////////////////////
// creat
int
vopfail_creat_notdir(struct vnode *vn, const char *name, bool excl,
mode_t mode, struct vnode **result)
{
(void)vn;
(void)name;
(void)excl;
(void)mode;
(void)result;
return ENOTDIR;
int vopfail_creat_notdir(struct vnode *vn, const char *name, bool excl,
mode_t mode, struct vnode **result) {
(void)vn;
(void)name;
(void)excl;
(void)mode;
(void)result;
return ENOTDIR;
}
////////////////////////////////////////////////////////////
// symlink
int
vopfail_symlink_notdir(struct vnode *vn, const char *contents,
const char *name)
{
(void)vn;
(void)contents;
(void)name;
return ENOTDIR;
int vopfail_symlink_notdir(struct vnode *vn, const char *contents,
const char *name) {
(void)vn;
(void)contents;
(void)name;
return ENOTDIR;
}
int
vopfail_symlink_nosys(struct vnode *vn, const char *contents,
const char *name)
{
(void)vn;
(void)contents;
(void)name;
return ENOSYS;
int vopfail_symlink_nosys(struct vnode *vn, const char *contents,
const char *name) {
(void)vn;
(void)contents;
(void)name;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// mkdir
int
vopfail_mkdir_notdir(struct vnode *vn, const char *name, mode_t mode)
{
(void)vn;
(void)name;
(void)mode;
return ENOTDIR;
int vopfail_mkdir_notdir(struct vnode *vn, const char *name, mode_t mode) {
(void)vn;
(void)name;
(void)mode;
return ENOTDIR;
}
int
vopfail_mkdir_nosys(struct vnode *vn, const char *name, mode_t mode)
{
(void)vn;
(void)name;
(void)mode;
return ENOSYS;
int vopfail_mkdir_nosys(struct vnode *vn, const char *name, mode_t mode) {
(void)vn;
(void)name;
(void)mode;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// link
int
vopfail_link_notdir(struct vnode *dir, const char *name, struct vnode *file)
{
(void)dir;
(void)name;
(void)file;
return ENOTDIR;
int vopfail_link_notdir(struct vnode *dir, const char *name,
struct vnode *file) {
(void)dir;
(void)name;
(void)file;
return ENOTDIR;
}
int
vopfail_link_nosys(struct vnode *dir, const char *name, struct vnode *file)
{
(void)dir;
(void)name;
(void)file;
return ENOSYS;
int vopfail_link_nosys(struct vnode *dir, const char *name,
struct vnode *file) {
(void)dir;
(void)name;
(void)file;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// string ops (remove and rmdir)
int
vopfail_string_notdir(struct vnode *vn, const char *name)
{
(void)vn;
(void)name;
return ENOTDIR;
int vopfail_string_notdir(struct vnode *vn, const char *name) {
(void)vn;
(void)name;
return ENOTDIR;
}
int
vopfail_string_nosys(struct vnode *vn, const char *name)
{
(void)vn;
(void)name;
return ENOSYS;
int vopfail_string_nosys(struct vnode *vn, const char *name) {
(void)vn;
(void)name;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// rename
int
vopfail_rename_notdir(struct vnode *fromdir, const char *fromname,
struct vnode *todir, const char *toname)
{
(void)fromdir;
(void)fromname;
(void)todir;
(void)toname;
return ENOTDIR;
int vopfail_rename_notdir(struct vnode *fromdir, const char *fromname,
struct vnode *todir, const char *toname) {
(void)fromdir;
(void)fromname;
(void)todir;
(void)toname;
return ENOTDIR;
}
int
vopfail_rename_nosys(struct vnode *fromdir, const char *fromname,
struct vnode *todir, const char *toname)
{
(void)fromdir;
(void)fromname;
(void)todir;
(void)toname;
return ENOSYS;
int vopfail_rename_nosys(struct vnode *fromdir, const char *fromname,
struct vnode *todir, const char *toname) {
(void)fromdir;
(void)fromname;
(void)todir;
(void)toname;
return ENOSYS;
}
////////////////////////////////////////////////////////////
// lookup
int
vopfail_lookup_notdir(struct vnode *vn, char *path, struct vnode **result)
{
(void)vn;
(void)path;
(void)result;
return ENOTDIR;
int vopfail_lookup_notdir(struct vnode *vn, char *path, struct vnode **result) {
(void)vn;
(void)path;
(void)result;
return ENOTDIR;
}
int
vopfail_lookparent_notdir(struct vnode *vn, char *path, struct vnode **result,
char *buf, size_t len)
{
(void)vn;
(void)path;
(void)result;
(void)buf;
(void)len;
return ENOTDIR;
int vopfail_lookparent_notdir(struct vnode *vn, char *path,
struct vnode **result, char *buf, size_t len) {
(void)vn;
(void)path;
(void)result;
(void)buf;
(void)len;
return ENOTDIR;
}

File diff suppressed because it is too large Load Diff

View File

@@ -45,18 +45,15 @@ static struct vnode *bootfs_vnode = NULL;
/*
* Helper function for actually changing bootfs_vnode.
*/
static
void
change_bootfs(struct vnode *newvn)
{
struct vnode *oldvn;
static void change_bootfs(struct vnode *newvn) {
struct vnode *oldvn;
oldvn = bootfs_vnode;
bootfs_vnode = newvn;
oldvn = bootfs_vnode;
bootfs_vnode = newvn;
if (oldvn != NULL) {
VOP_DECREF(oldvn);
}
if (oldvn != NULL) {
VOP_DECREF(oldvn);
}
}
/*
@@ -67,171 +64,161 @@ change_bootfs(struct vnode *newvn)
*
* It is also incidentally the system's first current directory.
*/
int
vfs_setbootfs(const char *fsname)
{
char tmp[NAME_MAX+1];
char *s;
int result;
struct vnode *newguy;
int vfs_setbootfs(const char *fsname) {
char tmp[NAME_MAX + 1];
char *s;
int result;
struct vnode *newguy;
vfs_biglock_acquire();
vfs_biglock_acquire();
snprintf(tmp, sizeof(tmp)-1, "%s", fsname);
s = strchr(tmp, ':');
if (s) {
/* If there's a colon, it must be at the end */
if (strlen(s)>0) {
vfs_biglock_release();
return EINVAL;
}
}
else {
strcat(tmp, ":");
}
snprintf(tmp, sizeof(tmp) - 1, "%s", fsname);
s = strchr(tmp, ':');
if (s) {
/* If there's a colon, it must be at the end */
if (strlen(s) > 0) {
vfs_biglock_release();
return EINVAL;
}
} else {
strcat(tmp, ":");
}
result = vfs_chdir(tmp);
if (result) {
vfs_biglock_release();
return result;
}
result = vfs_chdir(tmp);
if (result) {
vfs_biglock_release();
return result;
}
result = vfs_getcurdir(&newguy);
if (result) {
vfs_biglock_release();
return result;
}
result = vfs_getcurdir(&newguy);
if (result) {
vfs_biglock_release();
return result;
}
change_bootfs(newguy);
change_bootfs(newguy);
vfs_biglock_release();
return 0;
vfs_biglock_release();
return 0;
}
/*
* Clear the bootfs vnode (preparatory to system shutdown).
*/
void
vfs_clearbootfs(void)
{
vfs_biglock_acquire();
change_bootfs(NULL);
vfs_biglock_release();
void vfs_clearbootfs(void) {
vfs_biglock_acquire();
change_bootfs(NULL);
vfs_biglock_release();
}
/*
* Common code to pull the device name, if any, off the front of a
* path and choose the vnode to begin the name lookup relative to.
*/
static
int
getdevice(char *path, char **subpath, struct vnode **startvn)
{
int slash=-1, colon=-1, i;
struct vnode *vn;
int result;
static int getdevice(char *path, char **subpath, struct vnode **startvn) {
int slash = -1, colon = -1, i;
struct vnode *vn;
int result;
KASSERT(vfs_biglock_do_i_hold());
KASSERT(vfs_biglock_do_i_hold());
/*
* Entirely empty filenames aren't legal.
*/
if (path[0] == 0) {
return EINVAL;
}
/*
* Entirely empty filenames aren't legal.
*/
if (path[0] == 0) {
return EINVAL;
}
/*
* Locate the first colon or slash.
*/
/*
* Locate the first colon or slash.
*/
for (i=0; path[i]; i++) {
if (path[i]==':') {
colon = i;
break;
}
if (path[i]=='/') {
slash = i;
break;
}
}
for (i = 0; path[i]; i++) {
if (path[i] == ':') {
colon = i;
break;
}
if (path[i] == '/') {
slash = i;
break;
}
}
if (colon < 0 && slash != 0) {
/*
* No colon before a slash, so no device name
* specified, and the slash isn't leading or is also
* absent, so this is a relative path or just a bare
* filename. Start from the current directory, and
* use the whole thing as the subpath.
*/
*subpath = path;
return vfs_getcurdir(startvn);
}
if (colon < 0 && slash != 0) {
/*
* No colon before a slash, so no device name
* specified, and the slash isn't leading or is also
* absent, so this is a relative path or just a bare
* filename. Start from the current directory, and
* use the whole thing as the subpath.
*/
*subpath = path;
return vfs_getcurdir(startvn);
}
if (colon>0) {
/* device:path - get root of device's filesystem */
path[colon]=0;
while (path[colon+1]=='/') {
/* device:/path - skip slash, treat as device:path */
colon++;
}
*subpath = &path[colon+1];
if (colon > 0) {
/* device:path - get root of device's filesystem */
path[colon] = 0;
while (path[colon + 1] == '/') {
/* device:/path - skip slash, treat as device:path */
colon++;
}
*subpath = &path[colon + 1];
result = vfs_getroot(path, startvn);
if (result) {
return result;
}
result = vfs_getroot(path, startvn);
if (result) {
return result;
}
return 0;
}
return 0;
}
/*
* We have either /path or :path.
*
* /path is a path relative to the root of the "boot filesystem".
* :path is a path relative to the root of the current filesystem.
*/
KASSERT(colon==0 || slash==0);
/*
* We have either /path or :path.
*
* /path is a path relative to the root of the "boot filesystem".
* :path is a path relative to the root of the current filesystem.
*/
KASSERT(colon == 0 || slash == 0);
if (path[0]=='/') {
if (bootfs_vnode==NULL) {
return ENOENT;
}
VOP_INCREF(bootfs_vnode);
*startvn = bootfs_vnode;
}
else {
KASSERT(path[0]==':');
if (path[0] == '/') {
if (bootfs_vnode == NULL) {
return ENOENT;
}
VOP_INCREF(bootfs_vnode);
*startvn = bootfs_vnode;
} else {
KASSERT(path[0] == ':');
result = vfs_getcurdir(&vn);
if (result) {
return result;
}
result = vfs_getcurdir(&vn);
if (result) {
return result;
}
/*
* The current directory may not be a device, so it
* must have a fs.
*/
KASSERT(vn->vn_fs!=NULL);
/*
* The current directory may not be a device, so it
* must have a fs.
*/
KASSERT(vn->vn_fs != NULL);
result = FSOP_GETROOT(vn->vn_fs, startvn);
result = FSOP_GETROOT(vn->vn_fs, startvn);
VOP_DECREF(vn);
VOP_DECREF(vn);
if (result) {
return result;
}
}
if (result) {
return result;
}
}
while (path[1]=='/') {
/* ///... or :/... */
path++;
}
while (path[1] == '/') {
/* ///... or :/... */
path++;
}
*subpath = path+1;
*subpath = path + 1;
return 0;
return 0;
}
/*
@@ -239,62 +226,57 @@ getdevice(char *path, char **subpath, struct vnode **startvn)
* (In BSD, both of these are subsumed by namei().)
*/
int
vfs_lookparent(char *path, struct vnode **retval,
char *buf, size_t buflen)
{
struct vnode *startvn;
int result;
int vfs_lookparent(char *path, struct vnode **retval, char *buf,
size_t buflen) {
struct vnode *startvn;
int result;
vfs_biglock_acquire();
vfs_biglock_acquire();
result = getdevice(path, &path, &startvn);
if (result) {
vfs_biglock_release();
return result;
}
result = getdevice(path, &path, &startvn);
if (result) {
vfs_biglock_release();
return result;
}
if (strlen(path)==0) {
/*
* It does not make sense to use just a device name in
* a context where "lookparent" is the desired
* operation.
*/
result = EINVAL;
}
else {
result = VOP_LOOKPARENT(startvn, path, retval, buf, buflen);
}
if (strlen(path) == 0) {
/*
* It does not make sense to use just a device name in
* a context where "lookparent" is the desired
* operation.
*/
result = EINVAL;
} else {
result = VOP_LOOKPARENT(startvn, path, retval, buf, buflen);
}
VOP_DECREF(startvn);
VOP_DECREF(startvn);
vfs_biglock_release();
return result;
vfs_biglock_release();
return result;
}
int
vfs_lookup(char *path, struct vnode **retval)
{
struct vnode *startvn;
int result;
int vfs_lookup(char *path, struct vnode **retval) {
struct vnode *startvn;
int result;
vfs_biglock_acquire();
vfs_biglock_acquire();
result = getdevice(path, &path, &startvn);
if (result) {
vfs_biglock_release();
return result;
}
result = getdevice(path, &path, &startvn);
if (result) {
vfs_biglock_release();
return result;
}
if (strlen(path)==0) {
*retval = startvn;
vfs_biglock_release();
return 0;
}
if (strlen(path) == 0) {
*retval = startvn;
vfs_biglock_release();
return 0;
}
result = VOP_LOOKUP(startvn, path, retval);
result = VOP_LOOKUP(startvn, path, retval);
VOP_DECREF(startvn);
vfs_biglock_release();
return result;
VOP_DECREF(startvn);
vfs_biglock_release();
return result;
}

View File

@@ -39,185 +39,172 @@
#include <vfs.h>
#include <vnode.h>
/* Does most of the work for open(). */
int
vfs_open(char *path, int openflags, mode_t mode, struct vnode **ret)
{
int how;
int result;
int canwrite;
struct vnode *vn = NULL;
int vfs_open(char *path, int openflags, mode_t mode, struct vnode **ret) {
int how;
int result;
int canwrite;
struct vnode *vn = NULL;
how = openflags & O_ACCMODE;
how = openflags & O_ACCMODE;
switch (how) {
case O_RDONLY:
canwrite=0;
break;
case O_WRONLY:
case O_RDWR:
canwrite=1;
break;
default:
return EINVAL;
}
switch (how) {
case O_RDONLY:
canwrite = 0;
break;
case O_WRONLY:
case O_RDWR:
canwrite = 1;
break;
default:
return EINVAL;
}
if (openflags & O_CREAT) {
char name[NAME_MAX+1];
struct vnode *dir;
int excl = (openflags & O_EXCL)!=0;
if (openflags & O_CREAT) {
char name[NAME_MAX + 1];
struct vnode *dir;
int excl = (openflags & O_EXCL) != 0;
result = vfs_lookparent(path, &dir, name, sizeof(name));
if (result) {
return result;
}
result = vfs_lookparent(path, &dir, name, sizeof(name));
if (result) {
return result;
}
result = VOP_CREAT(dir, name, excl, mode, &vn);
result = VOP_CREAT(dir, name, excl, mode, &vn);
VOP_DECREF(dir);
}
else {
result = vfs_lookup(path, &vn);
}
VOP_DECREF(dir);
} else {
result = vfs_lookup(path, &vn);
}
if (result) {
return result;
}
if (result) {
return result;
}
KASSERT(vn != NULL);
KASSERT(vn != NULL);
result = VOP_EACHOPEN(vn, openflags);
if (result) {
VOP_DECREF(vn);
return result;
}
result = VOP_EACHOPEN(vn, openflags);
if (result) {
VOP_DECREF(vn);
return result;
}
if (openflags & O_TRUNC) {
if (canwrite==0) {
result = EINVAL;
}
else {
result = VOP_TRUNCATE(vn, 0);
}
if (result) {
VOP_DECREF(vn);
return result;
}
}
if (openflags & O_TRUNC) {
if (canwrite == 0) {
result = EINVAL;
} else {
result = VOP_TRUNCATE(vn, 0);
}
if (result) {
VOP_DECREF(vn);
return result;
}
}
*ret = vn;
*ret = vn;
return 0;
return 0;
}
/* Does most of the work for close(). */
void
vfs_close(struct vnode *vn)
{
/*
* VOP_DECREF doesn't return an error.
*
* We assume that the file system makes every reasonable
* effort to not fail. If it does fail - such as on a hard I/O
* error or something - vnode.c prints a warning. The reason
* we don't report errors up to or above this level is that
* (1) most application software does not check for close
* failing, and more importantly
* (2) we're often called from places like process exit
* where reporting the error is impossible and
* meaningful recovery is entirely impractical.
*/
void vfs_close(struct vnode *vn) {
/*
* VOP_DECREF doesn't return an error.
*
* We assume that the file system makes every reasonable
* effort to not fail. If it does fail - such as on a hard I/O
* error or something - vnode.c prints a warning. The reason
* we don't report errors up to or above this level is that
* (1) most application software does not check for close
* failing, and more importantly
* (2) we're often called from places like process exit
* where reporting the error is impossible and
* meaningful recovery is entirely impractical.
*/
VOP_DECREF(vn);
VOP_DECREF(vn);
}
/* Does most of the work for remove(). */
int
vfs_remove(char *path)
{
struct vnode *dir;
char name[NAME_MAX+1];
int result;
int vfs_remove(char *path) {
struct vnode *dir;
char name[NAME_MAX + 1];
int result;
result = vfs_lookparent(path, &dir, name, sizeof(name));
if (result) {
return result;
}
result = vfs_lookparent(path, &dir, name, sizeof(name));
if (result) {
return result;
}
result = VOP_REMOVE(dir, name);
VOP_DECREF(dir);
result = VOP_REMOVE(dir, name);
VOP_DECREF(dir);
return result;
return result;
}
/* Does most of the work for rename(). */
int
vfs_rename(char *oldpath, char *newpath)
{
struct vnode *olddir;
char oldname[NAME_MAX+1];
struct vnode *newdir;
char newname[NAME_MAX+1];
int result;
int vfs_rename(char *oldpath, char *newpath) {
struct vnode *olddir;
char oldname[NAME_MAX + 1];
struct vnode *newdir;
char newname[NAME_MAX + 1];
int result;
result = vfs_lookparent(oldpath, &olddir, oldname, sizeof(oldname));
if (result) {
return result;
}
result = vfs_lookparent(newpath, &newdir, newname, sizeof(newname));
if (result) {
VOP_DECREF(olddir);
return result;
}
result = vfs_lookparent(oldpath, &olddir, oldname, sizeof(oldname));
if (result) {
return result;
}
result = vfs_lookparent(newpath, &newdir, newname, sizeof(newname));
if (result) {
VOP_DECREF(olddir);
return result;
}
if (olddir->vn_fs==NULL || newdir->vn_fs==NULL ||
olddir->vn_fs != newdir->vn_fs) {
VOP_DECREF(newdir);
VOP_DECREF(olddir);
return EXDEV;
}
if (olddir->vn_fs == NULL || newdir->vn_fs == NULL ||
olddir->vn_fs != newdir->vn_fs) {
VOP_DECREF(newdir);
VOP_DECREF(olddir);
return EXDEV;
}
result = VOP_RENAME(olddir, oldname, newdir, newname);
result = VOP_RENAME(olddir, oldname, newdir, newname);
VOP_DECREF(newdir);
VOP_DECREF(olddir);
VOP_DECREF(newdir);
VOP_DECREF(olddir);
return result;
return result;
}
/* Does most of the work for link(). */
int
vfs_link(char *oldpath, char *newpath)
{
struct vnode *oldfile;
struct vnode *newdir;
char newname[NAME_MAX+1];
int result;
int vfs_link(char *oldpath, char *newpath) {
struct vnode *oldfile;
struct vnode *newdir;
char newname[NAME_MAX + 1];
int result;
result = vfs_lookup(oldpath, &oldfile);
if (result) {
return result;
}
result = vfs_lookparent(newpath, &newdir, newname, sizeof(newname));
if (result) {
VOP_DECREF(oldfile);
return result;
}
result = vfs_lookup(oldpath, &oldfile);
if (result) {
return result;
}
result = vfs_lookparent(newpath, &newdir, newname, sizeof(newname));
if (result) {
VOP_DECREF(oldfile);
return result;
}
if (oldfile->vn_fs==NULL || newdir->vn_fs==NULL ||
oldfile->vn_fs != newdir->vn_fs) {
VOP_DECREF(newdir);
VOP_DECREF(oldfile);
return EXDEV;
}
if (oldfile->vn_fs == NULL || newdir->vn_fs == NULL ||
oldfile->vn_fs != newdir->vn_fs) {
VOP_DECREF(newdir);
VOP_DECREF(oldfile);
return EXDEV;
}
result = VOP_LINK(newdir, newname, oldfile);
result = VOP_LINK(newdir, newname, oldfile);
VOP_DECREF(newdir);
VOP_DECREF(oldfile);
VOP_DECREF(newdir);
VOP_DECREF(oldfile);
return result;
return result;
}
/*
@@ -227,22 +214,20 @@ vfs_link(char *oldpath, char *newpath)
* other parts of the VFS layer are missing crucial elements of
* support for symlinks.
*/
int
vfs_symlink(const char *contents, char *path)
{
struct vnode *newdir;
char newname[NAME_MAX+1];
int result;
int vfs_symlink(const char *contents, char *path) {
struct vnode *newdir;
char newname[NAME_MAX + 1];
int result;
result = vfs_lookparent(path, &newdir, newname, sizeof(newname));
if (result) {
return result;
}
result = vfs_lookparent(path, &newdir, newname, sizeof(newname));
if (result) {
return result;
}
result = VOP_SYMLINK(newdir, newname, contents);
VOP_DECREF(newdir);
result = VOP_SYMLINK(newdir, newname, contents);
VOP_DECREF(newdir);
return result;
return result;
}
/*
@@ -252,65 +237,58 @@ vfs_symlink(const char *contents, char *path)
* other parts of the VFS layer are missing crucial elements of
* support for symlinks.
*/
int
vfs_readlink(char *path, struct uio *uio)
{
struct vnode *vn;
int result;
int vfs_readlink(char *path, struct uio *uio) {
struct vnode *vn;
int result;
result = vfs_lookup(path, &vn);
if (result) {
return result;
}
result = vfs_lookup(path, &vn);
if (result) {
return result;
}
result = VOP_READLINK(vn, uio);
result = VOP_READLINK(vn, uio);
VOP_DECREF(vn);
VOP_DECREF(vn);
return result;
return result;
}
/*
* Does most of the work for mkdir.
*/
int
vfs_mkdir(char *path, mode_t mode)
{
struct vnode *parent;
char name[NAME_MAX+1];
int result;
int vfs_mkdir(char *path, mode_t mode) {
struct vnode *parent;
char name[NAME_MAX + 1];
int result;
result = vfs_lookparent(path, &parent, name, sizeof(name));
if (result) {
return result;
}
result = vfs_lookparent(path, &parent, name, sizeof(name));
if (result) {
return result;
}
result = VOP_MKDIR(parent, name, mode);
result = VOP_MKDIR(parent, name, mode);
VOP_DECREF(parent);
VOP_DECREF(parent);
return result;
return result;
}
/*
* Does most of the work for rmdir.
*/
int
vfs_rmdir(char *path)
{
struct vnode *parent;
char name[NAME_MAX+1];
int result;
int vfs_rmdir(char *path) {
struct vnode *parent;
char name[NAME_MAX + 1];
int result;
result = vfs_lookparent(path, &parent, name, sizeof(name));
if (result) {
return result;
}
result = vfs_lookparent(path, &parent, name, sizeof(name));
if (result) {
return result;
}
result = VOP_RMDIR(parent, name);
result = VOP_RMDIR(parent, name);
VOP_DECREF(parent);
VOP_DECREF(parent);
return result;
return result;
}

View File

@@ -40,50 +40,43 @@
/*
* Initialize an abstract vnode.
*/
int
vnode_init(struct vnode *vn, const struct vnode_ops *ops,
struct fs *fs, void *fsdata)
{
KASSERT(vn != NULL);
KASSERT(ops != NULL);
int vnode_init(struct vnode *vn, const struct vnode_ops *ops, struct fs *fs,
void *fsdata) {
KASSERT(vn != NULL);
KASSERT(ops != NULL);
vn->vn_ops = ops;
vn->vn_refcount = 1;
spinlock_init(&vn->vn_countlock);
vn->vn_fs = fs;
vn->vn_data = fsdata;
return 0;
vn->vn_ops = ops;
vn->vn_refcount = 1;
spinlock_init(&vn->vn_countlock);
vn->vn_fs = fs;
vn->vn_data = fsdata;
return 0;
}
/*
* Destroy an abstract vnode.
*/
void
vnode_cleanup(struct vnode *vn)
{
KASSERT(vn->vn_refcount == 1);
void vnode_cleanup(struct vnode *vn) {
KASSERT(vn->vn_refcount == 1);
spinlock_cleanup(&vn->vn_countlock);
spinlock_cleanup(&vn->vn_countlock);
vn->vn_ops = NULL;
vn->vn_refcount = 0;
vn->vn_fs = NULL;
vn->vn_data = NULL;
vn->vn_ops = NULL;
vn->vn_refcount = 0;
vn->vn_fs = NULL;
vn->vn_data = NULL;
}
/*
* Increment refcount.
* Called by VOP_INCREF.
*/
void
vnode_incref(struct vnode *vn)
{
KASSERT(vn != NULL);
void vnode_incref(struct vnode *vn) {
KASSERT(vn != NULL);
spinlock_acquire(&vn->vn_countlock);
vn->vn_refcount++;
spinlock_release(&vn->vn_countlock);
spinlock_acquire(&vn->vn_countlock);
vn->vn_refcount++;
spinlock_release(&vn->vn_countlock);
}
/*
@@ -91,88 +84,79 @@ vnode_incref(struct vnode *vn)
* Called by VOP_DECREF.
* Calls VOP_RECLAIM if the refcount hits zero.
*/
void
vnode_decref(struct vnode *vn)
{
bool destroy;
int result;
void vnode_decref(struct vnode *vn) {
bool destroy;
int result;
KASSERT(vn != NULL);
KASSERT(vn != NULL);
spinlock_acquire(&vn->vn_countlock);
spinlock_acquire(&vn->vn_countlock);
KASSERT(vn->vn_refcount > 0);
if (vn->vn_refcount > 1) {
vn->vn_refcount--;
destroy = false;
}
else {
/* Don't decrement; pass the reference to VOP_RECLAIM. */
destroy = true;
}
spinlock_release(&vn->vn_countlock);
KASSERT(vn->vn_refcount > 0);
if (vn->vn_refcount > 1) {
vn->vn_refcount--;
destroy = false;
} else {
/* Don't decrement; pass the reference to VOP_RECLAIM. */
destroy = true;
}
spinlock_release(&vn->vn_countlock);
if (destroy) {
result = VOP_RECLAIM(vn);
if (result != 0 && result != EBUSY) {
// XXX: lame.
kprintf("vfs: Warning: VOP_RECLAIM: %s\n",
strerror(result));
}
}
if (destroy) {
result = VOP_RECLAIM(vn);
if (result != 0 && result != EBUSY) {
// XXX: lame.
kprintf("vfs: Warning: VOP_RECLAIM: %s\n", strerror(result));
}
}
}
/*
* Check for various things being valid.
* Called before all VOP_* calls.
*/
void
vnode_check(struct vnode *v, const char *opstr)
{
/* not safe, and not really needed to check constant fields */
/*vfs_biglock_acquire();*/
void vnode_check(struct vnode *v, const char *opstr) {
/* not safe, and not really needed to check constant fields */
/*vfs_biglock_acquire();*/
if (v == NULL) {
panic("vnode_check: vop_%s: null vnode\n", opstr);
}
if (v == (void *)0xdeadbeef) {
panic("vnode_check: vop_%s: deadbeef vnode\n", opstr);
}
if (v == NULL) {
panic("vnode_check: vop_%s: null vnode\n", opstr);
}
if (v == (void *)0xdeadbeef) {
panic("vnode_check: vop_%s: deadbeef vnode\n", opstr);
}
if (v->vn_ops == NULL) {
panic("vnode_check: vop_%s: null ops pointer\n", opstr);
}
if (v->vn_ops == (void *)0xdeadbeef) {
panic("vnode_check: vop_%s: deadbeef ops pointer\n", opstr);
}
if (v->vn_ops == NULL) {
panic("vnode_check: vop_%s: null ops pointer\n", opstr);
}
if (v->vn_ops == (void *)0xdeadbeef) {
panic("vnode_check: vop_%s: deadbeef ops pointer\n", opstr);
}
if (v->vn_ops->vop_magic != VOP_MAGIC) {
panic("vnode_check: vop_%s: ops with bad magic number %lx\n",
opstr, v->vn_ops->vop_magic);
}
if (v->vn_ops->vop_magic != VOP_MAGIC) {
panic("vnode_check: vop_%s: ops with bad magic number %lx\n", opstr,
v->vn_ops->vop_magic);
}
// Device vnodes have null fs pointers.
//if (v->vn_fs == NULL) {
// panic("vnode_check: vop_%s: null fs pointer\n", opstr);
//}
if (v->vn_fs == (void *)0xdeadbeef) {
panic("vnode_check: vop_%s: deadbeef fs pointer\n", opstr);
}
// Device vnodes have null fs pointers.
// if (v->vn_fs == NULL) {
// panic("vnode_check: vop_%s: null fs pointer\n", opstr);
//}
if (v->vn_fs == (void *)0xdeadbeef) {
panic("vnode_check: vop_%s: deadbeef fs pointer\n", opstr);
}
spinlock_acquire(&v->vn_countlock);
spinlock_acquire(&v->vn_countlock);
if (v->vn_refcount < 0) {
panic("vnode_check: vop_%s: negative refcount %d\n", opstr,
v->vn_refcount);
}
else if (v->vn_refcount == 0) {
panic("vnode_check: vop_%s: zero refcount\n", opstr);
}
else if (v->vn_refcount > 0x100000) {
kprintf("vnode_check: vop_%s: warning: large refcount %d\n",
opstr, v->vn_refcount);
}
if (v->vn_refcount < 0) {
panic("vnode_check: vop_%s: negative refcount %d\n", opstr, v->vn_refcount);
} else if (v->vn_refcount == 0) {
panic("vnode_check: vop_%s: zero refcount\n", opstr);
} else if (v->vn_refcount > 0x100000) {
kprintf("vnode_check: vop_%s: warning: large refcount %d\n", opstr,
v->vn_refcount);
}
spinlock_release(&v->vn_countlock);
/*vfs_biglock_release();*/
spinlock_release(&v->vn_countlock);
/*vfs_biglock_release();*/
}