14
14
#include <errno.h>
15
15
#include <glib.h>
16
16
#include <pthread.h>
17
+ #include <sys/stat.h>
17
18
18
19
#define DEFAULT_CACHE_TIMEOUT_SECS 20
19
20
#define DEFAULT_MAX_CACHE_SIZE 10000
@@ -40,7 +41,7 @@ static struct cache cache;
40
41
struct node {
41
42
struct stat stat ;
42
43
time_t stat_valid ;
43
- char * * dir ;
44
+ GPtrArray * dir ;
44
45
time_t dir_valid ;
45
46
char * link ;
46
47
time_t link_valid ;
@@ -63,14 +64,28 @@ struct file_handle {
63
64
unsigned long fs_fh ;
64
65
};
65
66
67
+ struct cache_dirent {
68
+ char * name ;
69
+ struct stat stat ;
70
+ };
71
+
66
72
static void free_node (gpointer node_ )
67
73
{
68
74
struct node * node = (struct node * ) node_ ;
69
- g_strfreev (node -> dir );
70
- g_free (node -> link );
75
+ if (node -> dir != NULL ) {
76
+ g_ptr_array_free (node -> dir , TRUE);
77
+ }
71
78
g_free (node );
72
79
}
73
80
81
+ static void free_cache_dirent (gpointer data ) {
82
+ struct cache_dirent * cache_dirent = (struct cache_dirent * ) data ;
83
+ if (cache_dirent != NULL ) {
84
+ g_free (cache_dirent -> name );
85
+ g_free (cache_dirent );
86
+ }
87
+ }
88
+
74
89
static int cache_clean_entry (void * key_ , struct node * node , time_t * now )
75
90
{
76
91
(void ) key_ ;
@@ -187,13 +202,15 @@ void cache_add_attr(const char *path, const struct stat *stbuf, uint64_t wrctr)
187
202
pthread_mutex_unlock (& cache .lock );
188
203
}
189
204
190
- static void cache_add_dir (const char * path , char * * dir )
205
+ static void cache_add_dir (const char * path , GPtrArray * dir )
191
206
{
192
207
struct node * node ;
193
208
194
209
pthread_mutex_lock (& cache .lock );
195
210
node = cache_get (path );
196
- g_strfreev (node -> dir );
211
+ if (node -> dir != NULL ) {
212
+ g_ptr_array_free (node -> dir , TRUE);
213
+ }
197
214
node -> dir = dir ;
198
215
node -> dir_valid = time (NULL ) + cache .dir_timeout_secs ;
199
216
if (node -> dir_valid > node -> valid )
@@ -342,7 +359,10 @@ static int cache_dirfill (void *buf, const char *name,
342
359
ch = (struct readdir_handle * ) buf ;
343
360
err = ch -> filler (ch -> buf , name , stbuf , off , flags );
344
361
if (!err ) {
345
- g_ptr_array_add (ch -> dir , g_strdup (name ));
362
+ struct cache_dirent * cdent = g_malloc (sizeof (struct cache_dirent ));
363
+ cdent -> name = g_strdup (name );
364
+ cdent -> stat = * stbuf ;
365
+ g_ptr_array_add (ch -> dir , cdent );
346
366
if (stbuf -> st_mode & S_IFMT ) {
347
367
char * fullpath ;
348
368
const char * basepath = !ch -> path [1 ] ? "" : ch -> path ;
@@ -362,8 +382,9 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
362
382
struct readdir_handle ch ;
363
383
struct file_handle * cfi ;
364
384
int err ;
365
- char * * dir ;
385
+ GPtrArray * dir ;
366
386
struct node * node ;
387
+ struct cache_dirent * * cdent ;
367
388
368
389
assert (offset == 0 );
369
390
@@ -372,9 +393,9 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
372
393
if (node != NULL && node -> dir != NULL ) {
373
394
time_t now = time (NULL );
374
395
if (node -> dir_valid - now >= 0 ) {
375
- for (dir = node -> dir ; * dir != NULL ; dir ++ )
376
- // FIXME: What about st_mode?
377
- filler ( buf , * dir , NULL , 0 , 0 );
396
+ for (cdent = ( struct cache_dirent * * ) node -> dir -> pdata ; * cdent != NULL ; cdent ++ ) {
397
+ filler ( buf , ( * cdent ) -> name , & ( * cdent ) -> stat , 0 , 0 );
398
+ }
378
399
pthread_mutex_unlock (& cache .lock );
379
400
return 0 ;
380
401
}
@@ -398,16 +419,16 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
398
419
ch .buf = buf ;
399
420
ch .filler = filler ;
400
421
ch .dir = g_ptr_array_new ();
422
+ g_ptr_array_set_free_func (ch .dir , free_cache_dirent );
401
423
ch .wrctr = cache_get_write_ctr ();
402
424
err = cache .next_oper -> readdir (path , & ch , cache_dirfill , offset , fi , flags );
403
425
g_ptr_array_add (ch .dir , NULL );
404
- dir = ( char * * ) ch .dir -> pdata ;
426
+ dir = ch .dir ;
405
427
if (!err ) {
406
428
cache_add_dir (path , dir );
407
429
} else {
408
- g_strfreev (dir );
430
+ g_ptr_array_free (dir , TRUE );
409
431
}
410
- g_ptr_array_free (ch .dir , FALSE);
411
432
412
433
return err ;
413
434
}
0 commit comments