ReactOS 0.4.16-dev-306-g647d351
extents.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: extents.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "ext2fs.h"
13
14/* GLOBALS *****************************************************************/
15
17
18/* DEFINITIONS *************************************************************/
19
20#ifdef ALLOC_PRAGMA
21#endif
22
23
26 IN PEXT2_IRP_CONTEXT IrpContext,
31 OUT PULONG Block,
33)
34{
35 EXT4_EXTENT_HEADER *eh;
36 struct buffer_head bh_got = {0};
37 int flags, rc;
38 ULONG max_blocks = 0;
39
40 memset(&bh_got, 0, sizeof(struct buffer_head));
41 eh = get_ext4_header(&Mcb->Inode);
42
43 if (eh->eh_magic != EXT4_EXT_MAGIC) {
44 if (Alloc) {
45 /* now initialize inode extent root node */
46 ext4_ext_tree_init(IrpContext, NULL, &Mcb->Inode);
47 } else {
48 /* return empty-mapping when inode extent isn't initialized */
49 if (Block)
50 *Block = 0;
51 if (Number) {
52 LONGLONG _len = _len = Mcb->Inode.i_size;
53 if (Mcb->Fcb)
54 _len = Mcb->Fcb->Header.AllocationSize.QuadPart;
55 *Number = (ULONG)((_len + BLOCK_SIZE - 1) >> BLOCK_BITS);
56 }
57 return STATUS_SUCCESS;
58 }
59 }
60
61 /* IrpContext is NULL when called during journal initialization */
62 if (IsMcbDirectory(Mcb) || IrpContext == NULL ||
63 IrpContext->MajorFunction == IRP_MJ_WRITE || !Alloc){
65 max_blocks = EXT_INIT_MAX_LEN;
66 } else {
68 max_blocks = EXT_UNWRITTEN_MAX_LEN;
69 }
70
71 if (Alloc) {
72 if (Number && !*Number) {
73 if (max_blocks > *Number) {
74 max_blocks = *Number;
75 }
76 } else {
77 max_blocks = 1;
78 }
79 }
80
81 if ((rc = ext4_ext_get_blocks(
82 IrpContext,
83 NULL,
84 &Mcb->Inode,
85 Index,
86 max_blocks,
87 &bh_got,
88 Alloc,
89 flags)) < 0) {
90 DEBUG(DL_ERR, ("Block insufficient resources, err: %d\n", rc));
91 return Ext2WinntError(rc);
92 }
93 if (Alloc)
94 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
95 if (Number)
96 *Number = rc ? rc : 1;
97 if (Block)
98 *Block = (ULONG)bh_got.b_blocknr;
99
100 return STATUS_SUCCESS;
101}
102
103
106 IN PEXT2_IRP_CONTEXT IrpContext,
109 IN ULONG Index,
110 IN OUT PULONG Block,
112)
113{
114 EXT4_EXTENT_HEADER *eh;
115 struct buffer_head bh_got;
116 int rc, flags;
117
118 if (IsMcbDirectory(Mcb) || IrpContext->MajorFunction == IRP_MJ_WRITE) {
120 } else {
122 }
123
124 memset(&bh_got, 0, sizeof(struct buffer_head));
125 eh = get_ext4_header(&Mcb->Inode);
126
127 if (eh->eh_magic != EXT4_EXT_MAGIC) {
128 ext4_ext_tree_init(IrpContext, NULL, &Mcb->Inode);
129 }
130
131 if ((rc = ext4_ext_get_blocks( IrpContext, NULL, &Mcb->Inode, Index,
132 *Number, &bh_got, 1, flags)) < 0) {
133 DEBUG(DL_ERR, ("Expand Block insufficient resources, Number: %u,"
134 " err: %d\n", *Number, rc));
135 DbgBreak();
136 return Ext2WinntError(rc);
137 }
138
139 if (Number)
140 *Number = rc ? rc : 1;
141 if (Block)
142 *Block = (ULONG)bh_got.b_blocknr;
143
144 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
145
146 return STATUS_SUCCESS;
147}
148
149
152 PEXT2_IRP_CONTEXT IrpContext,
155 ULONG Start,
156 ULONG End,
158 )
159{
160 ULONG Count = 0, Number = 0, Block = 0;
162
163 if (End <= Start)
164 return Status;
165
166 while (End > Start + Count) {
167
168 Number = End - Start - Count;
169 Status = Ext2DoExtentExpand(IrpContext, Vcb, Mcb, Start + Count,
170 &Block, &Number);
171 if (!NT_SUCCESS(Status)) {
173 break;
174 }
175 if (Number == 0) {
177 break;
178 }
179
180 if (Block && IsZoneInited(Mcb)) {
181 if (!Ext2AddBlockExtent(Vcb, Mcb, Start + Count, Block, Number)) {
182 DbgBreak();
184 Ext2ClearAllExtents(&Mcb->Extents);
185 }
186 }
187 Count += Number;
188 }
189
190 Size->QuadPart = ((LONGLONG)(Start + Count)) << BLOCK_BITS;
191
192 /* save inode whatever it succeeds to expand or not */
193 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
194
195 return Status;
196}
197
198
201 PEXT2_IRP_CONTEXT IrpContext,
205 )
206{
208
209 ULONG Extra = 0;
210 ULONG Wanted = 0;
211 ULONG End;
213 int err;
214
215 /* translate file size to block */
216 End = Vcb->max_data_blocks;
217 Wanted = (ULONG)((Size->QuadPart + BLOCK_SIZE - 1) >> BLOCK_BITS);
218
219 /* calculate blocks to be freed */
220 Extra = End - Wanted;
221
222 err = ext4_ext_truncate(IrpContext, &Mcb->Inode, Wanted);
223 if (err == 0) {
224 if (!Ext2RemoveBlockExtent(Vcb, Mcb, Wanted, Extra)) {
226 Ext2ClearAllExtents(&Mcb->Extents);
227 }
228 Extra = 0;
229 } else {
231 }
232
233 if (!NT_SUCCESS(Status)) {
234 Size->QuadPart += ((ULONGLONG)Extra << BLOCK_BITS);
235 }
236
237 if (Mcb->Inode.i_size > (loff_t)(Size->QuadPart))
238 Mcb->Inode.i_size = (loff_t)(Size->QuadPart);
239
240 /* Save modifications on i_blocks field and i_size field of the inode. */
241 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
242
243 return Status;
244}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
PVOID Alloc(IN DWORD dwFlags, IN SIZE_T dwBytes)
Definition: main.c:63
#define BLOCK_SIZE
Definition: dlist.c:220
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define BLOCK_BITS
Definition: stream.h:22
unsigned __int64 loff_t
Definition: types.h:84
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
NTSTATUS Ext2WinntError(int rc)
Definition: misc.c:410
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:552
BOOLEAN Ext2RemoveBlockExtent(IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Start, IN ULONG Number)
Definition: memory.c:1097
#define IsMcbDirectory(Mcb)
Definition: ext2fs.h:967
#define DbgBreak()
Definition: ext2fs.h:46
BOOLEAN Ext2AddBlockExtent(IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Start, IN ULONG Block, IN ULONG Number)
Definition: memory.c:1027
#define MCB_ZONE_INITED
Definition: ext2fs.h:957
#define DL_ERR
Definition: ext2fs.h:1434
VOID Ext2ClearAllExtents(PLARGE_MCB Zone)
Definition: memory.c:637
#define IsZoneInited(Mcb)
Definition: ext2fs.h:963
#define EXT4_GET_BLOCKS_IO_CREATE_EXT
Definition: ext4.h:33
#define EXT4_GET_BLOCKS_IO_CONVERT_EXT
Definition: ext4.h:36
int ext4_ext_tree_init(void *icb, handle_t *handle, struct inode *inode)
#define get_ext4_header(i)
Definition: ext4_ext.h:51
#define EXT_UNWRITTEN_MAX_LEN
Definition: ext4_ext.h:102
#define EXT4_EXT_MAGIC
Definition: ext4_ext.h:50
#define EXT_INIT_MAX_LEN
Definition: ext4_ext.h:101
int ext4_ext_truncate(void *icb, struct inode *inode, unsigned long start)
int ext4_ext_get_blocks(void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t iblock, unsigned long max_blocks, struct buffer_head *bh_result, int create, int flags)
NTSTATUS Ext2TruncateExtent(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, PLARGE_INTEGER Size)
Definition: extents.c:200
NTSTATUS Ext2ExpandExtent(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, ULONG Start, ULONG End, PLARGE_INTEGER Size)
Definition: extents.c:151
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2MapExtent(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Index, IN BOOLEAN Alloc, OUT PULONG Block, OUT PULONG Number)
Definition: extents.c:25
NTSTATUS Ext2DoExtentExpand(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Index, IN OUT PULONG Block, IN OUT PULONG Number)
Definition: extents.c:105
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:349
@ Removed
Definition: fbtusb.h:86
return pTarget Start()
Status
Definition: gdiplustypes.h:25
GLbitfield flags
Definition: glext.h:7161
int Count
Definition: noreturn.cpp:7
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
#define Vcb
Definition: cdprocs.h:1415
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
blkcnt_t b_blocknr
Definition: module.h:733
uint32_t * PULONG
Definition: typedefs.h:59
int64_t LONGLONG
Definition: typedefs.h:68
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533