57 #define INCOMPAT_SUPPORTED (BTRFS_INCOMPAT_FLAGS_MIXED_BACKREF | BTRFS_INCOMPAT_FLAGS_DEFAULT_SUBVOL | BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS | \ 58 BTRFS_INCOMPAT_FLAGS_COMPRESS_LZO | BTRFS_INCOMPAT_FLAGS_BIG_METADATA | BTRFS_INCOMPAT_FLAGS_RAID56 | \ 59 BTRFS_INCOMPAT_FLAGS_EXTENDED_IREF | BTRFS_INCOMPAT_FLAGS_SKINNY_METADATA | BTRFS_INCOMPAT_FLAGS_NO_HOLES | \ 60 BTRFS_INCOMPAT_FLAGS_COMPRESS_ZSTD | BTRFS_INCOMPAT_FLAGS_METADATA_UUID | BTRFS_INCOMPAT_FLAGS_RAID1C34) 61 #define COMPAT_RO_SUPPORTED (BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE | BTRFS_COMPAT_RO_FLAGS_FREE_SPACE_CACHE_VALID) 64 static const WCHAR dosdevice_name[] = {
'\\',
'D',
'o',
's',
'D',
'e',
'v',
'i',
'c',
'e',
's',
'\\',
'B',
't',
'r',
'f',
's',0};
66 DEFINE_GUID(BtrfsBusInterface, 0x4d414874, 0x6865, 0x6761, 0x6d, 0x65, 0x83, 0x69, 0x17, 0x9a, 0x7d, 0x1d);
125 static void init_serial(
bool first_time);
151 #define DEBUG_MESSAGE_LEN 1024 153 #ifdef DEBUG_LONG_MESSAGES 156 void _debug_message(
_In_ const char*
func,
_In_ char*
s, ...) {
170 DbgPrint(
"Couldn't allocate buffer in debug_message\n");
174 #ifdef DEBUG_LONG_MESSAGES 216 Irp->AssociatedIrp.SystemBuffer = buf2;
221 if (!
Irp->MdlAddress) {
228 Irp->UserBuffer = buf2;
257 }
else if (log_handle !=
NULL) {
350 searchkey.
obj_id = 0xffffffffffffffff;
352 searchkey.
offset = 0xffffffffffffffff;
356 ERR(
"error - find_item returned %08lx\n",
Status);
362 TRACE(
"last inode for tree %I64x is %I64x\n",
r->id,
r->lastinode);
373 TRACE(
"last inode for tree %I64x is %I64x\n",
r->id,
r->lastinode);
380 WARN(
"no INODE_ITEMs in tree %I64x\n",
r->id);
392 WARN(
"DIR_ITEM is truncated\n");
404 ERR(
"out of memory\n");
415 xasize =
sizeof(
DIR_ITEM) - 1 + xa->
m + xa->
n;
436 TRACE(
"(%p, %I64x, %I64x, %s, %08x, %p, %p)\n",
Vcb, subvol->id,
inode,
name,
crc32,
data,
datalen);
444 ERR(
"error - find_item returned %08lx\n",
Status);
476 TRACE(
"Closing file system\n");
495 Irp->IoStatus.Information = 0;
521 TRACE(
"flush buffers\n");
534 ERR(
"fcb was NULL\n");
539 if (
fcb ==
Vcb->volume_fcb) {
546 Irp->IoStatus.Information = 0;
584 nfactor =
Vcb->superblock.num_devices - 1;
587 nfactor =
Vcb->superblock.num_devices - 2;
600 sectors_used = (
Vcb->superblock.bytes_used /
Vcb->superblock.sector_size) * nfactor /
dfactor;
602 *totalsize = (
Vcb->superblock.total_bytes /
Vcb->superblock.sector_size) * nfactor /
dfactor;
603 *
freespace = sectors_used > *totalsize ? 0 : (*totalsize - sectors_used);
607 #define INIT_UNICODE_STRING(var, val) UNICODE_STRING us##var; us##var.Buffer = (WCHAR*)val; us##var.Length = us##var.MaximumLength = sizeof(val) - sizeof(WCHAR); 643 ERR(
"ZwQueryInformationProcess returned %08lx\n",
Status);
647 if (!
pbi.PebBaseAddress)
650 peb =
pbi.PebBaseAddress;
658 bool blacklist =
false;
660 if (
entry->FullDllName.Length >= usmpr.Length) {
663 name.Buffer = &
entry->FullDllName.Buffer[(
entry->FullDllName.Length - usmpr.Length) /
sizeof(
WCHAR)];
664 name.Length =
name.MaximumLength = usmpr.Length;
669 if (!blacklist &&
entry->FullDllName.Length >= uscmd.Length) {
672 name.Buffer = &
entry->FullDllName.Buffer[(
entry->FullDllName.Length - uscmd.Length) /
sizeof(
WCHAR)];
673 name.Length =
name.MaximumLength = uscmd.Length;
678 if (!blacklist &&
entry->FullDllName.Length >= usfsutil.Length) {
681 name.Buffer = &
entry->FullDllName.Buffer[(
entry->FullDllName.Length - usfsutil.Length) /
sizeof(
WCHAR)];
682 name.Length =
name.MaximumLength = usfsutil.Length;
687 if (!blacklist &&
entry->FullDllName.Length >= usstorsvc.Length) {
690 name.Buffer = &
entry->FullDllName.Buffer[(
entry->FullDllName.Length - usstorsvc.Length) /
sizeof(
WCHAR)];
691 name.Length =
name.MaximumLength = usstorsvc.Length;
702 ERR(
"out of memory\n");
708 for (
i = 0;
i < num_frames;
i++) {
724 #endif // __REACTOS__ 735 for (
i = 0;
i < src_len; ++
i) {
738 for (
ULONG i = 0;
i < src_len;
i++) {
744 else if ((
in[
i] & 0xe0) == 0xc0) {
745 if (
i == src_len - 1 || (
in[
i+1] & 0xc0) != 0x80) {
749 cp = ((
in[
i] & 0x1f) << 6) | (
in[
i+1] & 0x3f);
752 }
else if ((
in[
i] & 0xf0) == 0xe0) {
753 if (
i >= src_len - 2 || (
in[
i+1] & 0xc0) != 0x80 || (
in[
i+2] & 0xc0) != 0x80) {
757 cp = ((
in[
i] & 0xf) << 12) | ((
in[
i+1] & 0x3f) << 6) | (
in[
i+2] & 0x3f);
760 }
else if ((
in[
i] & 0xf8) == 0xf0) {
761 if (
i >= src_len - 3 || (
in[
i+1] & 0xc0) != 0x80 || (
in[
i+2] & 0xc0) != 0x80 || (
in[
i+3] & 0xc0) != 0x80) {
765 cp = ((
in[
i] & 0x7) << 18) | ((
in[
i+1] & 0x3f) << 12) | ((
in[
i+2] & 0x3f) << 6) | (
in[
i+3] & 0x3f);
793 *
out = 0xd800 | ((
cp & 0xffc00) >> 10);
796 *
out = 0xdc00 | (
cp & 0x3ff);
825 for (
i = 0;
i < in_len;
i++) {
828 for (
ULONG i = 0;
i < in_len;
i++) {
833 if ((
cp & 0xfc00) == 0xd800) {
834 if (
i == in_len - 1 || (*
in & 0xfc00) != 0xdc00) {
838 cp = (
cp & 0x3ff) << 10;
845 }
else if ((
cp & 0xfc00) == 0xdc00) {
864 }
else if (
cp < 0x800) {
868 *
out = 0xc0 | ((
cp & 0x7c0) >> 6);
871 *
out = 0x80 | (
cp & 0x3f);
875 }
else if (
cp < 0x10000) {
879 *
out = 0xe0 | ((
cp & 0xf000) >> 12);
882 *
out = 0x80 | ((
cp & 0xfc0) >> 6);
885 *
out = 0x80 | (
cp & 0x3f);
893 *
out = 0xf0 | ((
cp & 0x1c0000) >> 18);
896 *
out = 0x80 | ((
cp & 0x3f000) >> 12);
899 *
out = 0x80 | ((
cp & 0xfc0) >> 6);
902 *
out = 0x80 | (
cp & 0x3f);
913 else if (
cp < 0x10000)
936 TRACE(
"query volume information\n");
955 bool overflow =
false;
957 static const WCHAR ntfs[] =
L"NTFS";
959 static const WCHAR btrfs[] =
L"Btrfs";
960 const WCHAR* fs_name;
961 ULONG fs_name_len, orig_fs_name_len;
966 orig_fs_name_len = fs_name_len =
sizeof(ntfs) -
sizeof(
WCHAR);
969 orig_fs_name_len = fs_name_len =
sizeof(btrfs) -
sizeof(
WCHAR);
973 orig_fs_name_len = fs_name_len =
sizeof(btrfs) -
sizeof(
WCHAR);
976 TRACE(
"FileFsAttributeInformation\n");
996 data->MaximumComponentNameLength = 255;
997 data->FileSystemNameLength = orig_fs_name_len;
1009 TRACE(
"FileFsDeviceInformation\n");
1032 TRACE(
"FileFsFullSizeInformation\n");
1049 TRACE(
"FileFsObjectIdInformation\n");
1064 TRACE(
"FileFsSizeInformation\n");
1080 bool overflow =
false;
1081 ULONG label_len, orig_label_len;
1083 TRACE(
"FileFsVolumeInformation\n");
1090 ERR(
"utf8_to_utf16 returned %08lx\n",
Status);
1095 orig_label_len = label_len;
1106 TRACE(
"label_len = %lu\n", label_len);
1109 ffvi.
VolumeSerialNumber =
Vcb->superblock.uuid.uuid[12] << 24 |
Vcb->superblock.uuid.uuid[13] << 16 |
Vcb->superblock.uuid.uuid[14] << 8 |
Vcb->superblock.uuid.uuid[15];
1115 if (label_len > 0) {
1120 ERR(
"utf8_to_utf16 returned %08lx\n",
Status);
1125 TRACE(
"label = %.*S\n", (
int)(label_len /
sizeof(
WCHAR)),
data->VolumeLabel);
1136 #ifdef _MSC_VER // not in mingw yet 1137 case FileFsSectorSizeInformation:
1139 FILE_FS_SECTOR_SIZE_INFORMATION*
data =
Irp->AssociatedIrp.SystemBuffer;
1141 data->LogicalBytesPerSector =
Vcb->superblock.sector_size;
1142 data->PhysicalBytesPerSectorForAtomicity =
Vcb->superblock.sector_size;
1143 data->PhysicalBytesPerSectorForPerformance =
Vcb->superblock.sector_size;
1144 data->FileSystemEffectivePhysicalBytesPerSectorForAtomicity =
Vcb->superblock.sector_size;
1145 data->ByteOffsetForSectorAlignment = 0;
1146 data->ByteOffsetForPartitionAlignment = 0;
1148 data->Flags = SSINFO_FLAGS_ALIGNED_DEVICE | SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE;
1150 if (
Vcb->trim && !
Vcb->options.no_trim)
1151 data->Flags |= SSINFO_FLAGS_TRIM_ENABLED;
1153 BytesCopied =
sizeof(FILE_FS_SECTOR_SIZE_INFORMATION);
1163 WARN(
"unknown FsInformationClass %u\n",
IrpSp->
Parameters.QueryVolume.FsInformationClass);
1168 Irp->IoStatus.Information = 0;
1180 TRACE(
"query volume information returning %08lx\n",
Status);
1209 ERR(
"out of memory\n");
1215 ERR(
"out of memory\n");
1223 ERR(
"out of memory\n");
1231 t->is_unique =
true;
1232 t->uniqueness_determined =
true;
1238 ERR(
"out of memory\n");
1249 r->treeholder.address = 0;
1250 r->treeholder.generation =
Vcb->superblock.generation;
1251 r->treeholder.tree =
t;
1254 r->received =
false;
1259 r->root_item.num_references = 1;
1260 r->fcbs_version = 0;
1261 r->checked_for_orphans =
true;
1273 ERR(
"insert_tree_item returned %08lx\n",
Status);
1291 t->header.address = 0;
1294 t->header.generation =
Vcb->superblock.generation;
1295 t->header.tree_id =
id;
1296 t->header.num_items = 0;
1297 t->header.level = 0;
1299 t->has_address =
false;
1309 t->has_new_address =
false;
1310 t->updated_extents =
false;
1313 t->list_entry_hash.Flink =
NULL;
1316 Vcb->need_write =
true;
1329 TRACE(
"label = %.*S\n", (
int)(ffli->VolumeLabelLength /
sizeof(
WCHAR)), ffli->VolumeLabel);
1331 vollen = ffli->VolumeLabelLength;
1333 for (
i = 0;
i < ffli->VolumeLabelLength /
sizeof(
WCHAR);
i++) {
1334 if (ffli->VolumeLabel[
i] == 0) {
1335 vollen =
i *
sizeof(
WCHAR);
1337 }
else if (ffli->VolumeLabel[
i] ==
'/' || ffli->VolumeLabel[
i] ==
'\\') {
1368 Vcb->need_write =
true;
1389 TRACE(
"set volume information\n");
1403 if (
Vcb->readonly) {
1408 if (
Vcb->removing ||
Vcb->locked) {
1415 FIXME(
"STUB: FileFsControlInformation\n");
1419 TRACE(
"FileFsLabelInformation\n");
1425 FIXME(
"STUB: FileFsObjectIdInformation\n");
1429 WARN(
"Unrecognized FsInformationClass 0x%x\n",
IrpSp->
Parameters.SetVolume.FsInformationClass);
1435 Irp->IoStatus.Information = 0;
1456 fn.Length =
fn.MaximumLength = 0;
1459 ERR(
"fileref_get_filename returned %08lx\n",
Status);
1463 if (reqlen > 0xffff) {
1464 WARN(
"reqlen was too long for FsRtlNotifyFilterReportChange\n");
1470 ERR(
"out of memory\n");
1479 ERR(
"fileref_get_filename returned %08lx\n",
Status);
1495 if (fileref->fcb->inode_item.st_nlink == 1) {
1510 ERR(
"open_fileref_by_inode returned %08lx\n",
Status);
1515 fn.Length =
fn.MaximumLength = 0;
1518 ERR(
"fileref_get_filename returned %08lx\n",
Status);
1523 if (parfr !=
fcb->
Vcb->root_fileref)
1524 pathlen +=
sizeof(
WCHAR);
1527 WARN(
"pathlen + hl->name.Length was too long for FsRtlNotifyFilterReportChange\n");
1535 ERR(
"out of memory\n");
1542 ERR(
"fileref_get_filename returned %08lx\n",
Status);
1548 if (parfr !=
fcb->
Vcb->root_fileref) {
1549 fn.Buffer[(pathlen /
sizeof(
WCHAR)) - 1] =
'\\';
1603 ERR(
"out of memory\n");
1609 ERR(
"out of memory\n");
1627 #ifdef DEBUG_FCB_REFCOUNTS 1632 #ifdef DEBUG_FCB_REFCOUNTS 1634 WARN(
"fcb %p: refcount now %i\n",
fcb, rc);
1644 fcb->
Vcb->need_write =
true;
1648 if (!fileref->dirty) {
1649 fileref->dirty =
true;
1653 InsertTailList(&fileref->fcb->Vcb->dirty_filerefs, &fileref->list_entry_dirty);
1657 fileref->fcb->Vcb->need_write =
true;
1660 #ifdef DEBUG_FCB_REFCOUNTS 1668 #ifdef DEBUG_FCB_REFCOUNTS 1768 ExFreeToPagedLookasideList(&
fcb->
Vcb->fcb_lookaside,
fcb);
1774 le =
Vcb->all_fcbs.Flink;
1775 while (le != &
Vcb->all_fcbs) {
1794 #ifdef DEBUG_FCB_REFCOUNTS 1795 ERR(
"fileref %p: refcount now %i\n", fr, rc);
1800 ERR(
"fileref %p: refcount now %li\n", fr, rc);
1813 ExFreeToNPagedLookasideList(&
Vcb->fileref_np_lookaside, fr->
nonpaged);
1838 ExFreeToPagedLookasideList(&
Vcb->fileref_lookaside, fr);
1872 TRACE(
"FCB was NULL, returning success\n");
1880 TRACE(
"close called for fcb %p)\n",
fcb);
1894 if (
fcb->
Vcb->running_sends > 0) {
1895 bool send_cancelled =
false;
1901 send_cancelled =
true;
1907 if (send_cancelled) {
1920 if (open_files == 0 &&
fcb->
Vcb->removing) {
1943 if (!
Vcb->removing) {
1945 Vcb->removing =
true;
1949 if (
Vcb->vde &&
Vcb->vde->mounted_device ==
Vcb->devobj)
1950 Vcb->vde->mounted_device =
NULL;
1955 Vcb->Vpb->DeviceObject =
NULL;
1959 if (
Vcb->list_entry.Flink)
1962 if (
Vcb->balance.thread) {
1963 Vcb->balance.paused =
false;
1964 Vcb->balance.stopping =
true;
1969 if (
Vcb->scrub.thread) {
1970 Vcb->scrub.paused =
false;
1971 Vcb->scrub.stopping =
true;
1976 if (
Vcb->running_sends != 0) {
1977 bool send_cancelled =
false;
1981 le =
Vcb->send_ops.Flink;
1982 while (le != &
Vcb->send_ops) {
1985 if (!
send->cancelling) {
1986 send->cancelling =
true;
1987 send_cancelled =
true;
1997 if (send_cancelled) {
1998 while (
Vcb->running_sends != 0) {
2007 WARN(
"registry_mark_volume_unmounted returned %08lx\n",
Status);
2009 for (
i = 0;
i <
Vcb->calcthreads.num_threads;
i++) {
2010 Vcb->calcthreads.threads[
i].quit =
true;
2015 for (
i = 0;
i <
Vcb->calcthreads.num_threads;
i++) {
2033 le =
Vcb->chunks.Flink;
2034 while (le != &
Vcb->chunks) {
2144 if (
Vcb->devobj->AttachedDevice)
2159 ERR(
"excise_extents returned %08lx\n",
Status);
2164 fileref->fcb->Header.AllocationSize.QuadPart = 0;
2165 fileref->fcb->Header.FileSize.QuadPart = 0;
2166 fileref->fcb->Header.ValidDataLength.QuadPart = 0;
2172 ccfs.
FileSize = fileref->fcb->Header.FileSize;
2184 ERR(
"CcSetFileSizes threw exception %08lx\n",
Status);
2189 fileref->fcb->deleted =
true;
2191 le = fileref->children.
Flink;
2192 while (le != &fileref->children) {
2217 if (fileref->deleted) {
2222 if (fileref->fcb->subvol->send_ops > 0) {
2227 fileref->deleted =
true;
2232 TRACE(
"nlink = %u\n", fileref->fcb->inode_item.st_nlink);
2234 if (!fileref->fcb->ads) {
2235 if (fileref->parent->fcb->subvol == fileref->fcb->subvol) {
2240 fileref->fcb->inode_item_changed =
true;
2242 if (fileref->fcb->inode_item.st_nlink > 1 || make_orphan) {
2243 fileref->fcb->inode_item.st_nlink--;
2244 fileref->fcb->inode_item.transid = fileref->fcb->Vcb->superblock.generation;
2245 fileref->fcb->inode_item.sequence++;
2246 fileref->fcb->inode_item.st_ctime =
now;
2250 ERR(
"delete_fileref_fcb returned %08lx\n",
Status);
2257 le = fileref->fcb->hardlinks.
Flink;
2258 while (le != &fileref->fcb->hardlinks) {
2261 if (hl->
parent == fileref->parent->fcb->inode && hl->
index == fileref->dc->index) {
2277 }
else if (fileref->fcb->subvol->parent == fileref->parent->fcb->subvol->id) {
2278 if (fileref->fcb->subvol->root_item.num_references > 1) {
2279 fileref->fcb->subvol->root_item.num_references--;
2289 InsertTailList(&fileref->fcb->Vcb->drop_roots, &fileref->fcb->subvol->list_entry);
2291 le = fileref->children.
Flink;
2292 while (le != &fileref->children) {
2305 fileref->fcb->deleted =
true;
2312 TRACE(
"delete file %.*S\n", (
int)(fileref->dc->name.Length /
sizeof(
WCHAR)), fileref->dc->name.Buffer);
2317 if (!fileref->fcb->ads)
2322 if (!fileref->oldutf8.Buffer)
2323 fileref->oldutf8 = fileref->dc->utf8;
2327 utf8len = fileref->dc->utf8.Length;
2329 fileref->oldindex = fileref->dc->index;
2342 fileref->parent->fcb->inode_item.transid = fileref->fcb->Vcb->superblock.generation;
2343 fileref->parent->fcb->inode_item.sequence++;
2344 fileref->parent->fcb->inode_item.st_ctime =
now;
2346 if (!fileref->fcb->ads) {
2347 TRACE(
"fileref->parent->fcb->inode_item.st_size (inode %I64x) was %I64x\n", fileref->parent->fcb->inode, fileref->parent->fcb->inode_item.st_size);
2348 fileref->parent->fcb->inode_item.st_size -= utf8len * 2;
2349 TRACE(
"fileref->parent->fcb->inode_item.st_size (inode %I64x) now %I64x\n", fileref->parent->fcb->inode, fileref->parent->fcb->inode_item.st_size);
2350 fileref->parent->fcb->inode_item.st_mtime =
now;
2353 fileref->parent->fcb->inode_item_changed =
true;
2356 if (!fileref->fcb->ads && fileref->parent->dc)
2361 fileref->fcb->subvol->root_item.ctransid = fileref->fcb->Vcb->superblock.generation;
2362 fileref->fcb->subvol->root_item.ctime =
now;
2367 TRACE(
"CcUninitializeCacheMap failed\n");
2394 TRACE(
"closing file system\n");
2409 ERR(
"fcb was NULL\n");
2429 TRACE(
"fileref %p, refcount = %li, open_count = %li\n", fileref, fileref ? fileref->
refcount : 0, fileref ? fileref->
open_count : 0);
2444 #ifdef DEBUG_FCB_REFCOUNTS 2445 ERR(
"fileref %p: open_count now %i\n", fileref, oc);
2456 TRACE(
"unlocking volume\n");
2468 if (!
fcb->
Vcb->removing) {
2477 ERR(
"delete_fileref_fcb returned %08lx\n",
Status);
2492 if (!fileref->
fcb->
ads || fileref->
dc) {
2508 ERR(
"delete_fileref returned %08lx\n",
Status);
2538 TRACE(
"flushed cache on close (FileObject = %p, fcb = %p, AllocationSize = %I64x, FileSize = %I64x, ValidDataLength = %I64x)\n",
2561 Irp->IoStatus.Information = 0;
2575 if (
len > 2 &&
val[0] ==
'0' &&
val[1] ==
'x') {
2579 for (
i = 2;
i <
len;
i++) {
2582 if (
val[
i] >=
'0' &&
val[
i] <=
'9')
2583 dosnum |=
val[
i] -
'0';
2584 else if (
val[
i] >=
'a' &&
val[
i] <=
'f')
2585 dosnum |=
val[
i] + 10 -
'a';
2586 else if (
val[
i] >=
'A' &&
val[
i] <=
'F')
2587 dosnum |=
val[
i] + 10 -
'a';
2590 TRACE(
"DOSATTRIB: %08lx\n", dosnum);
2609 if (get_file_attributes_from_xattr(eaval, ealen, &dosnum)) {
2687 ERR(
"IoAllocateIrp failed\n");
2701 if (!
Irp->AssociatedIrp.SystemBuffer) {
2702 ERR(
"out of memory\n");
2712 if (!
Irp->MdlAddress) {
2713 ERR(
"IoAllocateMdl failed\n");
2727 ERR(
"MmProbeAndLockPages threw exception %08lx\n",
Status);
2793 WARN(
"superblock hash was invalid\n");
2806 WARN(
"superblock hash was invalid\n");
2828 ERR(
"out of memory\n");
2833 WARN(
"device was too short to have any superblock\n");
2839 valid_superblocks = 0;
2847 ERR(
"Failed to read superblock %lu: %08lx\n",
i,
Status);
2854 TRACE(
"not a BTRFS volume\n");
2859 TRACE(
"got superblock %lu!\n",
i);
2862 WARN(
"superblock sector size was 0\n");
2869 valid_superblocks++;
2878 if (valid_superblocks == 0) {
2879 ERR(
"could not find any valid superblocks\n");
2883 TRACE(
"label is %s\n",
Vcb->superblock.label);
2933 ERR(
"out of memory\n");
2939 r->received =
false;
2946 r->fcbs_version = 0;
2947 r->checked_for_orphans =
false;
2954 ERR(
"out of memory\n");
2975 r->lastinode = 0x100;
2986 Vcb->extent_root =
r;
2990 Vcb->chunk_root =
r;
2998 Vcb->checksum_root =
r;
3006 Vcb->space_root =
r;
3010 Vcb->data_reloc_root =
r;
3029 ERR(
"error - find_item returned %08lx\n",
Status);
3046 ERR(
"add_root returned %08lx\n",
Status);
3063 if (!
Vcb->readonly && !
Vcb->data_reloc_root) {
3071 WARN(
"data reloc root doesn't exist, creating it\n");
3076 ERR(
"create_root returned %08lx\n",
Status);
3082 reloc_root->root_item.inode.st_blocks =
Vcb->superblock.node_size;
3084 reloc_root->root_item.inode.st_mode = 040755;
3085 reloc_root->root_item.inode.flags = 0xffffffff80000000;
3087 reloc_root->root_item.bytes_used =
Vcb->superblock.node_size;
3091 ERR(
"out of memory\n");
3109 ERR(
"insert_tree_item returned %08lx\n",
Status);
3117 ERR(
"out of memory\n");
3128 ERR(
"insert_tree_item returned %08lx\n",
Status);
3134 Vcb->need_write =
true;
3163 ERR(
"error - find_item returned %08lx\n",
Status);
3177 ERR(
"add_space_entry returned %08lx\n",
Status);
3197 if (lastaddr < dev->devitem.num_bytes) {
3200 ERR(
"add_space_entry returned %08lx\n",
Status);
3215 le =
Vcb->devices.Flink;
3217 while (le != &
Vcb->devices) {
3237 le =
Vcb->devices.Flink;
3238 while (le != &
Vcb->devices) {
3241 TRACE(
"device %I64x, uuid %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
dev->devitem.
dev_id,
3242 dev->devitem.device_uuid.uuid[0],
dev->devitem.device_uuid.uuid[1],
dev->devitem.device_uuid.uuid[2],
dev->devitem.device_uuid.uuid[3],
dev->devitem.device_uuid.uuid[4],
dev->devitem.device_uuid.uuid[5],
dev->devitem.device_uuid.uuid[6],
dev->devitem.device_uuid.uuid[7],
3243 dev->devitem.device_uuid.uuid[8],
dev->devitem.device_uuid.uuid[9],
dev->devitem.device_uuid.uuid[10],
dev->devitem.device_uuid.uuid[11],
dev->devitem.device_uuid.uuid[12],
dev->devitem.device_uuid.uuid[13],
dev->devitem.device_uuid.uuid[14],
dev->devitem.device_uuid.uuid[15]);
3262 if (
Vcb->devices_loaded <
Vcb->superblock.num_devices) {
3274 ERR(
"out of memory\n");
3281 dev->devitem.device_uuid = *
uuid;
3283 dev->devitem.num_bytes = vc->
size;
3285 dev->readonly =
dev->seeding;
3287 dev->removable =
false;
3290 dev->num_trim_entries = 0;
3294 Vcb->devices_loaded++;
3308 WARN(
"could not find device with uuid %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
3322 ERR(
"dev_ioctl returned %08lx\n",
Status);
3337 ERR(
"dev_ioctl returned %08lx\n",
Status);
3342 ERR(
"iosb.Information was too short\n");
3366 WARN(
"IOCTL_STORAGE_GET_DEVICE_NUMBER returned %08lx\n",
Status);
3367 dev->disk_num = 0xffffffff;
3368 dev->part_num = 0xffffffff;
3376 dev->readonly =
dev->seeding;
3378 dev->num_trim_entries = 0;
3379 dev->stats_changed =
false;
3382 if (!
dev->readonly) {
3386 dev->readonly =
true;
3392 ERR(
"out of memory\n");
3406 apte, aptelen,
true,
NULL);
3409 TRACE(
"IOCTL_ATA_PASS_THROUGH returned %08lx for IDENTIFY DEVICE\n",
Status);
3414 dev->can_flush =
true;
3415 TRACE(
"FLUSH CACHE supported\n");
3417 TRACE(
"FLUSH CACHE not supported\n");
3422 #ifdef DEBUG_TRIM_EMULATION 3437 TRACE(
"TRIM supported\n");
3439 TRACE(
"TRIM not supported\n");
3457 Vcb->data_flags = 0;
3458 Vcb->metadata_flags = 0;
3459 Vcb->system_flags = 0;
3463 ERR(
"error - find_item returned %08lx\n",
Status);
3478 le =
Vcb->devices.Flink;
3485 if (le !=
Vcb->devices.Flink)
3495 if (!done &&
Vcb->vde) {
3501 if (
Vcb->devices_loaded <
Vcb->superblock.num_devices) {
3513 ERR(
"out of memory\n");
3525 if (
dev->devitem.num_bytes > vc->
size) {
3526 WARN(
"device %I64x: DEV_ITEM says %I64x bytes, but Windows only reports %I64x\n",
tp.
item->
key.
offset,
3527 dev->devitem.num_bytes, vc->
size);
3529 dev->devitem.num_bytes = vc->
size;
3535 Vcb->devices_loaded++;
3545 if (!
Vcb->options.allow_degraded) {
3546 ERR(
"volume not found: device %I64x, uuid %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
tp.
item->
key.
offset,
3555 ERR(
"out of memory\n");
3566 Vcb->devices_loaded++;
3582 ERR(
"out of memory\n");
3588 c->used =
c->oldused = 0;
3589 c->cache =
c->old_cache =
NULL;
3591 c->readonly =
false;
3593 c->cache_loaded =
false;
3595 c->space_changed =
false;
3600 if (!
c->chunk_item) {
3601 ERR(
"out of memory\n");
3609 Vcb->data_flags =
c->chunk_item->type;
3612 Vcb->metadata_flags =
c->chunk_item->type;
3615 Vcb->system_flags =
c->chunk_item->type;
3618 if (
c->chunk_item->sub_stripes == 0 ||
c->chunk_item->sub_stripes >
c->chunk_item->num_stripes) {
3619 ERR(
"chunk %I64x: invalid stripes (num_stripes %u, sub_stripes %u)\n",
c->offset,
c->chunk_item->num_stripes,
c->chunk_item->sub_stripes);
3626 if (
c->chunk_item->num_stripes > 0) {
3633 ERR(
"out of memory\n");
3639 for (
i = 0;
i <
c->chunk_item->num_stripes;
i++) {
3641 TRACE(
"device %u = %p\n",
i,
c->devices[
i]);
3643 if (!
c->devices[
i]) {
3644 ERR(
"missing device\n");
3650 if (
c->devices[
i]->readonly)
3654 ERR(
"chunk %I64x: number of stripes is 0\n",
c->offset);
3675 c->last_alloc_set =
false;
3681 c->list_entry_balance.Flink =
NULL;
3691 Vcb->log_to_phys_loaded =
true;
3693 if (
Vcb->data_flags == 0)
3696 if (
Vcb->metadata_flags == 0)
3699 if (
Vcb->system_flags == 0)
3704 Vcb->data_flags =
Vcb->metadata_flags;
3734 TRACE(
"cut out superblock in chunk %I64x\n",
c->offset);
3745 TRACE(
"j = %u, startoffstripe = %u\n",
j, startoffstripe);
3757 TRACE(
"cut out superblock in chunk %I64x\n",
c->offset);
3766 TRACE(
"cutting out %I64x, size %I64x\n",
c->offset + off_start, off_end - off_start);
3776 TRACE(
"cut out superblock in chunk %I64x\n",
c->offset);
3785 TRACE(
"cutting out %I64x, size %I64x\n",
c->offset + off_start, off_end - off_start);
3793 TRACE(
"cut out superblock in chunk %I64x\n",
c->offset);
3816 nfactor =
Vcb->superblock.num_devices - 1;
3819 nfactor =
Vcb->superblock.num_devices - 2;
3845 Vcb->superblock.bytes_used = 0;
3847 while (le != &
Vcb->chunks) {
3851 searchkey.
offset =
c->chunk_item->size;
3855 ERR(
"error - find_item returned %08lx\n",
Status);
3863 c->used =
c->oldused = bgi->
used;
3865 TRACE(
"chunk %I64x has %I64x bytes used\n",
c->offset,
c->used);
3869 ERR(
"(%I64x;%I64x,%x,%I64x) is %u bytes, expected %Iu\n",
3870 Vcb->extent_root->id,
tp.