cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
pbs@imm.dtu.dk
Visitor
Visitor
2,178 Views
Registered: ‎03-10-2010

xilfatfs sysace_readdir memory problem

Hello All,

 

I am having some problems with the xilfatfs library for reading and writing files on a compact flash through a sysace device. Opening, reading, writing and closing files seems to be working fine but the function ''sysace_readdir'' used for reading the content of a directory seems to leak memory. After invoking ''sysace_readdir'' a number of times any subsequent calls to sysace_fopen() fails (ie. returns 0 even though the file does exist).

  

Internally, the xilfatfs library uses an array of ''WorkingDirectory'' for dealing with paths. This array is given in xilfatfs_alloc.c:

 

static WorkingDirectory wd_buf[MAXWD];

 

The MAXWD is defined as MAXFILES * 10. The entries in the array are used by library for manipulating and navigating paths. Access to the array is governed by the ''malloc_wd'' and ''free_wd'' functions. My investigations, thus far, shows that ''sysace_readdir()'' allocates one more ''WorkingDirectory'' than it frees which eventually leads to failure. To test this I added some code to the ''malloc_wd'' and ''free_wd'' functions in the ''xilfatfs_alloc.c'' file:

 

 

/* Create and release WDs */ static WorkingDirectory wd_buf[MAXWD]; static int wd_init_flag = 1; static int count = 0; WorkingDirectory * malloc_wd(const char *name) { int i; /* Do initialization because MBlaze seems not to initialize statics per K&R */ if(wd_init_flag) { wd_init_flag = 0; for(i=0; i<MAXWD; i++ ) wd_buf[i].name[0] = 0; } for(i=0; i<MAXWD; i++) if(wd_buf[i].name[0] == 0) { strncpy(wd_buf[i].name, name, MAXFILENAMESIZE); count++; xil_printf("cnt: %d (malloc)\n", count); return wd_buf + i; } xil_printf("cnt: %d (malloc error)\n", count); return 0; } void free_wd(WorkingDirectory *wd) { wd->name[0] = 0; count--; xil_printf("cnt: %d (free)\n", count); }

 

 By adding a call to the function ''delete_working_directory_stack'' in the ''sysace_readdir'' function, as shown below, I have been able to fix this problem.

int sysace_readdir(char *path, dirent entry[], int n_entries) { BYTE buf[SECTORSIZE]; int bufcount; int is_sub_dir = 0; UINT32 sector; UINT32 filecount, filesize = 0; UINT32 nsectors; UINT32 cluster; DirectoryEntry *de; WorkingDirectory *wd = NULL; int cur_entry = 0; int place = 0; wd = _build_working_directory_stack(path, 1, 0); if (!wd) /* unable to locate */ return XILFATFS_ENOENT; if (wd->pi->FatType != FAT32 && wd->parent == 0) { /* Root directory */ filecount = wd->v.root.DirCount * DIRENT_SIZE; sector = wd->v.root.StartSector; nsectors = filecount / SECTORSIZE; cluster = 0; } else { /* Child directory || FAT32 * (In Fat32 root & child are treated similarly) */ cluster = wd->v.child.FirstCluster; sector = starting_sector(cluster, wd->pi); nsectors = wd->pi->SectorsPerCluster; filecount = nsectors * SECTORSIZE; is_sub_dir = 1; if (sector == 0) { /* FAT problem ? */ return XILFATFS_EIO; } } /* *********** MODIFICATION BEGIN ********** */ delete_working_directory_stack(wd); /* *******************END******************* */ cur_entry = 0; /* Keep going until the whole directory has been read. * Note: it is necessary to check filecount in the inner * loops as well because we can hit end-of-file anywhere * within a cluster. */ while (filecount) { ... } }

 

Experience has taught me that the library implementations are not wrong -- instead I simply use it the wrong way. Have anyone else experiences this problem?

 

Thanks

Peter

0 Kudos
Reply
0 Replies