Skip to content

Commit 4c8f1cb

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/hirofumi/fatfs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/hirofumi/fatfs-2.6: fat: Check s_dirt in fat_sync_fs() vfat: change the default from shortname=lower to shortname=mixed fat/nls: Fix handling of utf8 invalid char
2 parents 9c1fe83 + ed248b2 commit 4c8f1cb

File tree

6 files changed

+26
-27
lines changed

6 files changed

+26
-27
lines changed

Documentation/filesystems/vfat.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ shortname=lower|win95|winnt|mixed
102102
winnt: emulate the Windows NT rule for display/create.
103103
mixed: emulate the Windows NT rule for display,
104104
emulate the Windows 95 rule for create.
105-
Default setting is `lower'.
105+
Default setting is `mixed'.
106106

107107
tz=UTC -- Interpret timestamps as UTC rather than local time.
108108
This option disables the conversion of timestamps

fs/fat/fat.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
323323
/* fat/misc.c */
324324
extern void fat_fs_error(struct super_block *s, const char *fmt, ...)
325325
__attribute__ ((format (printf, 2, 3))) __cold;
326-
extern void fat_clusters_flush(struct super_block *sb);
326+
extern int fat_clusters_flush(struct super_block *sb);
327327
extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
328328
extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
329329
__le16 __time, __le16 __date, u8 time_cs);

fs/fat/inode.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,16 @@ static void fat_write_super(struct super_block *sb)
451451

452452
static int fat_sync_fs(struct super_block *sb, int wait)
453453
{
454-
lock_super(sb);
455-
fat_clusters_flush(sb);
456-
sb->s_dirt = 0;
457-
unlock_super(sb);
454+
int err = 0;
458455

459-
return 0;
456+
if (sb->s_dirt) {
457+
lock_super(sb);
458+
sb->s_dirt = 0;
459+
err = fat_clusters_flush(sb);
460+
unlock_super(sb);
461+
}
462+
463+
return err;
460464
}
461465

462466
static void fat_put_super(struct super_block *sb)
@@ -812,7 +816,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
812816
seq_puts(m, ",shortname=mixed");
813817
break;
814818
case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95:
815-
/* seq_puts(m, ",shortname=lower"); */
819+
seq_puts(m, ",shortname=lower");
816820
break;
817821
default:
818822
seq_puts(m, ",shortname=unknown");
@@ -963,7 +967,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
963967
opts->codepage = fat_default_codepage;
964968
opts->iocharset = fat_default_iocharset;
965969
if (is_vfat) {
966-
opts->shortname = VFAT_SFN_DISPLAY_LOWER|VFAT_SFN_CREATE_WIN95;
970+
opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95;
967971
opts->rodir = 0;
968972
} else {
969973
opts->shortname = 0;

fs/fat/misc.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,19 @@ EXPORT_SYMBOL_GPL(fat_fs_error);
4343

4444
/* Flushes the number of free clusters on FAT32 */
4545
/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
46-
void fat_clusters_flush(struct super_block *sb)
46+
int fat_clusters_flush(struct super_block *sb)
4747
{
4848
struct msdos_sb_info *sbi = MSDOS_SB(sb);
4949
struct buffer_head *bh;
5050
struct fat_boot_fsinfo *fsinfo;
5151

5252
if (sbi->fat_bits != 32)
53-
return;
53+
return 0;
5454

5555
bh = sb_bread(sb, sbi->fsinfo_sector);
5656
if (bh == NULL) {
5757
printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n");
58-
return;
58+
return -EIO;
5959
}
6060

6161
fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
@@ -74,6 +74,8 @@ void fat_clusters_flush(struct super_block *sb)
7474
mark_buffer_dirty(bh);
7575
}
7676
brelse(bh);
77+
78+
return 0;
7779
}
7880

7981
/*

fs/fat/namei_vfat.c

+4-11
Original file line numberDiff line numberDiff line change
@@ -499,17 +499,10 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
499499
int charlen;
500500

501501
if (utf8) {
502-
int name_len = strlen(name);
503-
504-
*outlen = utf8s_to_utf16s(name, PATH_MAX, (wchar_t *) outname);
505-
506-
/*
507-
* We stripped '.'s before and set len appropriately,
508-
* but utf8s_to_utf16s doesn't care about len
509-
*/
510-
*outlen -= (name_len - len);
511-
512-
if (*outlen > 255)
502+
*outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname);
503+
if (*outlen < 0)
504+
return *outlen;
505+
else if (*outlen > 255)
513506
return -ENAMETOOLONG;
514507

515508
op = &outname[*outlen * sizeof(wchar_t)];

fs/nls/nls_base.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs)
124124
while (*s && len > 0) {
125125
if (*s & 0x80) {
126126
size = utf8_to_utf32(s, len, &u);
127-
if (size < 0) {
128-
/* Ignore character and move on */
129-
size = 1;
130-
} else if (u >= PLANE_SIZE) {
127+
if (size < 0)
128+
return -EINVAL;
129+
130+
if (u >= PLANE_SIZE) {
131131
u -= PLANE_SIZE;
132132
*op++ = (wchar_t) (SURROGATE_PAIR |
133133
((u >> 10) & SURROGATE_BITS));

0 commit comments

Comments
 (0)