aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
authorAndrew Gabbasov <andrew_gabbasov@mentor.com>2016-01-15 03:44:22 -0500
committerJan Kara <jack@suse.cz>2016-02-09 07:05:23 -0500
commit9293fcfbc1812a22ad5ce1b542eb90c1bbe01be1 (patch)
treeef5e96d406e9ac257911571591e0bcfb58afd9ad /fs/udf
parent066b9cded00b8e3212df74a417bb074f3f3a1fe0 (diff)
udf: Remove struct ustr as non-needed intermediate storage
Although 'struct ustr' tries to structurize the data by combining the string and its length, it doesn't actually make much benefit, since it saves only one parameter, but introduces an extra copying of the whole buffer, serving as an intermediate storage. It looks quite inefficient and not actually needed. This commit gets rid of the struct ustr by changing the parameters of some functions appropriately. Also, it removes using 'dstring' type, since it doesn't make much sense too. Just using the occasion, add a 'const' qualifier to udf_get_filename to make consistent parameters sets. Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/super.c36
-rw-r--r--fs/udf/udfdecl.h13
-rw-r--r--fs/udf/unicode.c146
3 files changed, 61 insertions, 134 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index ffb35f7eab38..fa92fe839fda 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -887,18 +887,14 @@ static int udf_find_fileset(struct super_block *sb,
887static int udf_load_pvoldesc(struct super_block *sb, sector_t block) 887static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
888{ 888{
889 struct primaryVolDesc *pvoldesc; 889 struct primaryVolDesc *pvoldesc;
890 struct ustr *instr, *outstr; 890 uint8_t *outstr;
891 struct buffer_head *bh; 891 struct buffer_head *bh;
892 uint16_t ident; 892 uint16_t ident;
893 int ret = -ENOMEM; 893 int ret = -ENOMEM;
894 894
895 instr = kmalloc(sizeof(struct ustr), GFP_NOFS); 895 outstr = kmalloc(128, GFP_NOFS);
896 if (!instr)
897 return -ENOMEM;
898
899 outstr = kmalloc(sizeof(struct ustr), GFP_NOFS);
900 if (!outstr) 896 if (!outstr)
901 goto out1; 897 return -ENOMEM;
902 898
903 bh = udf_read_tagged(sb, block, block, &ident); 899 bh = udf_read_tagged(sb, block, block, &ident);
904 if (!bh) { 900 if (!bh) {
@@ -923,31 +919,25 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
923#endif 919#endif
924 } 920 }
925 921
926 if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) { 922 ret = udf_CS0toUTF8(outstr, 31, pvoldesc->volIdent, 32);
927 ret = udf_CS0toUTF8(outstr, instr); 923 if (ret < 0)
928 if (ret < 0) 924 goto out_bh;
929 goto out_bh;
930 925
931 strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name, 926 strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
932 outstr->u_len > 31 ? 31 : outstr->u_len); 927 udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
933 udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
934 }
935 928
936 if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) { 929 ret = udf_CS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128);
937 ret = udf_CS0toUTF8(outstr, instr); 930 if (ret < 0)
938 if (ret < 0) 931 goto out_bh;
939 goto out_bh;
940 932
941 udf_debug("volSetIdent[] = '%s'\n", outstr->u_name); 933 outstr[ret] = 0;
942 } 934 udf_debug("volSetIdent[] = '%s'\n", outstr);
943 935
944 ret = 0; 936 ret = 0;
945out_bh: 937out_bh:
946 brelse(bh); 938 brelse(bh);
947out2: 939out2:
948 kfree(outstr); 940 kfree(outstr);
949out1:
950 kfree(instr);
951 return ret; 941 return ret;
952} 942}
953 943
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 47a228248c5b..972b70625614 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -106,12 +106,6 @@ struct generic_desc {
106 __le32 volDescSeqNum; 106 __le32 volDescSeqNum;
107}; 107};
108 108
109struct ustr {
110 uint8_t u_cmpID;
111 uint8_t u_name[UDF_NAME_LEN];
112 uint8_t u_len;
113};
114
115 109
116/* super.c */ 110/* super.c */
117 111
@@ -214,12 +208,11 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
214} 208}
215 209
216/* unicode.c */ 210/* unicode.c */
217extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, 211extern int udf_get_filename(struct super_block *, const uint8_t *, int,
218 int); 212 uint8_t *, int);
219extern int udf_put_filename(struct super_block *, const uint8_t *, int, 213extern int udf_put_filename(struct super_block *, const uint8_t *, int,
220 uint8_t *, int); 214 uint8_t *, int);
221extern int udf_build_ustr(struct ustr *, dstring *, int); 215extern int udf_CS0toUTF8(uint8_t *, int, const uint8_t *, int);
222extern int udf_CS0toUTF8(struct ustr *, const struct ustr *);
223 216
224/* ialloc.c */ 217/* ialloc.c */
225extern void udf_free_inode(struct inode *); 218extern void udf_free_inode(struct inode *);
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index 5599e7535401..dc5990f4c952 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -28,53 +28,8 @@
28 28
29#include "udf_sb.h" 29#include "udf_sb.h"
30 30
31static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, 31static int udf_translate_to_linux(uint8_t *, int, const uint8_t *, int,
32 int); 32 const uint8_t *, int);
33
34static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
35{
36 if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN))
37 return 0;
38
39 memset(dest, 0, sizeof(struct ustr));
40 memcpy(dest->u_name, src, strlen);
41 dest->u_cmpID = 0x08;
42 dest->u_len = strlen;
43
44 return strlen;
45}
46
47/*
48 * udf_build_ustr
49 */
50int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
51{
52 int usesize;
53
54 if (!dest || !ptr || !size)
55 return -1;
56 BUG_ON(size < 2);
57
58 usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name));
59 usesize = min(usesize, size - 2);
60 dest->u_cmpID = ptr[0];
61 dest->u_len = usesize;
62 memcpy(dest->u_name, ptr + 1, usesize);
63 memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize);
64
65 return 0;
66}
67
68/*
69 * udf_build_ustr_exact
70 */
71static void udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
72{
73 memset(dest, 0, sizeof(struct ustr));
74 dest->u_cmpID = ptr[0];
75 dest->u_len = exactsize - 1;
76 memcpy(dest->u_name, ptr + 1, exactsize - 1);
77}
78 33
79static int udf_uni2char_utf8(wchar_t uni, 34static int udf_uni2char_utf8(wchar_t uni,
80 unsigned char *out, 35 unsigned char *out,
@@ -159,53 +114,50 @@ static int udf_char2uni_utf8(const unsigned char *in,
159 return u_len; 114 return u_len;
160} 115}
161 116
162static int udf_name_from_CS0(struct ustr *utf_o, 117static int udf_name_from_CS0(uint8_t *str_o, int str_max_len,
163 const struct ustr *ocu_i, 118 const uint8_t *ocu, int ocu_len,
164 int (*conv_f)(wchar_t, unsigned char *, int)) 119 int (*conv_f)(wchar_t, unsigned char *, int))
165{ 120{
166 const uint8_t *ocu; 121 uint8_t cmp_id;
167 uint8_t cmp_id, ocu_len;
168 int i, len; 122 int i, len;
123 int str_o_len = 0;
169 124
125 if (str_max_len <= 0)
126 return 0;
170 127
171 ocu_len = ocu_i->u_len;
172 if (ocu_len == 0) { 128 if (ocu_len == 0) {
173 memset(utf_o, 0, sizeof(struct ustr)); 129 memset(str_o, 0, str_max_len);
174 return 0; 130 return 0;
175 } 131 }
176 132
177 cmp_id = ocu_i->u_cmpID; 133 cmp_id = ocu[0];
178 if (cmp_id != 8 && cmp_id != 16) { 134 if (cmp_id != 8 && cmp_id != 16) {
179 memset(utf_o, 0, sizeof(struct ustr)); 135 memset(str_o, 0, str_max_len);
180 pr_err("unknown compression code (%d) stri=%s\n", 136 pr_err("unknown compression code (%d) stri=%s\n", cmp_id, ocu);
181 cmp_id, ocu_i->u_name);
182 return -EINVAL; 137 return -EINVAL;
183 } 138 }
184 139
185 ocu = ocu_i->u_name; 140 for (i = 1; (i < ocu_len) && (str_o_len < str_max_len);) {
186 utf_o->u_len = 0;
187 for (i = 0; (i < ocu_len) && (utf_o->u_len < UDF_NAME_LEN);) {
188 /* Expand OSTA compressed Unicode to Unicode */ 141 /* Expand OSTA compressed Unicode to Unicode */
189 uint32_t c = ocu[i++]; 142 uint32_t c = ocu[i++];
190 if (cmp_id == 16) 143 if (cmp_id == 16)
191 c = (c << 8) | ocu[i++]; 144 c = (c << 8) | ocu[i++];
192 145
193 len = conv_f(c, &utf_o->u_name[utf_o->u_len], 146 len = conv_f(c, &str_o[str_o_len], str_max_len - str_o_len);
194 UDF_NAME_LEN - utf_o->u_len);
195 /* Valid character? */ 147 /* Valid character? */
196 if (len >= 0) 148 if (len >= 0)
197 utf_o->u_len += len; 149 str_o_len += len;
198 else if (len == -ENAMETOOLONG) 150 else if (len == -ENAMETOOLONG)
199 break; 151 break;
200 else 152 else
201 utf_o->u_name[utf_o->u_len++] = '?'; 153 str_o[str_o_len++] = '?';
202 } 154 }
203 utf_o->u_cmpID = 8;
204 155
205 return utf_o->u_len; 156 return str_o_len;
206} 157}
207 158
208static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length, 159static int udf_name_to_CS0(uint8_t *ocu, int ocu_max_len,
160 const uint8_t *str_i, int str_len,
209 int (*conv_f)(const unsigned char *, int, wchar_t *)) 161 int (*conv_f)(const unsigned char *, int, wchar_t *))
210{ 162{
211 int i, len; 163 int i, len;
@@ -213,18 +165,21 @@ static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length,
213 wchar_t uni_char; 165 wchar_t uni_char;
214 int u_len, u_ch; 166 int u_len, u_ch;
215 167
216 memset(ocu, 0, sizeof(dstring) * length); 168 if (ocu_max_len <= 0)
169 return 0;
170
171 memset(ocu, 0, ocu_max_len);
217 ocu[0] = 8; 172 ocu[0] = 8;
218 max_val = 0xff; 173 max_val = 0xff;
219 u_ch = 1; 174 u_ch = 1;
220 175
221try_again: 176try_again:
222 u_len = 0; 177 u_len = 1;
223 for (i = 0; i < uni->u_len; i++) { 178 for (i = 0; i < str_len; i++) {
224 /* Name didn't fit? */ 179 /* Name didn't fit? */
225 if (u_len + 1 + u_ch >= length) 180 if (u_len + u_ch > ocu_max_len)
226 return 0; 181 return 0;
227 len = conv_f(&uni->u_name[i], uni->u_len - i, &uni_char); 182 len = conv_f(&str_i[i], str_len - i, &uni_char);
228 if (!len) 183 if (!len)
229 continue; 184 continue;
230 /* Invalid character, deal with it */ 185 /* Invalid character, deal with it */
@@ -241,41 +196,37 @@ try_again:
241 } 196 }
242 197
243 if (max_val == 0xffff) 198 if (max_val == 0xffff)
244 ocu[++u_len] = (uint8_t)(uni_char >> 8); 199 ocu[u_len++] = (uint8_t)(uni_char >> 8);
245 ocu[++u_len] = (uint8_t)(uni_char & 0xff); 200 ocu[u_len++] = (uint8_t)(uni_char & 0xff);
246 i += len - 1; 201 i += len - 1;
247 } 202 }
248 203
249 ocu[length - 1] = (uint8_t)u_len + 1; 204 return u_len;
250 return u_len + 1;
251} 205}
252 206
253int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i) 207int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len)
254{ 208{
255 return udf_name_from_CS0(utf_o, ocu_i, udf_uni2char_utf8); 209 return udf_name_from_CS0(utf_o, o_len, ocu_i, i_len,
210 udf_uni2char_utf8);
256} 211}
257 212
258int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, 213int udf_get_filename(struct super_block *sb, const uint8_t *sname, int slen,
259 uint8_t *dname, int dlen) 214 uint8_t *dname, int dlen)
260{ 215{
261 struct ustr *filename, *unifilename; 216 uint8_t *filename;
262 int (*conv_f)(wchar_t, unsigned char *, int); 217 int (*conv_f)(wchar_t, unsigned char *, int);
263 int ret; 218 int ret;
264 219
265 if (!slen) 220 if (!slen)
266 return -EIO; 221 return -EIO;
267 222
268 filename = kmalloc(sizeof(struct ustr), GFP_NOFS); 223 if (dlen <= 0)
224 return 0;
225
226 filename = kmalloc(dlen, GFP_NOFS);
269 if (!filename) 227 if (!filename)
270 return -ENOMEM; 228 return -ENOMEM;
271 229
272 unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS);
273 if (!unifilename) {
274 ret = -ENOMEM;
275 goto out1;
276 }
277
278 udf_build_ustr_exact(unifilename, sname, slen);
279 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { 230 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
280 conv_f = udf_uni2char_utf8; 231 conv_f = udf_uni2char_utf8;
281 } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { 232 } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
@@ -283,21 +234,18 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
283 } else 234 } else
284 BUG(); 235 BUG();
285 236
286 ret = udf_name_from_CS0(filename, unifilename, conv_f); 237 ret = udf_name_from_CS0(filename, dlen, sname, slen, conv_f);
287 if (ret < 0) { 238 if (ret < 0) {
288 udf_debug("Failed in udf_get_filename: sname = %s\n", sname); 239 udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
289 goto out2; 240 goto out2;
290 } 241 }
291 242
292 ret = udf_translate_to_linux(dname, dlen, 243 ret = udf_translate_to_linux(dname, dlen, filename, dlen,
293 filename->u_name, filename->u_len, 244 sname + 1, slen - 1);
294 unifilename->u_name, unifilename->u_len);
295 /* Zero length filename isn't valid... */ 245 /* Zero length filename isn't valid... */
296 if (ret == 0) 246 if (ret == 0)
297 ret = -EINVAL; 247 ret = -EINVAL;
298out2: 248out2:
299 kfree(unifilename);
300out1:
301 kfree(filename); 249 kfree(filename);
302 return ret; 250 return ret;
303} 251}
@@ -305,12 +253,8 @@ out1:
305int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen, 253int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen,
306 uint8_t *dname, int dlen) 254 uint8_t *dname, int dlen)
307{ 255{
308 struct ustr unifilename;
309 int (*conv_f)(const unsigned char *, int, wchar_t *); 256 int (*conv_f)(const unsigned char *, int, wchar_t *);
310 257
311 if (!udf_char_to_ustr(&unifilename, sname, slen))
312 return 0;
313
314 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { 258 if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
315 conv_f = udf_char2uni_utf8; 259 conv_f = udf_char2uni_utf8;
316 } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) { 260 } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
@@ -318,7 +262,7 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen,
318 } else 262 } else
319 BUG(); 263 BUG();
320 264
321 return udf_name_to_CS0(dname, &unifilename, dlen, conv_f); 265 return udf_name_to_CS0(dname, dlen, sname, slen, conv_f);
322} 266}
323 267
324#define ILLEGAL_CHAR_MARK '_' 268#define ILLEGAL_CHAR_MARK '_'
@@ -329,8 +273,8 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen,
329#define CRC_LEN 5 273#define CRC_LEN 5
330 274
331static int udf_translate_to_linux(uint8_t *newName, int newLen, 275static int udf_translate_to_linux(uint8_t *newName, int newLen,
332 uint8_t *udfName, int udfLen, 276 const uint8_t *udfName, int udfLen,
333 uint8_t *fidName, int fidNameLen) 277 const uint8_t *fidName, int fidNameLen)
334{ 278{
335 int index, newIndex = 0, needsCRC = 0; 279 int index, newIndex = 0, needsCRC = 0;
336 int extIndex = 0, newExtIndex = 0, hasExt = 0; 280 int extIndex = 0, newExtIndex = 0, hasExt = 0;