/*
* Copyright (C) 2007 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* Author: Steve Ratcliffe
* Create date: 25-Oct-2007
*/
package uk.me.parabola.imgfmt.sys;
import uk.me.parabola.imgfmt.MapFailedException;
import uk.me.parabola.log.Logger;
/**
* This is used to allocate blocks for files in the filesystem/archive.
*
* @author Steve Ratcliffe
*/
class BlockManager {
private static final Logger log = Logger.getLogger(BlockManager.class);
private final int blockSize;
private int currentBlock;
private int maxBlock = 0xfffe;
private int maxBlockAllocated;
private final int initialBlock;
BlockManager(int blockSize, int initialBlock) {
this.blockSize = blockSize;
this.currentBlock = initialBlock;
this.initialBlock = initialBlock;
this.maxBlockAllocated = initialBlock;
}
/**
* Well the algorithm is pretty simple - you just get the next unused block
* number.
*
* @return A block number that is free to be used.
*/
public int allocate() {
int n = currentBlock++;
if (maxBlock > 0 && n > maxBlock) {
log.error("overflowed directory with max block " + maxBlock + ", current=" + n);
// This problem is fixable so give some useful advice on what
// to do about it
String message = String.format("Too many blocks." +
" Use a larger block size with an option such as" +
" --block-size=%d or --block-size=%d",
blockSize * 2, blockSize * 4);
throw new MapFailedException(message);
}
maxBlockAllocated++;
return n;
}
public int getBlockSize() {
return blockSize;
}
public int getMaxBlock() {
return maxBlock;
}
public void setMaxBlock(int maxBlock) {
this.maxBlock = maxBlock;
}
public void setCurrentBlock(int n) {
if (maxBlockAllocated != initialBlock)
throw new IllegalStateException("Blocks already allocated");
currentBlock = n;
maxBlockAllocated = n;
}
public int getMaxBlockAllocated() {
return maxBlockAllocated;
}
}