@@ -50,8 +50,12 @@ typedef struct
50
50
uint8_t padding [CROMFS_PATITION_HEAD_SIZE - sizeof (partition_head_data )];
51
51
} partition_head ;
52
52
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
+ };
55
59
56
60
typedef struct
57
61
{
@@ -607,12 +611,12 @@ static int dfs_cromfs_unmount(struct dfs_mnt *mnt)
607
611
return RT_EOK ;
608
612
}
609
613
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 )
611
615
{
612
616
uint32_t cur_size = 0 , cur_pos = 0 , cur_osize = 0 ;
613
617
const char * subpath = NULL , * subpath_end = NULL ;
614
618
void * di_mem = NULL ;
615
- int isdir = 0 ;
619
+ int _file_type = 0 ;
616
620
617
621
if (path [0 ] == '\0' )
618
622
{
@@ -622,7 +626,7 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
622
626
cur_size = ci -> part_info .root_dir_size ;
623
627
cur_osize = 0 ;
624
628
cur_pos = ci -> part_info .root_dir_pos ;
625
- isdir = 1 ;
629
+ _file_type = CROMFS_DIRENT_ATTR_DIR ;
626
630
627
631
subpath_end = path ;
628
632
while (1 )
@@ -646,7 +650,7 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
646
650
}
647
651
648
652
/* if not dir or empty dir, error */
649
- if (! isdir || !cur_size )
653
+ if (_file_type != CROMFS_DIRENT_ATTR_DIR || !cur_size )
650
654
{
651
655
return CROMFS_POS_ERROR ;
652
656
}
@@ -673,13 +677,21 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
673
677
cur_size = di_iter -> dirent .file_size ;
674
678
cur_osize = di_iter -> dirent .file_origin_size ;
675
679
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 )
677
681
{
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 ;
679
691
}
680
692
else
681
693
{
682
- isdir = 0 ;
694
+ RT_ASSERT ( 0 ) ;
683
695
}
684
696
break ;
685
697
}
@@ -698,11 +710,11 @@ static uint32_t cromfs_lookup(cromfs_info *ci, const char *path, int* is_dir, ui
698
710
}
699
711
* size = cur_size ;
700
712
* osize = cur_osize ;
701
- * is_dir = isdir ;
713
+ * file_type = _file_type ;
702
714
return cur_pos ;
703
715
}
704
716
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 )
706
718
{
707
719
rt_err_t result = RT_EOK ;
708
720
uint32_t ret = 0 ;
@@ -712,7 +724,7 @@ static uint32_t __dfs_cromfs_lookup(cromfs_info *ci, const char *path, int* is_d
712
724
{
713
725
return CROMFS_POS_ERROR ;
714
726
}
715
- ret = cromfs_lookup (ci , path , is_dir , size , osize );
727
+ ret = cromfs_lookup (ci , path , file_type , size , osize );
716
728
rt_mutex_release (& ci -> lock );
717
729
return ret ;
718
730
}
@@ -839,7 +851,7 @@ static file_info *get_file_info(cromfs_info *ci, uint32_t partition_pos, int inc
839
851
return NULL ;
840
852
}
841
853
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 )
843
855
{
844
856
file_info * fi = NULL ;
845
857
void * file_buff = NULL ;
@@ -852,7 +864,7 @@ static file_info *inset_file_info(cromfs_info *ci, uint32_t partition_pos, int i
852
864
}
853
865
fi -> partition_pos = partition_pos ;
854
866
fi -> ci = ci ;
855
- if (is_dir )
867
+ if (file_type == CROMFS_DIRENT_ATTR_DIR )
856
868
{
857
869
fi -> size = size ;
858
870
}
@@ -949,7 +961,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
949
961
cromfs_info * ci = NULL ;
950
962
uint32_t file_pos = 0 ;
951
963
uint32_t size = 0 , osize = 0 ;
952
- int is_dir = 0 ;
964
+ int file_type = 0 ;
953
965
rt_err_t result = RT_EOK ;
954
966
955
967
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)
971
983
972
984
ci = (cromfs_info * )file -> dentry -> mnt -> data ;
973
985
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 );
975
987
if (file_pos == CROMFS_POS_ERROR )
976
988
{
977
989
ret = - ENOENT ;
978
990
goto end ;
979
991
}
980
992
981
993
/* entry is a directory file type */
982
- if (is_dir )
994
+ if (file_type == CROMFS_DIRENT_ATTR_DIR )
983
995
{
984
996
if (!(file -> flags & O_DIRECTORY ))
985
997
{
@@ -988,6 +1000,10 @@ static int dfs_cromfs_open(struct dfs_file *file)
988
1000
}
989
1001
file -> vnode -> type = FT_DIRECTORY ;
990
1002
}
1003
+ else if (file_type == CROMFS_DIRENT_ATTR_SYMLINK )
1004
+ {
1005
+ file -> vnode -> type = FT_SYMLINK ;
1006
+ }
991
1007
else
992
1008
{
993
1009
/* entry is a file, but open it as a directory */
@@ -1009,7 +1025,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
1009
1025
fi = get_file_info (ci , file_pos , 1 );
1010
1026
if (!fi )
1011
1027
{
1012
- fi = inset_file_info (ci , file_pos , is_dir , size , osize );
1028
+ fi = inset_file_info (ci , file_pos , file_type , size , osize );
1013
1029
}
1014
1030
rt_mutex_release (& ci -> lock );
1015
1031
if (!fi )
@@ -1019,7 +1035,7 @@ static int dfs_cromfs_open(struct dfs_file *file)
1019
1035
}
1020
1036
1021
1037
file -> vnode -> data = fi ;
1022
- if (is_dir )
1038
+ if (file_type )
1023
1039
{
1024
1040
file -> vnode -> size = size ;
1025
1041
}
@@ -1037,13 +1053,13 @@ static int dfs_cromfs_open(struct dfs_file *file)
1037
1053
static int dfs_cromfs_stat (struct dfs_dentry * dentry , struct stat * st )
1038
1054
{
1039
1055
uint32_t size = 0 , osize = 0 ;
1040
- int is_dir = 0 ;
1056
+ int file_type = 0 ;
1041
1057
cromfs_info * ci = NULL ;
1042
1058
uint32_t file_pos = 0 ;
1043
1059
1044
1060
ci = (cromfs_info * )dentry -> mnt -> data ;
1045
1061
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 );
1047
1063
if (file_pos == CROMFS_POS_ERROR )
1048
1064
{
1049
1065
return - ENOENT ;
@@ -1053,12 +1069,18 @@ static int dfs_cromfs_stat(struct dfs_dentry *dentry, struct stat *st)
1053
1069
st -> st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
1054
1070
S_IWUSR | S_IWGRP | S_IWOTH ;
1055
1071
1056
- if (is_dir )
1072
+ if (file_type == CROMFS_DIRENT_ATTR_DIR )
1057
1073
{
1058
1074
st -> st_mode &= ~S_IFREG ;
1059
1075
st -> st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH ;
1060
1076
st -> st_size = size ;
1061
1077
}
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
+ }
1062
1084
else
1063
1085
{
1064
1086
st -> st_size = osize ;
@@ -1167,8 +1189,8 @@ static struct dfs_vnode *dfs_cromfs_lookup (struct dfs_dentry *dentry)
1167
1189
if (ci )
1168
1190
{
1169
1191
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 );
1172
1194
1173
1195
if (file_pos != CROMFS_POS_ERROR )
1174
1196
{
@@ -1177,12 +1199,18 @@ static struct dfs_vnode *dfs_cromfs_lookup (struct dfs_dentry *dentry)
1177
1199
{
1178
1200
vnode -> nlink = 1 ;
1179
1201
1180
- if (is_dir )
1202
+ if (file_type == CROMFS_DIRENT_ATTR_DIR )
1181
1203
{
1182
1204
vnode -> mode = S_IFDIR | (0555 );
1183
1205
vnode -> type = FT_DIRECTORY ;
1184
1206
vnode -> size = size ;
1185
1207
}
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
+ }
1186
1214
else
1187
1215
{
1188
1216
vnode -> mode = S_IFREG | (0555 );
@@ -1203,6 +1231,85 @@ static int dfs_cromfs_free_vnode(struct dfs_vnode *vnode)
1203
1231
return 0 ;
1204
1232
}
1205
1233
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
+
1206
1313
static const struct dfs_file_ops _crom_fops =
1207
1314
{
1208
1315
.open = dfs_cromfs_open ,
@@ -1219,6 +1326,9 @@ static const struct dfs_filesystem_ops _cromfs_ops =
1219
1326
.default_fops = & _crom_fops ,
1220
1327
.mount = dfs_cromfs_mount ,
1221
1328
.umount = dfs_cromfs_unmount ,
1329
+
1330
+ .readlink = dfs_cromfs_readlink ,
1331
+
1222
1332
.stat = dfs_cromfs_stat ,
1223
1333
.lookup = dfs_cromfs_lookup ,
1224
1334
.free_vnode = dfs_cromfs_free_vnode
0 commit comments