Merged in paimonen/nuttx/pullreq_FAT_improvements (pull request #755)

Pullreq FAT improvements

* NuttX: Add CONFIG_FAT_LFN_ALIAS_HASH to speed up creating long filenames.

    Long filenames on FAT filesystems have associated 8.3 character alias
    short filenames. The traditional form of these is FILENA~1.EXT with
    a running count of the number of similar names. However creating this
    unique count can take several seconds if there are many similarly named
    files in the directory. Enabling FAT_LFN_ALIAS_HASH uses an alternative
    format of FI0123~1.TXT where the four digits are a hash of the original
    filename. This method is similar to what is used by Windows 2000 and
    later.

* NuttX: Add CONFIG_FAT_LFN_ALIAS_TRAILCHARS alternative format for 8.3 filenames.

    Traditional format for long filename 8.3 aliases takes first 6
    characters of long filename. If this option is set to N > 0,
    NuttX will instead take first 6-N and last N characters to form
    the short name. This is useful for filenames like "datafile12.txt"
    where the first characters would always remain the same.

* NuttX: FAT32: Fix file date corruption in fat_truncate().

* NuttX: if SD card wait seems to be a long one, give time for other threads to run.

Approved-by: GregoryN <gnutt@nuttx.org>
This commit is contained in:
Petteri Aimonen 2018-11-09 13:46:16 +00:00 committed by GregoryN
parent 071d69e082
commit 96da659c0b
4 changed files with 72 additions and 2 deletions

View File

@ -50,6 +50,7 @@
#include <time.h>
#include <errno.h>
#include <debug.h>
#include <unistd.h>
#include <nuttx/arch.h>
#include <nuttx/clock.h>
@ -441,6 +442,12 @@ static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot)
}
elapsed = ELAPSED_TIME(start);
if (elapsed > MMCSD_DELAY_10MS)
{
// Give other threads time to run
usleep(10000);
}
}
while (elapsed < MMCSD_DELAY_500MS);

View File

@ -46,6 +46,31 @@ config FAT_MAXFNAME
This setting may not exceed NAME_MAX. That will be verified at compile
time. The minimum values is 12 due to assumptions in internal logic.
config FAT_LFN_ALIAS_HASH
bool "Use faster method for forming long filename 8.3 alias"
depends on FAT_LFN
default n
---help---
Long filenames on FAT filesystems have associated 8.3 character alias
short filenames. The traditional form of these is FILENA~1.EXT with
a running count of the number of similar names. However creating this
unique count can take several seconds if there are many similarly named
files in the directory. Enabling FAT_LFN_ALIAS_HASH uses an alternative
format of FI0123~1.TXT where the four digits are a hash of the original
filename. This method is similar to what is used by Windows 2000 and
later.
config FAT_LFN_ALIAS_TRAILCHARS
int "Number of trailing characters to use for 8.3 alias"
depends on FAT_LFN
default 0
---help---
Traditional format for long filename 8.3 aliases takes first 6
characters of long filename. If this option is set to N > 0,
NuttX will instead take first 6-N and last N characters to form
the short name. This is useful for filenames like "datafile12.txt"
where the first characters would always remain the same.
config FS_FATTIME
bool "FAT timestamps"
default n

View File

@ -754,6 +754,17 @@ static inline int fat_createalias(struct fat_dirinfo_s *dirinfo)
return OK;
}
}
#if defined(CONFIG_FAT_LFN_ALIAS_TRAILCHARS) && CONFIG_FAT_LFN_ALIAS_TRAILCHARS > 0
/* Take first 6-N characters from beginning of filename and last N
* characters from end of the filename. Useful for filenames like
* "datafile123.txt". */
if (ndx == 6 - CONFIG_FAT_LFN_ALIAS_TRAILCHARS
&& namechars > CONFIG_FAT_LFN_ALIAS_TRAILCHARS)
{
src += namechars - CONFIG_FAT_LFN_ALIAS_TRAILCHARS;
}
#endif
}
}
#endif
@ -837,6 +848,33 @@ static inline int fat_uniquealias(struct fat_mountpt_s *fs,
lsdigit = tilde + 1;
DEBUGASSERT(dirinfo->fd_name[lsdigit] == '1');
#ifdef CONFIG_FAT_LFN_ALIAS_HASH
/* Add a hash of the long filename to the short filename, to reduce collisions. */
if ((ret = fat_findalias(fs, dirinfo)) == OK)
{
uint16_t hash = dirinfo->fd_seq.ds_offset;
for (i = 0; dirinfo->fd_lfname[i] != '\0'; i++)
{
hash = ((hash << 5) + hash) ^ dirinfo->fd_lfname[i];
}
for (i = 0; i < tilde - 2; i++)
{
uint8_t nibble = (hash >> (i * 4)) & 0x0F;
const char *digits = "0123456789ABCDEF";
dirinfo->fd_name[tilde - 1 - i] = digits[nibble];
}
}
else if (ret == -ENOENT)
{
return OK; /* Alias was unique already */
}
else
{
return ret; /* Other error */
}
#endif
/* Search for the single short file name directory entry in this directory */
while ((ret = fat_findalias(fs, dirinfo)) == OK)

View File

@ -1465,7 +1465,7 @@ int fat_dirtruncate(struct fat_mountpt_s *fs, FAR uint8_t *direntry)
writetime = fat_systime2fattime();
DIR_PUTWRTTIME(direntry, writetime & 0xffff);
DIR_PUTWRTDATE(direntry, writetime > 16);
DIR_PUTWRTDATE(direntry, writetime >> 16);
/* This sector needs to be written back to disk eventually */
@ -1526,7 +1526,7 @@ int fat_dirshrink(struct fat_mountpt_s *fs, FAR uint8_t *direntry,
writetime = fat_systime2fattime();
DIR_PUTWRTTIME(direntry, writetime & 0xffff);
DIR_PUTWRTDATE(direntry, writetime > 16);
DIR_PUTWRTDATE(direntry, writetime >> 16);
/* This sector needs to be written back to disk eventually */