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
MoveJob(PartitionReference * partition,PartitionReference * child)22 MoveJob::MoveJob(PartitionReference* partition, PartitionReference* child)
23 : DiskDeviceJob(partition, child),
24 fContents(NULL),
25 fContentsCount(0)
26 {
27 }
28
29
30 // destructor
~MoveJob()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
Init(off_t offset,PartitionReference ** contents,int32 contentsCount)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
Do()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