22#ifdef RT_USING_PAGECACHE
26#define DBG_TAG "DFS.file"
27#define DBG_LVL DBG_WARNING
30#define MAX_RW_COUNT 0xfffc0000
39 while (path[i] !=
'\0' && path[i] !=
'/')
48static int _get_parent_path(
const char *fullpath,
char *path)
53 str = strrchr(fullpath,
'/');
56 if (str && *(str + 1) ==
'\0')
58 str = strrchr(str - 1,
'/');
66 rt_memcpy(path, fullpath, len);
74static int _try_readlink(
const char *path,
struct dfs_mnt *mnt,
char *link)
79 if (dentry && dentry->
vnode->
type == FT_SYMLINK)
94static char *_dfs_normalize_path(
const char *path,
int path_len,
const char *link_fn,
int link_len)
98 tmp_path = (
char *)
rt_malloc(path_len + link_len + 2);
104 memcpy(tmp_path, path, path_len);
105 tmp_path[path_len] =
'/';
106 memcpy(tmp_path + path_len + 1, link_fn, link_len);
107 tmp_path[path_len + 1 + link_len] =
'\0';
115static int _insert_link_path(
const char *link_fn,
int link_len,
char *tmp_path,
int *index)
119 if (link_fn[0] !=
'/')
121 if (link_len + 1 <= *index)
124 rt_memcpy(tmp_path + *index, link_fn, link_len);
126 tmp_path[*index] =
'/';
130 else if (link_len <= *index)
133 rt_memcpy(tmp_path + *index, link_fn, link_len);
148 ssize_t retval = -EINVAL;
150 if ((
size_t)count < 0)
193 rt_memset(file, 0x00,
sizeof(
struct dfs_file));
208static void dfs_file_unref(
struct dfs_file *file)
220 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_unref(dentry(%s))", file->
dentry->
pathname);
224 else if (file->
vnode)
237 LOG_I(
"release a file: %p", file);
255 int path_len = 0, index = 0;
256 char *path =
RT_NULL, *link_fn, *tmp_path;
279 rt_strcpy(tmp_path + index,
fullpath);
283 path_len = _get_parent_path(
fullpath, path);
294 rt_memcpy(path + path_len, tmp_path + index, len);
295 path[path_len + len] =
'\0';
312 link_len = _try_readlink(path, *mnt, link_fn);
315 if (link_fn[0] ==
'/')
317 int ret = _insert_link_path(link_fn, link_len, tmp_path, &index);
326 char *fp = _dfs_normalize_path(path, path_len, link_fn, link_len);
329 int pos = rt_strncmp(path, fp, path_len);
332 int ret = _insert_link_path(fp + path_len, rt_strlen(fp + path_len), tmp_path, &index);
345 while(path_len > 0 && path[path_len] !=
'/')
352 pos = rt_strncmp(path, fp, path_len);
359 if (pos == 0 || path_len == 0)
363 ret = _insert_link_path(fp + path_len, rt_strlen(fp + path_len), tmp_path, &index);
418 mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
428 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)",
fullpath);
439 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_lookup(mnt, %s)",
fullpath);
441 if (dentry && dentry->
vnode->
type == FT_SYMLINK)
444 if (oflags & O_NOFOLLOW)
460 dentry = target_dentry;
466 if (oflags & O_DIRECTORY)
474 else if (dentry->
vnode->
type == FT_DIRECTORY)
483 oflags |= O_DIRECTORY;
488 if (oflags & O_CREAT)
510 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_create(%s)", fullpath);
525 dentry->
vnode = vnode;
546 file->
flags = oflags;
549 if (!(oflags & O_CREAT))
595 dfs_file_unref(file);
608 DLOG(msg,
"dfs_file",
mnt->
fs_ops->
name, DLOG_MSG,
"no permission or fops->open");
609 dfs_file_unref(file);
615 LOG_I(
"lookup file:%s failed in file system", path);
621 if (ret >= 0 && (oflags & O_TRUNC))
627 DLOG(msg,
"dfs_file",
"dfs_file", DLOG_MSG,
"dfs_file_unref(file), trunc on RDOnly or directory");
634 DLOG(msg,
"dfs_file", dentry->
mnt->
fs_ops->
name, DLOG_MSG,
"fops->truncate(file, 0)");
638#ifdef RT_USING_PAGECACHE
655 dfs_file_unref(file);
658 file->
flags &= ~O_TRUNC;
663 if (fullpath != NULL)
683#ifdef RT_USING_PAGECACHE
693 DLOG(msg,
"dfs_file",
"dfs_file", DLOG_MSG,
"dfs_file_unref(file)");
694 dfs_file_unref(file);
703 DLOG(msg,
"dfs_file",
"dfs_file", DLOG_MSG,
"dfs_file_unref(file)");
704 dfs_file_unref(file);
716 ssize_t ret = -EBADF;
740#ifdef RT_USING_PAGECACHE
743 ret = dfs_aspace_read(file, buf, len, &pos);
748 ret = file->
fops->
read(file, buf, len, &pos);
764 ssize_t ret = -EBADF;
789#ifdef RT_USING_PAGECACHE
792 ret = dfs_aspace_read(file, buf, len, &pos);
797 ret = file->
fops->
read(file, buf, len, &pos);
815 ssize_t ret = -EBADF;
821 LOG_W(
"bad write flags.");
826 LOG_W(
"no fops write.");
838 "dfs_file_write(fd, buf, %d)", len);
842#ifdef RT_USING_PAGECACHE
845 ret = dfs_aspace_write(file, buf, len, &pos);
850 ret = file->
fops->
write(file, buf, len, &pos);
853 if (file->
flags & O_SYNC)
871 ssize_t ret = -EBADF;
877 LOG_W(
"bad write flags.");
882 LOG_W(
"no fops write.");
889 if (!(file->
flags & O_APPEND))
904 "dfs_file_write(fd, buf, %d)", len);
908#ifdef RT_USING_PAGECACHE
911 ret = dfs_aspace_write(file, buf, len, &pos);
916 ret = file->
fops->
write(file, buf, len, &pos);
919 if (file->
flags & O_SYNC)
929 if (!(file->
flags & O_APPEND))
944 if (whence == SEEK_SET)
946 else if (whence == SEEK_CUR)
947 foffset = file->
fpos + offset;
948 else if (whence == SEEK_END)
958 off_t retval = -EINVAL;
966 retval = file->
fops->
lseek(file, offset, wherece);
989 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1000 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1004 DLOG(msg,
"dentry",
"dfs_file", DLOG_MSG_RET,
"return dentry");
1007 DLOG(msg,
"dfs_file",
mnt->
fs_ops->
name, DLOG_MSG,
"fs_ops->stat(dentry, buf)");
1016 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_unref(dentry)");
1043 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1054 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1058 DLOG(msg,
"dentry",
"dfs_file", DLOG_MSG_RET,
"return dentry");
1061 DLOG(msg,
"dfs_file",
mnt->
fs_ops->
name, DLOG_MSG,
"fs_ops->stat(dentry, buf)");
1070 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_unref(dentry)");
1091 size_t ret = -EBADF;
1114 int ret = -RT_ERROR;
1122 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1133 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1137 DLOG(msg,
"dentry",
"dfs_file", DLOG_MSG_RET,
"return dentry");
1140 DLOG(msg,
"dfs_file",
mnt->
fs_ops->
name, DLOG_MSG,
"fs_ops->setattr(dentry, attr)");
1149 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_unref(dentry)");
1172 ret = file->
fops->
ioctl(file, cmd, args);
1227 O_APPEND | O_NONBLOCK;
1230 file->
flags &= ~mask;
1239#ifdef RT_USING_MUSLLIBC
1240 case F_DUPFD_CLOEXEC:
1267#ifdef RT_USING_PAGECACHE
1287 int ret = -RT_ERROR;
1295 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1308 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_lookup(mnt, %s)", fullpath);
1315#ifdef RT_USING_PAGECACHE
1378 char *old_fullpath, *new_fullpath;
1382 rt_set_errno(-EPERM);
1394 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", old_fullpath);
1421 if (old_fullpath && new_fullpath)
1425 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_lookup(mnt, %s)", old_fullpath);
1427 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_create(%s)", new_fullpath);
1430 if (old_dentry && new_dentry)
1461 int ret = -RT_ERROR;
1466 if (target && linkpath)
1468 if (linkpath[0] !=
'/')
1474 fullpath = (
char*)linkpath;
1483 index = strrchr(fullpath,
'/');
1486 int length = index - fullpath;
1489 parent = (
char*)
rt_malloc (length + 1);
1492 memcpy(parent, fullpath, length);
1493 parent[length] =
'\0';
1509 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1520 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_lookup(mnt, %s)", fullpath);
1529 ret = rt_strncmp(parent, path, strlen(parent));
1532 tmp = path + strlen(parent);
1573 rt_set_errno(-EPERM);
1576 if (fullpath != linkpath)
1589 int ret = -RT_ERROR;
1597 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1608 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_lookup(mnt, %s)", fullpath);
1653 char *old_fullpath, *new_fullpath;
1658 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", old_fullpath);
1685 if (old_fullpath && new_fullpath)
1689 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_lookup(mnt, %s)", old_fullpath);
1691 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_create(%s)", new_fullpath);
1694 if (old_dentry && new_dentry)
1700#ifdef RT_USING_PAGECACHE
1738#ifdef RT_USING_PAGECACHE
1774#ifdef RT_USING_PAGECACHE
1802 int ret = -RT_ERROR;
1840 int ret = -RT_ERROR;
1848 DLOG(msg,
"dfs_file",
"mnt", DLOG_MSG,
"dfs_mnt_lookup(%s)", fullpath);
1859 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dentry = dfs_dentry_lookup(mnt, %s)", fullpath);
1863 DLOG(msg,
"dentry",
"dfs_file", DLOG_MSG_RET,
"return dentry");
1867 DLOG(msg,
"dfs_file", mnt->
fs_ops->
name, DLOG_MSG,
"fs_ops->stat(dentry, buf)");
1874 if (ret == RT_EOK && S_ISDIR(
stat.st_mode))
1885 DLOG(msg,
"dfs_file",
"dentry", DLOG_MSG,
"dfs_dentry_unref(dentry)");
1920#ifdef RT_USING_SMART
1921int dfs_file_mmap2(
struct dfs_file *file,
struct dfs_mmap2_args *mmap2)
1932 ret = ret > 0 ? ret : -ret;
1938 rt_set_errno(EINVAL);
1953 ret = ret > 0 ? ret : -ret;
1963#ifdef RT_USING_FINSH
1965#define _COLOR_RED "\033[31m"
1966#define _COLOR_GREEN "\033[32m"
1967#define _COLOR_YELLOW "\033[33m"
1968#define _COLOR_BLUE "\033[34m"
1969#define _COLOR_CYAN "\033[36m"
1970#define _COLOR_WHITE "\033[37m"
1971#define _COLOR_NORMAL "\033[0m"
1973void ls(
const char *pathname)
1975 struct dirent dirent;
1978 char *fullpath, *path;
1981 if (pathname == NULL)
1983#ifdef DFS_USING_WORKDIR
1987 path = rt_strdup(
"/");
2006 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_open(%s, O_DIRECTORY, 0)", path);
2015 memset(&dirent, 0,
sizeof(
struct dirent));
2017 DLOG(group,
"foreach_item");
2018 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_getdents(&dirent)");
2022 DLOG(msg,
"dfs_file",
"dfs", DLOG_MSG_RET,
"dirent.d_name=%s", dirent.d_name);
2023 memset(&
stat, 0,
sizeof(
struct stat));
2027 if (fullpath == NULL)
2030 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_lstat(%s, &stat)", fullpath);
2033 if (S_ISDIR(
stat.st_mode))
2038 else if (S_ISLNK(
stat.st_mode))
2047 char *link_path = link_fn;
2068 ret = rt_strncmp(
parent, link_fn, length);
2071 link_path = link_fn + length;
2072 if (*link_path ==
'/')
2091 else if (
stat.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
2096 else if (S_ISCHR(
stat.st_mode))
2116 DLOG(msg,
"dfs_file",
"dfs", DLOG_MSG_RET,
"return NULL");
2120 }
while (length > 0);
2125 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_close()");
2135 DLOG(msg,
"dfs_file",
"dfs", DLOG_MSG_RET,
"return");
2147 rt_kprintf(
"cat: %s Is a directory\n", filename);
2153 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_open(%s, O_RDONLY, 0)", filename);
2163 rt_memset(buffer, 0x0,
sizeof(buffer));
2164 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_read(fd, buffer, %d)",
sizeof(buffer) - 1);
2165 length =
dfs_file_read(&file, (
void *)buffer,
sizeof(buffer) - 1);
2168 buffer[length] =
'\0';
2171 }
while (length > 0);
2174 DLOG(msg,
"dfs",
"dfs_file", DLOG_MSG,
"dfs_file_close()");
2180static void copyfile(
const char *src,
const char *dst)
2183 struct dfs_file src_file, dst_file;
2188 if (block_ptr == NULL)
2207 ret =
dfs_file_open(&dst_file, dst, O_WRONLY | O_CREAT | O_TRUNC, 0);
2226 if (length != read_bytes)
2229 rt_kprintf(
"Write file data failed, errno=%d\n", length);
2233 }
while (read_bytes > 0);
2242extern int mkdir(
const char *path, mode_t
mode);
2243static void copydir(
const char *src,
const char *dst)
2245 struct dirent dirent;
2261 rt_memset(&dirent, 0,
sizeof(
struct dirent));
2266 char *src_entry_full = NULL;
2267 char *dst_entry_full = NULL;
2269 if (strcmp(dirent.d_name,
"..") == 0 || strcmp(dirent.d_name,
".") == 0)
2285 rt_memset(&
stat, 0,
sizeof(
struct stat));
2288 rt_kprintf(
"open file: %s failed\n", dirent.d_name);
2292 if (S_ISDIR(
stat.st_mode))
2294 mkdir(dst_entry_full, 0);
2295 copydir(src_entry_full, dst_entry_full);
2299 copyfile(src_entry_full, dst_entry_full);
2311static const char *_get_path_lastname(
const char *path)
2314 if ((ptr = (
char *)strrchr(path,
'/')) == NULL)
2321void copy(
const char *src,
const char *dst)
2323#define FLAG_SRC_TYPE 0x03
2324#define FLAG_SRC_IS_DIR 0x01
2325#define FLAG_SRC_IS_FILE 0x02
2326#define FLAG_SRC_NON_EXSIT 0x00
2328#define FLAG_DST_TYPE 0x0C
2329#define FLAG_DST_IS_DIR 0x04
2330#define FLAG_DST_IS_FILE 0x08
2331#define FLAG_DST_NON_EXSIT 0x00
2342 if (S_ISDIR(
stat.st_mode))
2353 if (S_ISDIR(
stat.st_mode))
2362 rt_kprintf(
"cp faild, cp dir to file is not permitted!\n");
2378 copyfile(src, fdst);
rt_inline int dfs_fflags(int oflags)
struct dfs_dentry * dfs_dentry_create(struct dfs_mnt *mnt, char *fullpath)
struct dfs_dentry * dfs_dentry_lookup(struct dfs_mnt *mnt, const char *path, uint32_t flags)
struct dfs_dentry * dfs_dentry_unref(struct dfs_dentry *dentry)
void dfs_dentry_insert(struct dfs_dentry *dentry)
int dfs_file_getdents(struct dfs_file *file, struct dirent *dirp, size_t nbytes)
int dfs_file_lstat(const char *path, struct stat *buf)
void copy(const char *src, const char *dst)
int dfs_file_access(const char *path, mode_t mode)
void ls(const char *pathname)
#define FLAG_DST_NON_EXSIT
void cat(const char *filename)
off_t dfs_file_get_fpos(struct dfs_file *file)
rt_inline int _first_path_len(const char *path)
int dfs_file_unlink(const char *path)
int dfs_file_ftruncate(struct dfs_file *file, off_t length)
void dfs_file_init(struct dfs_file *file)
ssize_t dfs_file_pwrite(struct dfs_file *file, const void *buf, size_t len, off_t offset)
off_t dfs_file_lseek(struct dfs_file *file, off_t offset, int wherece)
int dfs_file_setattr(const char *path, struct dfs_attr *attr)
int dfs_file_flush(struct dfs_file *file)
int dfs_file_symlink(const char *target, const char *linkpath)
int dfs_file_ioctl(struct dfs_file *file, int cmd, void *args)
ssize_t dfs_file_read(struct dfs_file *file, void *buf, size_t len)
ssize_t dfs_file_pread(struct dfs_file *file, void *buf, size_t len, off_t offset)
int dfs_file_fsync(struct dfs_file *file)
int dfs_file_fcntl(int fd, int cmd, unsigned long arg)
int dfs_file_isdir(const char *path)
int dfs_file_close(struct dfs_file *file)
ssize_t rw_verify_area(struct dfs_file *file, off_t *ppos, size_t count)
off_t generic_dfs_lseek(struct dfs_file *file, off_t offset, int whence)
char * dfs_file_realpath(struct dfs_mnt **mnt, const char *fullpath, int mode)
int dfs_file_readlink(const char *path, char *buf, int bufsize)
int dfs_file_open(struct dfs_file *file, const char *path, int oflags, mode_t mode)
void dfs_file_set_fpos(struct dfs_file *file, off_t fpos)
void dfs_file_deinit(struct dfs_file *file)
int dfs_file_stat(const char *path, struct stat *buf)
int dfs_file_rename(const char *old_file, const char *new_file)
int dfs_file_link(const char *oldname, const char *newname)
ssize_t dfs_file_write(struct dfs_file *file, const void *buf, size_t len)
int dfs_file_fstat(struct dfs_file *file, struct stat *buf)
#define DFS_REALPATH_EXCEPT_NONE
#define DFS_REALPATH_ONLY_LAST
#define DFS_REALPATH_EXCEPT_LAST
int dfs_file_mmap(struct dfs_file *file, struct dfs_mmap2_args *mmap2)
int dfs_is_mounted(struct dfs_mnt *mnt)
rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char *fullpath)
struct dfs_mnt * dfs_mnt_lookup(const char *fullpath)
int dfs_dup(int oldfd, int startfd)
char * dfs_normalize_path(const char *directory, const char *filename)
void dfs_file_unlock(void)
rt_err_t dfs_file_lock(void)
struct dfs_file * fd_get(int fd)
int mkdir(const char *path, mode_t mode)
int stat(const char *file, struct stat *buf)
#define RT_WAITING_FOREVER
rt_weak void rt_free(void *ptr)
This function will release the previously allocated memory block by rt_malloc. The released memory bl...
rt_weak void * rt_malloc(rt_size_t size)
Allocate a block of memory with a minimum of 'size' bytes.
#define FINSH_FUNCTION_EXPORT(name, desc)
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
rt_err_t rt_mutex_detach(rt_mutex_t mutex)
This function will detach a static mutex object.
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag)
Initialize a static mutex object.
rt_err_t rt_mutex_release(rt_mutex_t mutex)
This function will release a mutex. If there is thread suspended on the mutex, the thread will be res...
#define rt_atomic_sub(ptr, v)
#define rt_atomic_store(ptr, v)
#define rt_atomic_load(ptr)
int(* truncate)(struct dfs_file *file, off_t offset)
ssize_t(* write)(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
off_t(* lseek)(struct dfs_file *file, off_t offset, int wherece)
int(* flush)(struct dfs_file *file)
ssize_t(* read)(struct dfs_file *file, void *buf, size_t count, off_t *pos)
int(* ioctl)(struct dfs_file *file, int cmd, void *arg)
int(* open)(struct dfs_file *file)
int(* close)(struct dfs_file *file)
int(* getdents)(struct dfs_file *file, struct dirent *dirp, uint32_t count)
struct dfs_dentry * dentry
const struct dfs_file_ops * fops
int(* unlink)(struct dfs_dentry *dentry)
int(* setattr)(struct dfs_dentry *dentry, struct dfs_attr *attr)
int(* rename)(struct dfs_dentry *old_dentry, struct dfs_dentry *new_dentry)
int(* stat)(struct dfs_dentry *dentry, struct stat *buf)
int(* symlink)(struct dfs_dentry *parent_dentry, const char *target, const char *newpath)
int(* link)(struct dfs_dentry *src_dentry, struct dfs_dentry *dst_dentry)
const struct dfs_file_ops * default_fops
int(* readlink)(struct dfs_dentry *dentry, char *buf, int len)
struct dfs_vnode *(* create_vnode)(struct dfs_dentry *dentry, int type, mode_t mode)
const struct dfs_filesystem_ops * fs_ops
struct dfs_aspace * aspace
const struct dfs_file_ops * fops