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 + -
显示快捷键?