inode.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,246 行 · 第 1/3 页
JAVA
1,246 行
public void remove() { synchronized (_bytes) { long length = readLong(_bytes, 0); byte []bytes = _bytes; try { if (length <= INLINE_BLOB_SIZE || bytes == null) return; else if (length <= MINI_FRAG_BLOB_SIZE) { for (; length > 0; length -= MINI_FRAG_SIZE) { long fragAddr = readMiniFragAddr(bytes, 0, _store, length - 1); if ((fragAddr & Store.BLOCK_MASK) == 0) { _store.setCorrupted(true); String msg = _store + ": inode block " + Long.toHexString(length) + " has 0 fragment"; throw stateError(msg); } else if (fragAddr < 0) { String msg = _store + ": inode block " + Long.toHexString(length) + " has invalid fragment " + Long.toHexString(fragAddr); _store.setCorrupted(true); throw stateError(msg); } _store.deleteMiniFragment(_xa, fragAddr); } } else { long initLength = length; for (; length > 0; length -= INODE_BLOCK_SIZE) { long fragAddr = readFragmentAddr(bytes, 0, _store, length - 1); if ((fragAddr & Store.BLOCK_MASK) == 0) { String msg = _store + ": inode block " + Long.toHexString(length) + " has 0 fragment"; log.warning(msg); _store.setCorrupted(true); continue; } else if (fragAddr < 0) { String msg = _store + ": inode block " + Long.toHexString(length) + " has invalid fragment " + Long.toHexString(fragAddr); log.warning(msg); _store.setCorrupted(true); continue; } _store.deleteFragment(_xa, fragAddr); int fragCount = (int) ((length - 1) / INODE_BLOCK_SIZE); int dblFragCount = fragCount - DIRECT_BLOCKS - SINGLE_INDIRECT_BLOCKS; // remove the double indirect blocks if (dblFragCount >= 0 && dblFragCount % INDIRECT_BLOCKS == 0) { fragAddr = readLong(bytes, (DIRECT_BLOCKS + 1) * 8); int dblIndex = (int) (fragCount / INDIRECT_BLOCKS); fragAddr = _store.readFragmentLong(fragAddr, dblIndex); if (fragAddr != 0) _store.deleteFragment(_xa, fragAddr); } // remove the indirect blocks if (fragCount == DIRECT_BLOCKS) { fragAddr = readLong(bytes, (DIRECT_BLOCKS + 1) * 8); if (fragAddr != 0) { _store.deleteFragment(_xa, fragAddr); } } } } } catch (Throwable e) { log.log(Level.WARNING, e.toString(), e); } finally { System.arraycopy(NULL_BYTES, 0, _bytes, 0, NULL_BYTES.length); try { _store.saveAllocation(); } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } } } } /** * Clears the inode. */ static void clear(byte []inode, int inodeOffset) { int end = inodeOffset + INODE_SIZE; for (; inodeOffset < end; inodeOffset++) inode[inodeOffset] = 0; } /** * Returns the fragment id for the given offset. */ static long readMiniFragAddr(byte []inode, int inodeOffset, Store store, long fileOffset) throws IOException { long fragCount = fileOffset / MINI_FRAG_SIZE; return readLong(inode, (int) (inodeOffset + 8 + 8 * fragCount)); } /** * Writes the block id into the inode. */ private static void writeMiniFragAddr(byte []inode, int offset, Store store, StoreTransaction xa, long fragLength, long fragAddr) throws IOException { int fragCount = (int) (fragLength / MINI_FRAG_SIZE); if ((fragAddr & Store.BLOCK_MASK) == 0) { store.setCorrupted(true); throw new IllegalStateException(store + ": inode block " + fragLength + " has zero value " + fragAddr); } writeLong(inode, offset + (fragCount + 1) * 8, fragAddr); } /** * Returns the fragment id for the given offset. */ static long readFragmentAddr(byte []inode, int inodeOffset, Store store, long fileOffset) throws IOException { long fragCount = fileOffset / INODE_BLOCK_SIZE; if (fragCount < DIRECT_BLOCKS) return readLong(inode, (int) (inodeOffset + 8 + 8 * fragCount)); else if (fragCount < DIRECT_BLOCKS + SINGLE_INDIRECT_BLOCKS) { long indirectAddr; indirectAddr = readLong(inode, inodeOffset + (DIRECT_BLOCKS + 1) * 8); if (indirectAddr == 0) { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} null block id", store)); } int offset = (int) (8 * (fragCount - DIRECT_BLOCKS)); long fragAddr = store.readFragmentLong(indirectAddr, offset); return fragAddr; } else if (fragCount < (DIRECT_BLOCKS + SINGLE_INDIRECT_BLOCKS + DOUBLE_INDIRECT_BLOCKS * INDIRECT_BLOCKS)) { long indirectAddr; indirectAddr = readLong(inode, inodeOffset + (DIRECT_BLOCKS + 1) * 8); if (indirectAddr == 0) { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} null block id", store)); } fragCount -= DIRECT_BLOCKS + SINGLE_INDIRECT_BLOCKS; int index = (int) (fragCount / INDIRECT_BLOCKS); long doubleIndirectAddr = store.readFragmentLong(indirectAddr, index); int offset = (int) (8 * (fragCount % INDIRECT_BLOCKS)); return store.readFragmentLong(doubleIndirectAddr, offset); } else { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} fragment address is over 64M ({1}), internal error", store, fragCount)); } } /** * Writes the block id into the inode. */ private static void writeFragmentAddr(byte []inode, int offset, Store store, StoreTransaction xa, long fragLength, long fragAddr) throws IOException { int fragCount = (int) (fragLength / Store.FRAGMENT_SIZE); // XXX: not sure if correct, needs XA? if ((fragAddr & Store.BLOCK_MASK) == 0) { store.setCorrupted(true); String msg = store + ": inode block " + fragCount + " writing 0 fragment"; throw stateError(msg); } if (fragCount < DIRECT_BLOCKS) { writeLong(inode, offset + (fragCount + 1) * 8, fragAddr); } else if (fragCount < DIRECT_BLOCKS + SINGLE_INDIRECT_BLOCKS) { long indAddr = readLong(inode, offset + (DIRECT_BLOCKS + 1) * 8); if (indAddr == 0) { indAddr = store.allocateFragment(xa); writeLong(inode, offset + (DIRECT_BLOCKS + 1) * 8, indAddr); } int fragOffset = 8 * (fragCount - DIRECT_BLOCKS); store.writeFragmentLong(xa, indAddr, fragOffset, fragAddr); } else if (fragCount < (DIRECT_BLOCKS + SINGLE_INDIRECT_BLOCKS + DOUBLE_INDIRECT_BLOCKS * INDIRECT_BLOCKS)) { long indAddr = readLong(inode, offset + (DIRECT_BLOCKS + 1) * 8); if (indAddr == 0) { indAddr = store.allocateFragment(xa); writeLong(inode, offset + (DIRECT_BLOCKS + 1) * 8, indAddr); } int count = fragCount - DIRECT_BLOCKS - SINGLE_INDIRECT_BLOCKS; int dblIndCount = count / INDIRECT_BLOCKS; long dblIndAddr = store.readFragmentLong(indAddr, dblIndCount * 8); if (dblIndAddr == 0) { dblIndAddr = store.allocateFragment(xa); store.writeFragmentLong(xa, indAddr, dblIndCount * 8, dblIndAddr); } int fragOffset = 8 * (count % INDIRECT_BLOCKS); store.writeFragmentLong(xa, dblIndAddr, fragOffset, fragAddr); } else { store.setCorrupted(true); throw new IllegalStateException(L.l("{0}: can't yet support data over 64M (count={1})", store, fragCount)); } } /** * Returns the fragment id for the given offset. */ static long readBlockAddr(byte []inode, int inodeOffset, Store store, long fileOffset) throws IOException { if (fileOffset <= FRAGMENT_MAX) { store.setCorrupted(true); throw new IllegalStateException(store + " block/fragment mixup"); } else if (fileOffset <= DOUBLE_INDIRECT_MAX) { long indirectAddr; indirectAddr = readLong(inode, inodeOffset + (DIRECT_BLOCKS + 1) * 8); if (indirectAddr == 0) { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} null block id")); } int blockCount = (int) ((fileOffset - FRAGMENT_MAX) / BLOCK_SIZE); int offset = 8 * blockCount; long blockAddr = store.readFragmentLong(indirectAddr, offset); return blockAddr; } else { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} size over {1}M not supported", store, (DOUBLE_INDIRECT_MAX / (1024 * 1024)))); } } /** * Writes the block id into the inode. */ private static void writeBlockAddr(byte []inode, int inodeOffset, Store store, StoreTransaction xa, long fileOffset, long blockAddr) throws IOException { if (fileOffset <= FRAGMENT_MAX) { store.setCorrupted(true); throw new IllegalStateException(store + " block/fragment mixup"); } else if (fileOffset <= DOUBLE_INDIRECT_MAX) { long indAddr; indAddr = readLong(inode, inodeOffset + (DIRECT_BLOCKS + 1) * 8); if (indAddr == 0) { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} null block id", store)); } int blockCount = (int) ((fileOffset - FRAGMENT_MAX) / BLOCK_SIZE); int dblBlockCount = blockCount / (BLOCK_SIZE / 8); long dblIndAddr = store.readFragmentLong(indAddr, dblBlockCount * 8); if (dblIndAddr == 0) { Block block = store.allocateBlock(); dblIndAddr = Store.blockIdToAddress(block.getBlockId()); block.free(); store.writeBlockLong(xa, indAddr, dblBlockCount * 8, dblIndAddr); } int blockOffset = 8 * (blockCount % (BLOCK_SIZE / 8)); store.writeFragmentLong(xa, dblIndAddr, blockOffset, blockAddr); } else { store.setCorrupted(true); throw new IllegalStateException(L.l("{0} size over {1}M not supported", store, (DOUBLE_INDIRECT_MAX / (1024 * 1024)))); } } /** * Reads the long. */ public static long readLong(byte []buffer, int offset) { return (((buffer[offset + 0] & 0xffL) << 56) + ((buffer[offset + 1] & 0xffL) << 48) + ((buffer[offset + 2] & 0xffL) << 40) + ((buffer[offset + 3] & 0xffL) << 32) + ((buffer[offset + 4] & 0xffL) << 24) + ((buffer[offset + 5] & 0xffL) << 16) + ((buffer[offset + 6] & 0xffL) << 8) + ((buffer[offset + 7] & 0xffL))); } /** * Writes the long. */ public static void writeLong(byte []buffer, int offset, long v) { buffer[offset + 0] = (byte) (v >> 56); buffer[offset + 1] = (byte) (v >> 48); buffer[offset + 2] = (byte) (v >> 40); buffer[offset + 3] = (byte) (v >> 32); buffer[offset + 4] = (byte) (v >> 24); buffer[offset + 5] = (byte) (v >> 16); buffer[offset + 6] = (byte) (v >> 8); buffer[offset + 7] = (byte) (v); } /** * Reads the short. */ private static int readShort(byte []buffer, int offset) { return (((buffer[offset + 0] & 0xff) << 8) + ((buffer[offset + 1] & 0xff))); } /** * Writes the short. */ private static void writeShort(byte []buffer, int offset, int v) { buffer[offset + 0] = (byte) (v >> 8); buffer[offset + 1] = (byte) v; } private static IllegalStateException stateError(String msg) { IllegalStateException e = new IllegalStateException(msg); e.fillInStackTrace(); log.log(Level.WARNING, e.toString(), e); return e; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?