📄 udfstruc.h
字号:
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
UdfStruc.h
Abstract:
This module defines the data structures that make up the major internal
parts of the Udfs file system.
In-Memory structures:
The global data structures with the UdfDataRecord. It contains a pointer
to a File System Device object and a queue of Vcb's. There is a Vcb for
every currently or previously mounted volumes. We may be in the process
of tearing down the Vcb's which have been dismounted. The Vcb's are
allocated as an extension to a volume device object.
+---------+
| UdfData | +--------+
| | --> |FilSysDo|
| | | |
| | <+ +--------+
+---------+ |
|
| +--------+ +--------+
| |VolDo | |VolDo |
| | | | |
| +--------+ +--------+
+> |Vcb | <-> |Vcb | <-> ...
| | | |
+--------+ +--------+
Each Vcb contains a table of all the Fcbs for the volume indexed by
their FileId. Each Vcb contains a pointer to the root directory of
the volume. Each directory Fcb contains a queue of child Lcb's for
its children. Each Lcb is queued onto both its parent and child Fcb.
There can also be detached subtrees due to open operations by Id where
the Fcb's are not connected to the root.
The following diagram shows the root structure.
+--------+ +--------+
| Vcb |---->| Fcb |-------------------------------------------------------------------+
| | | Table |----------------------------------------------------------------+ |
| |--+ | |-------------------------------------------------------------+ | |
+--------+ | +--------+ | | |
| | | | | | |
| | | +---------------------------------------------+ | | |
| V +-----------------------+ | | | |
| +--------+ | | | | |
| |RootFcb | V V | | |
+->| | +-----+ +--------+ +--------+ | | |
| |<-->| Lcb |<-->|Child | +-----+ |Child | | | |
+--------+ +-----+ | Fcb |<-->| Lcb |<-->| Fcb |<--> ... | | |
| | +-----+ | | | | |
+--------+ +--------+ | | |
| | |
(Freestanding sub-tree) | | |
+--------+ | | |
|OpenById|<-------------------------------------------------------------+ | |
| Dir | +--------+ | |
| |--->|OpenById|<--------------------------------------------------+ |
+--------+ | Child | +--------+ |
| Dir |--->|OpenById|<---------------------------------------+
+--------+ | Child |
| File |
+--------+
Attached to each Directory Fcb is an prefix table containing the
Lcbs pointing to children of this directory for which there is an Fcb.
+--------+ +--------+
| Dir | | Prefix |
| Fcb |----->| Table |--------------------+
| | | |-------+ |
+--------+ +--------+ | |
^ | | |
| | | |
| V V V
| +--------+ +--------+ +--------+
| | Lcb | | Lcb | | Lcb |
+---------->| |<-->| |<-->| |
+--------+ +--------+ +--------+
Each file object open on a UDF volume contains two context pointers. The
first will point back to the Fcb for the file object. The second, if present,
points to a Ccb (ContextControlBlock) which contains the per-handle information.
This includes the state of any directory enumeration and the Lcb used to open
this file object.
+--------+ +--------+ +--------+
| Fcb |<------| File | | Ccb |
| | | Object|--->| |
| | | | | |
+--------+ +--------+ +--------+
^ ^
| | +--------+ +--------+
| | | File | | Ccb |
| +---------| Object|--->| |
| | | | |
| +--------+ +--------+
|
| +--------+
| |Stream |
+--------------| File |
| Object|
+--------+
Synchronization:
1. A resource in the UdfData synchronizes access to the Vcb queue. This
is used during mount/verify/dismount operations.
2. A resource in the Vcb is used to synchronize access to Vcb for
open/close operations. Typically acquired shared, it
is acquired exclusively to lock out these operations.
3. A second resource in the Vcb is used to synchronize all file operations.
Typically acquired shared, it is acquired exclusively to lock
out all file operations. Acquiring both Vcb resources will lock
the entire volume.
4. A resource in the nonpaged Fcb will synchronize open/close operations
on an Fcb.
5. A fast mutex in the Vcb will protect access to the Fcb table and
the open counts in the Vcb. It is also used to modify the reference
counts in all Fcbs/Lcbs. This mutex cannot be acquired
exclusely and is an end resource.
6. A fast mutex in the Fcb will synchronize access to all Fcb fields
which aren't synchronized in some other way. A thread may acquire
mutexes for multiple Fcb's as long as it works it way toward the
root of the tree. This mutex can also be acquired recursively.
7. Normal locking order is UdfData/Vcb/Fcb starting at any point in this
chain. The Vcb is required prior to acquiring resources for multiple
files. Shared ownership of the Vcb is sufficient in this case.
8. Normal locking order when acquiring multiple Fcb's is from some
starting Fcb and walking towards the root of tree. Create typically
walks down the tree. In this case we will attempt to acquire the
next node optimistically and if that fails we will reference
the current node in the tree, release it and acquire the next node.
At that point it will be safe to reacquire the parent node.
9. Locking order for the Fcb (via the fast mutex) will be from leaf of
tree back towards the root. No other resource may be acquired
after locking the Vcb (other than in-page reads).
10. Cleanup operations only lock the Vcb and Fcb long enough to change the
critical counts and share access fields. No reason to synchronize
otherwise. None of the structures can go away from beneath us
in this case.
Author:
Dan Lovinger [DanLo] 31-May-1996
Revision History:
--*/
#ifndef _UDFSTRUC_
#define _UDFSTRUC_
typedef PVOID PBCB;
//
// The following structure is used to encapsulate the converted timestamps for
// straightforward referencing.
//
typedef struct _TIMESTAMP_BUNDLE {
LARGE_INTEGER CreationTime;
LARGE_INTEGER AccessTime;
LARGE_INTEGER ModificationTime;
} TIMESTAMP_BUNDLE, *PTIMESTAMP_BUNDLE;
//
// The UDF_DATA record is the top record in the UDF file system in-memory
// data structure. This structure must be allocated from non-paged pool.
//
#define NUMBER_OF_FS_OBJECTS 2
typedef struct _UDF_DATA {
//
// The type and size of this record (must be UDFS_NTC_DATA_HEADER)
//
NODE_TYPE_CODE NodeTypeCode;
NODE_BYTE_SIZE NodeByteSize;
//
// A pointer to the Driver object we were initialized with
//
PDRIVER_OBJECT DriverObject;
//
// Vcb queue.
//
LIST_ENTRY VcbQueue;
//
// The following fields are used to allocate IRP context structures
// using a lookaside list, and other fixed sized structures from a
// small cache. We use the CdData mutex to protext these structures.
//
ULONG IrpContextDepth;
ULONG IrpContextMaxDepth;
SINGLE_LIST_ENTRY IrpContextList;
//
// Filesystem device objects for UDFS.
//
PDEVICE_OBJECT FileSystemDeviceObjects[NUMBER_OF_FS_OBJECTS];
//
// Following are used to manage the async and delayed close queue.
//
// FspCloseActive - Indicates whether there is a thread processing the
// two close queues.
// ReduceDelayedClose - Indicates that we have hit the upper threshold
// for the delayed close queue and need to reduce it to lower threshold.
//
// AsyncCloseQueue - Queue of IrpContext waiting for async close operation.
// AsyncCloseCount - Number of entries on the async close queue.
//
// DelayedCloseQueue - Queue of IrpContextLite waiting for delayed close
// operation.
// MaxDelayedCloseCount - Trigger delay close work at this threshold.
// MinDelayedCloseCount - Turn off delay close work at this threshold.
// DelayedCloseCount - Number of entries on the delayted close queue.
//
// CloseItem - Workqueue item used to start FspClose thread.
//
LIST_ENTRY AsyncCloseQueue;
ULONG AsyncCloseCount;
BOOLEAN FspCloseActive;
BOOLEAN ReduceDelayedClose;
USHORT PadUshort;
//
// The following fields describe the deferred close file objects.
//
LIST_ENTRY DelayedCloseQueue;
ULONG DelayedCloseCount;
ULONG MaxDelayedCloseCount;
ULONG MinDelayedCloseCount;
//
// Fast mutex used to lock the fields of this structure.
//
PVOID UdfDataLockThread;
FAST_MUTEX UdfDataMutex;
//
// A resource variable to control access to the global UDFS data record
//
ERESOURCE DataResource;
//
// Cache manager call back structure, which must be passed on each call
// to CcInitializeCacheMap.
//
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
CACHE_MANAGER_CALLBACKS CacheManagerVolumeCallbacks;
//
// This is the ExWorkerItem that does both kinds of deferred closes.
//
WORK_QUEUE_ITEM CloseItem;
} UDF_DATA, *PUDF_DATA;
//
// A PARTITION will record the VSN/LSN -> PSN retrieval information for a
// partition reference. Since we do not support multi-volume 13346/UDF,
// we will omit noting the volume sequence number that would tell us which
// piece of media contained the partition.
//
// There are currently three types of partitions used during operation: physical,
// sparable and virtual. However, since sparing merely adds another last layer
// of quick indirection, we consider them as a minor extension of a physical
// partition.
//
typedef enum _PARTITION_TYPE {
Uninitialized,
Physical,
Virtual
} PARTITION_TYPE, *PPARTITION_TYPE;
//
// A Physical partition corresponds to a single extent of the volume.
//
typedef struct _PARTITION_PHYSICAL {
//
// Starting Psn and length in sectors
//
ULONG Start;
ULONG Length;
//
// The partition number is specified by the LVD, and refers to
// a specific partition descriptor on the media. We use this
// in the second pass of partition discovery.
//
ULONG PartitionNumber;
PNSR_PART PartitionDescriptor;
//
// Spared partition map, saved temporarily between
// logical volume descriptor analysis and partition
// descriptor discover/pcb completion.
//
PPARTMAP_SPARABLE SparingMap;
} PARTITION_PHYSICAL, *PPARTITION_PHYSICAL;
//
// A Virtual partition is a remapping from VSN to LSN on a given Physical
// partition. The remapping is done through the VAT FCB.
//
typedef struct _PARTITION_VIRTUAL{
//
// The maximum Vbn in the virtual partition.
//
ULONG Length;
//
// A virtual partition refers to its "host" physical partition by partition
// number, which we translate to a partition reference during the second pass
// of partition discovery.
//
// Example: if the virtual partition is reference 1, hosted on partition 156
// (which is reference 0 for this logical volume), then NSRLBA 100/1 would
// refer to the block on partition ref 0 as mapped in the VAT at entry 100.
//
USHORT RelatedReference;
} PARTITION_VIRTUAL, *PPARTITION_VIRTUAL;
//
// There is exactly one PARTITION per partition. It is responsible for mapping
// from some form of logical sector to a physical sector.
//
typedef struct _PARTITION {
//
// This is the type of partition.
//
PARTITION_TYPE Type;
union {
PARTITION_PHYSICAL Physical;
PARTITION_VIRTUAL Virtual;
};
} PARTITION, *PPARTITION;
//
// The Pcb (Partition control block) record corresponds to the partitions
// which collectively form the mounted volume. Exactly one of these is
// linked off of the Vcb.
//
typedef struct _PCB {
//
// The type and size of this record (must be UDFS_NTC_PCB)
//
NODE_TYPE_CODE NodeTypeCode;
NODE_BYTE_SIZE NodeByteSize;
//
// This is the number of partitions in the map
//
USHORT Partitions;
//
// A bitmask of flags.
//
USHORT Flags;
//
// Sparing Mcb, if this volume has sparing.
//
PLARGE_MCB SparingMcb;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -