@@ -231,67 +231,61 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
231
231
prt_printf (out , " type %s" , bch2_d_type_str (d .v -> d_type ));
232
232
}
233
233
234
- static struct bkey_i_dirent * dirent_alloc_key (struct btree_trans * trans ,
235
- subvol_inum dir ,
236
- u8 type ,
237
- int name_len , int cf_name_len ,
238
- u64 dst )
234
+ int bch2_dirent_init_name (struct bkey_i_dirent * dirent ,
235
+ const struct bch_hash_info * hash_info ,
236
+ const struct qstr * name ,
237
+ const struct qstr * cf_name )
239
238
{
240
- struct bkey_i_dirent * dirent ;
241
- unsigned u64s = BKEY_U64s + dirent_val_u64s ( name_len , cf_name_len ) ;
239
+ EBUG_ON ( hash_info -> cf_encoding == NULL && cf_name ) ;
240
+ int cf_len = 0 ;
242
241
243
- BUG_ON (u64s > U8_MAX );
244
-
245
- dirent = bch2_trans_kmalloc (trans , u64s * sizeof (u64 ));
246
- if (IS_ERR (dirent ))
247
- return dirent ;
242
+ if (name -> len > BCH_NAME_MAX )
243
+ return - ENAMETOOLONG ;
248
244
249
- bkey_dirent_init (& dirent -> k_i );
250
- dirent -> k .u64s = u64s ;
245
+ dirent -> v .d_casefold = hash_info -> cf_encoding != NULL ;
251
246
252
- if (type != DT_SUBVOL ) {
253
- dirent -> v .d_inum = cpu_to_le64 (dst );
247
+ if (!dirent -> v .d_casefold ) {
248
+ memcpy (& dirent -> v .d_name [0 ], name -> name , name -> len );
249
+ memset (& dirent -> v .d_name [name -> len ], 0 ,
250
+ bkey_val_bytes (& dirent -> k ) -
251
+ offsetof(struct bch_dirent , d_name ) -
252
+ name -> len );
254
253
} else {
255
- dirent -> v .d_parent_subvol = cpu_to_le32 (dir .subvol );
256
- dirent -> v .d_child_subvol = cpu_to_le32 (dst );
257
- }
254
+ #ifdef CONFIG_UNICODE
255
+ memcpy (& dirent -> v .d_cf_name_block .d_names [0 ], name -> name , name -> len );
258
256
259
- dirent -> v .d_type = type ;
260
- dirent -> v .d_unused = 0 ;
261
- dirent -> v .d_casefold = cf_name_len ? 1 : 0 ;
257
+ char * cf_out = & dirent -> v .d_cf_name_block .d_names [name -> len ];
262
258
263
- return dirent ;
264
- }
259
+ if ( cf_name ) {
260
+ cf_len = cf_name -> len ;
265
261
266
- static void dirent_init_regular_name (struct bkey_i_dirent * dirent ,
267
- const struct qstr * name )
268
- {
269
- EBUG_ON (dirent -> v .d_casefold );
262
+ memcpy (cf_out , cf_name -> name , cf_name -> len );
263
+ } else {
264
+ cf_len = utf8_casefold (hash_info -> cf_encoding , name ,
265
+ cf_out ,
266
+ bkey_val_end (bkey_i_to_s (& dirent -> k_i )) - (void * ) cf_out );
267
+ if (cf_len <= 0 )
268
+ return cf_len ;
269
+ }
270
270
271
- memcpy (& dirent -> v .d_name [0 ], name -> name , name -> len );
272
- memset (& dirent -> v .d_name [name -> len ], 0 ,
273
- bkey_val_bytes (& dirent -> k ) -
274
- offsetof(struct bch_dirent , d_name ) -
275
- name -> len );
276
- }
271
+ memset (& dirent -> v .d_cf_name_block .d_names [name -> len + cf_len ], 0 ,
272
+ bkey_val_bytes (& dirent -> k ) -
273
+ offsetof(struct bch_dirent , d_cf_name_block .d_names ) -
274
+ name -> len + cf_len );
277
275
278
- static void dirent_init_casefolded_name (struct bkey_i_dirent * dirent ,
279
- const struct qstr * name ,
280
- const struct qstr * cf_name )
281
- {
282
- EBUG_ON (!dirent -> v .d_casefold );
283
- EBUG_ON (!cf_name -> len );
284
-
285
- dirent -> v .d_cf_name_block .d_name_len = cpu_to_le16 (name -> len );
286
- dirent -> v .d_cf_name_block .d_cf_name_len = cpu_to_le16 (cf_name -> len );
287
- memcpy (& dirent -> v .d_cf_name_block .d_names [0 ], name -> name , name -> len );
288
- memcpy (& dirent -> v .d_cf_name_block .d_names [name -> len ], cf_name -> name , cf_name -> len );
289
- memset (& dirent -> v .d_cf_name_block .d_names [name -> len + cf_name -> len ], 0 ,
290
- bkey_val_bytes (& dirent -> k ) -
291
- offsetof(struct bch_dirent , d_cf_name_block .d_names ) -
292
- name -> len + cf_name -> len );
293
-
294
- EBUG_ON (bch2_dirent_get_casefold_name (dirent_i_to_s_c (dirent )).len != cf_name -> len );
276
+ dirent -> v .d_cf_name_block .d_name_len = cpu_to_le16 (name -> len );
277
+ dirent -> v .d_cf_name_block .d_cf_name_len = cpu_to_le16 (cf_len );
278
+
279
+ EBUG_ON (bch2_dirent_get_casefold_name (dirent_i_to_s_c (dirent )).len != cf_len );
280
+ #else
281
+ return - EOPNOTSUPP ;
282
+ #endif
283
+ }
284
+
285
+ unsigned u64s = dirent_val_u64s (name -> len , cf_len );
286
+ BUG_ON (u64s > bkey_val_u64s (& dirent -> k ));
287
+ set_bkey_val_u64s (& dirent -> k , u64s );
288
+ return 0 ;
295
289
}
296
290
297
291
static struct bkey_i_dirent * dirent_create_key (struct btree_trans * trans ,
@@ -302,31 +296,28 @@ static struct bkey_i_dirent *dirent_create_key(struct btree_trans *trans,
302
296
const struct qstr * cf_name ,
303
297
u64 dst )
304
298
{
305
- struct bkey_i_dirent * dirent ;
306
- struct qstr _cf_name ;
307
-
308
- if (name -> len > BCH_NAME_MAX )
309
- return ERR_PTR (- ENAMETOOLONG );
299
+ struct bkey_i_dirent * dirent = bch2_trans_kmalloc (trans , BKEY_U64s_MAX * sizeof (u64 ));
300
+ if (IS_ERR (dirent ))
301
+ return dirent ;
310
302
311
- if (hash_info -> cf_encoding && !cf_name ) {
312
- int ret = bch2_casefold (trans , hash_info , name , & _cf_name );
313
- if (ret )
314
- return ERR_PTR (ret );
303
+ bkey_dirent_init (& dirent -> k_i );
304
+ dirent -> k .u64s = BKEY_U64s_MAX ;
315
305
316
- cf_name = & _cf_name ;
306
+ if (type != DT_SUBVOL ) {
307
+ dirent -> v .d_inum = cpu_to_le64 (dst );
308
+ } else {
309
+ dirent -> v .d_parent_subvol = cpu_to_le32 (dir .subvol );
310
+ dirent -> v .d_child_subvol = cpu_to_le32 (dst );
317
311
}
318
312
319
- dirent = dirent_alloc_key (trans , dir , type , name -> len , cf_name ? cf_name -> len : 0 , dst );
320
- if (IS_ERR (dirent ))
321
- return dirent ;
313
+ dirent -> v .d_type = type ;
314
+ dirent -> v .d_unused = 0 ;
322
315
323
- if (cf_name )
324
- dirent_init_casefolded_name (dirent , name , cf_name );
325
- else
326
- dirent_init_regular_name (dirent , name );
316
+ int ret = bch2_dirent_init_name (dirent , hash_info , name , cf_name );
317
+ if (ret )
318
+ return ERR_PTR (ret );
327
319
328
320
EBUG_ON (bch2_dirent_get_name (dirent_i_to_s_c (dirent )).len != name -> len );
329
-
330
321
return dirent ;
331
322
}
332
323
0 commit comments