20#define SCRUB_UNIT 0x100000
53 bool orig_subvol =
true, not_in_tree =
false;
59 le =
Vcb->roots.Flink;
60 while (le != &
Vcb->roots) {
63 if (
r2->id == subvol) {
72 ERR(
"could not find subvol %I64x\n", subvol);
81 if (
dir ==
r->root_item.objid) {
82 if (
r ==
Vcb->root_fileref->fcb->subvol)
87 searchkey.
offset = 0xffffffffffffffff;
91 ERR(
"find_item returned %08lx\n",
Status);
112 ERR(
"out of memory\n");
116 pp->name.Buffer = rr->
name;
117 pp->name.Length = pp->name.MaximumLength = rr->
n;
118 pp->orig_subvol =
false;
124 le =
Vcb->roots.Flink;
125 while (le != &
Vcb->roots) {
150 searchkey.
offset = 0xffffffffffffffff;
154 ERR(
"find_item returned %08lx\n",
Status);
175 ERR(
"out of memory\n");
179 pp->name.Buffer = ir->
name;
180 pp->name.Length = pp->name.MaximumLength = ir->
n;
181 pp->orig_subvol = orig_subvol;
207 ERR(
"out of memory\n");
211 pp->name.Buffer = ier->
name;
212 pp->name.Length = pp->name.MaximumLength = ier->
n;
213 pp->orig_subvol = orig_subvol;
222 ERR(
"could not find INODE_REF for inode %I64x in subvol %I64x\n",
dir,
r->id);
228 fn.MaximumLength = 0;
232 while (le != &
parts) {
247 while (le != &
parts) {
257 ERR(
"out of memory\n");
264 while (le != &
parts) {
267 fn.Buffer[
fn.Length] =
'\\';
277 ERR(
"subvol %I64x, %.*s, offset %I64x\n", subvol,
fn.Length,
fn.Buffer,
offset);
283 ERR(
"utf8_to_utf16 1 returned %08lx\n",
Status);
290 ERR(
"out of memory\n");
297 err->recovered =
false;
298 err->is_metadata =
false;
301 err->data.subvol = not_in_tree ? subvol : 0;
307 ERR(
"utf8_to_utf16 2 returned %08lx\n",
Status);
315 Vcb->scrub.num_errors++;
338 ERR(
"out of memory\n");
342 Status =
read_data(
Vcb, treeaddr,
Vcb->superblock.node_size,
NULL,
true, (
uint8_t*)
tree,
NULL,
NULL,
NULL, 0,
false,
NormalPagePriority);
344 ERR(
"read_data returned %08lx\n",
Status);
348 if (
tree->level != 0) {
349 ERR(
"tree level was %x, expected 0\n",
tree->level);
355 for (
i = 0;
i <
tree->num_items;
i++) {
374 ERR(
"out of memory\n");
380 err->recovered =
false;
381 err->is_metadata =
true;
388 ERR(
"root %I64x, level %u, first item (%I64x,%x,%I64x)\n",
root,
level, firstitem->
obj_id,
391 err->metadata.firstitem = *firstitem;
400 Vcb->scrub.num_errors++;
414 ERR(
"out of memory\n");
418 Status =
read_data(
Vcb,
offset,
Vcb->superblock.node_size,
NULL,
true, (
uint8_t*)
tree,
NULL,
NULL,
NULL, 0,
false,
NormalPagePriority);
420 ERR(
"read_data returned %08lx\n",
Status);
424 if (
tree->level == 0) {
425 ERR(
"tree level was 0\n");
431 for (
i = 0;
i <
tree->num_items;
i++) {
456 searchkey.
offset = 0xffffffffffffffff;
460 ERR(
"find_item returned %08lx\n",
Status);
505 ERR(
"TREE_BLOCK_REF takes up %Iu bytes, but only %lu remaining\n",
sizeof(
TREE_BLOCK_REF),
len);
566 ERR(
"unknown extent type %x\n",
type);
571 if (rc < ei->refcount) {
610 ERR(
"recovering from parity error at %I64x on device %I64x\n",
addr, devid);
613 ERR(
"recovering from metadata checksum error at %I64x on device %I64x\n",
addr, devid);
615 ERR(
"recovering from data checksum error at %I64x on device %I64x\n",
addr, devid);
620 ERR(
"out of memory\n");
626 err->recovered =
true;
628 err->parity = parity;
637 Vcb->scrub.num_errors++;
643 ERR(
"unrecoverable metadata checksum error at %I64x\n",
addr);
645 ERR(
"unrecoverable data checksum error at %I64x\n",
addr);
669 bool csum_error =
false;
675 ULONG good_stripe = 0xffffffff;
677 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
678 if (
c->devices[
i]->devobj) {
682 if (good_stripe != 0xffffffff) {
685 context->stripes[
i].csum_error =
true;
692 context->stripes[
i].csum_error =
true;
696 ERR(
"check_csum returned %08lx\n",
Status);
704 ULONG good_stripe = 0xffffffff;
706 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
709 if (
c->devices[
i]->devobj) {
711 if (good_stripe != 0xffffffff) {
714 context->stripes[
i].csum_error =
true;
719 for (
j = 0;
j <
context->stripes[
i].length /
Vcb->superblock.node_size;
j++) {
723 context->stripes[
i].csum_error =
true;
729 if (!
context->stripes[
i].csum_error)
741 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
742 if (
context->stripes[
i].csum_error) {
745 if (!
context->stripes[
i].bad_csums) {
746 ERR(
"out of memory\n");
755 if (!
context->stripes[
i].bad_csums) {
756 ERR(
"out of memory\n");
760 for (
j = 0;
j <
context->stripes[
i].length /
Vcb->superblock.node_size;
j++) {
769 if (present_devices > 1) {
770 ULONG good_stripe = 0xffffffff;
772 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
773 if (
c->devices[
i]->devobj && !
context->stripes[
i].csum_error) {
779 if (good_stripe != 0xffffffff) {
782 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
783 if (
context->stripes[
i].csum_error) {
787 for (
j = 0;
j <
context->stripes[
i].length >>
Vcb->sector_shift;
j++) {
796 for (
j = 0;
j <
context->stripes[
i].length /
Vcb->superblock.node_size;
j++) {
811 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
812 if (
context->stripes[
i].csum_error && !
c->devices[
i]->readonly) {
817 ERR(
"write_data_phys returned %08lx\n",
Status);
829 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
830 if (
c->devices[
i]->devobj) {
836 bool recovered =
false;
838 for (
k = 0;
k <
c->chunk_item->num_stripes;
k++) {
839 if (
i !=
k &&
c->devices[
k]->devobj &&
846 context->stripes[
k].buf + (
j <<
Vcb->sector_shift),
Vcb->superblock.sector_size);
866 bool recovered =
false;
868 for (
k = 0;
k <
c->chunk_item->num_stripes;
k++) {
869 if (
i !=
k &&
c->devices[
k]->devobj) {
896 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
897 if (
c->devices[
i]->devobj && !
c->devices[
i]->readonly) {
901 ERR(
"write_data_phys returned %08lx\n",
Status);
911 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
912 if (
c->devices[
i]->devobj) {
916 for (
j = 0;
j <
context->stripes[
i].length >>
Vcb->sector_shift;
j++) {
924 for (
j = 0;
j <
context->stripes[
i].length /
Vcb->superblock.node_size;
j++) {
946 ERR(
"out of memory\n");
962 for (
j = 0;
j < readlen;
j +=
Vcb->superblock.sector_size) {
970 pos +=
Vcb->superblock.sector_size;
971 stripeoff[
stripe] +=
Vcb->superblock.sector_size;
974 for (
j = 0;
j < readlen;
j +=
Vcb->superblock.node_size) {
983 pos +=
Vcb->superblock.node_size;
984 stripeoff[
stripe] +=
Vcb->superblock.node_size;
1000 bool csum_error =
false;
1006 ERR(
"out of memory\n");
1018 c->chunk_item->stripe_length - (
context->stripes[
stripe * sub_stripes].start %
c->chunk_item->stripe_length));
1023 ULONG good_stripe = 0xffffffff;
1026 for (
k = 0;
k < sub_stripes;
k++) {
1027 if (
c->devices[(
stripe * sub_stripes) +
k]->devobj) {
1029 if (good_stripe != 0xffffffff) {
1032 readlen) != readlen) {
1038 for (
j = 0;
j < readlen;
j +=
Vcb->superblock.sector_size) {
1055 stripeoff[
stripe] += readlen;
1057 ULONG good_stripe = 0xffffffff;
1060 for (
k = 0;
k < sub_stripes;
k++) {
1061 if (
c->devices[(
stripe * sub_stripes) +
k]->devobj) {
1063 if (good_stripe != 0xffffffff) {
1066 readlen) != readlen) {
1072 for (
j = 0;
j < readlen;
j +=
Vcb->superblock.node_size) {
1091 stripeoff[
stripe] += readlen;
1094 stripe = (
stripe + 1) % (
c->chunk_item->num_stripes / sub_stripes);
1102 for (
j = 0;
j <
c->chunk_item->num_stripes;
j += sub_stripes) {
1103 ULONG goodstripe = 0xffffffff;
1105 bool hasbadstripe =
false;
1107 if (
context->stripes[
j].length == 0)
1110 for (
k = 0;
k < sub_stripes;
k++) {
1111 if (
c->devices[
j +
k]->devobj) {
1112 if (!
context->stripes[
j +
k].csum_error)
1115 hasbadstripe =
true;
1120 if (goodstripe != 0xffffffff) {
1121 for (
k = 0;
k < sub_stripes;
k++) {
1122 if (
c->devices[
j +
k]->devobj &&
context->stripes[
j +
k].csum_error) {
1124 bool recovered =
false;
1134 c->chunk_item->stripe_length - (
context->stripes[
stripe * sub_stripes].start %
c->chunk_item->stripe_length));
1138 if (
stripe ==
j / sub_stripes) {
1142 for (
l = 0;
l < readlen;
l +=
Vcb->superblock.sector_size) {
1144 context->stripes[
j + goodstripe].buf + so,
1145 Vcb->superblock.sector_size) !=
Vcb->superblock.sector_size) {
1153 pos +=
Vcb->superblock.sector_size;
1154 so +=
Vcb->superblock.sector_size;
1159 for (
l = 0;
l < readlen;
l +=
Vcb->superblock.node_size) {
1161 context->stripes[
j + goodstripe].buf + so,
1162 Vcb->superblock.node_size) !=
Vcb->superblock.node_size) {
1170 pos +=
Vcb->superblock.node_size;
1171 so +=
Vcb->superblock.node_size;
1177 stripe = (
stripe + 1) % (
c->chunk_item->num_stripes / sub_stripes);
1183 if (!
c->devices[
j +
k]->readonly) {
1187 context->stripes[
j + goodstripe].buf,
context->stripes[
j + goodstripe].length);
1190 ERR(
"write_data_phys returned %08lx\n",
Status);
1200 bool recovered =
false;
1203 for (
k = 0;
k < sub_stripes;
k++) {
1204 if (
c->devices[
j +
k]->devobj) {
1207 if (!
context->stripes[
j +
k].bad_csums) {
1208 ERR(
"out of memory\n");
1217 for (
k = 0;
k < sub_stripes;
k++) {
1218 if (
c->devices[
j +
k]->devobj) {
1223 if (!
context->stripes[
j +
k].bad_csums) {
1224 ERR(
"out of memory\n");
1229 for (
l = 0;
l <
context->stripes[
j +
k].length /
Vcb->superblock.node_size;
l++) {
1246 c->chunk_item->stripe_length - (
context->stripes[
stripe * sub_stripes].start %
c->chunk_item->stripe_length));
1250 if (
stripe ==
j / sub_stripes) {
1254 for (
l = 0;
l < readlen;
l +=
Vcb->superblock.sector_size) {
1255 bool has_error =
false;
1257 goodstripe = 0xffffffff;
1258 for (
k = 0;
k < sub_stripes;
k++) {
1259 if (
c->devices[
j +
k]->devobj) {
1262 Vcb->csum_size) !=
Vcb->csum_size) {
1270 if (goodstripe != 0xffffffff) {
1271 for (
k = 0;
k < sub_stripes;
k++) {
1272 if (
c->devices[
j +
k]->devobj &&
1275 Vcb->csum_size) !=
Vcb->csum_size) {
1283 Vcb->superblock.sector_size);
1289 for (
k = 0;
k < sub_stripes;
k++) {
1290 if (
c->devices[
j +
j]->devobj) {
1298 pos +=
Vcb->superblock.sector_size;
1299 so +=
Vcb->superblock.sector_size;
1302 for (
l = 0;
l < readlen;
l +=
Vcb->superblock.node_size) {
1303 for (
k = 0;
k < sub_stripes;
k++) {
1304 if (
c->devices[
j +
k]->devobj) {
1313 for (
m = 0;
m < sub_stripes;
m++) {
1335 pos +=
Vcb->superblock.node_size;
1336 so +=
Vcb->superblock.node_size;
1342 stripe = (
stripe + 1) % (
c->chunk_item->num_stripes / sub_stripes);
1348 for (
k = 0;
k < sub_stripes;
k++) {
1349 if (
c->devices[
j +
k]->devobj && !
c->devices[
j +
k]->readonly) {
1356 ERR(
"write_data_phys returned %08lx\n",
Status);
1380 uint16_t startoffstripe = 0, num_missing, allowed_missing;
1382 TRACE(
"(%p, %p, %lx, %I64x, %x, %p)\n",
Vcb,
c,
type,
offset,
size,
csum);
1386 ERR(
"out of memory\n");
1401 get_raid0_offset(
offset -
c->offset,
c->chunk_item->stripe_length,
c->chunk_item->num_stripes, &startoff, &startoffstripe);
1404 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
1405 if (startoffstripe >
i)
1406 context.stripes[
i].start = startoff - (startoff %
c->chunk_item->stripe_length) +
c->chunk_item->stripe_length;
1407 else if (startoffstripe ==
i)
1408 context.stripes[
i].start = startoff;
1410 context.stripes[
i].start = startoff - (startoff %
c->chunk_item->stripe_length);
1412 if (endoffstripe >
i)
1413 context.stripes[
i].length = (
uint32_t)(endoff - (endoff %
c->chunk_item->stripe_length) +
c->chunk_item->stripe_length -
context.stripes[
i].start);
1414 else if (endoffstripe ==
i)
1420 allowed_missing = 0;
1423 uint16_t endoffstripe,
j, sub_stripes =
max(
c->chunk_item->sub_stripes, 1);
1425 get_raid0_offset(
offset -
c->offset,
c->chunk_item->stripe_length,
c->chunk_item->num_stripes / sub_stripes, &startoff, &startoffstripe);
1426 get_raid0_offset(
offset +
size -
c->offset - 1,
c->chunk_item->stripe_length,
c->chunk_item->num_stripes / sub_stripes, &endoff, &endoffstripe);
1428 if ((
c->chunk_item->num_stripes % sub_stripes) != 0) {
1429 ERR(
"chunk %I64x: num_stripes %x was not a multiple of sub_stripes %x!\n",
c->offset,
c->chunk_item->num_stripes, sub_stripes);
1434 startoffstripe *= sub_stripes;
1435 endoffstripe *= sub_stripes;
1437 for (
i = 0;
i <
c->chunk_item->num_stripes;
i += sub_stripes) {
1438 if (startoffstripe >
i)
1439 context.stripes[
i].start = startoff - (startoff %
c->chunk_item->stripe_length) +
c->chunk_item->stripe_length;
1440 else if (startoffstripe ==
i)
1441 context.stripes[
i].start = startoff;
1443 context.stripes[
i].start = startoff - (startoff %
c->chunk_item->stripe_length);
1445 if (endoffstripe >
i)
1446 context.stripes[
i].length = (
uint32_t)(endoff - (endoff %
c->chunk_item->stripe_length) +
c->chunk_item->stripe_length -
context.stripes[
i].start);
1447 else if (endoffstripe ==
i)
1452 for (
j = 1;
j < sub_stripes;
j++) {
1458 startoffstripe /= sub_stripes;
1459 allowed_missing = 1;
1461 allowed_missing =
c->chunk_item->num_stripes - 1;
1465 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
1474 ERR(
"unexpected chunk type %lx\n",
type);
1479 if (!
c->devices[
i]->devobj) {
1482 if (num_missing > allowed_missing) {
1483 ERR(
"too many missing devices (at least %u, maximum allowed %u)\n", num_missing, allowed_missing);
1487 }
else if (
context.stripes[
i].length > 0) {
1491 ERR(
"out of memory\n");
1499 ERR(
"IoAllocateIrp failed\n");
1510 if (!
context.stripes[
i].Irp->AssociatedIrp.SystemBuffer) {
1511 ERR(
"out of memory\n");
1521 if (!
context.stripes[
i].Irp->MdlAddress) {
1522 ERR(
"IoAllocateMdl failed\n");
1536 ERR(
"MmProbeAndLockPages threw exception %08lx\n",
Status);
1553 Vcb->scrub.data_scrubbed +=
context.stripes[
i].length;
1557 if (
context.stripes_left == 0) {
1558 ERR(
"error - not reading any stripes\n");
1565 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
1566 if (
c->devices[
i]->devobj &&
context.stripes[
i].length > 0)
1573 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
1584 ERR(
"scrub_extent_dup returned %08lx\n",
Status);
1590 ERR(
"scrub_extent_raid0 returned %08lx\n",
Status);
1596 ERR(
"scrub_extent_raid10 returned %08lx\n",
Status);
1603 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
1631 while (runlength != 0) {
1632 if (
index >= bmplen)
1635 if (
index + runlength >= bmplen) {
1636 runlength = bmplen -
index;
1653 ERR(
"scrub_data_extent_dup returned %08lx\n",
Status);
1659 }
while (runlength > 0);
1708 ULONG sectors_per_stripe = (
ULONG)(
c->chunk_item->stripe_length >>
Vcb->sector_shift), off;
1709 uint16_t stripe, parity = (bit_start +
num +
c->chunk_item->num_stripes - 1) %
c->chunk_item->num_stripes;
1712 stripe = (parity + 1) %
c->chunk_item->num_stripes;
1713 off = (
ULONG)(bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 1);
1714 stripeoff =
num * sectors_per_stripe;
1716 if (missing_devices == 0)
1719 while (
stripe != parity) {
1722 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1726 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 1) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1732 if (missing_devices > 0)
1736 off +=
Vcb->superblock.node_size >>
Vcb->sector_shift;
1737 stripeoff +=
Vcb->superblock.node_size >>
Vcb->sector_shift;
1738 i += (
Vcb->superblock.node_size >>
Vcb->sector_shift) - 1;
1746 if (missing_devices > 0) {
1747 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 1) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1759 if (missing_devices == 0)
1763 stripeoff =
num * sectors_per_stripe;
1768 if (missing_devices == 0) {
1771 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1774 o =
i <<
Vcb->sector_shift;
1775 for (
j = 0;
j <
Vcb->superblock.sector_size;
j++) {
1776 if (
context->parity_scratch[o] != 0) {
1787 if (missing_devices > 0)
1790 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1795 stripe = (parity + 1) %
c->chunk_item->num_stripes;
1796 off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 1)) +
i;
1798 while (
stripe != parity) {
1809 off += sectors_per_stripe;
1822 do_xor(&
context->stripes[parity].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
1824 Vcb->superblock.sector_size);
1826 bad_off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 1)) +
i;
1827 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 1) *
c->chunk_item->stripe_length) + (bad_off <<
Vcb->sector_shift);
1829 context->stripes[parity].rewrite =
true;
1834 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 1) *
c->chunk_item->stripe_length) + (bad_off <<
Vcb->sector_shift);
1840 &
context->stripes[bad_stripe].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
1841 Vcb->superblock.node_size);
1847 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
1849 context->stripes[bad_stripe].rewrite =
true;
1853 log_error(
Vcb,
addr,
c->devices[bad_stripe]->devitem.dev_id,
true,
true,
false);
1855 log_error(
Vcb,
addr,
c->devices[bad_stripe]->devitem.dev_id,
true,
false,
false);
1860 &
context->stripes[bad_stripe].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
1861 Vcb->superblock.sector_size);
1867 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
1869 context->stripes[bad_stripe].rewrite =
true;
1871 log_error(
Vcb,
addr,
c->devices[bad_stripe]->devitem.dev_id,
false,
true,
false);
1873 log_error(
Vcb,
addr,
c->devices[bad_stripe]->devitem.dev_id,
false,
false,
false);
1876 stripe = (parity + 1) %
c->chunk_item->num_stripes;
1877 off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 1)) +
i;
1879 while (
stripe != parity) {
1882 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 1) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1888 off += sectors_per_stripe;
1897 ULONG sectors_per_stripe = (
ULONG)(
c->chunk_item->stripe_length >>
Vcb->sector_shift), off;
1898 uint16_t stripe, parity1 = (bit_start +
num +
c->chunk_item->num_stripes - 2) %
c->chunk_item->num_stripes;
1899 uint16_t parity2 = (parity1 + 1) %
c->chunk_item->num_stripes;
1902 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
1903 off = (
ULONG)(bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2);
1904 stripeoff =
num * sectors_per_stripe;
1906 if (
c->devices[parity1]->devobj)
1909 if (
c->devices[parity2]->devobj)
1912 while (
stripe != parity1) {
1915 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1919 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1925 if (missing_devices == 2)
1929 off +=
Vcb->superblock.node_size >>
Vcb->sector_shift;
1930 stripeoff +=
Vcb->superblock.node_size >>
Vcb->sector_shift;
1931 i += (
Vcb->superblock.node_size >>
Vcb->sector_shift) - 1;
1940 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
1945 if (missing_devices == 2)
1955 if (
c->devices[parity1]->devobj)
1959 stripeoff =
num * sectors_per_stripe;
1964 if (missing_devices == 0 || (missing_devices == 1 && !
c->devices[parity2]->devobj)) {
1967 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1970 o =
i <<
Vcb->sector_shift;
1971 for (
j = 0;
j <
Vcb->superblock.sector_size;
j++) {
1972 if (
context->parity_scratch[o] != 0) {
1983 if (missing_devices == 0 || (missing_devices == 1 && !
c->devices[parity1]->devobj)) {
1986 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
1988 while (
stripe != parity2) {
1995 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
1997 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size) !=
Vcb->superblock.sector_size)
2002 if (missing_devices == 2)
2007 for (
ULONG i = 0;
i < sectors_per_stripe;
i++) {
2009 uint64_t bad_stripe1 = 0, bad_stripe2 = 0;
2010 ULONG bad_off1 = 0, bad_off2 = 0;
2013 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
2014 off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2016 while (
stripe != parity1) {
2032 off += sectors_per_stripe;
2046 do_xor(&
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2048 Vcb->superblock.sector_size);
2050 bad_off1 = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2051 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2053 context->stripes[parity1].rewrite =
true;
2061 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
2062 Vcb->superblock.sector_size);
2064 bad_off1 = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2065 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2067 context->stripes[parity2].rewrite =
true;
2074 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2081 ERR(
"out of memory\n");
2088 &
context->stripes[bad_stripe1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
len);
2090 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2092 if (
c->devices[parity2]->devobj) {
2093 uint16_t stripe_num, bad_stripe_num = 0;
2095 stripe_num =
c->chunk_item->num_stripes - 3;
2096 while (
stripe != parity2) {
2099 if (
stripe != bad_stripe1)
2102 bad_stripe_num = stripe_num;
2108 do_xor(scratch, &
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
len);
2110 if (bad_stripe_num != 0)
2119 if (
c->devices[parity1]->devobj) {
2124 if (
c->devices[parity2]->devobj) {
2133 scratch,
Vcb->superblock.node_size);
2135 if (
c->devices[parity1]->devobj) {
2138 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
2142 Vcb->superblock.node_size);
2147 do_xor(&
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2149 Vcb->superblock.node_size);
2154 context->stripes[parity1].rewrite =
true;
2161 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
2165 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2167 if (
c->devices[parity2]->devobj) {
2170 Vcb->superblock.node_size);
2174 while (
stripe != parity2) {
2177 do_xor(&
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2179 Vcb->superblock.node_size);
2184 context->stripes[parity2].rewrite =
true;
2192 context->stripes[bad_stripe1].rewrite =
true;
2196 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
true,
false);
2198 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
false,
false);
2203 if (
c->devices[parity1]->devobj)
2206 if (
c->devices[parity2]->devobj)
2213 scratch,
Vcb->superblock.sector_size);
2218 stripe = (parity1 + 2) %
c->chunk_item->num_stripes;
2222 Vcb->superblock.sector_size);
2227 do_xor(&
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2229 Vcb->superblock.sector_size);
2234 context->stripes[parity1].rewrite =
true;
2241 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
2245 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2249 Vcb->superblock.sector_size);
2253 while (
stripe != parity2) {
2256 do_xor(&
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)],
2258 Vcb->superblock.sector_size);
2263 context->stripes[parity2].rewrite =
true;
2270 context->stripes[bad_stripe1].rewrite =
true;
2272 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
true,
false);
2274 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
false,
false);
2278 }
else if (
num_errors == 2 && missing_devices == 0) {
2285 stripe = parity1 == 0 ? (
c->chunk_item->num_stripes - 1) : (parity1 - 1);
2290 k =
c->chunk_item->num_stripes - 3;
2295 if (
stripe == bad_stripe1)
2317 }
else if (
stripe == bad_stripe1)
2319 else if (
stripe == bad_stripe2)
2324 }
while (
stripe != parity2);
2329 denom =
gdiv(1, gyx ^ 1);
2330 a =
gmul(gyx, denom);
2331 b =
gmul(gx, denom);
2333 p = &
context->stripes[parity1].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)];
2334 q = &
context->stripes[parity2].buf[(
num *
c->chunk_item->stripe_length) + (
i <<
Vcb->sector_shift)];
2335 pxy = &
context->parity_scratch2[
i <<
Vcb->sector_shift];
2336 qxy = &
context->parity_scratch[
i <<
Vcb->sector_shift];
2338 for (
j = 0;
j <
len;
j++) {
2350 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off1 <<
Vcb->sector_shift);
2357 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
2359 context->stripes[bad_stripe1].rewrite =
true;
2363 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
true,
false);
2365 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
true,
false,
false);
2369 &
context->parity_scratch[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
2371 context->stripes[bad_stripe1].rewrite =
true;
2373 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
true,
false);
2375 log_error(
Vcb,
addr,
c->devices[bad_stripe1]->devitem.dev_id,
false,
false,
false);
2378 addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (bad_off2 <<
Vcb->sector_shift);
2385 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
Vcb->superblock.node_size);
2387 context->stripes[bad_stripe2].rewrite =
true;
2391 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
true,
true,
false);
2393 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
true,
false,
false);
2397 &
context->parity_scratch2[
i <<
Vcb->sector_shift],
Vcb->superblock.sector_size);
2399 context->stripes[bad_stripe2].rewrite =
true;
2401 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
false,
true,
false);
2403 log_error(
Vcb,
addr,
c->devices[bad_stripe2]->devitem.dev_id,
false,
false,
false);
2406 stripe = (parity2 + 1) %
c->chunk_item->num_stripes;
2407 off = (
ULONG)((bit_start +
num - stripe_start) * sectors_per_stripe * (
c->chunk_item->num_stripes - 2)) +
i;
2409 while (
stripe != parity1) {
2412 uint64_t addr =
c->offset + (stripe_start * (
c->chunk_item->num_stripes - 2) *
c->chunk_item->stripe_length) + (off <<
Vcb->sector_shift);
2418 off += sectors_per_stripe;
2437 TRACE(
"(%p, %p, %I64x, %I64x)\n",
Vcb,
c, stripe_start, stripe_end);
2439 full_stripe_len = (
c->chunk_item->num_stripes - num_parity_stripes) *
c->chunk_item->stripe_length;
2440 run_start =
c->offset + (stripe_start * full_stripe_len);
2441 run_end =
c->offset + ((stripe_end + 1) * full_stripe_len);
2443 searchkey.
obj_id = run_start;
2445 searchkey.
offset = 0xffffffffffffffff;
2449 ERR(
"find_item returned %08lx\n",
Status);
2453 num_sectors = (
uint32_t)(((stripe_end - stripe_start + 1) * full_stripe_len) >>
Vcb->sector_shift);
2458 ERR(
"out of memory\n");
2464 ERR(
"out of memory\n");
2476 if (!
context.parity_scratch) {
2477 ERR(
"out of memory\n");
2486 ERR(
"out of memory\n");
2498 ERR(
"out of memory\n");
2509 if (!
context.parity_scratch2) {
2510 ERR(
"out of memory\n");
2536 bool extent_is_tree =
false;
2541 extent_is_tree =
true;
2552 extent_is_tree =
true;
2563 searchkey.
offset = extent_start;
2567 ERR(
"find_item returned %08lx\n",
Status);
2585 (
ULONG)(((csum_end - csum_start) *
Vcb->csum_size) >>
Vcb->sector_shift));
2605 ERR(
"out of memory\n");
2610 max_read = (
uint32_t)
min(1048576 /
c->chunk_item->stripe_length, stripe_end - stripe_start + 1);
2612 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
2617 ERR(
"out of memory\n");
2619 for (
j = 0;
j <
i;
j++) {
2629 if (!
context.stripes[
i].errorarr) {
2632 ERR(
"out of memory\n");
2636 for (
j = 0;
j <
i;
j++) {
2648 context.stripes[
i].rewrite =
false;
2660 bool need_wait =
false;
2662 if (max_read < stripe_end + 1 -
stripe)
2663 read_stripes = max_read;
2667 context.stripes_left =
c->chunk_item->num_stripes;
2670 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
2671 if (
c->devices[
i]->devobj) {
2677 ERR(
"IoAllocateIrp failed\n");
2690 if (!
context.stripes[
i].Irp->AssociatedIrp.SystemBuffer) {
2691 ERR(
"out of memory\n");
2701 if (!
context.stripes[
i].Irp->MdlAddress) {
2702 ERR(
"IoAllocateMdl failed\n");
2716 ERR(
"MmProbeAndLockPages threw exception %08lx\n",
Status);
2729 context.stripes[
i].missing =
false;
2733 Vcb->scrub.data_scrubbed += read_stripes *
c->chunk_item->stripe_length;
2744 ERR(
"too many missing devices (%u, maximum 1)\n", missing_devices);
2748 ERR(
"too many missing devices (%u, maximum 2)\n", missing_devices);
2756 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
2757 if (
c->devices[
i]->devobj)
2765 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
2774 for (
i = 0;
i < read_stripes;
i++) {
2778 for (
i = 0;
i < read_stripes;
i++) {
2785 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
2796 context.stripes[
i].buf, (
uint32_t)(read_stripes *
c->chunk_item->stripe_length));
2799 ERR(
"write_data_phys returned %08lx\n",
Status);
2809 }
while (
stripe < stripe_end);
2814 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
2841 uint64_t full_stripe_len,
stripe, stripe_start = 0, stripe_end = 0, total_data = 0;
2844 full_stripe_len = (
c->chunk_item->num_stripes - num_parity_stripes) *
c->chunk_item->stripe_length;
2851 searchkey.
offset = 0xffffffffffffffff;
2855 ERR(
"find_item returned %08lx\n",
Status);
2873 ERR(
"extent %I64x has size less than sector_size (%I64x < %x)\n",
tp.
item->
key.
obj_id,
size,
Vcb->superblock.sector_size);
2880 if (
stripe > stripe_end + 1) {
2883 ERR(
"scrub_chunk_raid56_stripe_run returned %08lx\n",
Status);
2900 if (num_extents >= 64 || total_data >= 0x8000000)
2913 ERR(
"scrub_chunk_raid56_stripe_run returned %08lx\n",
Status);
2917 *
offset =
c->offset + ((stripe_end + 1) * full_stripe_len);
2927 bool b =
false, tree_run =
false;
2929 uint64_t total_data = 0, tree_run_start = 0, tree_run_end = 0;
2931 TRACE(
"chunk %I64x\n",
c->offset);
2958 searchkey.
offset = 0xffffffffffffffff;
2962 ERR(
"error - find_item returned %08lx\n",
Status);
2999 ERR(
"extent %I64x has size less than sector_size (%I64x < %x)\n",
tp.
item->
key.
obj_id,
size,
Vcb->superblock.sector_size);
3010 ERR(
"out of memory\n");
3019 ERR(
"out of memory\n");
3034 ERR(
"find_item returned %08lx\n",
Status);
3053 (
ULONG)(((ce -
cs) *
Vcb->csum_size) >>
Vcb->sector_shift));
3074 ERR(
"scrub_extent returned %08lx\n",
Status);
3086 }
else if (is_tree) {
3095 ERR(
"scrub_data_extent returned %08lx\n",
Status);
3112 if (num_extents >= 64 || total_data >= 0x8000000)
3125 ERR(
"scrub_extent returned %08lx\n",
Status);
3151 if (
Vcb->need_write && !
Vcb->readonly)
3160 ERR(
"do_write returned %08lx\n",
Status);
3170 Vcb->scrub.finish_time.QuadPart = 0;
3171 Vcb->scrub.resume_time.QuadPart =
Vcb->scrub.start_time.QuadPart;
3172 Vcb->scrub.duration.QuadPart = 0;
3173 Vcb->scrub.total_chunks = 0;
3174 Vcb->scrub.chunks_left = 0;
3175 Vcb->scrub.data_scrubbed = 0;
3176 Vcb->scrub.num_errors = 0;
3185 le =
Vcb->chunks.Flink;
3186 while (le != &
Vcb->chunks) {
3193 Vcb->scrub.total_chunks++;
3194 Vcb->scrub.chunks_left++;
3217 if (!
Vcb->scrub.stopping) {
3223 ERR(
"scrub_chunk returned %08lx\n",
Status);
3224 Vcb->scrub.stopping =
true;
3229 if (
offset ==
c->offset +
c->chunk_item->size ||
Vcb->scrub.stopping)
3238 if (!
Vcb->scrub.stopping)
3239 Vcb->scrub.chunks_left--;
3247 c->list_entry_balance.Flink =
NULL;
3251 Vcb->scrub.duration.QuadPart +=
time.QuadPart -
Vcb->scrub.resume_time.QuadPart;
3268 WARN(
"cannot start scrub while locked\n");
3272 if (
Vcb->balance.thread) {
3273 WARN(
"cannot start scrub while balance running\n");
3277 if (
Vcb->scrub.thread) {
3278 WARN(
"scrub already running\n");
3285 Vcb->scrub.stopping =
false;
3286 Vcb->scrub.paused =
false;
3294 ERR(
"PsCreateSystemThread returned %08lx\n",
Status);
3316 if (
Vcb->scrub.thread &&
Vcb->scrub.chunks_left > 0)
3342 le =
Vcb->scrub.errors.Flink;
3343 while (le != &
Vcb->scrub.errors) {
3347 if (
err->is_metadata)
3378 if (
err->is_metadata) {
3381 bse->
metadata.firstitem =
err->metadata.firstitem;
3383 bse->
data.subvol =
err->data.subvol;
3384 bse->
data.offset =
err->data.offset;
3385 bse->
data.filename_length =
err->data.filename_length;
3407 if (!
Vcb->scrub.thread)
3410 if (
Vcb->scrub.paused)
3413 Vcb->scrub.paused =
true;
3417 Vcb->scrub.duration.QuadPart +=
time.QuadPart -
Vcb->scrub.resume_time.QuadPart;
3426 if (!
Vcb->scrub.thread)
3429 if (!
Vcb->scrub.paused)
3432 Vcb->scrub.paused =
false;
3444 if (!
Vcb->scrub.thread)
3447 Vcb->scrub.paused =
false;
3448 Vcb->scrub.stopping =
true;
#define STATUS_PRIVILEGE_NOT_HELD
std::map< E_STRING, PART_TEST > parts
unsigned short int uint16_t
#define InterlockedDecrement
#define acquire_chunk_lock(c, Vcb)
uint8_t gdiv(uint8_t a, uint8_t b)
_Post_satisfies_ static stripe __inline void get_raid0_offset(_In_ uint64_t off, _In_ uint64_t stripe_length, _In_ uint16_t num_stripes, _Out_ uint64_t *stripeoff, _Out_ uint16_t *stripe)
uint8_t gmul(uint8_t a, uint8_t b)
void do_calc_job(device_extension *Vcb, uint8_t *data, uint32_t sectors, void *csum)
void galois_double(uint8_t *data, uint32_t len)
NTSTATUS do_write(device_extension *Vcb, PIRP Irp)
bool check_sector_csum(device_extension *Vcb, void *buf, void *csum)
void galois_divpower(uint8_t *data, uint8_t div, uint32_t readlen)
NTSTATUS write_data_phys(_In_ PDEVICE_OBJECT device, _In_ PFILE_OBJECT fileobj, _In_ uint64_t address, _In_reads_bytes_(length) void *data, _In_ uint32_t length)
NTSTATUS NTSTATUS bool bool void free_trees(device_extension *Vcb) __attribute__((nonnull(1)))
void get_sector_csum(device_extension *Vcb, void *buf, void *csum)
bool check_tree_checksum(device_extension *Vcb, tree_header *th)
NTSTATUS NTSTATUS bool find_next_item(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, const traverse_ptr *tp, traverse_ptr *next_tp, bool ignore, PIRP Irp) __attribute__((nonnull(1
void get_tree_checksum(device_extension *Vcb, tree_header *th, void *csum)
#define release_chunk_lock(c, Vcb)
#define BTRFS_SCRUB_PAUSED
#define BTRFS_SCRUB_STOPPED
#define BTRFS_SCRUB_RUNNING
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define RtlInitializeBitMap
#define RtlFindNextForwardRunClear
#define RtlFindFirstRunClear
#define NT_SUCCESS(StatCode)
wstring utf8_to_utf16(const string_view &utf8)
static LONG find_item(PropertyBag *This, LPCOLESTR name)
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
void log_device_error(_In_ device_extension *Vcb, _Inout_ device *dev, _In_ int error)
void chunk_lock_range(_In_ device_extension *Vcb, _In_ chunk *c, _In_ uint64_t start, _In_ uint64_t length)
void chunk_unlock_range(_In_ device_extension *Vcb, _In_ chunk *c, _In_ uint64_t start, _In_ uint64_t length)
#define TYPE_EXTENT_DATA_REF
#define TYPE_INODE_EXTREF
#define BTRFS_DEV_STAT_READ_ERRORS
#define TYPE_SHARED_BLOCK_REF
#define BLOCK_FLAG_RAID1C4
#define EXTENT_ITEM_TREE_BLOCK
#define TYPE_SHARED_DATA_REF
#define BTRFS_DEV_STAT_WRITE_ERRORS
#define TYPE_ROOT_BACKREF
#define TYPE_TREE_BLOCK_REF
#define EXTENT_TYPE_REGULAR
#define BLOCK_FLAG_RAID1C3
#define BTRFS_DEV_STAT_CORRUPTION_ERRORS
#define TYPE_METADATA_ITEM
_In_ PIO_STACK_LOCATION IrpSp
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define IsListEmpty(ListHead)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define RtlCompareMemory(s1, s2, l)
#define KeInitializeEvent(pEvt, foo, foo2)
#define ExConvertExclusiveToSharedLite(res)
#define KeSetEvent(pEvt, foo, foo2)
#define KeQuerySystemTime(t)
#define RemoveTailList(ListHead)
#define ExAcquireResourceExclusiveLite(res, wait)
#define RemoveHeadList(ListHead)
#define InitializeListHead(ListHead)
#define ExAcquireResourceSharedLite(res, wait)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei GLenum type
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble r
GLdouble GLdouble GLdouble GLdouble q
GLboolean GLboolean GLboolean b
GLuint GLsizei GLsizei * length
GLenum const GLvoid * addr
GLboolean GLboolean GLboolean GLboolean a
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
#define OBJ_KERNEL_HANDLE
#define EXCEPTION_EXECUTE_HANDLER
#define UInt32x32To64(a, b)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
#define SE_MANAGE_VOLUME_PRIVILEGE
static CRYPT_DATA_BLOB b2[]
#define InitializeObjectAttributes(p, n, a, r, s)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define _Function_class_(n)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
VOID NTAPI IoFreeIrp(IN PIRP Irp)
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
#define STATUS_INTERNAL_ERROR
#define STATUS_UNEXPECTED_IO_ERROR
#define _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
static bool check_csum(btrfs_send_command *cmd, uint8_t *data)
static void log_error(device_extension *Vcb, uint64_t addr, uint64_t devid, bool metadata, bool recoverable, bool parity)
static NTSTATUS scrub_extent_dup(device_extension *Vcb, chunk *c, uint64_t offset, void *csum, scrub_context *context)
static void scrub_raid5_stripe(device_extension *Vcb, chunk *c, scrub_context_raid56 *context, uint64_t stripe_start, uint64_t bit_start, uint64_t num, uint16_t missing_devices)
NTSTATUS stop_scrub(device_extension *Vcb, KPROCESSOR_MODE processor_mode)
static NTSTATUS scrub_chunk_raid56_stripe_run(device_extension *Vcb, chunk *c, uint64_t stripe_start, uint64_t stripe_end)
NTSTATUS pause_scrub(device_extension *Vcb, KPROCESSOR_MODE processor_mode)
static void scrub_raid6_stripe(device_extension *Vcb, chunk *c, scrub_context_raid56 *context, uint64_t stripe_start, uint64_t bit_start, uint64_t num, uint16_t missing_devices)
static NTSTATUS scrub_chunk(device_extension *Vcb, chunk *c, uint64_t *offset, bool *changed)
static void log_tree_checksum_error_shared(device_extension *Vcb, uint64_t offset, uint64_t address, uint64_t devid)
static void log_file_checksum_error_shared(device_extension *Vcb, uint64_t treeaddr, uint64_t addr, uint64_t devid, uint64_t extent)
static NTSTATUS scrub_chunk_raid56(device_extension *Vcb, chunk *c, uint64_t *offset, bool *changed)
struct _scrub_context scrub_context
static NTSTATUS scrub_extent_raid10(device_extension *Vcb, chunk *c, uint64_t offset, uint32_t length, uint16_t startoffstripe, void *csum, scrub_context *context)
static NTSTATUS scrub_extent_raid0(device_extension *Vcb, chunk *c, uint64_t offset, uint32_t length, uint16_t startoffstripe, void *csum, scrub_context *context)
NTSTATUS query_scrub(device_extension *Vcb, KPROCESSOR_MODE processor_mode, void *data, ULONG length)
static void log_file_checksum_error(device_extension *Vcb, uint64_t addr, uint64_t devid, uint64_t subvol, uint64_t inode, uint64_t offset)
static NTSTATUS scrub_extent(device_extension *Vcb, chunk *c, ULONG type, uint64_t offset, uint32_t size, void *csum)
NTSTATUS start_scrub(device_extension *Vcb, KPROCESSOR_MODE processor_mode)
static NTSTATUS scrub_data_extent(device_extension *Vcb, chunk *c, uint64_t offset, ULONG type, void *csum, RTL_BITMAP *bmp, ULONG bmplen)
static void log_tree_checksum_error(device_extension *Vcb, uint64_t addr, uint64_t devid, uint64_t root, uint8_t level, KEY *firstitem)
static void log_unrecoverable_error(device_extension *Vcb, uint64_t address, uint64_t devid)
NTSTATUS resume_scrub(device_extension *Vcb, KPROCESSOR_MODE processor_mode)
#define offsetof(TYPE, MEMBER)
#define STATUS_DEVICE_NOT_READY
#define STATUS_MORE_PROCESSING_REQUIRED
#define BLOCK_FLAG_DUPLICATE
#define BLOCK_FLAG_RAID10
#define STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_OVERFLOW
struct _IO_STACK_LOCATION::@3983::@3987 Read
union _IO_STACK_LOCATION::@1584 Parameters
struct _LIST_ENTRY * Blink
struct _LIST_ENTRY * Flink
scrub_context_stripe * stripes
LARGE_INTEGER finish_time
struct btrfs_scrub_error::@671::@674 metadata
struct btrfs_scrub_error::@671::@673 data
scrub_context_raid56_stripe * stripes
uint8_t * parity_scratch2
struct _scrub_context * context
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
#define STATUS_MEDIA_WRITE_PROTECTED
#define STATUS_INSUFFICIENT_RESOURCES
_In_ PDEVICE_OBJECT DeviceObject
static GLenum _GLUfuncptr fn
#define ExReleaseResource(R)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
#define IRP_DEALLOCATE_BUFFER
#define IRP_INPUT_OPERATION