| 197 | |
| 198 | |
| 199 | NTSTATUS |
| 200 | Ext2TruncateExtent( |
| 201 | PEXT2_IRP_CONTEXT IrpContext, |
| 202 | PEXT2_VCB Vcb, |
| 203 | PEXT2_MCB Mcb, |
| 204 | PLARGE_INTEGER Size |
| 205 | ) |
| 206 | { |
| 207 | NTSTATUS Status = STATUS_SUCCESS; |
| 208 | |
| 209 | ULONG Extra = 0; |
| 210 | ULONG Wanted = 0; |
| 211 | ULONG End; |
| 212 | ULONG Removed; |
| 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)) { |
| 225 | ClearFlag(Mcb->Flags, MCB_ZONE_INITED); |
| 226 | Ext2ClearAllExtents(&Mcb->Extents); |
| 227 | } |
| 228 | Extra = 0; |
| 229 | } else { |
| 230 | Status = STATUS_INSUFFICIENT_RESOURCES; |
| 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 | } |
no test coverage detected