| 1076 | } |
| 1077 | |
| 1078 | NTSTATUS |
| 1079 | Ext2TruncateIndirect( |
| 1080 | PEXT2_IRP_CONTEXT IrpContext, |
| 1081 | PEXT2_VCB Vcb, |
| 1082 | PEXT2_MCB Mcb, |
| 1083 | PLARGE_INTEGER Size |
| 1084 | ) |
| 1085 | { |
| 1086 | NTSTATUS Status = STATUS_SUCCESS; |
| 1087 | |
| 1088 | ULONG Layer = 0; |
| 1089 | |
| 1090 | ULONG Extra = 0; |
| 1091 | ULONG Wanted = 0; |
| 1092 | ULONG End; |
| 1093 | ULONG Base; |
| 1094 | |
| 1095 | ULONG SizeArray = 0; |
| 1096 | PULONG BlockArray = NULL; |
| 1097 | |
| 1098 | /* translate file size to block */ |
| 1099 | End = Base = Vcb->max_data_blocks; |
| 1100 | Wanted = (ULONG)((Size->QuadPart + BLOCK_SIZE - 1) >> BLOCK_BITS); |
| 1101 | |
| 1102 | /* do fast deletion here */ |
| 1103 | if (Wanted == 0) { |
| 1104 | Status = Ext2TruncateIndirectFast(IrpContext, Vcb, Mcb); |
| 1105 | if (NT_SUCCESS(Status)) |
| 1106 | goto errorout; |
| 1107 | } |
| 1108 | |
| 1109 | /* calculate blocks to be freed */ |
| 1110 | Extra = End - Wanted; |
| 1111 | |
| 1112 | for (Layer = EXT2_BLOCK_TYPES; Layer > 0 && Extra; Layer--) { |
| 1113 | |
| 1114 | if (Vcb->max_blocks_per_layer[Layer - 1] == 0) { |
| 1115 | continue; |
| 1116 | } |
| 1117 | |
| 1118 | Base -= Vcb->max_blocks_per_layer[Layer - 1]; |
| 1119 | |
| 1120 | if (Layer - 1 == 0) { |
| 1121 | BlockArray = &Mcb->Inode.i_block[0]; |
| 1122 | SizeArray = End; |
| 1123 | ASSERT(End == EXT2_NDIR_BLOCKS && Base == 0); |
| 1124 | } else { |
| 1125 | BlockArray = &Mcb->Inode.i_block[EXT2_NDIR_BLOCKS - 1 + Layer - 1]; |
| 1126 | SizeArray = 1; |
| 1127 | } |
| 1128 | |
| 1129 | Status = Ext2TruncateBlock( |
| 1130 | IrpContext, |
| 1131 | Vcb, |
| 1132 | Mcb, |
| 1133 | Base, |
| 1134 | End - Base - 1, |
| 1135 | Layer - 1, |
no test coverage detected