aboutsummaryrefslogtreecommitdiffstats
path: root/features/vfat/FAT-Add-CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES-option.patch
blob: 80a7a1094a6560ea179d8b500f82aee64e7b268e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From 083bea42015efba517dacf5e78b8c138add4d24e Mon Sep 17 00:00:00 2001
From: Andrew Tridgell <tridge@samba.org>
Date: Wed, 15 Jul 2009 10:14:59 +1000
Subject: [PATCH] FAT: Add CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES option

When this option is enabled this will refuse to create new files with
long names. Accessing existing files with long names will continue to
work.

File names to be created must conform to the 8.3 format.  Mixed case is
not allowed in either the prefix or the suffix.

Signed-off-by: Andrew Tridgell <tridge@samba.org>
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig
index 1f103d835e8c..ca5c78bda750 100644
--- a/fs/fat/Kconfig
+++ b/fs/fat/Kconfig
@@ -121,6 +121,17 @@ config FAT_DEFAULT_IOCHARSET
 	  Enable any character sets you need in File Systems/Native Language
 	  Support.
 
+config VFAT_NO_CREATE_WITH_LONGNAMES
+	bool "Disable creating files with long names"
+	depends on VFAT_FS
+	default n
+	help
+	  Set this to disable support for creating files or directories with
+	  names longer than 8.3 (the original DOS maximum file name length)
+	  e.g. naming a file FILE1234.TXT would be allowed but creating or
+	  renaming a file to FILE12345.TXT or FILE1234.TEXT would not
+	  be permitted.  Reading files with long file names is still permitted.
+
 config FAT_DEFAULT_UTF8
 	bool "Enable FAT UTF-8 option by default"
 	depends on VFAT_FS
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 13aa43b1ec96..eb611277eee4 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -442,6 +442,15 @@ static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
 	memcpy(name_res, base, baselen);
 	memcpy(name_res + 8, ext, extlen);
 	*lcase = 0;
+
+#ifdef CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES
+	if (is_shortname == 0)
+		return -ENAMETOOLONG;
+	if (!base_info.valid || !ext_info.valid)
+		return -EINVAL;
+	opts_shortname = VFAT_SFN_CREATE_WINNT;
+#endif
+
 	if (is_shortname && base_info.valid && ext_info.valid) {
 		if (vfat_find_form(dir, name_res) == 0)
 			return -EEXIST;
@@ -654,15 +663,19 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
 	struct fat_mount_options *opts = &sbi->options;
-	struct msdos_dir_slot *ps;
 	struct msdos_dir_entry *de;
-	unsigned char cksum, lcase;
+	unsigned char lcase;
 	unsigned char msdos_name[MSDOS_NAME];
 	wchar_t *uname;
 	__le16 time, date;
 	u8 time_cs;
-	int err, ulen, usize, i;
+	int err, ulen, usize;
+#ifndef CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES
+	int i;
+	struct msdos_dir_slot *ps;
+	unsigned char cksum;
 	loff_t offset;
+#endif
 
 	*nr_slots = 0;
 
@@ -696,6 +709,9 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
 	lcase = FAT_NO_83NAME;
 #endif
 
+#ifdef CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES
+	de = (struct msdos_dir_entry *)slots;
+#else
 	/* build the entry of long file name */
 	cksum = fat_checksum(msdos_name);
 
@@ -713,6 +729,7 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
 	}
 	slots[0].id |= 0x40;
 	de = (struct msdos_dir_entry *)ps;
+#endif
 
 shortname:
 	/* build the entry of 8.3 alias name */
@@ -1143,7 +1160,11 @@ static struct dentry *vfat_mount(struct file_system_type *fs_type,
 
 static struct file_system_type vfat_fs_type = {
 	.owner		= THIS_MODULE,
+#ifdef CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES
+	.name		= "lfat",
+#else
 	.name		= "vfat",
+#endif
 	.mount		= vfat_mount,
 	.kill_sb	= kill_block_super,
 	.fs_flags	= FS_REQUIRES_DEV,
@@ -1163,6 +1184,9 @@ static void __exit exit_vfat_fs(void)
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("VFAT filesystem support");
 MODULE_AUTHOR("Gordon Chaffee");
+#ifdef CONFIG_VFAT_NO_CREATE_WITH_LONGNAMES
+MODULE_ALIAS("lfat");
+#endif
 
 module_init(init_vfat_fs)
 module_exit(exit_vfat_fs)
-- 
2.10.1