Index: common/dir_uncached.c
===================================================================
--- common/dir_uncached.c (revision 28570)
+++ common/dir_uncached.c (working copy)
@@ -204,14 +204,29 @@
char *basename;
char *parent;
struct dirent_uncached *entry;
- struct fat_dir newdir;
+ int dd;
+ DIR_UNCACHED* pdir = opendirs;
+ struct fat_dir *newdir;
int rc;

if ( name[0] != '/' ) {
DEBUGF("mkdir: Only absolute paths supported right now\n");
return -1;
}
+ /* find a free dir descriptor */
+ for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++)
+ if ( !pdir->busy )
+ break;

+ if ( dd == MAX_OPEN_DIRS ) {
+ DEBUGF("Too many dirs open\n");
+ errno = EMFILE;
+ return -5;
+ }
+
+ pdir->busy = true;
+ newdir = &pdir->fatdir;
+
strlcpy(namecopy, name, sizeof(namecopy));

/* Split the base name and the path */
@@ -230,11 +245,13 @@

if(!dir) {
DEBUGF("mkdir: can't open parent dir\n");
+ pdir->busy = false;
return -2;
}

if(basename[0] == 0) {
DEBUGF("mkdir: Empty dir name\n");
+ pdir->busy = false;
errno = EINVAL;
return -3;
}
@@ -245,14 +262,16 @@
DEBUGF("mkdir error: file exists\n");
errno = EEXIST;
closedir_uncached(dir);
+ pdir->busy = false;
return - 4;
}
}

- memset(&newdir, 0, sizeof(struct fat_dir));
+ memset(newdir, 0, sizeof(struct fat_dir));

- rc = fat_create_dir(basename, &newdir, &(dir->fatdir));
+ rc = fat_create_dir(basename, newdir, &(dir->fatdir));
closedir_uncached(dir);
+ pdir->busy = false;

return rc;
}
Index: drivers/fat.c
===================================================================
--- drivers/fat.c (revision 28570)
+++ drivers/fat.c (working copy)
@@ -1967,7 +1967,7 @@
int attr)
{
int rc;
- struct fat_dir olddir;
+ struct fat_file olddir_file;
struct fat_file newfile = *file;
unsigned char* entry = NULL;
unsigned short* clusptr = NULL;
@@ -1988,11 +1988,6 @@
return -2;
}

- /* create a temporary file handle */
- rc = fat_opendir(IF_MV2(file->volume,) &olddir, file->dircluster, NULL);
- if (rc < 0)
- return rc * 10 - 1;
-
/* create new name */
rc = add_dir_entry(dir, &newfile, newname, false, false);
if (rc < 0)
@@ -2016,18 +2011,17 @@
it points to its parent directory (we don't check if it was a move) */
if(FAT_ATTR_DIRECTORY == attr) {
unsigned char buf[SECTOR_SIZE];
- /* open the dir that was renamed, we re-use the olddir struct */
- rc = fat_opendir(IF_MV2(file->volume,) &olddir, newfile.firstcluster,
- NULL);
+ /* open the dir that was renamed, we re-use the olddir_file struct */
+ rc = fat_open(IF_MV2(volume,) newfile.firstcluster, &olddir_file, NULL);
if (rc < 0)
return rc * 10 - 6;

/* get the first sector of the dir */
- rc = fat_seek(&olddir.file, 0);
+ rc = fat_seek(&olddir_file, 0);
if (rc < 0)
return rc * 10 - 7;

- rc = fat_readwrite(&olddir.file, 1, buf, false);
+ rc = fat_readwrite(&olddir_file, 1, buf, false);
if (rc < 0)
return rc * 10 - 8;

@@ -2051,11 +2045,11 @@
*clusptr = htole16(parentcluster & 0xffff);

/* write back this sector */
- rc = fat_seek(&olddir.file, 0);
+ rc = fat_seek(&olddir_file, 0);
if (rc < 0)
return rc * 10 - 7;

- rc = fat_readwrite(&olddir.file, 1, buf, true);
+ rc = fat_readwrite(&olddir_file, 1, buf, true);
if (rc < 1)
return rc * 10 - 8;
}