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
18using std::nothrow;
19
20
21// constructor
22MoveJob::MoveJob(PartitionReference* partition, PartitionReference* child)
23	: DiskDeviceJob(partition, child),
24	  fContents(NULL),
25	  fContentsCount(0)
26{
27}
28
29
30// destructor
31MoveJob::~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
42status_t
43MoveJob::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
62status_t
63MoveJob::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