fat: don't use free_clusters for fat32

It seems that the recent Windows changed specification, and it's
undocumented.  Windows doesn't update ->free_clusters correctly.

This patch doesn't use ->free_clusters by default.  (instead, add "usefree"
for forcing to use it)

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Juergen Beisert <juergen127@kreuzholzen.de>
Cc: Andreas Schwab <schwab@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
OGAWA Hirofumi 2007-05-08 00:31:01 -07:00 committed by Linus Torvalds
parent 4ff773bbde
commit 28ec039c21
3 changed files with 20 additions and 4 deletions

View file

@ -57,6 +57,13 @@ nonumtail=<bool> -- When creating 8.3 aliases, normally the alias will
currently exist in the directory, 'longfile.txt' will currently exist in the directory, 'longfile.txt' will
be the short alias instead of 'longfi~1.txt'. be the short alias instead of 'longfi~1.txt'.
usefree -- Use the "free clusters" value stored on FSINFO. It'll
be used to determine number of free clusters without
scanning disk. But it's not used by default, because
recent Windows don't update it correctly in some
case. If you are sure the "free clusters" on FSINFO is
correct, by this option you can avoid scanning disk.
quiet -- Stops printing certain warning messages. quiet -- Stops printing certain warning messages.
check=s|r|n -- Case sensitivity checking setting. check=s|r|n -- Case sensitivity checking setting.

View file

@ -825,6 +825,8 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
} }
if (opts->name_check != 'n') if (opts->name_check != 'n')
seq_printf(m, ",check=%c", opts->name_check); seq_printf(m, ",check=%c", opts->name_check);
if (opts->usefree)
seq_puts(m, ",usefree");
if (opts->quiet) if (opts->quiet)
seq_puts(m, ",quiet"); seq_puts(m, ",quiet");
if (opts->showexec) if (opts->showexec)
@ -850,7 +852,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
enum { enum {
Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase, Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_usefree, Opt_nocase,
Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable, Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
Opt_dots, Opt_nodots, Opt_dots, Opt_nodots,
Opt_charset, Opt_shortname_lower, Opt_shortname_win95, Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
@ -872,6 +874,7 @@ static match_table_t fat_tokens = {
{Opt_dmask, "dmask=%o"}, {Opt_dmask, "dmask=%o"},
{Opt_fmask, "fmask=%o"}, {Opt_fmask, "fmask=%o"},
{Opt_codepage, "codepage=%u"}, {Opt_codepage, "codepage=%u"},
{Opt_usefree, "usefree"},
{Opt_nocase, "nocase"}, {Opt_nocase, "nocase"},
{Opt_quiet, "quiet"}, {Opt_quiet, "quiet"},
{Opt_showexec, "showexec"}, {Opt_showexec, "showexec"},
@ -951,7 +954,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0; opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0;
opts->utf8 = opts->unicode_xlate = 0; opts->utf8 = opts->unicode_xlate = 0;
opts->numtail = 1; opts->numtail = 1;
opts->nocase = 0; opts->usefree = opts->nocase = 0;
*debug = 0; *debug = 0;
if (!options) if (!options)
@ -979,6 +982,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
case Opt_check_n: case Opt_check_n:
opts->name_check = 'n'; opts->name_check = 'n';
break; break;
case Opt_usefree:
opts->usefree = 1;
break;
case Opt_nocase: case Opt_nocase:
if (!is_vfat) if (!is_vfat)
opts->nocase = 1; opts->nocase = 1;
@ -1304,7 +1310,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
le32_to_cpu(fsinfo->signature2), le32_to_cpu(fsinfo->signature2),
sbi->fsinfo_sector); sbi->fsinfo_sector);
} else { } else {
sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters); if (sbi->options.usefree)
sbi->free_clusters =
le32_to_cpu(fsinfo->free_clusters);
sbi->prev_free = le32_to_cpu(fsinfo->next_cluster); sbi->prev_free = le32_to_cpu(fsinfo->next_cluster);
} }

View file

@ -205,7 +205,8 @@ struct fat_mount_options {
numtail:1, /* Does first alias have a numeric '~1' type tail? */ numtail:1, /* Does first alias have a numeric '~1' type tail? */
atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */ atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */
flush:1, /* write things quickly */ flush:1, /* write things quickly */
nocase:1; /* Does this need case conversion? 0=need case conversion*/ nocase:1, /* Does this need case conversion? 0=need case conversion*/
usefree:1; /* Use free_clusters for FAT32 */
}; };
#define FAT_HASH_BITS 8 #define FAT_HASH_BITS 8