1414#include <errno.h>
1515#include <glib.h>
1616#include <pthread.h>
17+ #include <sys/stat.h>
1718
1819#define DEFAULT_CACHE_TIMEOUT_SECS 20
1920#define DEFAULT_MAX_CACHE_SIZE 10000
@@ -40,7 +41,7 @@ static struct cache cache;
4041struct node {
4142 struct stat stat ;
4243 time_t stat_valid ;
43- char * * dir ;
44+ GPtrArray * dir ;
4445 time_t dir_valid ;
4546 char * link ;
4647 time_t link_valid ;
@@ -63,14 +64,28 @@ struct file_handle {
6364 unsigned long fs_fh ;
6465};
6566
67+ struct cache_dirent {
68+ char * name ;
69+ struct stat stat ;
70+ };
71+
6672static void free_node (gpointer node_ )
6773{
6874 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+ }
7178 g_free (node );
7279}
7380
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+
7489static int cache_clean_entry (void * key_ , struct node * node , time_t * now )
7590{
7691 (void ) key_ ;
@@ -187,13 +202,15 @@ void cache_add_attr(const char *path, const struct stat *stbuf, uint64_t wrctr)
187202 pthread_mutex_unlock (& cache .lock );
188203}
189204
190- static void cache_add_dir (const char * path , char * * dir )
205+ static void cache_add_dir (const char * path , GPtrArray * dir )
191206{
192207 struct node * node ;
193208
194209 pthread_mutex_lock (& cache .lock );
195210 node = cache_get (path );
196- g_strfreev (node -> dir );
211+ if (node -> dir != NULL ) {
212+ g_ptr_array_free (node -> dir , TRUE);
213+ }
197214 node -> dir = dir ;
198215 node -> dir_valid = time (NULL ) + cache .dir_timeout_secs ;
199216 if (node -> dir_valid > node -> valid )
@@ -342,7 +359,10 @@ static int cache_dirfill (void *buf, const char *name,
342359 ch = (struct readdir_handle * ) buf ;
343360 err = ch -> filler (ch -> buf , name , stbuf , off , flags );
344361 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 );
346366 if (stbuf -> st_mode & S_IFMT ) {
347367 char * fullpath ;
348368 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,
362382 struct readdir_handle ch ;
363383 struct file_handle * cfi ;
364384 int err ;
365- char * * dir ;
385+ GPtrArray * dir ;
366386 struct node * node ;
387+ struct cache_dirent * * cdent ;
367388
368389 assert (offset == 0 );
369390
@@ -372,9 +393,9 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
372393 if (node != NULL && node -> dir != NULL ) {
373394 time_t now = time (NULL );
374395 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+ }
378399 pthread_mutex_unlock (& cache .lock );
379400 return 0 ;
380401 }
@@ -398,16 +419,16 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
398419 ch .buf = buf ;
399420 ch .filler = filler ;
400421 ch .dir = g_ptr_array_new ();
422+ g_ptr_array_set_free_func (ch .dir , free_cache_dirent );
401423 ch .wrctr = cache_get_write_ctr ();
402424 err = cache .next_oper -> readdir (path , & ch , cache_dirfill , offset , fi , flags );
403425 g_ptr_array_add (ch .dir , NULL );
404- dir = ( char * * ) ch .dir -> pdata ;
426+ dir = ch .dir ;
405427 if (!err ) {
406428 cache_add_dir (path , dir );
407429 } else {
408- g_strfreev (dir );
430+ g_ptr_array_free (dir , TRUE );
409431 }
410- g_ptr_array_free (ch .dir , FALSE);
411432
412433 return err ;
413434}
0 commit comments