@@ -2195,7 +2195,7 @@ static void target_complete_ok_work(struct work_struct *work)
2195
2195
transport_handle_queue_full (cmd , cmd -> se_dev );
2196
2196
}
2197
2197
2198
- static inline void transport_free_sgl (struct scatterlist * sgl , int nents )
2198
+ void target_free_sgl (struct scatterlist * sgl , int nents )
2199
2199
{
2200
2200
struct scatterlist * sg ;
2201
2201
int count ;
@@ -2205,6 +2205,7 @@ static inline void transport_free_sgl(struct scatterlist *sgl, int nents)
2205
2205
2206
2206
kfree (sgl );
2207
2207
}
2208
+ EXPORT_SYMBOL (target_free_sgl );
2208
2209
2209
2210
static inline void transport_reset_sgl_orig (struct se_cmd * cmd )
2210
2211
{
@@ -2225,7 +2226,7 @@ static inline void transport_reset_sgl_orig(struct se_cmd *cmd)
2225
2226
static inline void transport_free_pages (struct se_cmd * cmd )
2226
2227
{
2227
2228
if (!(cmd -> se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC )) {
2228
- transport_free_sgl (cmd -> t_prot_sg , cmd -> t_prot_nents );
2229
+ target_free_sgl (cmd -> t_prot_sg , cmd -> t_prot_nents );
2229
2230
cmd -> t_prot_sg = NULL ;
2230
2231
cmd -> t_prot_nents = 0 ;
2231
2232
}
@@ -2236,7 +2237,7 @@ static inline void transport_free_pages(struct se_cmd *cmd)
2236
2237
* SG_TO_MEM_NOALLOC to function with COMPARE_AND_WRITE
2237
2238
*/
2238
2239
if (cmd -> se_cmd_flags & SCF_COMPARE_AND_WRITE ) {
2239
- transport_free_sgl (cmd -> t_bidi_data_sg ,
2240
+ target_free_sgl (cmd -> t_bidi_data_sg ,
2240
2241
cmd -> t_bidi_data_nents );
2241
2242
cmd -> t_bidi_data_sg = NULL ;
2242
2243
cmd -> t_bidi_data_nents = 0 ;
@@ -2246,11 +2247,11 @@ static inline void transport_free_pages(struct se_cmd *cmd)
2246
2247
}
2247
2248
transport_reset_sgl_orig (cmd );
2248
2249
2249
- transport_free_sgl (cmd -> t_data_sg , cmd -> t_data_nents );
2250
+ target_free_sgl (cmd -> t_data_sg , cmd -> t_data_nents );
2250
2251
cmd -> t_data_sg = NULL ;
2251
2252
cmd -> t_data_nents = 0 ;
2252
2253
2253
- transport_free_sgl (cmd -> t_bidi_data_sg , cmd -> t_bidi_data_nents );
2254
+ target_free_sgl (cmd -> t_bidi_data_sg , cmd -> t_bidi_data_nents );
2254
2255
cmd -> t_bidi_data_sg = NULL ;
2255
2256
cmd -> t_bidi_data_nents = 0 ;
2256
2257
}
@@ -2324,20 +2325,22 @@ EXPORT_SYMBOL(transport_kunmap_data_sg);
2324
2325
2325
2326
int
2326
2327
target_alloc_sgl (struct scatterlist * * sgl , unsigned int * nents , u32 length ,
2327
- bool zero_page )
2328
+ bool zero_page , bool chainable )
2328
2329
{
2329
2330
struct scatterlist * sg ;
2330
2331
struct page * page ;
2331
2332
gfp_t zero_flag = (zero_page ) ? __GFP_ZERO : 0 ;
2332
- unsigned int nent ;
2333
+ unsigned int nalloc , nent ;
2333
2334
int i = 0 ;
2334
2335
2335
- nent = DIV_ROUND_UP (length , PAGE_SIZE );
2336
- sg = kmalloc (sizeof (struct scatterlist ) * nent , GFP_KERNEL );
2336
+ nalloc = nent = DIV_ROUND_UP (length , PAGE_SIZE );
2337
+ if (chainable )
2338
+ nalloc ++ ;
2339
+ sg = kmalloc_array (nalloc , sizeof (struct scatterlist ), GFP_KERNEL );
2337
2340
if (!sg )
2338
2341
return - ENOMEM ;
2339
2342
2340
- sg_init_table (sg , nent );
2343
+ sg_init_table (sg , nalloc );
2341
2344
2342
2345
while (length ) {
2343
2346
u32 page_len = min_t (u32 , length , PAGE_SIZE );
@@ -2361,6 +2364,7 @@ target_alloc_sgl(struct scatterlist **sgl, unsigned int *nents, u32 length,
2361
2364
kfree (sg );
2362
2365
return - ENOMEM ;
2363
2366
}
2367
+ EXPORT_SYMBOL (target_alloc_sgl );
2364
2368
2365
2369
/*
2366
2370
* Allocate any required resources to execute the command. For writes we
@@ -2376,7 +2380,7 @@ transport_generic_new_cmd(struct se_cmd *cmd)
2376
2380
if (cmd -> prot_op != TARGET_PROT_NORMAL &&
2377
2381
!(cmd -> se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC )) {
2378
2382
ret = target_alloc_sgl (& cmd -> t_prot_sg , & cmd -> t_prot_nents ,
2379
- cmd -> prot_length , true);
2383
+ cmd -> prot_length , true, false );
2380
2384
if (ret < 0 )
2381
2385
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE ;
2382
2386
}
@@ -2401,13 +2405,13 @@ transport_generic_new_cmd(struct se_cmd *cmd)
2401
2405
2402
2406
ret = target_alloc_sgl (& cmd -> t_bidi_data_sg ,
2403
2407
& cmd -> t_bidi_data_nents ,
2404
- bidi_length , zero_flag );
2408
+ bidi_length , zero_flag , false );
2405
2409
if (ret < 0 )
2406
2410
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE ;
2407
2411
}
2408
2412
2409
2413
ret = target_alloc_sgl (& cmd -> t_data_sg , & cmd -> t_data_nents ,
2410
- cmd -> data_length , zero_flag );
2414
+ cmd -> data_length , zero_flag , false );
2411
2415
if (ret < 0 )
2412
2416
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE ;
2413
2417
} else if ((cmd -> se_cmd_flags & SCF_COMPARE_AND_WRITE ) &&
@@ -2421,7 +2425,7 @@ transport_generic_new_cmd(struct se_cmd *cmd)
2421
2425
2422
2426
ret = target_alloc_sgl (& cmd -> t_bidi_data_sg ,
2423
2427
& cmd -> t_bidi_data_nents ,
2424
- caw_length , zero_flag );
2428
+ caw_length , zero_flag , false );
2425
2429
if (ret < 0 )
2426
2430
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE ;
2427
2431
}
0 commit comments