if( hasROFeature(Ext2Constants.EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { log.info(getDevice().getId()+" Unsupported filesystem feature (LARGE_FILE) forces readonly mode"); setReadOnly(true); } if( hasROFeature(Ext2Constants.EXT2_FEATURE_RO_COMPAT_BTREE_DIR)) { log.info(getDevice().getId()+" Unsupported filesystem feature (BTREE_DIR) forces readonly mode"); setReadOnly(true); }   if(superblock.getState()==Ext2Constants.EXT2_ERROR_FS) { log.info(getDevice().getId()+" Filesystem has not been cleanly unmounted, mounting it readonly"); setReadOnly(true); }   if(!isReadOnly()) { log.info(getDevice().getId()+" mounting fs r/w"); superblock.setState(Ext2Constants.EXT2_ERROR_FS); }   log.debug( "	superblock:	#blocks:		"+superblock.getBlocksCount()+"\n"+ "				#blocks/group:	"+superblock.getBlocksPerGroup()+"\n"+ "				#block groups:	"+groupCount+"\n"+ "				block size:		"+superblock.getBlockSize()+"\n"+ "				#inodes:		"+superblock.getINodesCount()+"\n"+ "				#inodes/group:	"+superblock.getINodesPerGroup()); }
groupCount = (int) Math.ceil((double) superblock.getBlocksCount() / (double) superblock.getBlocksPerGroup()); groupDescriptors = new GroupDescriptor[groupCount]; iNodeTables = new INodeTable[groupCount];  for (int i = 0; i < groupCount; i++) {  groupDescriptors[i] = new GroupDescriptor(); groupDescriptors[i].read(i, this);  iNodeTables[i] = new INodeTable(this, (int) groupDescriptors[i] .getInodeTable()); }  } catch (FileSystemException e) { throw e; } catch (Exception e) { throw new FileSystemException(e); }     if (hasIncompatFeature(Ext2Constants.EXT2_FEATURE_INCOMPAT_COMPRESSION)) throw new FileSystemException( getDevice().getId() + " Unsupported filesystem feature (COMPRESSION) disallows mounting"); if (hasIncompatFeature(Ext2Constants.EXT2_FEATURE_INCOMPAT_META_BG)) throw new FileSystemException( getDevice().getId() + " Unsupported filesystem feature (META_BG) disallows mounting"); if (hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) throw new FileSystemException( getDevice().getId() + " Unsupported filesystem feature (JOURNAL_DEV) disallows mounting"); if (hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_RECOVER)) throw new FileSystemException( getDevice().getId() + " Unsupported filesystem feature (RECOVER) disallows mounting");    if (hasROFeature(Ext2Constants.EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { log .info(getDevice().getId() + " Unsupported filesystem feature (LARGE_FILE) forces readonly mode"); setReadOnly(true); } if (hasROFeature(Ext2Constants.EXT2_FEATURE_RO_COMPAT_BTREE_DIR)) { log .info(getDevice().getId() + " Unsupported filesystem feature (BTREE_DIR) forces readonly mode"); setReadOnly(true); }   if (superblock.getState() == Ext2Constants.EXT2_ERROR_FS) { log .info(getDevice().getId() + " Filesystem has not been cleanly unmounted, mounting it readonly"); setReadOnly(true); }   if (!isReadOnly()) { log.info(getDevice().getId() + " mounting fs r/w"); superblock.setState(Ext2Constants.EXT2_ERROR_FS); }   log.debug("	superblock:	#blocks:		" + superblock.getBlocksCount() + "\n" + "				#blocks/group:	" + superblock.getBlocksPerGroup() + "\n" + "				#block groups:	" + groupCount + "\n" + "				block size:		" + superblock.getBlockSize() + "\n" + "				#inodes:		" + superblock.getINodesCount() + "\n" + "				#inodes/group:	" + superblock.getINodesPerGroup()); }
	public void read() throws FileSystemException {		byte data[];		try {			data = new byte[Superblock.SUPERBLOCK_LENGTH];			//skip the first 1024 bytes (bootsector) and read the superblock 			//TODO: the superblock should read itself			getApi().read(1024, data, 0, Superblock.SUPERBLOCK_LENGTH);			//superblock = new Superblock(data, this);			superblock = new Superblock();			superblock.read(data, this);						//read the group descriptors			groupCount = (int)Math.ceil((double)superblock.getBlocksCount() / (double)superblock.getBlocksPerGroup());			groupDescriptors = new GroupDescriptor[groupCount];			iNodeTables = new INodeTable[groupCount];									for(int i=0; i<groupCount; i++) {				//groupDescriptors[i]=new GroupDescriptor(i, this);				groupDescriptors[i]=new GroupDescriptor();				groupDescriptors[i].read(i, this);								iNodeTables[i] = new INodeTable(this, (int)groupDescriptors[i].getInodeTable());			}						} catch (FileSystemException e) {			throw e;		} catch (Exception e) {			throw new FileSystemException(e);		}						//check for unsupported filesystem options 		//(an unsupported INCOMPAT feature means that the fs may not be mounted at all)		if( hasIncompatFeature(Ext2Constants.EXT2_FEATURE_INCOMPAT_COMPRESSION) )			throw new FileSystemException(getDevice().getId()+" Unsupported filesystem feature (COMPRESSION) disallows mounting");		if( hasIncompatFeature(Ext2Constants.EXT2_FEATURE_INCOMPAT_META_BG) )			throw new FileSystemException(getDevice().getId()+" Unsupported filesystem feature (META_BG) disallows mounting");		if( hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) )			throw new FileSystemException(getDevice().getId()+" Unsupported filesystem feature (JOURNAL_DEV) disallows mounting");		if( hasIncompatFeature(Ext2Constants.EXT3_FEATURE_INCOMPAT_RECOVER) )			throw new FileSystemException(getDevice().getId()+" Unsupported filesystem feature (RECOVER) disallows mounting");		//an unsupported RO_COMPAT feature means that the filesystem can only be mounted readonly		if( hasROFeature(Ext2Constants.EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {			log.info(getDevice().getId()+" Unsupported filesystem feature (LARGE_FILE) forces readonly mode");			setReadOnly(true);		}				if( hasROFeature(Ext2Constants.EXT2_FEATURE_RO_COMPAT_BTREE_DIR)) {			log.info(getDevice().getId()+" Unsupported filesystem feature (BTREE_DIR) forces readonly mode");			setReadOnly(true);		}				//if the filesystem has not been cleanly unmounted, mount it readonly		if(superblock.getState()==Ext2Constants.EXT2_ERROR_FS) {			log.info(getDevice().getId()+" Filesystem has not been cleanly unmounted, mounting it readonly");			setReadOnly(true);		}				//if the filesystem has been mounted R/W, set it to "unclean"		if(!isReadOnly()) {			log.info(getDevice().getId()+" mounting fs r/w");			superblock.setState(Ext2Constants.EXT2_ERROR_FS);		}				//log.info(  "Ext2fs filesystem constructed sucessfully");		log.debug( "	superblock:	#blocks:		"+superblock.getBlocksCount()+"\n"+					"				#blocks/group:	"+superblock.getBlocksPerGroup()+"\n"+					"				#block groups:	"+groupCount+"\n"+					"				block size:		"+superblock.getBlockSize()+"\n"+					"				#inodes:		"+superblock.getINodesCount()+"\n"+					"				#inodes/group:	"+superblock.getINodesPerGroup());	}