未验证 提交 69d94315 编写于 作者: G geniusgogo 提交者: GitHub

update dfs (#7887)

上级 31fec3bb
......@@ -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)
{
if (offset <= (off_t)file->vnode->size)
switch (wherece)
{
file->fpos = offset;
case SEEK_SET:
break;
case SEEK_CUR:
offset += file->fpos;
break;
case SEEK_END:
offset += file->vnode->size;
break;
return file->fpos;
default:
return -EINVAL;
}
if (offset <= (off_t)file->vnode->size)
{
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;
if (!file)
return -EBADF;
off_t retval = -EINVAL;
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);
if (rt_atomic_load(&(mnt->ref_count)) == 0)
{
rt_atomic_sub(&(mnt->ref_count), 1);
dfs_lock();
if (rt_atomic_load(&(mnt->ref_count)) < 0)
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);
/**@}*/
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册