/*
Author: Josepth, Jun
Date: 03/13/2020
Description: Starting block after superblock.
Includes 12 blocks, the starting 11s are direct and
the last one is indirect lbok.
16 inodes stored in one block.
each inode size is 32 byte
*/
public class Inode {
private final static int iNodeSize = 32;
public final static int directSize = 11;
// 16 inodes can be stored in 1 block
// private final static int perBlockSize = 16;
// 16 inodes in one block 512 (data retrieved from disk.java)
private final static int diskBlockSize = 512;
public int length;
public short count;
public short flag; // 0 = unused, 1 = used ...
public short direct[] = new short[directSize];
public short indirect;
public final static short UNUSED = 0;
public final static short USED = 1;
public final static short READ = 2;
public final static short WRITE = 3;
public final static short DELETE = 4;
// make all direct and indirect block to -1
Inode() {
length = 0;
count = 0;
flag = 1;
for (int i = 0; i < directSize; i++) {
direct[i] = -1;
}
indirect = -1;
}
// retrieve inode from the disk based on iNumber(index)
Inode(short iNumber) {
// basic case
// if (iNumber < 0) {
// return;
// }
// get block number
int blockNumber = iNumber / 16 + 1;
int offset = (iNumber % 16) * 32;
byte[] data = new byte[diskBlockSize];
// read from disk
SysLib.rawread(blockNumber, data);
length = SysLib.bytes2int(data, offset);
// int byte size
offset += 4;
count = SysLib.bytes2short(data, offset);
// short byte size
offset += 2;
flag = SysLib.bytes2short(data, offset);
offset += 2;
// assign direct[i]
for (int i = 0; i < directSize; i++) {
direct[i] = SysLib.bytes2short(data, offset);
offset += 2;
}
// assign indirect 12th
indirect = SysLib.bytes2short(data, offset);
offset += 2;
}
// save to disk based on index param must converted to bytes
// require inode number
int toDisk(short iNumber) {
// basic case
// if (iNumber < 0) {
// return -1;
// }
byte[] data = new byte[iNodeSize];
int offset = 0;
SysLib.int2bytes(length, data, offset);
// integer size
offset += 4;
SysLib.short2bytes(count, data, offset);
// short byte
offset += 2;
SysLib.short2bytes(flag, data, offset);
offset += 2;
// moved offset += 2 from loop
// removed (short)
for (int i = 0; i < directSize; i++) {
SysLib.short2bytes(direct[i], data, offset);
offset+=2;
}
// 12th indirect
SysLib.short2bytes(indirect, data, offset);
offset += 2;
int blockNumber = iNumber / 16 + 1;
byte[] newByteData = new byte[diskBlockSize];
SysLib.rawread(blockNumber, newByteData);
offset = (iNumber % 16) * 32;
// copy source, source-loc, copyto, copy-loc len
System.arraycopy(data, 0, newByteData, offset, iNodeSize);
SysLib.rawwrite(blockNumber, newByteData);
return 0;
}
int getTargetBlock(int taregetBlock) {
int block = taregetBlock / diskBlockSize;
if (block < directSize)
return direct[block];
if (indirect < 0)
return -1;
byte[] blockBytes = new byte[diskBlockSize];
SysLib.rawread(indirect, blockBytes);
int blockOffset = (block - directSize) * 2;
return SysLib.bytes2short(blockBytes, blockOffset);
}
int getIndexBlock(int entry, short offset) {
int blockNum = entry / diskBlockSize;
if (blockNum < directSize) {
if (direct[blockNum] >= 0)
return -1;
if (blockNum > 0 && direct[blockNum - 1] == -1)
return -2;
direct[blockNum] = offset;
return 0;
}
if (indirect < 0)
return -3;
else {
byte[] byteArr = new byte[diskBlockSize];
SysLib.rawread(indirect, byteArr);
int blockSize = (blockNum - directSize) * 2;
if (SysLib.bytes2short(byteArr, blockSize) > 0)
return -1;
else {
SysLib.short2bytes(offset, byteArr, blockSize);
SysLib.rawwrite(indirect, byteArr);
}
}
return 0;
}
boolean setIndexBlock(short blockNum) {
for (int i = 0; i < directSize; i++) {
if (direct[i] == -1)
return false;
}
if (indirect != -1)
return false;
indirect = blockNum;
byte[] byteArr = new byte[diskBlockSize];
for (int i = 0; i < (diskBlockSize / 2); i++)
SysLib.short2bytes((short)-1, byteArr, i * 2);
SysLib.rawwrite(blockNum, byteArr);
return true;
}
byte[] freeIndexBlock(){
if (indirect >= 0) {
byte[] byteArr = new byte[diskBlockSize];
SysLib.rawread(indirect, byteArr);
indirect = -1;
return byteArr;
}
else
return null;
}
}
댓글 0