@@ -20,14 +20,10 @@ struct fakefs_super {
20
20
21
21
// free with __putname
22
22
static char * dentry_name (struct dentry * dentry ) {
23
- /* I know this sucks, but __dentry_path isn't public for some reason */
24
- struct vfsmount fake_mnt = {};
25
- struct path root = {.dentry = dentry -> d_sb -> s_root , .mnt = & fake_mnt };
26
- struct path new_path = {.dentry = dentry , .mnt = & fake_mnt };
27
23
char * name = __getname ();
28
24
if (name == NULL )
29
25
return ERR_PTR (- ENOMEM );
30
- char * path = __d_path ( & new_path , & root , name , PATH_MAX );
26
+ char * path = dentry_path_raw ( dentry , name , PATH_MAX );
31
27
if (IS_ERR (path ))
32
28
return path ;
33
29
BUG_ON (path [0 ] != '/' );
@@ -170,12 +166,12 @@ static int fakefs_rename(struct user_namespace *mnt_userns, struct inode *from_d
170
166
struct fakefs_super * info = from_dir -> i_sb -> s_fs_info ;
171
167
172
168
char * from_path = dentry_name (from_dentry );
173
- if (from_path == NULL )
174
- return - ENOMEM ;
169
+ if (IS_ERR ( from_path ) )
170
+ return PTR_ERR ( from_path ) ;
175
171
char * to_path = dentry_name (to_dentry );
176
- if (to_path == NULL ) {
172
+ if (IS_ERR ( to_path ) ) {
177
173
__putname (from_path );
178
- return - ENOMEM ;
174
+ return PTR_ERR ( to_path ) ;
179
175
}
180
176
181
177
db_begin (& info -> db );
@@ -199,12 +195,12 @@ static int fakefs_link(struct dentry *from, struct inode *ino, struct dentry *to
199
195
struct inode * inode ;
200
196
201
197
char * from_path = dentry_name (from );
202
- if (from_path == NULL )
203
- return - ENOMEM ;
198
+ if (IS_ERR ( from_path ) )
199
+ return PTR_ERR ( from_path ) ;
204
200
char * to_path = dentry_name (to );
205
- if (to_path == NULL ) {
201
+ if (IS_ERR ( to_path ) ) {
206
202
__putname (from_path );
207
- return - ENOMEM ;
203
+ return PTR_ERR ( to_path ) ;
208
204
}
209
205
210
206
db_begin (& info -> db );
@@ -229,8 +225,8 @@ static int fakefs_link(struct dentry *from, struct inode *ino, struct dentry *to
229
225
static int unlink_common (struct inode * dir , struct dentry * dentry , int is_dir ) {
230
226
struct fakefs_super * info = dir -> i_sb -> s_fs_info ;
231
227
char * path = dentry_name (dentry );
232
- if (path == NULL )
233
- return - ENOMEM ;
228
+ if (IS_ERR ( path ) )
229
+ return PTR_ERR ( path ) ;
234
230
235
231
db_begin (& info -> db );
236
232
path_unlink (& info -> db , path );
@@ -369,6 +365,8 @@ static const struct inode_operations fakefs_link_iops = {
369
365
#define FILE_DIR (file ) ((file)->private_data)
370
366
371
367
static int fakefs_iterate (struct file * file , struct dir_context * ctx ) {
368
+ struct fakefs_super * info = file -> f_inode -> i_sb -> s_fs_info ;
369
+
372
370
if (FILE_DIR (file ) == NULL ) {
373
371
int err = host_dup_opendir (INODE_FD (file -> f_inode ), & FILE_DIR (file ));
374
372
if (err < 0 )
@@ -382,14 +380,33 @@ static int fakefs_iterate(struct file *file, struct dir_context *ctx) {
382
380
res = host_seekdir (dir , ctx -> pos - 1 );
383
381
if (res < 0 )
384
382
return res ;
383
+
384
+ char * dir_path = dentry_name (file -> f_path .dentry );
385
+ if (IS_ERR (dir_path ))
386
+ return PTR_ERR (dir_path );
387
+ size_t dir_path_len = strlen (dir_path );
388
+
389
+
385
390
struct host_dirent ent ;
386
391
for (;;) {
387
392
res = host_readdir (dir , & ent );
388
393
if (res <= 0 )
389
394
break ;
390
395
ctx -> pos = host_telldir (dir ) + 1 ;
391
- // TODO fix inode numbers!!!!!
392
- ent .ino = 0 ;
396
+ // Get the inode number by constructing the file path and looking it up in the database
397
+ if (strcmp (ent .name , "." ) == 0 ) {
398
+ ent .ino = file -> f_inode -> i_ino ;
399
+ } else if (strcmp (ent .name , ".." ) == 0 ) {
400
+ ent .ino = d_inode (file -> f_path .dentry -> d_parent )-> i_ino ;
401
+ } else {
402
+ db_begin (& info -> db );
403
+ if (dir_path_len + 1 + strlen (ent .name ) + 1 > PATH_MAX )
404
+ continue ; // a
405
+ dir_path [dir_path_len ] = '/' ;
406
+ strcpy (& dir_path [dir_path_len + 1 ], ent .name );
407
+ ent .ino = path_get_inode (& info -> db , dir_path );
408
+ db_commit (& info -> db );
409
+ }
393
410
if (!dir_emit (ctx , ent .name , strlen (ent .name ), ent .ino , ent .type ))
394
411
break ;
395
412
}
0 commit comments