ReactOS  0.4.14-dev-323-g6fe6a88
rfsdblock.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
3  * PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
4  * FILE: rfsdblock.c
5  * PURPOSE: Disk block operations that are specific to ReiserFS.
6  * PROGRAMMER: Mark Piper, Matt Wu, Bo BrantÚn.
7  * HOMEPAGE:
8  * UPDATE HISTORY:
9  */
10 
11 /* INCLUDES *****************************************************************/
12 
13 #include "rfsd.h"
14 
15 /* GLOBALS ***************************************************************/
16 
18 
19 /* DEFINITIONS *************************************************************/
20 
21 #ifdef ALLOC_PRAGMA
22 #pragma alloc_text(PAGE, RfsdAllocateAndLoadBlock)
23 #pragma alloc_text(PAGE, RfsdFindItemHeaderInBlock)
24 #pragma alloc_text(PAGE, RfsdLoadItem)
25 #endif
26 
27 /* FUNCTIONS *************************************************************/
28 
33 PUCHAR
36  IN ULONG BlockIndex) // The ordinal block number to read
37 {
38  // Allocate the return buffer (the caller will be responsible for freeing this!)
39  PUCHAR pReturnBuffer = ExAllocatePoolWithTag(NonPagedPool, Vcb->BlockSize, RFSD_POOL_TAG); // NOTE: for now, I'm switching this to non-paged, because i was getting crashes
40 
41  PAGED_CODE();
42 
43  if (!pReturnBuffer)
44  { DbgBreak(); return NULL; }
45 
46  // Read the block in from disk, or from cache.
47  if (!RfsdLoadBlock(Vcb, BlockIndex, pReturnBuffer))
48  { DbgBreak(); ExFreePool(pReturnBuffer); return NULL; }
49 
50  // Return the result to the caller.
51  return pReturnBuffer;
52 }
53 
63  IN PRFSD_KEY_IN_MEMORY pTargetKey, // The key to match against
64  IN PUCHAR pBlockBuffer, // A filled disk block, provided by the caller
65  OUT PRFSD_ITEM_HEAD* ppMatchingItemHeader, // A pointer to a PRFSD_ITEM_HEAD. The PRFSD_ITEM_HEAD will point to the item head matching Key, or NULL if there was no such item head in the given block.
67  )
68 {
69  // Read the block header
70  PRFSD_BLOCK_HEAD pBlockHeader = (PRFSD_BLOCK_HEAD) pBlockBuffer;
71  PUCHAR pItemHeaderListBuffer = (PUCHAR) pBlockBuffer + sizeof(RFSD_BLOCK_HEAD);
72 
73  PAGED_CODE();
74 
75  *ppMatchingItemHeader = NULL;
76 
77  // Sanity check that the block (and therefore its header) is there
78  if (!pBlockHeader) { return STATUS_INVALID_HANDLE; }
79  ASSERT(pBlockHeader->blk_level == 1);
80 
81  // Search through the item headers to find one with a key matching pTargetKey
82  {
83  ULONG idxCurrentItemHeader = 0;
84  PRFSD_ITEM_HEAD pCurrentItemHeader = NULL;
85  RFSD_KEY_IN_MEMORY CurrentItemKey;
86 
87  for(idxCurrentItemHeader = 0; idxCurrentItemHeader < pBlockHeader->blk_nr_item; idxCurrentItemHeader++)
88  {
89  // Grab the item header, and its key
90  pCurrentItemHeader = (PRFSD_ITEM_HEAD) (pItemHeaderListBuffer + idxCurrentItemHeader * sizeof(RFSD_ITEM_HEAD));
91 
93  &( pCurrentItemHeader->ih_key ), pCurrentItemHeader->ih_version,
94  &( CurrentItemKey ) ); // <
95 
96  // Check if this item is the one being searched for
97  if ( RFSD_KEYS_MATCH == (*fpComparisonFunction)( pTargetKey , &CurrentItemKey ) )
98  {
99  *ppMatchingItemHeader = pCurrentItemHeader;
100  return STATUS_SUCCESS;
101  }
102  }
103 
104  // If a matching key was never found, simply return
105  return STATUS_NO_SUCH_MEMBER;
106  }
107 }
108 
117 NTSTATUS
119  IN PRFSD_VCB Vcb,
120  IN PRFSD_KEY_IN_MEMORY pItemKey, // The key of the item to find
121  OUT PRFSD_ITEM_HEAD* ppMatchingItemHeader,
122  OUT PUCHAR* ppItemBuffer,
123  OUT PUCHAR* ppBlockBuffer, // Block buffer, which backs the other output data structures. The caller must free this (even in the case of an error)!
124  OPTIONAL OUT PULONG pBlockNumber, // The ordinal disk block number at which the item was found
126  )
127 {
129  ULONG LeafNodeBlockNumber;
130 
131  PAGED_CODE();
132 
133  // Clear the output pointers
134  *ppItemBuffer = *ppBlockBuffer = NULL;
135  *ppMatchingItemHeader = NULL;
136  if (pBlockNumber) *pBlockNumber = 0;
137 
138 
139  // Find the block number of the leaf node bock (on disk), that should contain the item w/ pItemKey
141  Vcb, pItemKey, Vcb->SuperBlock->s_root_block,
142  &(LeafNodeBlockNumber)
143  );
144  if (!NT_SUCCESS(Status)){ DbgBreak(); return STATUS_INTERNAL_ERROR; }
145  if (pBlockNumber) *pBlockNumber = LeafNodeBlockNumber;
146 
147 
148  // Load the block (which the caller must later free)
149  *ppBlockBuffer = RfsdAllocateAndLoadBlock(Vcb, LeafNodeBlockNumber);
150  if (!*ppBlockBuffer) { return STATUS_INSUFFICIENT_RESOURCES; }
151 
152 
153  // Get the item header and its information
155  Vcb, pItemKey, *ppBlockBuffer,
156  ( ppMatchingItemHeader ), //<
157  fpComparisonFunction
158  );
160  if (!*ppMatchingItemHeader) { return STATUS_INTERNAL_ERROR; }
161 
162  // Setup the item buffer
163  *ppItemBuffer = (PUCHAR) *ppBlockBuffer + (*ppMatchingItemHeader)->ih_item_location;
164 
165  return STATUS_SUCCESS;
166 }
PRFSD_GLOBAL RfsdGlobal
Definition: init.c:17
void FillInMemoryKey(IN PRFSD_KEY_ON_DISK pKeyOnDisk, IN RFSD_KEY_VERSION KeyVersion, IN OUT PRFSD_KEY_IN_MEMORY pKeyInMemory)
Definition: rfsd.c:2777
#define IN
Definition: typedefs.h:38
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NO_SUCH_MEMBER
Definition: ntstatus.h:597
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
struct item_head * PRFSD_ITEM_HEAD
Definition: rfsd.h:40
#define RFSD_POOL_TAG
Definition: rfsd.h:99
PUCHAR RfsdAllocateAndLoadBlock(IN PRFSD_VCB Vcb, IN ULONG BlockIndex)
Definition: rfsdblock.c:34
NTSTATUS RfsdLoadItem(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pItemKey, OUT PRFSD_ITEM_HEAD *ppMatchingItemHeader, OUT PUCHAR *ppItemBuffer, OUT PUCHAR *ppBlockBuffer, OPTIONAL OUT PULONG pBlockNumber, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY))
Definition: rfsdblock.c:118
__u16 blk_level
Definition: reiserfs_fs.h:679
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
__u16 blk_nr_item
Definition: reiserfs_fs.h:680
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RFSD_KEYS_MATCH
Definition: rfsd.h:63
#define Vcb
Definition: cdprocs.h:1425
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
__u16 ih_version
Definition: reiserfs_fs.h:538
Status
Definition: gdiplustypes.h:24
struct reiserfs_key ih_key
Definition: reiserfs_fs.h:522
NTSTATUS RfsdFindItemHeaderInBlock(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pTargetKey, IN PUCHAR pBlockBuffer, OUT PRFSD_ITEM_HEAD *ppMatchingItemHeader, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY))
Definition: rfsdblock.c:61
unsigned int * PULONG
Definition: retypes.h:1
short RFSD_KEY_COMPARISON
Definition: rfsd.h:55
struct block_head * PRFSD_BLOCK_HEAD
Definition: rfsd.h:38
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define DbgBreak()
Definition: ext2fs.h:46
NTSTATUS NavigateToLeafNode(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, OUT PULONG out_NextBlockNumber)
Definition: rfsd.c:2896
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
BOOLEAN RfsdLoadBlock(IN PRFSD_VCB Vcb, IN ULONG dwBlk, IN PVOID Buffer)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68