Skip to content

Commit 9293fcf

Browse files
agabbasovjankara
authored andcommitted
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>
1 parent 066b9cd commit 9293fcf

File tree

3 files changed

+61
-134
lines changed

3 files changed

+61
-134
lines changed

fs/udf/super.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -887,18 +887,14 @@ static int udf_find_fileset(struct super_block *sb,
887887
static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
888888
{
889889
struct primaryVolDesc *pvoldesc;
890-
struct ustr *instr, *outstr;
890+
uint8_t *outstr;
891891
struct buffer_head *bh;
892892
uint16_t ident;
893893
int ret = -ENOMEM;
894894

895-
instr = kmalloc(sizeof(struct ustr), GFP_NOFS);
896-
if (!instr)
897-
return -ENOMEM;
898-
899-
outstr = kmalloc(sizeof(struct ustr), GFP_NOFS);
895+
outstr = kmalloc(128, GFP_NOFS);
900896
if (!outstr)
901-
goto out1;
897+
return -ENOMEM;
902898

903899
bh = udf_read_tagged(sb, block, block, &ident);
904900
if (!bh) {
@@ -923,31 +919,25 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
923919
#endif
924920
}
925921

926-
if (!udf_build_ustr(instr, pvoldesc->volIdent, 32)) {
927-
ret = udf_CS0toUTF8(outstr, instr);
928-
if (ret < 0)
929-
goto out_bh;
922+
ret = udf_CS0toUTF8(outstr, 31, pvoldesc->volIdent, 32);
923+
if (ret < 0)
924+
goto out_bh;
930925

931-
strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name,
932-
outstr->u_len > 31 ? 31 : outstr->u_len);
933-
udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
934-
}
926+
strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
927+
udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
935928

936-
if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128)) {
937-
ret = udf_CS0toUTF8(outstr, instr);
938-
if (ret < 0)
939-
goto out_bh;
929+
ret = udf_CS0toUTF8(outstr, 127, pvoldesc->volSetIdent, 128);
930+
if (ret < 0)
931+
goto out_bh;
940932

941-
udf_debug("volSetIdent[] = '%s'\n", outstr->u_name);
942-
}
933+
outstr[ret] = 0;
934+
udf_debug("volSetIdent[] = '%s'\n", outstr);
943935

944936
ret = 0;
945937
out_bh:
946938
brelse(bh);
947939
out2:
948940
kfree(outstr);
949-
out1:
950-
kfree(instr);
951941
return ret;
952942
}
953943

fs/udf/udfdecl.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,6 @@ struct generic_desc {
106106
__le32 volDescSeqNum;
107107
};
108108

109-
struct ustr {
110-
uint8_t u_cmpID;
111-
uint8_t u_name[UDF_NAME_LEN];
112-
uint8_t u_len;
113-
};
114-
115109

116110
/* super.c */
117111

@@ -214,12 +208,11 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
214208
}
215209

216210
/* unicode.c */
217-
extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *,
218-
int);
211+
extern int udf_get_filename(struct super_block *, const uint8_t *, int,
212+
uint8_t *, int);
219213
extern int udf_put_filename(struct super_block *, const uint8_t *, int,
220214
uint8_t *, int);
221-
extern int udf_build_ustr(struct ustr *, dstring *, int);
222-
extern int udf_CS0toUTF8(struct ustr *, const struct ustr *);
215+
extern int udf_CS0toUTF8(uint8_t *, int, const uint8_t *, int);
223216

224217
/* ialloc.c */
225218
extern void udf_free_inode(struct inode *);

fs/udf/unicode.c

Lines changed: 45 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -28,53 +28,8 @@
2828

2929
#include "udf_sb.h"
3030

31-
static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *,
32-
int);
33-
34-
static 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-
*/
50-
int 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-
*/
71-
static 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-
}
31+
static int udf_translate_to_linux(uint8_t *, int, const uint8_t *, int,
32+
const uint8_t *, int);
7833

7934
static int udf_uni2char_utf8(wchar_t uni,
8035
unsigned char *out,
@@ -159,72 +114,72 @@ static int udf_char2uni_utf8(const unsigned char *in,
159114
return u_len;
160115
}
161116

162-
static int udf_name_from_CS0(struct ustr *utf_o,
163-
const struct ustr *ocu_i,
117+
static int udf_name_from_CS0(uint8_t *str_o, int str_max_len,
118+
const uint8_t *ocu, int ocu_len,
164119
int (*conv_f)(wchar_t, unsigned char *, int))
165120
{
166-
const uint8_t *ocu;
167-
uint8_t cmp_id, ocu_len;
121+
uint8_t cmp_id;
168122
int i, len;
123+
int str_o_len = 0;
169124

125+
if (str_max_len <= 0)
126+
return 0;
170127

171-
ocu_len = ocu_i->u_len;
172128
if (ocu_len == 0) {
173-
memset(utf_o, 0, sizeof(struct ustr));
129+
memset(str_o, 0, str_max_len);
174130
return 0;
175131
}
176132

177-
cmp_id = ocu_i->u_cmpID;
133+
cmp_id = ocu[0];
178134
if (cmp_id != 8 && cmp_id != 16) {
179-
memset(utf_o, 0, sizeof(struct ustr));
180-
pr_err("unknown compression code (%d) stri=%s\n",
181-
cmp_id, ocu_i->u_name);
135+
memset(str_o, 0, str_max_len);
136+
pr_err("unknown compression code (%d) stri=%s\n", cmp_id, ocu);
182137
return -EINVAL;
183138
}
184139

185-
ocu = ocu_i->u_name;
186-
utf_o->u_len = 0;
187-
for (i = 0; (i < ocu_len) && (utf_o->u_len < UDF_NAME_LEN);) {
140+
for (i = 1; (i < ocu_len) && (str_o_len < str_max_len);) {
188141
/* Expand OSTA compressed Unicode to Unicode */
189142
uint32_t c = ocu[i++];
190143
if (cmp_id == 16)
191144
c = (c << 8) | ocu[i++];
192145

193-
len = conv_f(c, &utf_o->u_name[utf_o->u_len],
194-
UDF_NAME_LEN - utf_o->u_len);
146+
len = conv_f(c, &str_o[str_o_len], str_max_len - str_o_len);
195147
/* Valid character? */
196148
if (len >= 0)
197-
utf_o->u_len += len;
149+
str_o_len += len;
198150
else if (len == -ENAMETOOLONG)
199151
break;
200152
else
201-
utf_o->u_name[utf_o->u_len++] = '?';
153+
str_o[str_o_len++] = '?';
202154
}
203-
utf_o->u_cmpID = 8;
204155

205-
return utf_o->u_len;
156+
return str_o_len;
206157
}
207158

208-
static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length,
159+
static int udf_name_to_CS0(uint8_t *ocu, int ocu_max_len,
160+
const uint8_t *str_i, int str_len,
209161
int (*conv_f)(const unsigned char *, int, wchar_t *))
210162
{
211163
int i, len;
212164
unsigned int max_val;
213165
wchar_t uni_char;
214166
int u_len, u_ch;
215167

216-
memset(ocu, 0, sizeof(dstring) * length);
168+
if (ocu_max_len <= 0)
169+
return 0;
170+
171+
memset(ocu, 0, ocu_max_len);
217172
ocu[0] = 8;
218173
max_val = 0xff;
219174
u_ch = 1;
220175

221176
try_again:
222-
u_len = 0;
223-
for (i = 0; i < uni->u_len; i++) {
177+
u_len = 1;
178+
for (i = 0; i < str_len; i++) {
224179
/* Name didn't fit? */
225-
if (u_len + 1 + u_ch >= length)
180+
if (u_len + u_ch > ocu_max_len)
226181
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);
228183
if (!len)
229184
continue;
230185
/* Invalid character, deal with it */
@@ -241,84 +196,73 @@ static int udf_name_to_CS0(dstring *ocu, struct ustr *uni, int length,
241196
}
242197

243198
if (max_val == 0xffff)
244-
ocu[++u_len] = (uint8_t)(uni_char >> 8);
245-
ocu[++u_len] = (uint8_t)(uni_char & 0xff);
199+
ocu[u_len++] = (uint8_t)(uni_char >> 8);
200+
ocu[u_len++] = (uint8_t)(uni_char & 0xff);
246201
i += len - 1;
247202
}
248203

249-
ocu[length - 1] = (uint8_t)u_len + 1;
250-
return u_len + 1;
204+
return u_len;
251205
}
252206

253-
int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
207+
int udf_CS0toUTF8(uint8_t *utf_o, int o_len, const uint8_t *ocu_i, int i_len)
254208
{
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);
256211
}
257212

258-
int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
213+
int udf_get_filename(struct super_block *sb, const uint8_t *sname, int slen,
259214
uint8_t *dname, int dlen)
260215
{
261-
struct ustr *filename, *unifilename;
216+
uint8_t *filename;
262217
int (*conv_f)(wchar_t, unsigned char *, int);
263218
int ret;
264219

265220
if (!slen)
266221
return -EIO;
267222

268-
filename = kmalloc(sizeof(struct ustr), GFP_NOFS);
223+
if (dlen <= 0)
224+
return 0;
225+
226+
filename = kmalloc(dlen, GFP_NOFS);
269227
if (!filename)
270228
return -ENOMEM;
271229

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);
279230
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
280231
conv_f = udf_uni2char_utf8;
281232
} else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
282233
conv_f = UDF_SB(sb)->s_nls_map->uni2char;
283234
} else
284235
BUG();
285236

286-
ret = udf_name_from_CS0(filename, unifilename, conv_f);
237+
ret = udf_name_from_CS0(filename, dlen, sname, slen, conv_f);
287238
if (ret < 0) {
288239
udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
289240
goto out2;
290241
}
291242

292-
ret = udf_translate_to_linux(dname, dlen,
293-
filename->u_name, filename->u_len,
294-
unifilename->u_name, unifilename->u_len);
243+
ret = udf_translate_to_linux(dname, dlen, filename, dlen,
244+
sname + 1, slen - 1);
295245
/* Zero length filename isn't valid... */
296246
if (ret == 0)
297247
ret = -EINVAL;
298248
out2:
299-
kfree(unifilename);
300-
out1:
301249
kfree(filename);
302250
return ret;
303251
}
304252

305253
int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen,
306254
uint8_t *dname, int dlen)
307255
{
308-
struct ustr unifilename;
309256
int (*conv_f)(const unsigned char *, int, wchar_t *);
310257

311-
if (!udf_char_to_ustr(&unifilename, sname, slen))
312-
return 0;
313-
314258
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
315259
conv_f = udf_char2uni_utf8;
316260
} else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
317261
conv_f = UDF_SB(sb)->s_nls_map->char2uni;
318262
} else
319263
BUG();
320264

321-
return udf_name_to_CS0(dname, &unifilename, dlen, conv_f);
265+
return udf_name_to_CS0(dname, dlen, sname, slen, conv_f);
322266
}
323267

324268
#define ILLEGAL_CHAR_MARK '_'
@@ -329,8 +273,8 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, int slen,
329273
#define CRC_LEN 5
330274

331275
static int udf_translate_to_linux(uint8_t *newName, int newLen,
332-
uint8_t *udfName, int udfLen,
333-
uint8_t *fidName, int fidNameLen)
276+
const uint8_t *udfName, int udfLen,
277+
const uint8_t *fidName, int fidNameLen)
334278
{
335279
int index, newIndex = 0, needsCRC = 0;
336280
int extIndex = 0, newExtIndex = 0, hasExt = 0;

0 commit comments

Comments
 (0)