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:
parent
071d69e082
commit
96da659c0b
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user