[Yaffs] Slow yaffs_readdir(..)

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Beat Morf
Date:  
To: yaffs
Subject: [Yaffs] Slow yaffs_readdir(..)
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 special ordered way?

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