xref: /haiku/src/kits/storage/disk_device/jobs/MoveJob.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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