Hi
I am using YAFFS direct implementation and actually testing some
basically requirements.
When I write hundreds of files into the root of my YAFFS-FS (let's say
600) and dump them afterwards ('yaffs_opendir()', 'yaffs_readdir()'), I
saw, that the 'yaffs_readdir(...)' functions needs much more time for
the last files than for the first one.
Each call to the 'yaffs_readdir(...)' function will start at the first
object within the 'yaffs_DIR'. For knowing which object was allready
returned, a separate list of allready showed objects is applied (the
objects are identifiable with the ObjectID); Means long times for a lot
of files!
What is exactly the reason for such a method if I don't need to give
them out in an ordered way? And should they now be ordered?
Actually I am using following 'yaffs_xxxxdir(...)' functions with a good
performance ('dsc->list' is used for pointing to the next
yaffsfs_ObjectListEntry entry):
Beat
yaffs_DIR *yaffs_opendir(const char *dirname)
{
yaffs_DIR *dir = NULL;
struct list_head *i;
yaffs_Object *obj = NULL;
yaffsfs_DirectorySearchContext *dsc = NULL;
yaffsfs_Lock();
obj = yaffsfs_FindObject(NULL,dirname,0);
i = obj->variant.directoryVariant.children.next;
if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
{
dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext));
dir = (yaffs_DIR *)dsc;
if(dsc)
{
dsc->magic = YAFFS_MAGIC;
dsc->list = NULL;
memset(dsc->name,0,NAME_MAX+1);
strncpy(dsc->name,dirname,NAME_MAX);
dsc->list = (struct yaffsfs_ObjectListEntry*)i;
}
}
yaffsfs_Unlock();
return dir;
}
struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp)
{
yaffsfs_DirectorySearchContext *dsc =
(yaffsfs_DirectorySearchContext *)dirp;
struct yaffs_dirent *retVal = NULL;
yaffs_Object *entry = NULL;
int offset;
struct list_head *i;
yaffs_Object *obj = NULL;
yaffsfs_Lock();
offset = -1;
if(dsc && dsc->magic == YAFFS_MAGIC)
{
yaffsfs_SetError(0);
obj = yaffsfs_FindObject(NULL,dsc->name,0);
if ( ((i = (struct list_head*) dsc->list) != NULL) &&
(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) &&
(i != &obj->variant.directoryVariant.children) )
{
entry = (i) ? list_entry(i, yaffs_Object,siblings) : NULL;
i = i->next;
dsc->list = (struct yaffsfs_ObjectListEntry*)i;
dsc->de.d_ino = yaffs_GetEquivalentObject(entry)->objectId;
dsc->de.d_off = offset;
yaffs_GetObjectName(entry,dsc->de.d_name,NAME_MAX+1);
dsc->de.d_reclen = sizeof(struct yaffs_dirent);
retVal = &dsc->de;
}
}
else
{
yaffsfs_SetError(-EBADF);
}
yaffsfs_Unlock();
return retVal;
}
void yaffs_rewinddir(yaffs_DIR *dirp)
{
yaffsfs_DirectorySearchContext *dsc =
(yaffsfs_DirectorySearchContext *)dirp;
yaffs_Object *obj = NULL;
struct list_head *i;
yaffsfs_Lock();
obj = yaffsfs_FindObject(NULL,dsc->name,0);
i = obj->variant.directoryVariant.children.next;
dsc->list = (struct yaffsfs_ObjectListEntry*)i;
yaffsfs_Unlock();
}
int yaffs_closedir(yaffs_DIR *dirp)
{
yaffsfs_DirectorySearchContext *dsc =
(yaffsfs_DirectorySearchContext *)dirp;
yaffsfs_Lock();
dsc->list = NULL;
dsc->magic = 0;
YFREE(dsc);
yaffsfs_Unlock();
return 0;
}