update dfs (#7887)
This commit is contained in:
parent
31fec3bb70
commit
69d94315b8
@ -485,7 +485,7 @@ int dfs_tmpfs_stat(struct dfs_filesystem *fs,
|
||||
if (d_file == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
st->st_dev = 0;
|
||||
st->st_dev = (dev_t)dfs_filesystem_lookup(fs->path);
|
||||
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
|
||||
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
if (d_file->type == TMPFS_TYPE_DIR)
|
||||
|
@ -591,39 +591,23 @@ int dfs_file_stat(const char *path, struct stat *buf)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if ((fullpath[0] == '/' && fullpath[1] == '\0') ||
|
||||
(dfs_subdir(fs->path, fullpath) == NULL))
|
||||
if (fs->ops->stat == NULL)
|
||||
{
|
||||
/* it's the root directory */
|
||||
buf->st_dev = 0;
|
||||
|
||||
buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH |
|
||||
S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
|
||||
buf->st_size = 0;
|
||||
buf->st_mtime = 0;
|
||||
|
||||
/* release full path */
|
||||
rt_free(fullpath);
|
||||
LOG_E("the filesystem didn't implement this function");
|
||||
|
||||
return RT_EOK;
|
||||
return -ENOSYS;
|
||||
}
|
||||
/* get the real file path and get file stat */
|
||||
if (fs->ops->flags & DFS_FS_FLAG_FULLPATH)
|
||||
{
|
||||
result = fs->ops->stat(fs, fullpath, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fs->ops->stat == NULL)
|
||||
{
|
||||
rt_free(fullpath);
|
||||
LOG_E("the filesystem didn't implement this function");
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* get the real file path and get file stat */
|
||||
if (fs->ops->flags & DFS_FS_FLAG_FULLPATH)
|
||||
result = fs->ops->stat(fs, fullpath, buf);
|
||||
else
|
||||
result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf);
|
||||
const char *subdir = dfs_subdir(fs->path, fullpath);
|
||||
subdir = subdir ? subdir : "/";
|
||||
result = fs->ops->stat(fs, subdir, buf);
|
||||
}
|
||||
|
||||
rt_free(fullpath);
|
||||
|
@ -232,6 +232,10 @@ int dfs_devfs_free_vnode(struct dfs_vnode *vnode)
|
||||
int dfs_devfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
|
||||
{
|
||||
RT_ASSERT(mnt != RT_NULL);
|
||||
|
||||
rt_atomic_add(&(mnt->ref_count), 1);
|
||||
mnt->flags |= MNT_IS_LOCKED;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
@ -507,15 +507,13 @@ int dfs_elm_close(struct dfs_file *file)
|
||||
else if (file->vnode->type == FT_REGULAR)
|
||||
{
|
||||
FIL *fd = RT_NULL;
|
||||
|
||||
fd = (FIL *)(file->vnode->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
result = f_close(fd);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* release memory */
|
||||
rt_free(fd);
|
||||
}
|
||||
f_close(fd);
|
||||
/* release memory */
|
||||
rt_free(fd);
|
||||
}
|
||||
|
||||
return elm_result_to_dfs(result);
|
||||
@ -573,8 +571,7 @@ ssize_t dfs_elm_read(struct dfs_file *file, void *buf, size_t len, off_t *pos)
|
||||
|
||||
result = f_read(fd, buf, len, &byte_read);
|
||||
/* update position */
|
||||
file->fpos = fd->fptr;
|
||||
*pos = file->fpos;
|
||||
*pos = fd->fptr;
|
||||
if (result == FR_OK)
|
||||
return byte_read;
|
||||
|
||||
@ -597,8 +594,7 @@ ssize_t dfs_elm_write(struct dfs_file *file, const void *buf, size_t len, off_t
|
||||
|
||||
result = f_write(fd, buf, len, &byte_write);
|
||||
/* update position and file size */
|
||||
file->fpos = fd->fptr;
|
||||
*pos = file->fpos;
|
||||
*pos = fd->fptr;
|
||||
file->vnode->size = f_size(fd);
|
||||
if (result == FR_OK)
|
||||
return byte_write;
|
||||
@ -621,6 +617,24 @@ int dfs_elm_flush(struct dfs_file *file)
|
||||
off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||
{
|
||||
FRESULT result = FR_OK;
|
||||
|
||||
switch (wherece)
|
||||
{
|
||||
case SEEK_SET:
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
offset += file->fpos;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
offset += file->vnode->size;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (file->vnode->type == FT_REGULAR)
|
||||
{
|
||||
FIL *fd;
|
||||
@ -633,7 +647,6 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* return current position */
|
||||
file->fpos = fd->fptr;
|
||||
return fd->fptr;
|
||||
}
|
||||
}
|
||||
@ -649,8 +662,7 @@ off_t dfs_elm_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||
if (result == FR_OK)
|
||||
{
|
||||
/* update file position */
|
||||
file->fpos = offset;
|
||||
return file->fpos;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,11 +230,6 @@ static struct dfs_filesystem_type _mqueue = {
|
||||
|
||||
int dfs_mqueue_init(void) {
|
||||
/* register mqueue file system */
|
||||
dfs_register(&_mqueue);
|
||||
mkdir("/dev/mqueue", 0x777);
|
||||
if (dfs_mount(RT_NULL, "/dev/mqueue", "mqueue", 0, 0) != 0) {
|
||||
rt_kprintf("Dir /dev/mqueue mount failed!\n");
|
||||
}
|
||||
return 0;
|
||||
return dfs_register(&_mqueue);
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(dfs_mqueue_init);
|
||||
|
@ -280,17 +280,16 @@ static ssize_t dfs_tmpfs_read(struct dfs_file *file, void *buf, size_t count, of
|
||||
d_file = (struct tmpfs_file *)file->vnode->data;
|
||||
RT_ASSERT(d_file != NULL);
|
||||
|
||||
if (count < file->vnode->size - file->fpos)
|
||||
if (count < file->vnode->size - *pos)
|
||||
length = count;
|
||||
else
|
||||
length = file->vnode->size - file->fpos;
|
||||
length = file->vnode->size - *pos;
|
||||
|
||||
if (length > 0)
|
||||
memcpy(buf, &(d_file->data[file->fpos]), length);
|
||||
memcpy(buf, &(d_file->data[*pos]), length);
|
||||
|
||||
/* update file current position */
|
||||
file->fpos += length;
|
||||
*pos = file->fpos;
|
||||
*pos += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
@ -306,41 +305,55 @@ static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t co
|
||||
superblock = d_file->sb;
|
||||
RT_ASSERT(superblock != NULL);
|
||||
|
||||
if (count + file->fpos > file->vnode->size)
|
||||
if (count + *pos > file->vnode->size)
|
||||
{
|
||||
rt_uint8_t *ptr;
|
||||
ptr = rt_realloc(d_file->data, file->fpos + count);
|
||||
ptr = rt_realloc(d_file->data, *pos + count);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
rt_set_errno(-ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
superblock->df_size += (file->fpos - d_file->size + count);
|
||||
superblock->df_size += (*pos - d_file->size + count);
|
||||
/* update d_file and file size */
|
||||
d_file->data = ptr;
|
||||
d_file->size = file->fpos + count;
|
||||
d_file->size = *pos + count;
|
||||
file->vnode->size = d_file->size;
|
||||
LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size);
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
memcpy(d_file->data + file->fpos, buf, count);
|
||||
memcpy(d_file->data + *pos, buf, count);
|
||||
|
||||
/* update file current position */
|
||||
file->fpos += count;
|
||||
*pos = file->fpos;
|
||||
*pos += count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static off_t dfs_tmpfs_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||
{
|
||||
switch (wherece)
|
||||
{
|
||||
case SEEK_SET:
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
offset += file->fpos;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
offset += file->vnode->size;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (offset <= (off_t)file->vnode->size)
|
||||
{
|
||||
file->fpos = offset;
|
||||
|
||||
return file->fpos;
|
||||
return offset;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
|
@ -140,6 +140,8 @@ void dfs_file_deinit(struct dfs_file *file);
|
||||
int dfs_file_open(struct dfs_file *file, const char *path, int flags, mode_t mode);
|
||||
int dfs_file_close(struct dfs_file *file);
|
||||
|
||||
off_t dfs_file_get_fpos(struct dfs_file *file);
|
||||
void dfs_file_set_fpos(struct dfs_file *file, off_t fpos);
|
||||
ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len);
|
||||
ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len);
|
||||
off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence);
|
||||
|
@ -77,6 +77,7 @@ struct dfs_filesystem_type
|
||||
struct dfs_filesystem_type *next;
|
||||
};
|
||||
|
||||
struct dfs_filesystem_type *dfs_filesystems(void);
|
||||
int dfs_unregister(struct dfs_filesystem_type *fs);
|
||||
int dfs_register(struct dfs_filesystem_type *fs);
|
||||
const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
|
||||
@ -86,8 +87,9 @@ int dfs_mount(const char *device_name,
|
||||
const char *filesystemtype,
|
||||
unsigned long rwflag,
|
||||
const void *data);
|
||||
int dfs_umount(const char *specialfile);
|
||||
int dfs_umount(const char *specialfile, int flags);
|
||||
int dfs_unmount(const char *specialfile);
|
||||
int dfs_is_mounted(struct dfs_mnt *mnt);
|
||||
int dfs_mkfs(const char *fs_name, const char *device_name);
|
||||
int dfs_statfs(const char *path, struct statfs *buffer);
|
||||
int dfs_filesystem_get_partition(struct dfs_partition *part,
|
||||
|
@ -36,6 +36,9 @@ struct dfs_mnt
|
||||
#define MNT_IS_ALLOCED 0x1 /* the mnt struct is allocated */
|
||||
#define MNT_IS_ADDLIST 0x2 /* the mnt struct is added into list */
|
||||
#define MNT_IS_MOUNTED 0x4 /* the mnt struct is mounted */
|
||||
#define MNT_IS_UMOUNT 0x8 /* the mnt is unmount */
|
||||
#define MNT_IS_LOCKED 0x10 /* the mnt is locked */
|
||||
#define MNT_FORCE 0x20 /* the mnt force unmount */
|
||||
|
||||
rt_atomic_t ref_count; /* reference count */
|
||||
|
||||
@ -58,6 +61,8 @@ int dfs_mnt_unref(struct dfs_mnt* mnt);
|
||||
|
||||
rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath);
|
||||
|
||||
int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -197,7 +197,7 @@ int fdt_fd_new(struct dfs_fdtable *fdt)
|
||||
dfs_file_lock();
|
||||
|
||||
/* find an empty fd entry */
|
||||
idx = fd_alloc(fdt, 0);
|
||||
idx = fd_alloc(fdt, (fdt == &_fdtab) ? DFS_STDIO_OFFSET : 0);
|
||||
/* can't find an empty fd entry */
|
||||
if (idx < 0)
|
||||
{
|
||||
@ -452,7 +452,7 @@ sysret_t sys_dup(int oldfd)
|
||||
int sys_dup(int oldfd)
|
||||
#endif
|
||||
{
|
||||
int newfd = dfs_dup(oldfd, DFS_STDIO_OFFSET);
|
||||
int newfd = dfs_dup(oldfd, (dfs_fdtable_get() == &_fdtab) ? DFS_STDIO_OFFSET : 0);
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
return (sysret_t)newfd;
|
||||
|
@ -185,7 +185,7 @@ void dfs_dentry_insert(struct dfs_dentry *dentry)
|
||||
struct dfs_dentry *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags)
|
||||
{
|
||||
struct dfs_dentry *dentry;
|
||||
struct dfs_vnode *vnode;
|
||||
struct dfs_vnode *vnode = RT_NULL;
|
||||
int mntpoint_len = strlen(mnt->fullpath);
|
||||
|
||||
if (rt_strncmp(mnt->fullpath, path, mntpoint_len) == 0)
|
||||
@ -210,7 +210,12 @@ struct dfs_dentry *dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint
|
||||
if (dentry)
|
||||
{
|
||||
DLOG(msg, "dentry", mnt->fs_ops->name, DLOG_MSG, "vnode=fs_ops->lookup(dentry)");
|
||||
vnode = mnt->fs_ops->lookup(dentry);
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
vnode = mnt->fs_ops->lookup(dentry);
|
||||
}
|
||||
|
||||
if (vnode)
|
||||
{
|
||||
DLOG(msg, mnt->fs_ops->name, "dentry", DLOG_MSG_RET, "return vnode");
|
||||
|
@ -48,11 +48,28 @@ ssize_t rw_verify_area(struct dfs_file *file, off_t *ppos, size_t count)
|
||||
return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
|
||||
}
|
||||
|
||||
off_t dfs_file_get_fpos(struct dfs_file *file)
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
if (file->vnode->type == FT_REGULAR)
|
||||
{
|
||||
rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER);
|
||||
}
|
||||
return file->fpos;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dfs_file_set_fpos(struct dfs_file *file, off_t fpos)
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER);
|
||||
if (file->vnode->type != FT_REGULAR)
|
||||
{
|
||||
rt_mutex_take(&file->pos_lock, RT_WAITING_FOREVER);
|
||||
}
|
||||
file->fpos = fpos;
|
||||
rt_mutex_release(&file->pos_lock);
|
||||
}
|
||||
@ -116,6 +133,7 @@ static void dfs_file_unref(struct dfs_file *file)
|
||||
struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
|
||||
{
|
||||
int ret = 0;
|
||||
struct dfs_dentry *tmp = dfs_dentry_ref(dentry);
|
||||
|
||||
if (dentry && dentry->vnode && dentry->vnode->type == FT_SYMLINK)
|
||||
{
|
||||
@ -126,14 +144,18 @@ struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
|
||||
{
|
||||
do
|
||||
{
|
||||
ret = dentry->mnt->fs_ops->readlink(dentry, buf, DFS_PATH_MAX);
|
||||
if (dfs_is_mounted(tmp->mnt) == 0)
|
||||
{
|
||||
ret = tmp->mnt->fs_ops->readlink(tmp, buf, DFS_PATH_MAX);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
struct dfs_mnt *mnt = NULL;
|
||||
|
||||
if (buf[0] != '/')
|
||||
{
|
||||
char *dir = dfs_dentry_pathname(dentry);
|
||||
char *dir = dfs_dentry_pathname(tmp);
|
||||
|
||||
/* is the relative directory */
|
||||
if (dir)
|
||||
@ -155,21 +177,21 @@ struct dfs_dentry* dfs_file_follow_link(struct dfs_dentry *dentry)
|
||||
struct dfs_dentry *de = dfs_dentry_lookup(mnt, buf, 0);
|
||||
|
||||
/* release the old dentry */
|
||||
dfs_dentry_unref(dentry);
|
||||
dentry = de;
|
||||
dfs_dentry_unref(tmp);
|
||||
tmp = de;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (dentry && dentry->vnode->type == FT_SYMLINK);
|
||||
} while (tmp && tmp->vnode->type == FT_SYMLINK);
|
||||
}
|
||||
|
||||
rt_free(buf);
|
||||
}
|
||||
|
||||
return dentry;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -215,7 +237,10 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
|
||||
|
||||
if ((*mnt)->fs_ops->readlink)
|
||||
{
|
||||
ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
|
||||
if (dfs_is_mounted((*mnt)) == 0)
|
||||
{
|
||||
ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
@ -264,7 +289,10 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
|
||||
|
||||
if ((*mnt)->fs_ops->readlink)
|
||||
{
|
||||
ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
|
||||
if (dfs_is_mounted((*mnt)) == 0)
|
||||
{
|
||||
ret = (*mnt)->fs_ops->readlink(dentry, link_fn, DFS_PATH_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
@ -316,7 +344,7 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
|
||||
*/
|
||||
int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mode)
|
||||
{
|
||||
int ret = -RT_ERROR;;
|
||||
int ret = -RT_ERROR;
|
||||
char *fullpath = RT_NULL;
|
||||
struct dfs_dentry *dentry = RT_NULL;
|
||||
int fflags = dfs_fflags(oflags);
|
||||
@ -361,10 +389,8 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
|
||||
/* follow symbol link */
|
||||
target_dentry = dfs_file_follow_link(dentry);
|
||||
if (target_dentry)
|
||||
{
|
||||
dentry = target_dentry;
|
||||
}
|
||||
dfs_dentry_unref(dentry);
|
||||
dentry = target_dentry;
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,7 +445,11 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
{
|
||||
mode &= ~S_IFMT;
|
||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->create_vnode");
|
||||
vnode = mnt->fs_ops->create_vnode(dentry, oflags & O_DIRECTORY ? FT_DIRECTORY:FT_REGULAR, mode);
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
vnode = mnt->fs_ops->create_vnode(dentry, oflags & O_DIRECTORY ? FT_DIRECTORY:FT_REGULAR, mode);
|
||||
}
|
||||
|
||||
if (vnode)
|
||||
{
|
||||
@ -477,7 +507,16 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
if (permission && file->fops->open)
|
||||
{
|
||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fops->open(file)");
|
||||
ret = file->fops->open(file);
|
||||
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->open(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
LOG_E("open %s failed in file system: %s", path, dentry->mnt->fs_ops->name);
|
||||
@ -523,7 +562,16 @@ int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mo
|
||||
if (file->fops->truncate)
|
||||
{
|
||||
DLOG(msg, "dfs_file", dentry->mnt->fs_ops->name, DLOG_MSG, "fops->truncate(file, 0)");
|
||||
ret = file->fops->truncate(file, 0);
|
||||
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->truncate(file, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,6 +600,7 @@ int dfs_file_close(struct dfs_file *file)
|
||||
if (ref_count == 1 && file->fops && file->fops->close)
|
||||
{
|
||||
DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->close(file)");
|
||||
|
||||
ret = file->fops->close(file);
|
||||
|
||||
if (ret == 0) /* close file sucessfully */
|
||||
@ -594,20 +643,25 @@ ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len)
|
||||
}
|
||||
else if (file->vnode && file->vnode->type != FT_DIRECTORY)
|
||||
{
|
||||
off_t pos;
|
||||
pos = file->fpos;
|
||||
/* fpos lock */
|
||||
off_t pos = dfs_file_get_fpos(file);
|
||||
|
||||
ret = rw_verify_area(file, &pos, len);
|
||||
if (ret > 0)
|
||||
{
|
||||
len = ret;
|
||||
|
||||
ret = file->fops->read(file, buf, len, &pos);
|
||||
if (ret > 0)
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
dfs_file_set_fpos(file, pos);
|
||||
ret = file->fops->read(file, buf, len, &pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
/* fpos unlock */
|
||||
dfs_file_set_fpos(file, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,21 +686,27 @@ ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len)
|
||||
}
|
||||
else if (file->vnode && file->vnode->type != FT_DIRECTORY)
|
||||
{
|
||||
off_t pos;
|
||||
/* fpos lock */
|
||||
off_t pos = dfs_file_get_fpos(file);
|
||||
|
||||
pos = file->fpos;
|
||||
ret = rw_verify_area(file, &pos, len);
|
||||
if (ret > 0)
|
||||
{
|
||||
len = ret;
|
||||
DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG,
|
||||
"dfs_file_write(fd, buf, %d)", len);
|
||||
ret = file->fops->write(file, buf, len, &pos);
|
||||
if (ret > 0)
|
||||
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
dfs_file_set_fpos(file, pos);
|
||||
ret = file->fops->write(file, buf, len, &pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
/* fpos unlock */
|
||||
dfs_file_set_fpos(file, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -666,25 +726,26 @@ off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence)
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
dfs_file_set_fpos(file, foffset);
|
||||
|
||||
return foffset;
|
||||
}
|
||||
|
||||
off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece)
|
||||
{
|
||||
off_t retval;
|
||||
off_t retval = -EINVAL;
|
||||
|
||||
if (!file)
|
||||
return -EBADF;
|
||||
|
||||
retval = -EINVAL;
|
||||
if (file->fops->lseek)
|
||||
if (file && file->fops->lseek)
|
||||
{
|
||||
retval = file->fops->lseek(file, offset, wherece);
|
||||
if (retval >= 0)
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
dfs_file_set_fpos(file, retval);
|
||||
/* fpos lock */
|
||||
off_t pos = dfs_file_get_fpos(file);
|
||||
retval = file->fops->lseek(file, offset, wherece);
|
||||
if (retval >= 0)
|
||||
{
|
||||
pos = retval;
|
||||
}
|
||||
/* fpos unlock */
|
||||
dfs_file_set_fpos(file, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,7 +781,11 @@ int dfs_file_stat(const char *path, struct stat *buf)
|
||||
if (mnt->fs_ops->stat)
|
||||
{
|
||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
|
||||
ret = mnt->fs_ops->stat(dentry, buf);
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->stat(dentry, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* unref dentry */
|
||||
@ -770,7 +835,11 @@ int dfs_file_lstat(const char *path, struct stat *buf)
|
||||
if (mnt->fs_ops->stat)
|
||||
{
|
||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
|
||||
ret = mnt->fs_ops->stat(dentry, buf);
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->stat(dentry, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* unref dentry */
|
||||
@ -845,7 +914,11 @@ int dfs_file_setattr(const char *path, struct dfs_attr *attr)
|
||||
if (mnt->fs_ops->setattr)
|
||||
{
|
||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->setattr(dentry, attr)");
|
||||
ret = mnt->fs_ops->setattr(dentry, attr);
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->setattr(dentry, attr);
|
||||
}
|
||||
}
|
||||
|
||||
/* unref dentry */
|
||||
@ -870,7 +943,14 @@ int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args)
|
||||
{
|
||||
if (file->fops && file->fops->ioctl)
|
||||
{
|
||||
ret = file->fops->ioctl(file, cmd, args);
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->ioctl(file, cmd, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -953,7 +1033,14 @@ int dfs_file_fsync(struct dfs_file *file)
|
||||
{
|
||||
if (file->fops->flush)
|
||||
{
|
||||
ret = file->fops->flush(file);
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->flush(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,7 +1084,10 @@ int dfs_file_unlink(const char *path)
|
||||
|
||||
if (mnt->fs_ops->unlink)
|
||||
{
|
||||
ret = mnt->fs_ops->unlink(dentry);
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->unlink(dentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1096,7 +1186,10 @@ int dfs_file_link(const char *oldname, const char *newname)
|
||||
{
|
||||
if (mnt->fs_ops->link)
|
||||
{
|
||||
ret = mnt->fs_ops->link(old_dentry, new_dentry);
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->link(old_dentry, new_dentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1211,7 +1304,10 @@ int dfs_file_symlink(const char *target, const char *linkpath)
|
||||
}
|
||||
}
|
||||
|
||||
ret = mnt->fs_ops->symlink(dentry, tmp, index + 1);
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->symlink(dentry, tmp, index + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1280,7 +1376,10 @@ int dfs_file_readlink(const char *path, char *buf, int bufsize)
|
||||
{
|
||||
if (mnt->fs_ops->readlink)
|
||||
{
|
||||
ret = mnt->fs_ops->readlink(dentry, buf, bufsize);
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->readlink(dentry, buf, bufsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1361,7 +1460,10 @@ int dfs_file_rename(const char *old_file, const char *new_file)
|
||||
{
|
||||
if (mnt->fs_ops->rename)
|
||||
{
|
||||
ret = mnt->fs_ops->rename(old_dentry, new_dentry);
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->rename(old_dentry, new_dentry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1390,7 +1492,14 @@ int dfs_file_ftruncate(struct dfs_file *file, off_t length)
|
||||
{
|
||||
if (file->fops->truncate)
|
||||
{
|
||||
ret = file->fops->truncate(file, length);
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->truncate(file, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1413,7 +1522,14 @@ int dfs_file_flush(struct dfs_file *file)
|
||||
{
|
||||
if (file->fops->flush)
|
||||
{
|
||||
ret = file->fops->flush(file);
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->flush(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1439,7 +1555,15 @@ int dfs_file_getdents(struct dfs_file *file, struct dirent *dirp, size_t nbytes)
|
||||
if (file->fops && file->fops->getdents)
|
||||
{
|
||||
DLOG(msg, "dfs_file", file->dentry->mnt->fs_ops->name, DLOG_MSG, "fops->getdents()");
|
||||
ret = file->fops->getdents(file, dirp, nbytes);
|
||||
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->fops->getdents(file, dirp, nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1488,7 +1612,12 @@ int dfs_file_isdir(const char *path)
|
||||
{
|
||||
struct stat stat = {0};
|
||||
DLOG(msg, "dfs_file", mnt->fs_ops->name, DLOG_MSG, "fs_ops->stat(dentry, buf)");
|
||||
ret = mnt->fs_ops->stat(dentry, &stat);
|
||||
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->stat(dentry, &stat);
|
||||
}
|
||||
|
||||
if (ret == RT_EOK && S_ISDIR(stat.st_mode))
|
||||
{
|
||||
ret = RT_EOK;
|
||||
@ -1547,7 +1676,15 @@ int dfs_file_mmap2(struct dfs_file *file, struct dfs_mmap2_args *mmap2)
|
||||
}
|
||||
else if (file->vnode->type == FT_DEVICE && file->vnode->fops->ioctl)
|
||||
{
|
||||
ret = file->vnode->fops->ioctl(file, RT_FIOMMAP2, mmap2);
|
||||
if (dfs_is_mounted(file->vnode->mnt) == 0)
|
||||
{
|
||||
ret = file->vnode->fops->ioctl(file, RT_FIOMMAP2, mmap2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
ret = ret > 0 ? ret : -ret;
|
||||
|
@ -43,6 +43,11 @@ static struct dfs_filesystem_type **_find_filesystem(const char *name)
|
||||
return type;
|
||||
}
|
||||
|
||||
struct dfs_filesystem_type *dfs_filesystems(void)
|
||||
{
|
||||
return file_systems;
|
||||
}
|
||||
|
||||
int dfs_register(struct dfs_filesystem_type *fs)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -160,6 +165,8 @@ int dfs_mount(const char *device_name,
|
||||
DLOG(msg, type->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK, ret root_dentry");
|
||||
|
||||
mnt_child = mnt_parent;
|
||||
mnt_child->flags |= MNT_IS_MOUNTED;
|
||||
|
||||
DLOG(note_right, "mnt", "mount sucessfully");
|
||||
DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_insert(, mnt_child)");
|
||||
dfs_mnt_insert(RT_NULL, mnt_child);
|
||||
@ -202,7 +209,7 @@ int dfs_mount(const char *device_name,
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
else if (strcmp(mnt_parent->fullpath, fullpath) != 0)
|
||||
else if (mnt_parent && (strcmp(mnt_parent->fullpath, fullpath) != 0))
|
||||
{
|
||||
DLOG(msg, "dfs", "dentry", DLOG_MSG, "mntpoint_dentry = dfs_dentry_lookup(mnt_parent, %s, 0)", fullpath);
|
||||
mntpoint_dentry = dfs_dentry_lookup(mnt_parent, fullpath, 0);
|
||||
@ -224,6 +231,8 @@ int dfs_mount(const char *device_name,
|
||||
ret = mnt_child->fs_ops->mount(mnt_child, rwflag, data);
|
||||
if (ret == RT_EOK)
|
||||
{
|
||||
mnt_child->flags |= MNT_IS_MOUNTED;
|
||||
|
||||
LOG_D("mount %s sucessfully", fullpath);
|
||||
DLOG(msg, mnt_child->fs_ops->name, "dfs", DLOG_MSG_RET, "mount OK");
|
||||
|
||||
@ -285,7 +294,7 @@ int dfs_mount(const char *device_name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfs_umount(const char *specialfile)
|
||||
int dfs_umount(const char *specialfile, int flags)
|
||||
{
|
||||
int ret = -RT_ERROR;
|
||||
char *fullpath = RT_NULL;
|
||||
@ -301,22 +310,13 @@ int dfs_umount(const char *specialfile)
|
||||
if (strcmp(mnt->fullpath, fullpath) == 0)
|
||||
{
|
||||
/* is the mount point */
|
||||
rt_atomic_t ref_count = rt_atomic_load(&(mnt->ref_count));
|
||||
|
||||
if (rt_atomic_load(&(mnt->ref_count)) == 1 && rt_list_isempty(&mnt->child))
|
||||
if (!(mnt->flags & MNT_IS_LOCKED) && rt_list_isempty(&mnt->child) && (ref_count == 1 || (flags & MNT_FORCE)))
|
||||
{
|
||||
DLOG(msg, "dfs", mnt->fs_ops->name, DLOG_MSG, "fs_ops->umount(mnt)");
|
||||
ret = mnt->fs_ops->umount(mnt);
|
||||
if (ret == 0)
|
||||
{
|
||||
DLOG(msg, mnt->fs_ops->name, "dfs", DLOG_MSG_RET, "return OK");
|
||||
/* destroy this mount point */
|
||||
DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt)");
|
||||
dfs_mnt_destroy(mnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("umount file system: %s failed.", fullpath);
|
||||
}
|
||||
/* destroy this mount point */
|
||||
DLOG(msg, "dfs", "mnt", DLOG_MSG, "dfs_mnt_destroy(mnt)");
|
||||
ret = dfs_mnt_destroy(mnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -345,7 +345,19 @@ int dfs_umount(const char *specialfile)
|
||||
/* for compatibility */
|
||||
int dfs_unmount(const char *specialfile)
|
||||
{
|
||||
return dfs_umount(specialfile);
|
||||
return dfs_umount(specialfile, 0);
|
||||
}
|
||||
|
||||
int dfs_is_mounted(struct dfs_mnt *mnt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (mnt && !(mnt->flags & MNT_IS_MOUNTED))
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfs_mkfs(const char *fs_name, const char *device_name)
|
||||
@ -407,7 +419,10 @@ int dfs_statfs(const char *path, struct statfs *buffer)
|
||||
{
|
||||
if (mnt->fs_ops->statfs)
|
||||
{
|
||||
ret = mnt->fs_ops->statfs(mnt, buffer);
|
||||
if (dfs_is_mounted(mnt) == 0)
|
||||
{
|
||||
ret = mnt->fs_ops->statfs(mnt, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,7 @@ int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child)
|
||||
{
|
||||
/* it's root mnt */
|
||||
mnt = child;
|
||||
mnt->flags |= MNT_IS_LOCKED;
|
||||
|
||||
/* ref to gobal root */
|
||||
if (_root_mnt)
|
||||
@ -194,22 +195,34 @@ int dfs_mnt_unref(struct dfs_mnt* mnt)
|
||||
|
||||
if (mnt)
|
||||
{
|
||||
ret = dfs_lock();
|
||||
if (ret == RT_EOK)
|
||||
{
|
||||
rt_atomic_sub(&(mnt->ref_count), 1);
|
||||
rt_atomic_sub(&(mnt->ref_count), 1);
|
||||
|
||||
if (rt_atomic_load(&(mnt->ref_count)) < 0)
|
||||
if (rt_atomic_load(&(mnt->ref_count)) == 0)
|
||||
{
|
||||
dfs_lock();
|
||||
|
||||
if (mnt->flags & MNT_IS_UMOUNT)
|
||||
{
|
||||
LOG_W("bug on mnt(%s) release ref_count(%d).", mnt->fullpath, mnt->ref_count);
|
||||
mnt->fs_ops->umount(mnt);
|
||||
}
|
||||
DLOG(note, "mnt", "mnt(%s),ref_count=%d", mnt->fs_ops->name, rt_atomic_load(&(mnt->ref_count)));
|
||||
|
||||
/* free full path */
|
||||
rt_free(mnt->fullpath);
|
||||
mnt->fullpath = RT_NULL;
|
||||
|
||||
/* destroy self and the ref_count should be 0 */
|
||||
DLOG(msg, "mnt", "mnt", DLOG_MSG, "free mnt(%s)", mnt->fs_ops->name);
|
||||
rt_free(mnt);
|
||||
|
||||
dfs_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
DLOG(note, "mnt", "mnt(%s),ref_count=%d", mnt->fs_ops->name, rt_atomic_load(&(mnt->ref_count)));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfs_mnt_destroy(struct dfs_mnt* mnt)
|
||||
@ -218,33 +231,21 @@ int dfs_mnt_destroy(struct dfs_mnt* mnt)
|
||||
|
||||
if (mnt)
|
||||
{
|
||||
ret = dfs_lock();
|
||||
if (ret == RT_EOK)
|
||||
if (mnt->flags & MNT_IS_MOUNTED)
|
||||
{
|
||||
if (rt_atomic_load(&(mnt->ref_count)) != 1)
|
||||
{
|
||||
LOG_W("bug on mnt(%s) ref_count(%d).", mnt->fullpath, mnt->ref_count);
|
||||
}
|
||||
|
||||
mnt->flags &= ~MNT_IS_MOUNTED;
|
||||
mnt->flags |= MNT_IS_UMOUNT;
|
||||
/* remote it from mnt list */
|
||||
if (mnt->flags & MNT_IS_ADDLIST)
|
||||
{
|
||||
dfs_mnt_remove(mnt);
|
||||
}
|
||||
|
||||
/* free full path */
|
||||
rt_free(mnt->fullpath);
|
||||
mnt->fullpath = RT_NULL;
|
||||
|
||||
dfs_unlock();
|
||||
|
||||
/* destroy self and the ref_count should be 0 */
|
||||
DLOG(msg, "mnt", "mnt", DLOG_MSG, "free mnt(%s)", mnt->fs_ops->name);
|
||||
rt_free(mnt);
|
||||
}
|
||||
|
||||
dfs_mnt_unref(mnt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dfs_mnt* _dfs_mnt_foreach(struct dfs_mnt *mnt, struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter)
|
||||
@ -384,3 +385,14 @@ int dfs_mnt_list(struct dfs_mnt *mnt)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter)
|
||||
{
|
||||
/* lock file system */
|
||||
dfs_lock();
|
||||
_dfs_mnt_foreach(_root_mnt, func, parameter);
|
||||
/* unlock file system */
|
||||
dfs_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ RTM_EXPORT(stat);
|
||||
*/
|
||||
int fstat(int fildes, struct stat *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = -1;
|
||||
struct dfs_file *file;
|
||||
|
||||
if (buf == NULL)
|
||||
@ -430,7 +430,10 @@ int fstat(int fildes, struct stat *buf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = file->dentry->mnt->fs_ops->stat(file->dentry, buf);
|
||||
if (dfs_is_mounted(file->dentry->mnt) == 0)
|
||||
{
|
||||
ret = file->dentry->mnt->fs_ops->stat(file->dentry, buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -624,7 +627,7 @@ RTM_EXPORT(statfs);
|
||||
*/
|
||||
int fstatfs(int fildes, struct statfs *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = -1;
|
||||
struct dfs_file *file;
|
||||
|
||||
if (buf == NULL)
|
||||
@ -642,7 +645,10 @@ int fstatfs(int fildes, struct statfs *buf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = file->dentry->mnt->fs_ops->statfs(file->dentry->mnt, buf);
|
||||
if (dfs_is_mounted(file->dentry->mnt) == 0)
|
||||
{
|
||||
ret = file->dentry->mnt->fs_ops->statfs(file->dentry->mnt, buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1223,4 +1229,102 @@ char *getcwd(char *buf, size_t size)
|
||||
}
|
||||
RTM_EXPORT(getcwd);
|
||||
|
||||
/**
|
||||
* this function is a POSIX compliant version, which will read specified data
|
||||
* buffer length for an open file descriptor.
|
||||
*
|
||||
* @param fd the file descriptor.
|
||||
* @param buf the buffer to save the read data.
|
||||
* @param len the maximal length of data buffer
|
||||
* @param offset the file pos
|
||||
*
|
||||
* @return the actual read data buffer length. If the returned value is 0, it
|
||||
* may be reach the end of file, please check errno.
|
||||
*/
|
||||
ssize_t pread(int fd, void *buf, size_t len, off_t offset)
|
||||
{
|
||||
ssize_t result;
|
||||
off_t fpos;
|
||||
struct dfs_file *file;
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
rt_set_errno(-EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
file = fd_get(fd);
|
||||
if (file == NULL)
|
||||
{
|
||||
rt_set_errno(-EBADF);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fpos lock */
|
||||
fpos = dfs_file_get_fpos(file);
|
||||
dfs_file_lseek(file, offset, SEEK_SET);
|
||||
result = dfs_file_read(file, buf, len);
|
||||
dfs_file_lseek(file, fpos, SEEK_SET);
|
||||
/* fpos unlock */
|
||||
dfs_file_set_fpos(file, fpos);
|
||||
if (result < 0)
|
||||
{
|
||||
rt_set_errno(result);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
RTM_EXPORT(pread);
|
||||
|
||||
/**
|
||||
* this function is a POSIX compliant version, which will write specified data
|
||||
* buffer length for an open file descriptor.
|
||||
*
|
||||
* @param fd the file descriptor
|
||||
* @param buf the data buffer to be written.
|
||||
* @param len the data buffer length.
|
||||
* @param offset the file pos
|
||||
*
|
||||
* @return the actual written data buffer length.
|
||||
*/
|
||||
ssize_t pwrite(int fd, const void *buf, size_t len, off_t offset)
|
||||
{
|
||||
ssize_t result;
|
||||
off_t fpos;
|
||||
struct dfs_file *file;
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
rt_set_errno(-EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
file = fd_get(fd);
|
||||
if (file == NULL)
|
||||
{
|
||||
rt_set_errno(-EBADF);
|
||||
|
||||
return -1;
|
||||
}
|
||||
/* fpos lock */
|
||||
fpos = dfs_file_get_fpos(file);
|
||||
dfs_file_lseek(file, offset, SEEK_SET);
|
||||
result = dfs_file_write(file, buf, len);
|
||||
dfs_file_lseek(file, fpos, SEEK_SET);
|
||||
/* fpos unlock */
|
||||
dfs_file_set_fpos(file, fpos);
|
||||
if (result < 0)
|
||||
{
|
||||
rt_set_errno(result);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
RTM_EXPORT(pwrite);
|
||||
|
||||
/**@}*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user