+//
+// Directory search context
+//
+// NB this is an opaque structure.
+
+
+typedef struct
+{
+ __u32 magic;
+ yaffs_dirent de; /* directory entry being used by this dsc */
+ char name[NAME_MAX+1]; /* name of directory being searched */
+ yaffs_Object *dirObj; /* ptr to directory being searched */
+ yaffs_Object *nextReturn; /* obj to be returned by next readddir */
+ int offset;
+ struct list_head others;
+} yaffsfs_DirectorySearchContext;
+
+
+
+static struct list_head search_contexts;
+
+
+static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
+{
+ if(dsc &&
+ dsc->dirObj &&
+ dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
+
+ dsc->offset = 0;
+
+ if( list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+ dsc->nextReturn = NULL;
+ } else {
+ dsc->nextReturn = list_entry(dsc->dirObj->variant.directoryVariant.children.next,
+ yaffs_Object,siblings);
+ }
+ } else {
+ /* Hey someone isn't playing nice! */
+ }
+}
+
+static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc)
+{
+ if(dsc &&
+ dsc->dirObj &&
+ dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
+
+ if( dsc->nextReturn == NULL ||
+ list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+ dsc->nextReturn = NULL;
+ } else {
+ struct list_head *next = dsc->nextReturn->siblings.next;
+
+ if( next == &dsc->dirObj->variant.directoryVariant.children)
+ dsc->nextReturn = NULL; /* end of list */
+ else
+ dsc->nextReturn = list_entry(next,yaffs_Object,siblings);
+ }
+ } else {
+ /* Hey someone isn't playing nice! */
+ }
+}
+
+static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
+{
+
+ struct list_head *i;
+ yaffsfs_DirectorySearchContext *dsc;
+
+ /* if search contexts not initilised then skip */
+ if(!search_contexts.next)
+ return;
+
+ /* Iteratethrough the directory search contexts.
+ * If any are the one being removed, then advance the dsc to
+ * the next one to prevent a hanging ptr.
+ */
+ list_for_each(i, &search_contexts) {
+ if (i) {
+ dsc = list_entry(i, yaffsfs_DirectorySearchContext,others);
+ if(dsc->nextReturn == obj)
+ yaffsfs_DirAdvance(dsc);
+ }
+ }
+
+}
+