mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
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:
committed by
GregoryN
parent
071d69e082
commit
96da659c0b
@@ -50,6 +50,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
@@ -441,6 +442,12 @@ static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
elapsed = ELAPSED_TIME(start);
|
elapsed = ELAPSED_TIME(start);
|
||||||
|
|
||||||
|
if (elapsed > MMCSD_DELAY_10MS)
|
||||||
|
{
|
||||||
|
// Give other threads time to run
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (elapsed < MMCSD_DELAY_500MS);
|
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
|
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.
|
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
|
config FS_FATTIME
|
||||||
bool "FAT timestamps"
|
bool "FAT timestamps"
|
||||||
default n
|
default n
|
||||||
|
|||||||
@@ -754,6 +754,17 @@ static inline int fat_createalias(struct fat_dirinfo_s *dirinfo)
|
|||||||
return OK;
|
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
|
#endif
|
||||||
@@ -837,6 +848,33 @@ static inline int fat_uniquealias(struct fat_mountpt_s *fs,
|
|||||||
lsdigit = tilde + 1;
|
lsdigit = tilde + 1;
|
||||||
DEBUGASSERT(dirinfo->fd_name[lsdigit] == '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 */
|
/* Search for the single short file name directory entry in this directory */
|
||||||
|
|
||||||
while ((ret = fat_findalias(fs, dirinfo)) == OK)
|
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();
|
writetime = fat_systime2fattime();
|
||||||
DIR_PUTWRTTIME(direntry, writetime & 0xffff);
|
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 */
|
/* 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();
|
writetime = fat_systime2fattime();
|
||||||
DIR_PUTWRTTIME(direntry, writetime & 0xffff);
|
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 */
|
/* This sector needs to be written back to disk eventually */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user