Skip to content

Commit 1e0f406

Browse files
authored
✨ feat(dfs_v2/cromfs): add symlink support (#8132)
1 parent 61f7d48 commit 1e0f406

File tree

2 files changed

+143
-26
lines changed

2 files changed

+143
-26
lines changed

components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c

+135-25
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ typedef struct
5050
uint8_t padding[CROMFS_PATITION_HEAD_SIZE - sizeof(partition_head_data)];
5151
} partition_head;
5252

53-
#define CROMFS_DIRENT_ATTR_DIR 0x1UL
54-
#define CROMFS_DIRENT_ATTR_FILE 0x0UL
53+
enum
54+
{
55+
CROMFS_DIRENT_ATTR_FILE = 0x0UL,
56+
CROMFS_DIRENT_ATTR_DIR = 0x1UL,
57+
CROMFS_DIRENT_ATTR_SYMLINK = 0x2UL,
58+
};
5559

5660
typedef struct
5761
{
@@ -607,12 +611,12 @@ static int dfs_cromfs_unmount(struct dfs_mnt *mnt)
607611
return RT_EOK;
608612
}
609613

610-
static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
614+
static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* file_type, uint32_t *size, uint32_t *osize)
611615
{
612616
uint32_t cur_size = 0, cur_pos = 0, cur_osize = 0;
613617
const char *subpath = NULL, *subpath_end = NULL;
614618
void *di_mem = NULL;
615-
int isdir = 0;
619+
int _file_type = 0;
616620

617621
if (path[0] == '\0')
618622
{
@@ -622,7 +626,7 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
622626
cur_size = ci->part_info.root_dir_size;
623627
cur_osize = 0;
624628
cur_pos = ci->part_info.root_dir_pos;
625-
isdir = 1;
629+
_file_type = CROMFS_DIRENT_ATTR_DIR;
626630

627631
subpath_end = path;
628632
while (1)
@@ -646,7 +650,7 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
646650
}
647651

648652
/* if not dir or empty dir, error */
649-
if (!isdir || !cur_size)
653+
if (_file_type != CROMFS_DIRENT_ATTR_DIR || !cur_size)
650654
{
651655
return CROMFS_POS_ERROR;
652656
}
@@ -673,13 +677,21 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
673677
cur_size = di_iter->dirent.file_size;
674678
cur_osize = di_iter->dirent.file_origin_size;
675679
cur_pos = di_iter->dirent.parition_pos;
676-
if (di_iter->dirent.attr == CROMFS_DIRENT_ATTR_DIR)
680+
if (di_iter->dirent.attr == CROMFS_DIRENT_ATTR_FILE)
677681
{
678-
isdir = 1;
682+
_file_type = CROMFS_DIRENT_ATTR_FILE;
683+
}
684+
else if (di_iter->dirent.attr == CROMFS_DIRENT_ATTR_DIR)
685+
{
686+
_file_type = CROMFS_DIRENT_ATTR_DIR;
687+
}
688+
else if (di_iter->dirent.attr == CROMFS_DIRENT_ATTR_SYMLINK)
689+
{
690+
_file_type = CROMFS_DIRENT_ATTR_SYMLINK;
679691
}
680692
else
681693
{
682-
isdir = 0;
694+
RT_ASSERT(0);
683695
}
684696
break;
685697
}
@@ -698,11 +710,11 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
698710
}
699711
*size = cur_size;
700712
*osize = cur_osize;
701-
*is_dir = isdir;
713+
*file_type = _file_type;
702714
return cur_pos;
703715
}
704716

705-
static uint32_t __dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, uint32_t *size, uint32_t *osize)
717+
static uint32_t __dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* file_type, uint32_t *size, uint32_t *osize)
706718
{
707719
rt_err_t result = RT_EOK;
708720
uint32_t ret = 0;
@@ -712,7 +724,7 @@ static uint32_t __dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* is_d
712724
{
713725
return CROMFS_POS_ERROR;
714726
}
715-
ret = cromfs_lookup(ci, path, is_dir, size, osize);
727+
ret = cromfs_lookup(ci, path, file_type, size, osize);
716728
rt_mutex_release(&ci->lock);
717729
return ret;
718730
}
@@ -839,7 +851,7 @@ static file_info *get_file_info(cromfs_info *ci, uint32_t partition_pos, int inc
839851
return NULL;
840852
}
841853

842-
static file_info *inset_file_info(cromfs_info *ci, uint32_t partition_pos, int is_dir, uint32_t size, uint32_t osize)
854+
static file_info *inset_file_info(cromfs_info *ci, uint32_t partition_pos, int file_type, uint32_t size, uint32_t osize)
843855
{
844856
file_info *fi = NULL;
845857
void *file_buff = NULL;
@@ -852,7 +864,7 @@ static file_info *inset_file_info(cromfs_info *ci, uint32_t partition_pos, int i
852864
}
853865
fi->partition_pos = partition_pos;
854866
fi->ci = ci;
855-
if (is_dir)
867+
if (file_type == CROMFS_DIRENT_ATTR_DIR)
856868
{
857869
fi->size = size;
858870
}
@@ -949,7 +961,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
949961
cromfs_info *ci = NULL;
950962
uint32_t file_pos = 0;
951963
uint32_t size = 0, osize = 0;
952-
int is_dir = 0;
964+
int file_type = 0;
953965
rt_err_t result = RT_EOK;
954966

955967
if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
@@ -971,15 +983,15 @@ static int dfs_cromfs_open(struct dfs_file *file)
971983

972984
ci = (cromfs_info *)file->dentry->mnt->data;
973985

974-
file_pos = __dfs_cromfs_lookup(ci, file->dentry->pathname, &is_dir, &size, &osize);
986+
file_pos = __dfs_cromfs_lookup(ci, file->dentry->pathname, &file_type, &size, &osize);
975987
if (file_pos == CROMFS_POS_ERROR)
976988
{
977989
ret = -ENOENT;
978990
goto end;
979991
}
980992

981993
/* entry is a directory file type */
982-
if (is_dir)
994+
if (file_type == CROMFS_DIRENT_ATTR_DIR)
983995
{
984996
if (!(file->flags & O_DIRECTORY))
985997
{
@@ -988,6 +1000,10 @@ static int dfs_cromfs_open(struct dfs_file *file)
9881000
}
9891001
file->vnode->type = FT_DIRECTORY;
9901002
}
1003+
else if (file_type == CROMFS_DIRENT_ATTR_SYMLINK)
1004+
{
1005+
file->vnode->type = FT_SYMLINK;
1006+
}
9911007
else
9921008
{
9931009
/* entry is a file, but open it as a directory */
@@ -1009,7 +1025,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
10091025
fi = get_file_info(ci, file_pos, 1);
10101026
if (!fi)
10111027
{
1012-
fi = inset_file_info(ci, file_pos, is_dir, size, osize);
1028+
fi = inset_file_info(ci, file_pos, file_type, size, osize);
10131029
}
10141030
rt_mutex_release(&ci->lock);
10151031
if (!fi)
@@ -1019,7 +1035,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
10191035
}
10201036

10211037
file->vnode->data = fi;
1022-
if (is_dir)
1038+
if (file_type)
10231039
{
10241040
file->vnode->size = size;
10251041
}
@@ -1037,13 +1053,13 @@ static int dfs_cromfs_open(struct dfs_file *file)
10371053
static int dfs_cromfs_stat(struct dfs_dentry *dentry, struct stat *st)
10381054
{
10391055
uint32_t size = 0, osize = 0;
1040-
int is_dir = 0;
1056+
int file_type = 0;
10411057
cromfs_info *ci = NULL;
10421058
uint32_t file_pos = 0;
10431059

10441060
ci = (cromfs_info *)dentry->mnt->data;
10451061

1046-
file_pos = __dfs_cromfs_lookup(ci, dentry->pathname, &is_dir, &size, &osize);
1062+
file_pos = __dfs_cromfs_lookup(ci, dentry->pathname, &file_type, &size, &osize);
10471063
if (file_pos == CROMFS_POS_ERROR)
10481064
{
10491065
return -ENOENT;
@@ -1053,12 +1069,18 @@ static int dfs_cromfs_stat(struct dfs_dentry *dentry, struct stat *st)
10531069
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
10541070
S_IWUSR | S_IWGRP | S_IWOTH;
10551071

1056-
if (is_dir)
1072+
if (file_type == CROMFS_DIRENT_ATTR_DIR)
10571073
{
10581074
st->st_mode &= ~S_IFREG;
10591075
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
10601076
st->st_size = size;
10611077
}
1078+
else if(file_type == CROMFS_DIRENT_ATTR_SYMLINK)
1079+
{
1080+
st->st_mode &= ~S_IFREG;
1081+
st->st_mode |= S_IFLNK | S_IXUSR | S_IXGRP | S_IXOTH;
1082+
st->st_size = osize;
1083+
}
10621084
else
10631085
{
10641086
st->st_size = osize;
@@ -1167,8 +1189,8 @@ static struct dfs_vnode *dfs_cromfs_lookup (struct dfs_dentry *dentry)
11671189
if (ci)
11681190
{
11691191
uint32_t size = 0, osize = 0;
1170-
int is_dir = 0;
1171-
uint32_t file_pos = __dfs_cromfs_lookup(ci, dentry->pathname, &is_dir, &size, &osize);
1192+
int file_type = 0;
1193+
uint32_t file_pos = __dfs_cromfs_lookup(ci, dentry->pathname, &file_type, &size, &osize);
11721194

11731195
if (file_pos != CROMFS_POS_ERROR)
11741196
{
@@ -1177,12 +1199,18 @@ static struct dfs_vnode *dfs_cromfs_lookup (struct dfs_dentry *dentry)
11771199
{
11781200
vnode->nlink = 1;
11791201

1180-
if (is_dir)
1202+
if (file_type == CROMFS_DIRENT_ATTR_DIR)
11811203
{
11821204
vnode->mode = S_IFDIR | (0555);
11831205
vnode->type = FT_DIRECTORY;
11841206
vnode->size = size;
11851207
}
1208+
else if (file_type == CROMFS_DIRENT_ATTR_SYMLINK)
1209+
{
1210+
vnode->mode = S_IFLNK | (0555);
1211+
vnode->type = FT_SYMLINK;
1212+
vnode->size = osize;
1213+
}
11861214
else
11871215
{
11881216
vnode->mode = S_IFREG | (0555);
@@ -1203,6 +1231,85 @@ static int dfs_cromfs_free_vnode(struct dfs_vnode *vnode)
12031231
return 0;
12041232
}
12051233

1234+
static int cromfs_readlink(cromfs_info *ci, char *path, char *buf, int len)
1235+
{
1236+
int ret = 0;
1237+
file_info *fi = NULL;
1238+
uint32_t file_pos = 0;
1239+
int file_type = 0;
1240+
uint32_t size = 0, osize = 0;
1241+
rt_err_t result = RT_EOK;
1242+
1243+
file_pos = __dfs_cromfs_lookup(ci, path, &file_type, &size, &osize);
1244+
if (file_pos == CROMFS_POS_ERROR)
1245+
{
1246+
ret = -ENOENT;
1247+
goto end1;
1248+
}
1249+
1250+
result = rt_mutex_take(&ci->lock, RT_WAITING_FOREVER);
1251+
if (result != RT_EOK)
1252+
{
1253+
ret = -EINTR;
1254+
goto end;
1255+
}
1256+
1257+
fi = get_file_info(ci, file_pos, 1);
1258+
if (!fi)
1259+
{
1260+
fi = inset_file_info(ci, file_pos, file_type, size, osize);
1261+
}
1262+
rt_mutex_release(&ci->lock);
1263+
if (!fi)
1264+
{
1265+
ret = -ENOENT;
1266+
goto end;
1267+
}
1268+
1269+
if (len > 0)
1270+
{
1271+
RT_ASSERT(fi->size != 0);
1272+
RT_ASSERT(fi->buff);
1273+
1274+
int fill_ret = 0;
1275+
fill_ret = fill_file_data(fi);
1276+
if (fill_ret < 0)
1277+
{
1278+
ret = -ENOENT;
1279+
deref_file_info(ci, fi->partition_pos);
1280+
goto end;
1281+
}
1282+
len = len - 1;
1283+
osize = osize < len ? osize : len;
1284+
memcpy(buf, fi->buff, osize);
1285+
}
1286+
1287+
if (ret == 0)
1288+
{
1289+
buf[osize] = '\0';
1290+
ret = osize;
1291+
}
1292+
1293+
deref_file_info(ci, fi->partition_pos);
1294+
end:
1295+
rt_mutex_release(&ci->lock);
1296+
end1:
1297+
return ret;
1298+
}
1299+
1300+
static int dfs_cromfs_readlink(struct dfs_dentry *dentry, char *buf, int len)
1301+
{
1302+
cromfs_info *ci = NULL;
1303+
1304+
if (dentry && buf)
1305+
{
1306+
ci = (cromfs_info *)dentry->mnt->data;
1307+
return cromfs_readlink(ci, dentry->pathname, buf, len);
1308+
}
1309+
1310+
return -EBADF;
1311+
}
1312+
12061313
static const struct dfs_file_ops _crom_fops =
12071314
{
12081315
.open = dfs_cromfs_open,
@@ -1219,6 +1326,9 @@ static const struct dfs_filesystem_ops _cromfs_ops =
12191326
.default_fops = &_crom_fops,
12201327
.mount = dfs_cromfs_mount,
12211328
.umount = dfs_cromfs_unmount,
1329+
1330+
.readlink = dfs_cromfs_readlink,
1331+
12221332
.stat = dfs_cromfs_stat,
12231333
.lookup = dfs_cromfs_lookup,
12241334
.free_vnode = dfs_cromfs_free_vnode

components/dfs/dfs_v2/src/dfs_file.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
210210
char link_fn[DFS_PATH_MAX] = {0};
211211
struct dfs_dentry *dentry = RT_NULL;
212212

213-
path = (char *)rt_malloc(DFS_PATH_MAX);
213+
path = (char *)rt_malloc((DFS_PATH_MAX * 2) + 1); // path + syslink + \0
214214
if (!path)
215215
{
216216
return path;
@@ -317,6 +317,13 @@ static char *dfs_nolink_path(struct dfs_mnt **mnt, char *fullpath, int mode)
317317
{
318318
rt_kprintf("link error: %s\n", path);
319319
}
320+
321+
char *_fullpath = dfs_normalize_path(RT_NULL, path);
322+
if (_fullpath)
323+
{
324+
strncpy(path, _fullpath, DFS_PATH_MAX);
325+
rt_free(_fullpath);
326+
}
320327
}
321328
dfs_dentry_unref(dentry);
322329
}

0 commit comments

Comments
 (0)