#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/conf.h>
#include <sys/dkio.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/pledge.h>
int
diskmapopen(dev_t dev, int flag, int fmt, struct proc *p)
{
return 0;
}
int
diskmapclose(dev_t dev, int flag, int fmt, struct proc *p)
{
return 0;
}
int
diskmapioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
struct dk_diskmap *dm;
struct nameidata ndp;
struct filedesc *fdp = p->p_fd;
struct file *fp0 = NULL, *fp = NULL;
struct vnode *vp = NULL;
char *devname, flags;
int error, fd;
if (cmd != DIOCMAP)
return ENOTTY;
dm = (struct dk_diskmap *)addr;
fd = dm->fd;
devname = malloc(PATH_MAX, M_DEVBUF, M_WAITOK);
if ((error = copyinstr(dm->device, devname, PATH_MAX, NULL)) != 0)
goto invalid;
if (disk_map(devname, devname, PATH_MAX, dm->flags) == 0) {
error = copyoutstr(devname, dm->device, PATH_MAX, NULL);
if (error != 0)
goto invalid;
}
if ((error = getvnode(p, fd, &fp0)) != 0)
goto invalid;
NDINIT(&ndp, 0, 0, UIO_SYSSPACE, devname, p);
ndp.ni_pledge = PLEDGE_RPATH;
ndp.ni_unveil = UNVEIL_READ;
if ((error = vn_open(&ndp, fp0->f_flag, 0)) != 0)
goto invalid;
vp = ndp.ni_vp;
VOP_UNLOCK(vp);
fdplock(fdp);
if (fdp->fd_ofiles[fd] != fp0) {
error = EAGAIN;
goto bad;
}
fp = fnew(p);
if (fp == NULL) {
error = ENFILE;
goto bad;
}
mtx_enter(&fdp->fd_fplock);
KASSERT(fdp->fd_ofiles[fd] == fp0);
flags = fdp->fd_ofileflags[fd];
fdp->fd_ofiles[fd] = NULL;
fdp->fd_ofileflags[fd] = 0;
mtx_leave(&fdp->fd_fplock);
fp->f_flag = fp0->f_flag;
fp->f_type = DTYPE_VNODE;
fp->f_ops = &vnops;
fp->f_data = (caddr_t)vp;
fdinsert(fdp, fd, flags, fp);
fdpunlock(fdp);
closef(fp0, p);
free(devname, M_DEVBUF, PATH_MAX);
return 0;
bad:
fdpunlock(fdp);
(void)vn_close(vp, fp0->f_flag, p->p_ucred, p);
invalid:
if (fp0)
FRELE(fp0, p);
free(devname, M_DEVBUF, PATH_MAX);
return error;
}
int
diskmapread(dev_t dev, struct uio *uio, int flag)
{
return ENXIO;
}
int
diskmapwrite(dev_t dev, struct uio *uio, int flag)
{
return ENXIO;
}