@@ -1339,6 +1339,84 @@ static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry,
1339
1339
memmove (to , from , n );
1340
1340
}
1341
1341
1342
+ /*
1343
+ * Move xattr pointed to by 'entry' from inode into external xattr block
1344
+ */
1345
+ static int ext4_xattr_move_to_block (handle_t * handle , struct inode * inode ,
1346
+ struct ext4_inode * raw_inode ,
1347
+ struct ext4_xattr_entry * entry )
1348
+ {
1349
+ struct ext4_xattr_ibody_find * is = NULL ;
1350
+ struct ext4_xattr_block_find * bs = NULL ;
1351
+ char * buffer = NULL , * b_entry_name = NULL ;
1352
+ size_t value_offs , value_size ;
1353
+ struct ext4_xattr_info i = {
1354
+ .value = NULL ,
1355
+ .value_len = 0 ,
1356
+ .name_index = entry -> e_name_index ,
1357
+ };
1358
+ struct ext4_xattr_ibody_header * header = IHDR (inode , raw_inode );
1359
+ int error ;
1360
+
1361
+ value_offs = le16_to_cpu (entry -> e_value_offs );
1362
+ value_size = le32_to_cpu (entry -> e_value_size );
1363
+
1364
+ is = kzalloc (sizeof (struct ext4_xattr_ibody_find ), GFP_NOFS );
1365
+ bs = kzalloc (sizeof (struct ext4_xattr_block_find ), GFP_NOFS );
1366
+ buffer = kmalloc (value_size , GFP_NOFS );
1367
+ b_entry_name = kmalloc (entry -> e_name_len + 1 , GFP_NOFS );
1368
+ if (!is || !bs || !buffer || !b_entry_name ) {
1369
+ error = - ENOMEM ;
1370
+ goto out ;
1371
+ }
1372
+
1373
+ is -> s .not_found = - ENODATA ;
1374
+ bs -> s .not_found = - ENODATA ;
1375
+ is -> iloc .bh = NULL ;
1376
+ bs -> bh = NULL ;
1377
+
1378
+ /* Save the entry name and the entry value */
1379
+ memcpy (buffer , (void * )IFIRST (header ) + value_offs , value_size );
1380
+ memcpy (b_entry_name , entry -> e_name , entry -> e_name_len );
1381
+ b_entry_name [entry -> e_name_len ] = '\0' ;
1382
+ i .name = b_entry_name ;
1383
+
1384
+ error = ext4_get_inode_loc (inode , & is -> iloc );
1385
+ if (error )
1386
+ goto out ;
1387
+
1388
+ error = ext4_xattr_ibody_find (inode , & i , is );
1389
+ if (error )
1390
+ goto out ;
1391
+
1392
+ /* Remove the chosen entry from the inode */
1393
+ error = ext4_xattr_ibody_set (handle , inode , & i , is );
1394
+ if (error )
1395
+ goto out ;
1396
+
1397
+ i .name = b_entry_name ;
1398
+ i .value = buffer ;
1399
+ i .value_len = value_size ;
1400
+ error = ext4_xattr_block_find (inode , & i , bs );
1401
+ if (error )
1402
+ goto out ;
1403
+
1404
+ /* Add entry which was removed from the inode into the block */
1405
+ error = ext4_xattr_block_set (handle , inode , & i , bs );
1406
+ if (error )
1407
+ goto out ;
1408
+ error = 0 ;
1409
+ out :
1410
+ kfree (b_entry_name );
1411
+ kfree (buffer );
1412
+ if (is )
1413
+ brelse (is -> iloc .bh );
1414
+ kfree (is );
1415
+ kfree (bs );
1416
+
1417
+ return error ;
1418
+ }
1419
+
1342
1420
/*
1343
1421
* Expand an inode by new_extra_isize bytes when EAs are present.
1344
1422
* Returns 0 on success or negative error number on failure.
@@ -1349,9 +1427,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
1349
1427
struct ext4_xattr_ibody_header * header ;
1350
1428
struct ext4_xattr_entry * entry , * last , * first ;
1351
1429
struct buffer_head * bh = NULL ;
1352
- struct ext4_xattr_ibody_find * is = NULL ;
1353
- struct ext4_xattr_block_find * bs = NULL ;
1354
- char * buffer = NULL , * b_entry_name = NULL ;
1355
1430
size_t min_offs ;
1356
1431
size_t ifree , bfree ;
1357
1432
int total_ino ;
@@ -1427,27 +1502,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
1427
1502
}
1428
1503
1429
1504
while (isize_diff > ifree ) {
1430
- size_t offs , size , entry_size ;
1431
1505
struct ext4_xattr_entry * small_entry = NULL ;
1432
- struct ext4_xattr_info i = {
1433
- .value = NULL ,
1434
- .value_len = 0 ,
1435
- };
1436
- unsigned int total_size ; /* EA entry size + value size */
1506
+ unsigned int entry_size ; /* EA entry size */
1507
+ unsigned int total_size ; /* EA entry size + value size */
1437
1508
unsigned int min_total_size = ~0U ;
1438
1509
1439
- is = kzalloc (sizeof (struct ext4_xattr_ibody_find ), GFP_NOFS );
1440
- bs = kzalloc (sizeof (struct ext4_xattr_block_find ), GFP_NOFS );
1441
- if (!is || !bs ) {
1442
- error = - ENOMEM ;
1443
- goto cleanup ;
1444
- }
1445
-
1446
- is -> s .not_found = - ENODATA ;
1447
- bs -> s .not_found = - ENODATA ;
1448
- is -> iloc .bh = NULL ;
1449
- bs -> bh = NULL ;
1450
-
1451
1510
last = IFIRST (header );
1452
1511
/* Find the entry best suited to be pushed into EA block */
1453
1512
entry = NULL ;
@@ -1474,67 +1533,25 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
1474
1533
s_min_extra_isize ) {
1475
1534
tried_min_extra_isize ++ ;
1476
1535
new_extra_isize = s_min_extra_isize ;
1477
- kfree (is ); is = NULL ;
1478
- kfree (bs ); bs = NULL ;
1479
1536
brelse (bh );
1480
1537
goto retry ;
1481
1538
}
1482
1539
error = -1 ;
1483
1540
goto cleanup ;
1484
1541
}
1485
1542
}
1486
- offs = le16_to_cpu (entry -> e_value_offs );
1487
- size = le32_to_cpu (entry -> e_value_size );
1488
- entry_size = EXT4_XATTR_LEN (entry -> e_name_len );
1489
- total_size = entry_size + EXT4_XATTR_SIZE (size );
1490
- i .name_index = entry -> e_name_index ,
1491
- buffer = kmalloc (EXT4_XATTR_SIZE (size ), GFP_NOFS );
1492
- b_entry_name = kmalloc (entry -> e_name_len + 1 , GFP_NOFS );
1493
- if (!buffer || !b_entry_name ) {
1494
- error = - ENOMEM ;
1495
- goto cleanup ;
1496
- }
1497
- /* Save the entry name and the entry value */
1498
- memcpy (buffer , (void * )IFIRST (header ) + offs ,
1499
- EXT4_XATTR_SIZE (size ));
1500
- memcpy (b_entry_name , entry -> e_name , entry -> e_name_len );
1501
- b_entry_name [entry -> e_name_len ] = '\0' ;
1502
- i .name = b_entry_name ;
1503
-
1504
- error = ext4_get_inode_loc (inode , & is -> iloc );
1505
- if (error )
1506
- goto cleanup ;
1507
1543
1508
- error = ext4_xattr_ibody_find (inode , & i , is );
1544
+ entry_size = EXT4_XATTR_LEN (entry -> e_name_len );
1545
+ total_size = entry_size +
1546
+ EXT4_XATTR_SIZE (le32_to_cpu (entry -> e_value_size ));
1547
+ error = ext4_xattr_move_to_block (handle , inode , raw_inode ,
1548
+ entry );
1509
1549
if (error )
1510
1550
goto cleanup ;
1511
1551
1512
- /* Remove the chosen entry from the inode */
1513
- error = ext4_xattr_ibody_set (handle , inode , & i , is );
1514
- if (error )
1515
- goto cleanup ;
1516
1552
total_ino -= entry_size ;
1517
1553
ifree += total_size ;
1518
1554
bfree -= total_size ;
1519
-
1520
- i .name = b_entry_name ;
1521
- i .value = buffer ;
1522
- i .value_len = size ;
1523
- error = ext4_xattr_block_find (inode , & i , bs );
1524
- if (error )
1525
- goto cleanup ;
1526
-
1527
- /* Add entry which was removed from the inode into the block */
1528
- error = ext4_xattr_block_set (handle , inode , & i , bs );
1529
- if (error )
1530
- goto cleanup ;
1531
- kfree (b_entry_name );
1532
- kfree (buffer );
1533
- b_entry_name = NULL ;
1534
- buffer = NULL ;
1535
- brelse (is -> iloc .bh );
1536
- kfree (is );
1537
- kfree (bs );
1538
1555
}
1539
1556
1540
1557
shift :
@@ -1552,12 +1569,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
1552
1569
return 0 ;
1553
1570
1554
1571
cleanup :
1555
- kfree (b_entry_name );
1556
- kfree (buffer );
1557
- if (is )
1558
- brelse (is -> iloc .bh );
1559
- kfree (is );
1560
- kfree (bs );
1561
1572
brelse (bh );
1562
1573
/*
1563
1574
* We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
0 commit comments