/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.fs.ext2; /** * @author Andras Nagy */ public class BlockBitmap extends FSBitmap { /** * Test whether the block is free, and if yes: - mark it as used - prealloc * the next free blocks, at most 7 * * SYNCHRONIZATION: BlockBitmap.testAndSetBlock() is not synchronized, so * Ext2FileSystem.testAndSetBlock() is synchronized to the bitmap block it * operates on. */ protected static BlockReservation testAndSetBlock(byte[] data, int index) { if (isFree(data, index)) { setBit(data, index); // do preallocation int j = 0; while ((j < Ext2Constants.EXT2_PREALLOC_BLOCK) && isFree(data, index + 1 + j)) { setBit(data, index + 1 + j); j++; } return new BlockReservation(true, index, j); } else return new BlockReservation(false, -1, -1); } /** * Find free blocks in the bitmap. First check for a whole byte of free * blocks (0x00) in the bitmap, then check for any free bit. If a block is * found, mark it as allocated. If the following blocks are free, then they * are preallocated (at most 7 blocks), but preallocation can't be performed * over the group boundary (because the bitmap data is only available for a * single block group). * * SYNCHRONIZATION: BlockBitmap.findFreeBlocks() is not synchronized, so * Ext2FileSystem.findFreeBlocks() is synchronized to the bitmap block it * operates on. */ protected static BlockReservation findFreeBlocks(byte[] data, int metadataLength) { // BlockReservation result; int nonfullBitmap = -1; // points to a nonfull byte in the bitmap // skip the metadata (superblock copy?, groupgrescriptor copies?, inode // table) int first = (int) Ext2Utils.ceilDiv(metadataLength, 8); for (int i = first; i < data.length; i++) { if (data[i] == 0x00) { // allocate the block and do preallocation // preallocate a fixed number of blocks (7) data[i] = (byte) 0xFF; return new BlockReservation(true, ((long) i) * 8, 7); } if ((nonfullBitmap == -1) && (data[i] != 0xFF)) nonfullBitmap = i; } // a full byte of 0x00 was not found in the bitmap: // go for any free bit // no free bit found: if (nonfullBitmap == -1) return new BlockReservation(false, -1, -1); // a free bit has been found: for (int i = 0; i < 8; i++) if (isFree(data[nonfullBitmap], i)) { setBit(data, nonfullBitmap, i); int block = nonfullBitmap * 8 + i; //do preallocation: int j = 0; while ((j < Ext2Constants.EXT2_PREALLOC_BLOCK) && isFree(data, block + 1 + j)) { setBit(data, block + 1 + j); j++; } return new BlockReservation(true, block, j); } return new BlockReservation(false, -1, -1); } }