--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+#include <fcntl.h>
+
+#include <string>
+#include <vector>
+
+#include <klay/filesystem.h>
+#include <klay/process.h>
+#include <klay/exception.h>
+#include <klay/audit/logger.h>
+
+#include "ext4-tool.h"
+
+namespace ode {
+
+#define ODE_SUPERBLOCK_OFFSET 1024
+#define ODE_SUPERBLOCK_SIZE 1024
+#define ODE_EXT2_MIN_DESC_SIZE 32
+#define ODE_EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
+#define ODE_EXT2_MIN_BLOCK_SIZE (1 << ODE_EXT2_MIN_BLOCK_LOG_SIZE)
+
+static unsigned int divCeilSafely(unsigned int a, unsigned int b)
+{
+ if (!a)
+ return 0;
+
+ return ((a - 1) / b) + 1;
+}
+
+Ext4Tool::Ext4Tool(const std::string &src) :
+ source(src), totalBlockCount(0)
+{
+ unsigned int firstDataBlock = 0;
+ unsigned int blockSize = 0;
+ unsigned int blocksPerGroup = 0;
+ unsigned int clustersPerGroup = 0;
+ runtime::File device(source);
+
+ if (device.exists() == false)
+ throw runtime::Exception("Source doesn't exist");
+
+ device.open(O_RDONLY);
+
+ // read totalBlockCount
+ device.lseek(ODE_SUPERBLOCK_OFFSET + 4, SEEK_SET);
+ device.read(&totalBlockCount, 4);
+
+ // read firstDataBlock
+ device.lseek(ODE_SUPERBLOCK_OFFSET + 20, SEEK_SET);
+ device.read(&firstDataBlock, 4);
+
+ // read blockSize
+ device.lseek(ODE_SUPERBLOCK_OFFSET + 24, SEEK_SET);
+ device.read(&blockSize, 4);
+ blockSize = (ODE_EXT2_MIN_BLOCK_SIZE << blockSize);
+
+ // read blocksPerGroup
+ device.lseek(ODE_SUPERBLOCK_OFFSET + 32, SEEK_SET);
+ device.read(&blocksPerGroup, 4);
+
+ // read clustersPerGroup
+ device.lseek(ODE_SUPERBLOCK_OFFSET + 36, SEEK_SET);
+ device.read(&clustersPerGroup, 4);
+
+ // read bitmap
+ bitmap.resize(totalBlockCount + 1);
+
+ unsigned int groupDescCount = divCeilSafely(totalBlockCount - firstDataBlock, blocksPerGroup);
+ int blockNbytes = clustersPerGroup / 8;
+
+ // read group_desc
+ unsigned int descPerBlock = blockSize / ODE_EXT2_MIN_DESC_SIZE;
+ unsigned int descBlockCount = divCeilSafely(groupDescCount, descPerBlock);
+
+ // read first meta block
+ data group_desc(descBlockCount * blockSize);
+ device.lseek((firstDataBlock + 1) * blockSize, SEEK_SET);
+ device.read(group_desc.data(), (descBlockCount * blockSize));
+
+ unsigned int cnt = 0;
+ unsigned int blkItr = firstDataBlock;
+
+ // this structure just is used for easy type-casting.
+ struct odeExtGroupDesc {
+ unsigned int blockBitmap; /* Blocks bitmap block */
+ /* skip other member */
+ };
+
+ for (unsigned int i = 0; i < groupDescCount; i++) {
+ data block_bitmap(blockSize);
+
+ unsigned int blk = (((struct odeExtGroupDesc *)(((unsigned char *)(group_desc.data())) + i * ODE_EXT2_MIN_DESC_SIZE))->blockBitmap);
+ device.lseek(blk * blockSize, SEEK_SET);
+ device.read(block_bitmap.data(), blockSize);
+
+ cnt = blockNbytes << 3;
+ memcpy(bitmap.data() + (blkItr >> 3), block_bitmap.data(), (cnt + 7) >> 3);
+ blkItr += blockNbytes << 3;
+ }
+
+ device.close();
+}
+
+Ext4Tool::~Ext4Tool()
+{
+}
+
+unsigned int Ext4Tool::getTotalBlockCount()
+{
+ return totalBlockCount;
+}
+
+bool Ext4Tool::isUsedBlock(unsigned int blockIndex)
+{
+ unsigned char *addr = (bitmap.data() + (blockIndex >> 3));
+ int mask = 1 << (blockIndex & 0x07);
+
+ if (mask & *addr)
+ return true;
+
+ return false;
+}
+
+void Ext4Tool::forceCleanUp()
+{
+ std::vector<std::string> args = {
+ "-f",
+ "-y",
+ source
+ };
+
+ runtime::Process proc("/sbin/e2fsck", args);
+ proc.execute();
+ proc.waitForFinished();
+}
+
+} // namespace ode
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#ifndef __EXT4_TOOL_H__
+#define __EXT4_TOOL_H__
+
+#include <string>
+#include <vector>
+
+namespace ode {
+
+class Ext4Tool final {
+public:
+ Ext4Tool(const std::string &src);
+ Ext4Tool(const Ext4Tool &) = delete;
+ Ext4Tool(Ext4Tool &&) = delete;
+ ~Ext4Tool();
+
+ Ext4Tool &operator=(const Ext4Tool &) = delete;
+ Ext4Tool &operator=(Ext4Tool &&) = delete;
+
+ typedef std::vector<unsigned char> data;
+
+ unsigned int getTotalBlockCount();
+ bool isUsedBlock(unsigned int blockIndex);
+
+ void forceCleanUp();
+
+private:
+ std::string source;
+ unsigned int totalBlockCount;
+ data bitmap;
+};
+
+} // namespace ode
+
+#endif // __EXT4_TOOL_H__