1 /* 2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "MoveJob.h" 7 8 #include <new> 9 10 #include <AutoDeleter.h> 11 12 #include <syscalls.h> 13 14 #include "DiskDeviceUtils.h" 15 #include "PartitionReference.h" 16 17 18 using std::nothrow; 19 20 21 // constructor 22 MoveJob::MoveJob(PartitionReference* partition, PartitionReference* child) 23 : DiskDeviceJob(partition, child), 24 fContents(NULL), 25 fContentsCount(0) 26 { 27 } 28 29 30 // destructor 31 MoveJob::~MoveJob() 32 { 33 if (fContents) { 34 for (int32 i = 0; i < fContentsCount; i++) 35 fContents[i]->ReleaseReference(); 36 delete[] fContents; 37 } 38 } 39 40 41 // Init 42 status_t 43 MoveJob::Init(off_t offset, PartitionReference** contents, int32 contentsCount) 44 { 45 fContents = new(nothrow) PartitionReference*[contentsCount]; 46 if (!fContents) 47 return B_NO_MEMORY; 48 49 fContentsCount = contentsCount; 50 for (int32 i = 0; i < contentsCount; i++) { 51 fContents[i] = contents[i]; 52 fContents[i]->AcquireReference(); 53 } 54 55 fOffset = offset; 56 57 return B_OK; 58 } 59 60 61 // Do 62 status_t 63 MoveJob::Do() 64 { 65 int32 changeCounter = fPartition->ChangeCounter(); 66 int32 childChangeCounter = fChild->ChangeCounter(); 67 68 partition_id* descendantIDs = new(nothrow) partition_id[fContentsCount]; 69 int32* descendantChangeCounters = new(nothrow) int32[fContentsCount]; 70 ArrayDeleter<partition_id> _(descendantIDs); 71 ArrayDeleter<int32> _2(descendantChangeCounters); 72 73 if (!descendantIDs || !descendantChangeCounters) 74 return B_NO_MEMORY; 75 76 for (int32 i = 0; i < fContentsCount; i++) { 77 descendantIDs[i] = fContents[i]->PartitionID(); 78 descendantChangeCounters[i] = fContents[i]->ChangeCounter(); 79 } 80 81 status_t error = _kern_move_partition(fPartition->PartitionID(), 82 &changeCounter, fChild->PartitionID(), &childChangeCounter, fOffset, 83 descendantIDs, descendantChangeCounters, fContentsCount); 84 85 if (error != B_OK) 86 return error; 87 88 fPartition->SetChangeCounter(changeCounter); 89 fChild->SetChangeCounter(childChangeCounter); 90 91 for (int32 i = 0; i < fContentsCount; i++) 92 fContents[i]->SetChangeCounter(descendantChangeCounters[i]); 93 94 return B_OK; 95 } 96 97