sync update dfs v2. (#8336)
This commit is contained in:
parent
a1df90dcf0
commit
304ce5919c
|
@ -36,6 +36,12 @@ ssize_t dfs_devfs_write(struct dfs_file *file, const void *buf, size_t count, of
|
||||||
int dfs_devfs_ioctl(struct dfs_file *file, int cmd, void *args);
|
int dfs_devfs_ioctl(struct dfs_file *file, int cmd, void *args);
|
||||||
int dfs_devfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count);
|
int dfs_devfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count);
|
||||||
static int dfs_devfs_poll(struct dfs_file *file, struct rt_pollreq *req);
|
static int dfs_devfs_poll(struct dfs_file *file, struct rt_pollreq *req);
|
||||||
|
int dfs_devfs_flush(struct dfs_file *file);
|
||||||
|
off_t dfs_devfs_lseek(struct dfs_file *file, off_t offset, int wherece);
|
||||||
|
int dfs_devfs_truncate(struct dfs_file *file, off_t offset);
|
||||||
|
int dfs_devfs_mmap(struct dfs_file *file, struct lwp_avl_struct *mmap);
|
||||||
|
int dfs_devfs_lock(struct dfs_file *file, struct file_lock *flock);
|
||||||
|
int dfs_devfs_flock(struct dfs_file *file, int operation, struct file_lock *flock);
|
||||||
|
|
||||||
int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data);
|
int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data);
|
||||||
int dfs_devfs_umount(struct dfs_mnt *mnt);
|
int dfs_devfs_umount(struct dfs_mnt *mnt);
|
||||||
|
@ -48,14 +54,21 @@ static int dfs_devfs_free_vnode(struct dfs_vnode *vnode);
|
||||||
|
|
||||||
static const struct dfs_file_ops _dev_fops =
|
static const struct dfs_file_ops _dev_fops =
|
||||||
{
|
{
|
||||||
.open = dfs_devfs_open,
|
.open = dfs_devfs_open,
|
||||||
.close = dfs_devfs_close,
|
.close = dfs_devfs_close,
|
||||||
.lseek = generic_dfs_lseek,
|
.lseek = generic_dfs_lseek,
|
||||||
.read = dfs_devfs_read,
|
.read = dfs_devfs_read,
|
||||||
.write = dfs_devfs_write,
|
.write = dfs_devfs_write,
|
||||||
.ioctl = dfs_devfs_ioctl,
|
.ioctl = dfs_devfs_ioctl,
|
||||||
.getdents = dfs_devfs_getdents,
|
.getdents = dfs_devfs_getdents,
|
||||||
.poll = dfs_devfs_poll,
|
.poll = dfs_devfs_poll,
|
||||||
|
|
||||||
|
.flush = dfs_devfs_flush,
|
||||||
|
.lseek = dfs_devfs_lseek,
|
||||||
|
.truncate = dfs_devfs_truncate,
|
||||||
|
.mmap = dfs_devfs_mmap,
|
||||||
|
.lock = dfs_devfs_lock,
|
||||||
|
.flock = dfs_devfs_flock,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct dfs_filesystem_ops _devfs_ops =
|
static const struct dfs_filesystem_ops _devfs_ops =
|
||||||
|
@ -175,14 +188,7 @@ static struct dfs_vnode *dfs_devfs_lookup(struct dfs_dentry *dentry)
|
||||||
vnode->mode = _device_to_mode(device);
|
vnode->mode = _device_to_mode(device);
|
||||||
vnode->size = device->ref_count;
|
vnode->size = device->ref_count;
|
||||||
vnode->nlink = 1;
|
vnode->nlink = 1;
|
||||||
if (device->fops)
|
vnode->fops = &_dev_fops;
|
||||||
{
|
|
||||||
vnode->fops = device->fops;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vnode->fops = &_dev_fops;
|
|
||||||
}
|
|
||||||
vnode->data = device;
|
vnode->data = device;
|
||||||
vnode->mnt = dentry->mnt;
|
vnode->mnt = dentry->mnt;
|
||||||
vnode->type = FT_DEVICE;
|
vnode->type = FT_DEVICE;
|
||||||
|
@ -259,64 +265,94 @@ int dfs_devfs_statfs(struct dfs_mnt *mnt, struct statfs *buf)
|
||||||
|
|
||||||
int dfs_devfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
int dfs_devfs_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result = RT_EOK;
|
||||||
rt_device_t dev_id;
|
rt_device_t device;
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
/* get device handler */
|
/* get device handler */
|
||||||
dev_id = (rt_device_t)file->vnode->data;
|
device = (rt_device_t)file->vnode->data;
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
|
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
|
||||||
return -RT_ENOSYS;
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
/* close device handler */
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
result = rt_device_control(dev_id, cmd, args);
|
if (device->fops && device->fops->ioctl)
|
||||||
if (result == RT_EOK)
|
{
|
||||||
return RT_EOK;
|
result = device->fops->ioctl(file, cmd, args);
|
||||||
|
}
|
||||||
|
else if (device->ops)
|
||||||
|
#else
|
||||||
|
if (device->ops)
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
{
|
||||||
|
result = rt_device_control(device, cmd, args);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
|
ssize_t dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
|
||||||
{
|
{
|
||||||
int result;
|
int result = -RT_EIO;
|
||||||
rt_device_t dev_id;
|
rt_device_t device;
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
/* get device handler */
|
/* get device handler */
|
||||||
dev_id = (rt_device_t)file->vnode->data;
|
device = (rt_device_t)file->vnode->data;
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
|
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
|
||||||
return -RT_ENOSYS;
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
/* read device data */
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
result = rt_device_read(dev_id, *pos, buf, count);
|
if (device->fops && device->fops->read)
|
||||||
*pos += result;
|
{
|
||||||
|
result = device->fops->read(file, buf, count, pos);
|
||||||
|
}
|
||||||
|
else if (device->ops)
|
||||||
|
#else
|
||||||
|
if (device->ops)
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
{
|
||||||
|
/* read device data */
|
||||||
|
result = rt_device_read(device, *pos, buf, count);
|
||||||
|
*pos += result;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t dfs_devfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
|
ssize_t dfs_devfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
|
||||||
{
|
{
|
||||||
int result;
|
int result = -RT_EIO;
|
||||||
rt_device_t dev_id;
|
rt_device_t device;
|
||||||
|
|
||||||
RT_ASSERT(file != RT_NULL);
|
RT_ASSERT(file != RT_NULL);
|
||||||
|
|
||||||
/* get device handler */
|
/* get device handler */
|
||||||
dev_id = (rt_device_t)file->vnode->data;
|
device = (rt_device_t)file->vnode->data;
|
||||||
RT_ASSERT(dev_id != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
|
if ((file->dentry->pathname[0] == '/') && (file->dentry->pathname[1] == '\0'))
|
||||||
return -RT_ENOSYS;
|
return -RT_ENOSYS;
|
||||||
|
|
||||||
/* read device data */
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
result = rt_device_write(dev_id, *pos, buf, count);
|
if (device->fops && device->fops->write)
|
||||||
*pos += result;
|
{
|
||||||
|
result = device->fops->write(file, buf, count, pos);
|
||||||
|
}
|
||||||
|
else if (device->ops)
|
||||||
|
#else
|
||||||
|
if (device->ops)
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
{
|
||||||
|
/* read device data */
|
||||||
|
result = rt_device_write(device, *pos, buf, count);
|
||||||
|
*pos += result;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -334,8 +370,19 @@ int dfs_devfs_close(struct dfs_file *file)
|
||||||
device = (rt_device_t)file->vnode->data;
|
device = (rt_device_t)file->vnode->data;
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
/* close device handler */
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
result = rt_device_close(device);
|
if (device->fops && device->fops->close)
|
||||||
|
{
|
||||||
|
result = device->fops->close(file);
|
||||||
|
}
|
||||||
|
else if (device->ops)
|
||||||
|
#else
|
||||||
|
if (device->ops)
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
{
|
||||||
|
/* close device handler */
|
||||||
|
result = rt_device_close(device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -361,21 +408,18 @@ int dfs_devfs_open(struct dfs_file *file)
|
||||||
if (device)
|
if (device)
|
||||||
{
|
{
|
||||||
#ifdef RT_USING_POSIX_DEVIO
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
if (device->fops)
|
if (device->fops && device->fops->open)
|
||||||
{
|
{
|
||||||
/* use device fops */
|
result = device->fops->open(file);
|
||||||
file->fops = device->fops;
|
if (result == RT_EOK || result == -RT_ENOSYS)
|
||||||
/* use fops->open */
|
|
||||||
if (file->vnode->fops->open)
|
|
||||||
{
|
{
|
||||||
result = file->vnode->fops->open(file);
|
file->fops = &_dev_fops;
|
||||||
if (result == RT_EOK || result == -RT_ENOSYS)
|
return RT_EOK;
|
||||||
{
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (device->ops)
|
||||||
|
#else
|
||||||
|
if (device->ops)
|
||||||
#endif /* RT_USING_POSIX_DEVIO */
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
{
|
{
|
||||||
result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
|
||||||
|
@ -395,18 +439,18 @@ int dfs_devfs_open(struct dfs_file *file)
|
||||||
int dfs_devfs_unlink(struct dfs_dentry *dentry)
|
int dfs_devfs_unlink(struct dfs_dentry *dentry)
|
||||||
{
|
{
|
||||||
#ifdef RT_USING_DEV_BUS
|
#ifdef RT_USING_DEV_BUS
|
||||||
rt_device_t dev_id;
|
rt_device_t device;
|
||||||
|
|
||||||
dev_id = rt_device_find(&dentry->pathname[1]);
|
device = rt_device_find(&dentry->pathname[1]);
|
||||||
if (dev_id == RT_NULL)
|
if (device == RT_NULL)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (dev_id->type != RT_Device_Class_Bus)
|
if (device->type != RT_Device_Class_Bus)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rt_device_bus_destroy(dev_id);
|
rt_device_bus_destroy(device);
|
||||||
#endif
|
#endif
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -441,10 +485,10 @@ int dfs_devfs_stat(struct dfs_dentry *dentry, struct stat *st)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rt_device_t dev_id;
|
rt_device_t device;
|
||||||
|
|
||||||
dev_id = rt_device_find(&path[1]);
|
device = rt_device_find(&path[1]);
|
||||||
if (dev_id != RT_NULL)
|
if (device != RT_NULL)
|
||||||
{
|
{
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
st->st_gid = vnode->gid;
|
st->st_gid = vnode->gid;
|
||||||
|
@ -505,10 +549,136 @@ int dfs_devfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t coun
|
||||||
static int dfs_devfs_poll(struct dfs_file *file, struct rt_pollreq *req)
|
static int dfs_devfs_poll(struct dfs_file *file, struct rt_pollreq *req)
|
||||||
{
|
{
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->poll)
|
||||||
|
{
|
||||||
|
mask = device->fops->poll(file, req);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dfs_devfs_flush(struct dfs_file *file)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->flush)
|
||||||
|
{
|
||||||
|
ret = device->fops->flush(file);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t dfs_devfs_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||||
|
{
|
||||||
|
off_t ret = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->lseek)
|
||||||
|
{
|
||||||
|
ret = device->fops->lseek(file, offset, wherece);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_devfs_truncate(struct dfs_file *file, off_t offset)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->truncate)
|
||||||
|
{
|
||||||
|
ret = device->fops->truncate(file, offset);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_devfs_mmap(struct dfs_file *file, struct lwp_avl_struct *mmap)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->mmap)
|
||||||
|
{
|
||||||
|
ret = device->fops->mmap(file, mmap);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_devfs_lock(struct dfs_file *file, struct file_lock *flock)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->lock)
|
||||||
|
{
|
||||||
|
ret = device->fops->lock(file, flock);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dfs_devfs_flock(struct dfs_file *file, int operation, struct file_lock *flock)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rt_device_t device;
|
||||||
|
|
||||||
|
/* get device handler */
|
||||||
|
device = (rt_device_t)file->vnode->data;
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
#ifdef RT_USING_POSIX_DEVIO
|
||||||
|
if (device->fops && device->fops->flock)
|
||||||
|
{
|
||||||
|
ret = device->fops->flock(file, operation, flock);
|
||||||
|
}
|
||||||
|
#endif /* RT_USING_POSIX_DEVIO */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int dfs_devfs_init(void)
|
int dfs_devfs_init(void)
|
||||||
{
|
{
|
||||||
/* register devfs file system */
|
/* register devfs file system */
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
|
|
||||||
static int dfs_elm_free_vnode(struct dfs_vnode *vnode);
|
static int dfs_elm_free_vnode(struct dfs_vnode *vnode);
|
||||||
|
static int dfs_elm_truncate(struct dfs_file *file, off_t offset);
|
||||||
|
|
||||||
#ifdef RT_USING_PAGECACHE
|
#ifdef RT_USING_PAGECACHE
|
||||||
static ssize_t dfs_elm_page_read(struct dfs_file *file, struct dfs_page *page);
|
static ssize_t dfs_elm_page_read(struct dfs_file *file, struct dfs_page *page);
|
||||||
|
@ -547,33 +548,14 @@ int dfs_elm_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case RT_FIOFTRUNCATE:
|
case RT_FIOFTRUNCATE:
|
||||||
{
|
{
|
||||||
FIL *fd;
|
off_t offset = (off_t)(size_t)(args);
|
||||||
FSIZE_t fptr, length;
|
return dfs_elm_truncate(file, offset);
|
||||||
FRESULT result = FR_OK;
|
}
|
||||||
fd = (FIL *)(file->vnode->data);
|
|
||||||
RT_ASSERT(fd != RT_NULL);
|
|
||||||
|
|
||||||
/* save file read/write point */
|
|
||||||
fptr = fd->fptr;
|
|
||||||
length = *(off_t*)args;
|
|
||||||
if (length <= fd->obj.objsize)
|
|
||||||
{
|
|
||||||
fd->fptr = length;
|
|
||||||
result = f_truncate(fd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = f_lseek(fd, length);
|
|
||||||
}
|
|
||||||
/* restore file read/write point */
|
|
||||||
fd->fptr = fptr;
|
|
||||||
return elm_result_to_dfs(result);
|
|
||||||
}
|
|
||||||
case F_GETLK:
|
case F_GETLK:
|
||||||
return 0;
|
return 0;
|
||||||
case F_SETLK:
|
case F_SETLK:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
@ -701,6 +683,30 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||||
return elm_result_to_dfs(result);
|
return elm_result_to_dfs(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dfs_elm_truncate(struct dfs_file *file, off_t offset)
|
||||||
|
{
|
||||||
|
FIL *fd;
|
||||||
|
FSIZE_t fptr;
|
||||||
|
FRESULT result = FR_OK;
|
||||||
|
fd = (FIL *)(file->vnode->data);
|
||||||
|
RT_ASSERT(fd != RT_NULL);
|
||||||
|
|
||||||
|
/* save file read/write point */
|
||||||
|
fptr = fd->fptr;
|
||||||
|
if (offset <= fd->obj.objsize)
|
||||||
|
{
|
||||||
|
fd->fptr = offset;
|
||||||
|
result = f_truncate(fd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = f_lseek(fd, offset);
|
||||||
|
}
|
||||||
|
/* restore file read/write point */
|
||||||
|
fd->fptr = fptr;
|
||||||
|
return elm_result_to_dfs(result);
|
||||||
|
}
|
||||||
|
|
||||||
int dfs_elm_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
|
int dfs_elm_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
@ -1065,6 +1071,7 @@ static const struct dfs_file_ops dfs_elm_fops =
|
||||||
.write = dfs_elm_write,
|
.write = dfs_elm_write,
|
||||||
.flush = dfs_elm_flush,
|
.flush = dfs_elm_flush,
|
||||||
.lseek = dfs_elm_lseek,
|
.lseek = dfs_elm_lseek,
|
||||||
|
.truncate = dfs_elm_truncate,
|
||||||
.getdents = dfs_elm_getdents,
|
.getdents = dfs_elm_getdents,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,9 @@ void dfs_unlock(void);
|
||||||
rt_err_t dfs_file_lock(void);
|
rt_err_t dfs_file_lock(void);
|
||||||
void dfs_file_unlock(void);
|
void dfs_file_unlock(void);
|
||||||
|
|
||||||
|
int dfs_fdtable_dup(struct dfs_fdtable *fdt_dst, struct dfs_fdtable *fdt_src, int fd_src);
|
||||||
|
int dfs_fdtable_drop_fd(struct dfs_fdtable *fdtab, int fd);
|
||||||
|
|
||||||
#ifdef DFS_USING_POSIX
|
#ifdef DFS_USING_POSIX
|
||||||
/* FD APIs */
|
/* FD APIs */
|
||||||
int fdt_fd_new(struct dfs_fdtable *fdt);
|
int fdt_fd_new(struct dfs_fdtable *fdt);
|
||||||
|
|
|
@ -181,6 +181,8 @@ int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
|
||||||
int dfs_file_mmap(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
|
int dfs_file_mmap(struct dfs_file *file, struct dfs_mmap2_args *mmap2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode);
|
||||||
|
|
||||||
/* 0x5254 is just a magic number to make these relatively unique ("RT") */
|
/* 0x5254 is just a magic number to make these relatively unique ("RT") */
|
||||||
#define RT_FIOFTRUNCATE 0x52540000U
|
#define RT_FIOFTRUNCATE 0x52540000U
|
||||||
#define RT_FIOGETADDR 0x52540001U
|
#define RT_FIOGETADDR 0x52540001U
|
||||||
|
|
|
@ -421,6 +421,99 @@ struct dfs_fdtable *dfs_fdtable_get_global(void)
|
||||||
return &_fdtab;
|
return &_fdtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dup the specified fd_src from fdt_src to fdt_dst.
|
||||||
|
*
|
||||||
|
* @param fdt_dst is the fd table for destination, if empty, use global (_fdtab).
|
||||||
|
*
|
||||||
|
* @param fdt_src is the fd table for source, if empty, use global (_fdtab).
|
||||||
|
*
|
||||||
|
* @param fd_src is the fd in the designate fdt_src table.
|
||||||
|
*
|
||||||
|
* @return -1 on failed or the allocated file descriptor.
|
||||||
|
*/
|
||||||
|
int dfs_fdtable_dup(struct dfs_fdtable *fdt_dst, struct dfs_fdtable *fdt_src, int fd_src)
|
||||||
|
{
|
||||||
|
int newfd = -1;
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
|
||||||
|
if (fdt_src == NULL)
|
||||||
|
{
|
||||||
|
fdt_src = &_fdtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdt_dst == NULL)
|
||||||
|
{
|
||||||
|
fdt_dst = &_fdtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check fd */
|
||||||
|
if ((fd_src < 0) || (fd_src >= fdt_src->maxfd))
|
||||||
|
{
|
||||||
|
goto _EXIT;
|
||||||
|
}
|
||||||
|
if (!fdt_src->fds[fd_src])
|
||||||
|
{
|
||||||
|
goto _EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a new fd*/
|
||||||
|
newfd = fdt_fd_new(fdt_dst);
|
||||||
|
if (newfd >= 0)
|
||||||
|
{
|
||||||
|
fdt_dst->fds[newfd]->mode = fdt_src->fds[fd_src]->mode;
|
||||||
|
fdt_dst->fds[newfd]->flags = fdt_src->fds[fd_src]->flags;
|
||||||
|
fdt_dst->fds[newfd]->fops = fdt_src->fds[fd_src]->fops;
|
||||||
|
fdt_dst->fds[newfd]->dentry = dfs_dentry_ref(fdt_src->fds[fd_src]->dentry);
|
||||||
|
fdt_dst->fds[newfd]->vnode = fdt_src->fds[fd_src]->vnode;
|
||||||
|
fdt_dst->fds[newfd]->mmap_context = RT_NULL;
|
||||||
|
fdt_dst->fds[newfd]->data = fdt_src->fds[fd_src]->data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dma-buf/socket fd is without dentry, so should used the vnode reference.
|
||||||
|
*/
|
||||||
|
if (!fdt_dst->fds[newfd]->dentry)
|
||||||
|
{
|
||||||
|
rt_atomic_add(&(fdt_dst->fds[newfd]->vnode->ref_count), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_EXIT:
|
||||||
|
dfs_file_unlock();
|
||||||
|
|
||||||
|
return newfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief drop fd from the fd table.
|
||||||
|
*
|
||||||
|
* @param fdt is the fd table, if empty, use global (_fdtab).
|
||||||
|
*
|
||||||
|
* @param fd is the fd in the designate fd table.
|
||||||
|
*
|
||||||
|
* @return -1 on failed the drop file descriptor.
|
||||||
|
*/
|
||||||
|
int dfs_fdtable_drop_fd(struct dfs_fdtable *fdt, int fd)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (fdt == NULL)
|
||||||
|
{
|
||||||
|
fdt = &_fdtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs_file_lock();
|
||||||
|
err = dfs_file_close(fdt->fds[fd]);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
fdt_fd_release(fdt, fd);
|
||||||
|
}
|
||||||
|
dfs_file_unlock();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int dfs_dup(int oldfd, int startfd)
|
int dfs_dup(int oldfd, int startfd)
|
||||||
{
|
{
|
||||||
int newfd = -1;
|
int newfd = -1;
|
||||||
|
|
|
@ -131,6 +131,7 @@ struct dfs_dentry *dfs_dentry_unref(struct dfs_dentry *dentry)
|
||||||
LOG_I("free a dentry: %p", dentry);
|
LOG_I("free a dentry: %p", dentry);
|
||||||
rt_free(dentry->pathname);
|
rt_free(dentry->pathname);
|
||||||
rt_free(dentry);
|
rt_free(dentry);
|
||||||
|
dentry = RT_NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -268,7 +269,7 @@ char* dfs_dentry_full_path(struct dfs_dentry* dentry)
|
||||||
path = (char *) rt_malloc(mnt_len + path_len + 3);
|
path = (char *) rt_malloc(mnt_len + path_len + 3);
|
||||||
if (path)
|
if (path)
|
||||||
{
|
{
|
||||||
if (dentry->pathname[0] == '/')
|
if (dentry->pathname[0] == '/' || dentry->mnt->fullpath[mnt_len - 1] == '/')
|
||||||
{
|
{
|
||||||
rt_snprintf(path, mnt_len + path_len + 2, "%s%s", dentry->mnt->fullpath,
|
rt_snprintf(path, mnt_len + path_len + 2, "%s%s", dentry->mnt->fullpath,
|
||||||
dentry->pathname);
|
dentry->pathname);
|
||||||
|
|
|
@ -429,7 +429,6 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||||
dentry = dfs_dentry_create(mnt, fullpath);
|
dentry = dfs_dentry_create(mnt, fullpath);
|
||||||
if (dentry)
|
if (dentry)
|
||||||
{
|
{
|
||||||
mode &= ~S_IFMT;
|
|
||||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode");
|
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode");
|
||||||
|
|
||||||
if (dfs_is_mounted(mnt) == 0)
|
if (dfs_is_mounted(mnt) == 0)
|
||||||
|
@ -565,7 +564,6 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||||
{
|
{
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -350,6 +350,38 @@ rt_err_t on_varea_merge(struct rt_varea *merge_to, struct rt_varea *merge_from)
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *on_varea_mremap(struct rt_varea *varea, rt_size_t new_size, int flags, void *new_address)
|
||||||
|
{
|
||||||
|
void *vaddr = RT_NULL;
|
||||||
|
struct dfs_file *file = dfs_mem_obj_get_file(varea->mem_obj);
|
||||||
|
|
||||||
|
#ifndef MREMAP_MAYMOVE
|
||||||
|
#define MREMAP_MAYMOVE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (file && flags == MREMAP_MAYMOVE)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
rt_mem_obj_t mem_obj = dfs_get_mem_obj(file);
|
||||||
|
|
||||||
|
vaddr = new_address ? new_address : varea->start;
|
||||||
|
new_size = (new_size + ARCH_PAGE_SIZE - 1);
|
||||||
|
new_size &= ~ARCH_PAGE_MASK;
|
||||||
|
ret = rt_aspace_map(varea->aspace, &vaddr, new_size, varea->attr, varea->flag, mem_obj, varea->offset);
|
||||||
|
if (ret != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("failed to map %lx with size %lx with errno %d", vaddr, new_size, ret);
|
||||||
|
vaddr = RT_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_I("old: %p size: %p new: %p size: %p", varea->start, varea->size, vaddr, new_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
static struct rt_mem_obj _mem_obj =
|
static struct rt_mem_obj _mem_obj =
|
||||||
{
|
{
|
||||||
.hint_free = hint_free,
|
.hint_free = hint_free,
|
||||||
|
@ -365,6 +397,8 @@ static struct rt_mem_obj _mem_obj =
|
||||||
.on_varea_expand = on_varea_expand,
|
.on_varea_expand = on_varea_expand,
|
||||||
.on_varea_split = on_varea_split,
|
.on_varea_split = on_varea_split,
|
||||||
.on_varea_merge = on_varea_merge,
|
.on_varea_merge = on_varea_merge,
|
||||||
|
|
||||||
|
.on_varea_mremap = on_varea_mremap,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dfs_mem_obj {
|
struct dfs_mem_obj {
|
||||||
|
|
|
@ -1355,6 +1355,10 @@ int dfs_aspace_unmap(struct dfs_file *file, struct rt_varea *varea)
|
||||||
|
|
||||||
if (map && varea == map->varea)
|
if (map && varea == map->varea)
|
||||||
{
|
{
|
||||||
|
void *vaddr = dfs_aspace_vaddr(map->varea, page->fpos);
|
||||||
|
|
||||||
|
rt_varea_unmap_page(map->varea, vaddr);
|
||||||
|
|
||||||
if (varea->attr == MMU_MAP_U_RWCB && page->fpos < page->aspace->vnode->size)
|
if (varea->attr == MMU_MAP_U_RWCB && page->fpos < page->aspace->vnode->size)
|
||||||
{
|
{
|
||||||
dfs_page_dirty(page);
|
dfs_page_dirty(page);
|
||||||
|
|
Loading…
Reference in New Issue