if(!canWrite()) throw new ReadOnlyFileSystemException("FileSystem or File is readonly");  long blockSize = iNode.getExt2FileSystem().getBlockSize();    synchronized(((Ext2FileSystem)getFileSystem()).getInodeCache()) {   rereadInode();      iNode.incLocked(); }    synchronized(iNode) { try{  if(length<getLength()) { long blockNr 	 = length / blockSize; long blockOffset = length % blockSize; long nextBlock; if(blockOffset==0) nextBlock=blockNr; else nextBlock=blockNr+1;  for(long i=iNode.getAllocatedBlockCount()-1; i>=nextBlock; i--)  { log.debug("setLength(): freeing up block "+i+" of inode"); iNode.freeDataBlock(i); } iNode.setSize(length);  iNode.setMtime(System.currentTimeMillis()/1000);   iNode.decLocked(); return; }     if(length>getLength()) { long len = length - getLength(); long blocksAllocated = getLengthInBlocks(); long bytesAllocated  = getLength(); long bytesCovered=0; while( bytesCovered < len ) { long blockIndex = 	(bytesAllocated+bytesCovered) / blockSize; long blockOffset = 	(bytesAllocated+bytesCovered) % blockSize; long newSection = Math.min(len-bytesCovered, blockSize - blockOffset);   if(blockIndex >= blocksAllocated) { iNode.allocateDataBlock(blockIndex); blocksAllocated++; }  bytesCovered += newSection; } iNode.setSize(length);  iNode.setMtime(System.currentTimeMillis()/1000);   iNode.decLocked(); return; } }catch(Throwable t) {  iNode.decLocked(); throw new IOException(t); } } }
if (!canWrite()) throw new ReadOnlyFileSystemException( "FileSystem or File is readonly");  long blockSize = iNode.getExt2FileSystem().getBlockSize();     synchronized (((Ext2FileSystem) getFileSystem()).getInodeCache()) {   rereadInode();          iNode.incLocked(); }      synchronized (iNode) { try {  if (length < getLength()) { long blockNr = length / blockSize; long blockOffset = length % blockSize; long nextBlock; if (blockOffset == 0) nextBlock = blockNr; else nextBlock = blockNr + 1;  for (long i = iNode.getAllocatedBlockCount() - 1; i >= nextBlock; i--) { log.debug("setLength(): freeing up block " + i + " of inode"); iNode.freeDataBlock(i); } iNode.setSize(length);  iNode.setMtime(System.currentTimeMillis() / 1000);   iNode.decLocked(); return; }       if (length > getLength()) { long len = length - getLength(); long blocksAllocated = getLengthInBlocks(); long bytesAllocated = getLength(); long bytesCovered = 0; while (bytesCovered < len) { long blockIndex = (bytesAllocated + bytesCovered) / blockSize; long blockOffset = (bytesAllocated + bytesCovered) % blockSize; long newSection = Math.min(len - bytesCovered, blockSize - blockOffset);   if (blockIndex >= blocksAllocated) { iNode.allocateDataBlock(blockIndex); blocksAllocated++; }  bytesCovered += newSection; } iNode.setSize(length);  iNode.setMtime(System.currentTimeMillis() / 1000);  return; } } catch (Throwable ex) { final IOException ioe = new IOException(); ioe.initCause(ex); throw ioe; } finally {  iNode.decLocked(); } } }
	public void setLength(long length) throws IOException {		if(!canWrite())			throw new ReadOnlyFileSystemException("FileSystem or File is readonly");				long blockSize = iNode.getExt2FileSystem().getBlockSize();			//synchronize to the inode cache to make sure that the inode does not get		//flushed between reading it and locking it		synchronized(((Ext2FileSystem)getFileSystem()).getInodeCache()) {			//reread the inode before synchronizing to it to make sure			//all threads use the same instance			rereadInode();					//lock the inode into the cache so it is not flushed before synchronizing to it			//(otherwise a new instance of INode referring to the same inode could be put			//in the cache resulting in the possibility of two threads manipulating the same			//inode at the same time because they would synchronize to different INode instances)			iNode.incLocked();		}		//a single inode may be represented by more than one Ext2Directory instances, 		//but each will use the same instance of the underlying inode (see Ext2FileSystem.getINode()),		//so synchronize to the inode		synchronized(iNode) {					try{				//if length<getLength(), then the file is truncated				if(length<getLength()) {					long blockNr 	 = length / blockSize;					long blockOffset = length % blockSize;					long nextBlock;					if(blockOffset==0)						nextBlock=blockNr;					else						nextBlock=blockNr+1;											for(long i=iNode.getAllocatedBlockCount()-1; i>=nextBlock; i--)  {						log.debug("setLength(): freeing up block "+i+" of inode");						iNode.freeDataBlock(i);											}					iNode.setSize(length);								iNode.setMtime(System.currentTimeMillis()/1000);								//setLength done, unlock the inode from the cache					iNode.decLocked();					return;				}								//if length>getLength(), then new blocks are allocated for the file				//The content of the new blocks is undefined (see the setLength(long i) 				//method of java.io.RandomAccessFile				if(length>getLength()) {					long len = length - getLength();					long blocksAllocated = getLengthInBlocks();					long bytesAllocated  = getLength();					long bytesCovered=0;					while( bytesCovered < len ) {						long blockIndex = 	(bytesAllocated+bytesCovered) / blockSize;						long blockOffset = 	(bytesAllocated+bytesCovered) % blockSize;						long newSection = Math.min(len-bytesCovered, blockSize - blockOffset);											//allocate a new block if needed						if(blockIndex >= blocksAllocated) {							iNode.allocateDataBlock(blockIndex);							blocksAllocated++;						}												bytesCovered += newSection;					}				iNode.setSize(length);							iNode.setMtime(System.currentTimeMillis()/1000);								//setLength done, unlock the inode from the cache				iNode.decLocked();				return;				}			}catch(Throwable t) {				//could not fininsh the operation, unlock the inode from the cache				iNode.decLocked();				throw new IOException(t);						}		} // synchronized(inode)	}