[Yaffs] Slow yaffs_readdir(..)

Beat Morf beat.morf at duagon.com
Wed Jun 29 07:59:16 BST 2005


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;
}




More information about the yaffs mailing list