Как то так. Если кто то заметит ошибку, кричите.

Код:
/*-----------------------------------------------------------------------*/
/* Format name for directory entry                                       */
/*-----------------------------------------------------------------------*/

// Стандартная функция create_name изменяет второй аргумент, а это
// нам не надо.

static FRESULT create_name_2(DIR* dj, const char* name) {
  return create_name(dj, &name);
}

/*-----------------------------------------------------------------------*/
/* Save sector                                                           */
/*-----------------------------------------------------------------------*/

// Сохранить сектор на диск

static DRESULT disk_write(const BYTE* buf, DWORD sector) {  
  DRESULT r;
  // Начало операции записи
  if(r = disk_writep(0, sector)) return r;
  // Запись данных
  if(r = disk_writep(buf, 512)) return r;
  // Окончание операции записи
  return disk_writep(0, 0);
}

/*-----------------------------------------------------------------------*/
/* Reset free space counters on start                                    */
/*-----------------------------------------------------------------------*/

// Вызов этой функции надо добавить в конец pf_mount
//
// if(fs->fs_type==FS_FAT32 && LD_WORD(buf+BPB_RsvdSecCnt-13)>0) 
//   if(resetFreeSpace(bsect+1, buf512)) 
//     return FR_DISK_ERR; 

static DRESULT resetFreeSpaceFat32(unsigned long bootSectorPlus1, BYTE* buf512) {  
  DRESULT r;
  if(r = disk_readp(buf512, bootSectorPlus1, 0, 512)) return r;
  if(*(unsigned long*)buf512 != 0x41615252) return RES_OK;
  if(*(unsigned long*)(buf512+0x1E4) != 0x61417272) return RES_OK;
  if(*(unsigned long*)(buf512+0x1FC) != 0xAA550000) return RES_OK;
  *(unsigned long*)(buf512+0x1E8) = 0xFFFFFFFF;
  *(unsigned long*)(buf512+0x1EC) = 0xFFFFFFFF;
  return disk_write(buf512, bootSectorPlus1);
}

/*-----------------------------------------------------------------------*/
/* Save fat sector in all FAT tables                                     */
/*-----------------------------------------------------------------------*/

static char saveFatSector(unsigned long sector, const BYTE* buf) { 
  if(sector == -1) return 0;
  if(FatFs->fatbase2) if(disk_write(buf, FatFs->fatbase2 + sector)) return 1;
  return disk_write(buf, FatFs->fatbase + sector);
}

/*-----------------------------------------------------------------------*/
/* Alloc cluster                                                         */
/*-----------------------------------------------------------------------*/

static FRESULT allocClusterFat32(unsigned long* cluster, BYTE* buf) {
  unsigned char i;
  unsigned long s, sectorsInFat, *a;

  // Кол-во секторов в таблице FAT
  sectorsInFat = (FatFs->n_fatent + 127) / 128;
  // В первом секторе первых 2 числа пропускаем
  i = 2, a = ((unsigned long*)buf)+2;
  // Последовательно перебираем сектора
  for(s = 0; s < sectorsInFat; s++) {
    if(disk_readp(buf, FatFs->fatbase + s, 0, 512)) return FR_DISK_ERR;
    // Среди 128 чисел в секторе ищем 0
    for(; i < 128; i++, a++) {
      if(*a == 0) {
        // Мы могли вылететь за пределы таблицы FAT
        *cluster = i + s * 128;
        if(*cluster >= FatFs->n_fatent) return FR_NO_FREE_SPACE;
        // Помечаем кластер как последний
        *a = 0x0FFFFFFF;
        // Сохраняем изменения
        if(saveFatSector(s, buf)) return FR_DISK_ERR;
        // Ок
        return FR_OK;
      }
    }
    // Для цикла выше.
    i = 0, a = (unsigned long*)buf;
  }
  // Свобожных кластеров нет.
  return FR_NO_FREE_SPACE;
}

/*-----------------------------------------------------------------------*/
/* Add cluster in chain                                                  */
/*-----------------------------------------------------------------------*/

static char setNextClusterFat32(unsigned long cluster, unsigned long nextCluster, BYTE* buf512) {
  unsigned long sector;
  sector = cluster/128;
  if(disk_readp(buf512, FatFs->fatbase + sector, 0, 512)) return 1;
  ((unsigned long*)buf512)[cluster % 128] = nextCluster;  
  return saveFatSector(sector, buf512);
}

/*-----------------------------------------------------------------------*/
/* Alloc directoy entry                                                  */
/*-----------------------------------------------------------------------*/

static FRESULT allocEntryFat32(DIR* dj, const char* name, BYTE* buf512, BYTE** outEntry) {
	FRESULT res;
	BYTE c, *a;
  unsigned char i;
  DWORD cluster;
 
  // Форматируем имя
  if(res = create_name_2(dj, name)) return res;
  // Ищем это имя в папке
  res = dir_find(dj, buf512);
  if(res != FR_NO_FILE) {
    if(res == FR_OK) return FR_FILE_EXISTS;
    return res;
  }
  // Перематываем папку в начало
  if(res = dir_rewind(dj)) return res;
  // Ищем в папке пустой описатель
	res = FR_NO_FILE;
	while (dj->sect) {
		if (disk_readp(buf512, dj->sect, 0, 512)) return FR_DISK_ERR;
    for(i=0, a=buf512; i<16; i++, a+=32) {
      if((a[DIR_Attr] & AM_VOL) == 0 && (*a == 0 || *a == 0xE5)) {
        // Если мы добавляем в последний элемент, то надо надо создать последний элемент
        if(*a==0) {
          if(i<15) {
            memset(a+32, 0, 512-32-i*32); 
          } else
          if(dj->index/16+1 < FatFs->csize) {
            // Это последний элемент в секторе, но не в кластере
            memset(buf512, 0, 512);
          	if(disk_write(buf512, dj->sect+1)) return FR_DISK_ERR;
            // Восстанавливаем буфер
            if(disk_readp(buf512, dj->sect, 0, 512)) return FR_DISK_ERR;
          }
        }
        // Инициализируем найденный элемент
        memset(a, 0, 32);
        goto break2;
      }
    }
    // Следующий сектор
		dj->index += 15;
		if(res = dir_next(dj)) {
      if(res != FR_NO_FILE) return res;
      // В папке может быть не более 65535 файлов
      if((unsigned short)dj->index==65535)
        return FR_DIR_FULL;
      // Добавить еще один кластер к папке.
      if(res = allocClusterFat32(&cluster, buf512)) return res;
      if(setNextClusterFat32(dj->clust, cluster, buf512)) return FR_DISK_ERR; 
      dj->clust = cluster;
      dj->sect = clust2sect(cluster);
      // Инициализируем сектор
      memset(buf512, 0, 512);
      a = buf512;
      break;
    }
	}
break2:
  // Запоняем имя
  dj->fn = a;
  create_name_2(dj, name);
  // Возвращаем указатель на найденный элемент
  if(outEntry) *outEntry = a;
  // Ок
  return FR_OK;
}

/*-----------------------------------------------------------------------*/
/* Free cluster chain                                                    */
/*-----------------------------------------------------------------------*/

static FRESULT freeChain(unsigned long cluster, BYTE* buf512) {
  unsigned long s, s1, *a;
  s1 = -1;
  while(cluster >= 2 && cluster < FatFs->n_fatent) {
    s = cluster/128;
    if(s!=s1) {
      if(saveFatSector(s1, buf512)) return FR_DISK_ERR;
      s1 = s;
      if(disk_readp(buf512, FatFs->fatbase+s, 0, 512)) return FR_DISK_ERR;
    }
    a = (unsigned long*)(buf512 + (cluster%128)*4);
    cluster = *a;
    *a = 0;
  }
  if(saveFatSector(s1, buf512)) return FR_DISK_ERR;
  return FR_OK;
}

/*-----------------------------------------------------------------------*/
/* Is empty folder                                                       */
/*-----------------------------------------------------------------------*/

static FRESULT isEmptyFolder(DWORD cluster, BYTE* buf512) {
  DIR dir;
  FRESULT res;
  BYTE* a;
  unsigned char i;
 
  // Для последовательного четния всех секторов папки
  dir.sclust = cluster;
  if(res = dir_rewind(&dir)) return res;
  // Первые два элемента пропускаем (должны быть .. и .)
  i = 2, a = buf512 + 64;
  // Обрабатываем все сектора
  while(dir.sect) {
    if(disk_readp(buf512, dir.sect, 0, 512)) return FR_DISK_ERR;
    // В секторе 16 описателей
    for(; i < 16; i++, a += 32) {
      // Это был последний описатель
      if(*a == 0) return FR_OK;
      // Найден файл или папка, ошибка
      if((a[DIR_Attr] & AM_VOL) == 0 && *a != 0xE5) return FR_DIR_NOT_EMPTY;
    }
    // Следующий сектор
    dir.index += 15;
    if(res = dir_next(&dir)) {
      // Это был последний сектор, всё ок.
      if(res == FR_NO_FILE) return FR_OK;
      // Ошибка
      return res;
    }
    // Для цикла выше
    i = 0, a = buf512;
  }
}

/*-----------------------------------------------------------------------*/
/* Convert bytyes to clusters                                            */
/*-----------------------------------------------------------------------*/

static unsigned long bytesToClusters(unsigned long sizeInBytes) {
  unsigned long bytesInCluster;
  bytesInCluster = FatFs->csize*512;
  return (sizeInBytes + bytesInCluster - 1) / bytesInCluster;
}