diff options
Diffstat (limited to 'fs/fat/fat.c')
-rw-r--r-- | fs/fat/fat.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 9e1b842dac..68ce658386 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -869,6 +869,14 @@ static dir_entry *extract_vfat_name(fat_itr *itr) return NULL; } + /* + * We are now at the short file name entry. + * If it is marked as deleted, just skip it. + */ + if (dent->name[0] == DELETED_FLAG || + dent->name[0] == aRING) + return NULL; + itr->l_name[n] = '\0'; chksum = mkcksum(dent->name, dent->ext); @@ -898,6 +906,16 @@ static int fat_itr_next(fat_itr *itr) itr->name = NULL; + /* + * One logical directory entry consist of following slots: + * name[0] Attributes + * dent[N - N]: LFN[N - 1] N|0x40 ATTR_VFAT + * ... + * dent[N - 2]: LFN[1] 2 ATTR_VFAT + * dent[N - 1]: LFN[0] 1 ATTR_VFAT + * dent[N]: SFN ATTR_ARCH + */ + while (1) { dent = next_dent(itr); if (!dent) @@ -910,7 +928,17 @@ static int fat_itr_next(fat_itr *itr) if (dent->attr & ATTR_VOLUME) { if ((dent->attr & ATTR_VFAT) == ATTR_VFAT && (dent->name[0] & LAST_LONG_ENTRY_MASK)) { + /* long file name */ dent = extract_vfat_name(itr); + /* + * If succeeded, dent has a valid short file + * name entry for the current entry. + * If failed, itr points to a current bogus + * entry. So after fetching a next one, + * it may have a short file name entry + * for this bogus entry so that we can still + * check for a short name. + */ if (!dent) continue; itr->name = itr->l_name; @@ -919,8 +947,11 @@ static int fat_itr_next(fat_itr *itr) /* Volume label or VFAT entry, skip */ continue; } - } + } else if (!(dent->attr & ATTR_ARCH) && + !(dent->attr & ATTR_DIR)) + continue; + /* short file name */ break; } |