1323 {
1328
1329 switch (bi->operation) {
1332 ERR(
"(%I64x,%x,%I64x) was %u bytes, expected at least %Iu\n", bi->key.obj_id, bi->key.obj_type, bi->key.offset, td->size,
sizeof(
DIR_ITEM));
1333 } else {
1338
1339 while (true) {
1341
1343 ERR(
"(%I64x,%x,%I64x) was truncated\n", bi->key.obj_id, bi->key.obj_type, bi->key.offset);
1344 break;
1345 }
1346
1347 oldxasize =
sizeof(
DIR_ITEM) - 1 + xa->m + xa->n;
1348
1351
1352
1353
1354 if (td->size + bi->datalen - oldxasize > maxlen)
1355 ERR(
"DIR_ITEM would be over maximum size, truncating (%u + %u - %lu > %u)\n", td->size, bi->datalen, oldxasize, maxlen);
1356
1358 if (!newdata) {
1359 ERR(
"out of memory\n");
1361 }
1362
1366
1370 } else
1372
1374
1375 bi->datalen = (
uint16_t)
min(td->size + bi->datalen - oldxasize, maxlen);
1376
1378 bi->data = newdata;
1379
1380 break;
1381 }
1382
1384
1385
1386 if (td->size + bi->datalen > maxlen)
1387 ERR(
"DIR_ITEM would be over maximum size, truncating (%u + %u > %u)\n", td->size, bi->datalen, maxlen);
1388
1390 if (!newdata) {
1391 ERR(
"out of memory\n");
1393 }
1394
1396
1399
1400 bi->datalen =
min(bi->datalen + td->size, maxlen);
1401
1403 bi->data = newdata;
1404
1405 break;
1406 } else {
1407 xa = (
DIR_ITEM*)&xa->name[xa->m + xa->n];
1409 }
1410 }
1411 }
1412 break;
1413 }
1414
1417
1418 if (td->size + bi->datalen > maxlen) {
1419 ERR(
"DIR_ITEM would be over maximum size (%u + %u > %u)\n", td->size, bi->datalen, maxlen);
1421 }
1422
1424 if (!newdata) {
1425 ERR(
"out of memory\n");
1427 }
1428
1430
1432
1433 bi->datalen += td->size;
1434
1436 bi->data = newdata;
1437
1438 break;
1439 }
1440
1443
1444 if (td->size + bi->datalen > maxlen) {
1451 bool inserted = false;
1452
1453 TRACE(
"INODE_REF would be too long, adding INODE_EXTREF instead\n");
1454
1456
1458 if (!ier) {
1459 ERR(
"out of memory\n");
1461 }
1462
1463 ier->dir = bi->key.offset;
1464 ier->index = ir->
index;
1467
1468 bi2 = ExAllocateFromPagedLookasideList(&
Vcb->batch_item_lookaside);
1469 if (!bi2) {
1470 ERR(
"out of memory\n");
1473 }
1474
1475 bi2->key.obj_id = bi->key.obj_id;
1478 bi2->data = ier;
1479 bi2->datalen = ierlen;
1481
1482 le = bi->list_entry.Flink;
1483 while (le != listhead) {
1485
1488 inserted = true;
1489 }
1490
1491 le = le->Flink;
1492 }
1493
1494 if (!inserted)
1496
1497 *ignore = true;
1499 } else {
1500 ERR(
"INODE_REF would be over maximum size (%u + %u > %u)\n", td->size, bi->datalen, maxlen);
1502 }
1503 }
1504
1506 if (!newdata) {
1507 ERR(
"out of memory\n");
1509 }
1510
1512
1514
1515 bi->datalen += td->size;
1516
1518 bi->data = newdata;
1519
1520 break;
1521 }
1522
1525
1526 if (td->size + bi->datalen > maxlen) {
1527 ERR(
"INODE_EXTREF would be over maximum size (%u + %u > %u)\n", td->size, bi->datalen, maxlen);
1529 }
1530
1532 if (!newdata) {
1533 ERR(
"out of memory\n");
1535 }
1536
1538
1540
1541 bi->datalen += td->size;
1542
1544 bi->data = newdata;
1545
1546 break;
1547 }
1548
1551 ERR(
"DIR_ITEM was %u bytes, expected at least %Iu\n", td->size,
sizeof(
DIR_ITEM));
1553 } else {
1556
1560
1561 do {
1564
1565 if (newlen == 0) {
1566 TRACE(
"deleting DIR_ITEM\n");
1567 } else {
1570
1571 if (!newdi) {
1572 ERR(
"out of memory\n");
1574 }
1575
1576 TRACE(
"modifying DIR_ITEM\n");
1577
1578 if ((
uint8_t*)di > td->data) {
1580 dioff = newdi + ((
uint8_t*)di - td->data);
1581 } else {
1582 dioff = newdi;
1583 }
1584
1585 if ((
uint8_t*)&di->
name[di->
n + di->
m] < td->data + td->size)
1587
1588 td2 = ExAllocateFromPagedLookasideList(&
Vcb->tree_data_lookaside);
1589 if (!td2) {
1590 ERR(
"out of memory\n");
1593 }
1594
1600
1602
1603 t->header.num_items++;
1606 }
1607
1608 break;
1609 }
1610
1613
1615 TRACE(
"could not find DIR_ITEM to delete\n");
1616 *ignore = true;
1618 }
1620 }
1621 break;
1622 }
1623
1626 ERR(
"INODE_REF was %u bytes, expected at least %Iu\n", td->size,
sizeof(
INODE_REF));
1628 } else {
1631 bool changed = false;
1632
1636
1637 do {
1639
1641 ERR(
"INODE_REF was truncated\n");
1642 break;
1643 }
1644
1646
1648 uint16_t newlen = td->size - itemlen;
1649
1650 changed = true;
1651
1652 if (newlen == 0)
1653 TRACE(
"deleting INODE_REF\n");
1654 else {
1657
1658 if (!newir) {
1659 ERR(
"out of memory\n");
1661 }
1662
1663 TRACE(
"modifying INODE_REF\n");
1664
1665 if ((
uint8_t*)ir > td->data) {
1667 iroff = newir + ((
uint8_t*)ir - td->data);
1668 } else {
1669 iroff = newir;
1670 }
1671
1674
1675 td2 = ExAllocateFromPagedLookasideList(&
Vcb->tree_data_lookaside);
1676 if (!td2) {
1677 ERR(
"out of memory\n");
1680 }
1681
1687
1689
1690 t->header.num_items++;
1693 }
1694
1695 break;
1696 }
1697
1698 if (
len > itemlen) {
1701 } else
1702 break;
1704
1705 if (!changed) {
1707 TRACE(
"entry in INODE_REF not found, adding Batch_DeleteInodeExtRef entry\n");
1708
1709 add_delete_inode_extref(
Vcb, bi, listhead);
1710
1711 *ignore = true;
1713 } else
1714 WARN(
"entry not found in INODE_REF\n");
1715 }
1716 }
1717
1718 break;
1719 }
1720
1723 ERR(
"INODE_EXTREF was %u bytes, expected at least %Iu\n", td->size,
sizeof(
INODE_EXTREF));
1725 } else {
1728
1732
1733 do {
1735
1737 ERR(
"INODE_REF was truncated\n");
1738 break;
1739 }
1740
1742
1744 uint16_t newlen = td->size - itemlen;
1745
1746 if (newlen == 0)
1747 TRACE(
"deleting INODE_EXTREF\n");
1748 else {
1751
1752 if (!newier) {
1753 ERR(
"out of memory\n");
1755 }
1756
1757 TRACE(
"modifying INODE_EXTREF\n");
1758
1759 if ((
uint8_t*)ier > td->data) {
1761 ieroff = newier + ((
uint8_t*)ier - td->data);
1762 } else {
1763 ieroff = newier;
1764 }
1765
1766 if ((
uint8_t*)&ier->
name[ier->
n] < td->data + td->size)
1768
1769 td2 = ExAllocateFromPagedLookasideList(&
Vcb->tree_data_lookaside);
1770 if (!td2) {
1771 ERR(
"out of memory\n");
1774 }
1775
1781
1783
1784 t->header.num_items++;
1787 }
1788
1789 break;
1790 }
1791
1792 if (
len > itemlen) {
1795 } else
1796 break;
1798 }
1799 break;
1800 }
1801
1804 ERR(
"XATTR_ITEM was %u bytes, expected at least %Iu\n", td->size,
sizeof(
DIR_ITEM));
1806 } else {
1809
1813
1814 do {
1817
1818 if (newlen == 0)
1819 TRACE(
"deleting XATTR_ITEM\n");
1820 else {
1823
1824 if (!newdi) {
1825 ERR(
"out of memory\n");
1827 }
1828
1829 TRACE(
"modifying XATTR_ITEM\n");
1830
1831 if ((
uint8_t*)di > td->data) {
1833 dioff = newdi + ((
uint8_t*)di - td->data);
1834 } else
1835 dioff = newdi;
1836
1837 if ((
uint8_t*)&di->
name[di->
n + di->
m] < td->data + td->size)
1839
1840 td2 = ExAllocateFromPagedLookasideList(&
Vcb->tree_data_lookaside);
1841 if (!td2) {
1842 ERR(
"out of memory\n");
1845 }
1846
1852
1854
1855 t->header.num_items++;
1858 }
1859
1860 break;
1861 }
1862
1865
1867 TRACE(
"could not find DIR_ITEM to delete\n");
1868 *ignore = true;
1870 }
1872 }
1873 break;
1874 }
1875
1877 break;
1878
1879 default:
1880 ERR(
"unexpected batch operation type\n");
1882 }
1883
1884
1885 if (!td->ignore) {
1886 td->ignore = true;
1887
1888 t->header.num_items--;
1891 }
1892
1893 if (newtd) {
1894 newtd->data = bi->data;
1895 newtd->size = bi->datalen;
1897 }
1898 } else {
1899 ERR(
"(%I64x,%x,%I64x) already exists\n", bi->key.obj_id, bi->key.obj_type, bi->key.offset);
1901 }
1902
1903 *ignore = false;
1905}
unsigned short int uint16_t
@ Batch_DeleteInodeExtRef
#define keycmp(key1, key2)
#define TYPE_INODE_EXTREF
#define BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define RtlCompareMemory(s1, s2, l)
#define STATUS_INTERNAL_ERROR
#define offsetof(TYPE, MEMBER)
#define RtlCopyMemory(Destination, Source, Length)