![]() | ![]() |
|
||||||||||||||||||||||||||||||
|
File SystemA disk or disk partition is represented by a KernelBlockDevice abstraction. This abstraction encapsulates a sequence of disk blocks that can be read, written and released. Inode cacheAn Inode is an in-memory representation of an inode on disk. The inode allocator addresses three issues. The first is that a file could be open more than once at the same time and updates must be immediately available to all instances of the open file. The Inode allocator uses a cache to ensure that all references to an inode refer to the same in-memory copy. The second issue is that a buffer can hold more than one inode. In this implementation, an inode is 128 bytes while a block is 512 bytes. The Inode cache has to take care that the same buffer is used by two different inodes when they reside in the same block. The third issue has to do with deleting files. The link count in an inode tracks the number of times the file appears in a directory entry. When the link count goes to zero, the inode can be recycled, but only after all open references have been closed.
Inodes are delivered from cache or manufactured on the fly when the Inode allocator is presented with a file system and an inode index. In the code below, inodepack is the blocking factor for inodes. Inodes reside in contiguous storage on the disk, relocated by a value in the superblock. The key for the hash table is a combination of the disk identifier and the inode index. If the inode is not in memory, its block is acquired from the disk manager and a new InodeStruct is allocated. The InodeStruct relocates itself within the block based on the index, the inode size and the inode blocking factor. public InodeStruct open(FileSystem fs, int index) {
SuperBlockStruct sblock = fs.getSblock();
Integer hashkey = new Integer(fs.getDisk().hashCode() ^ index);
InodeStruct inode = (InodeStruct)table.get(hashkey);
if (inode == null) {
int inodeBlock = sblock.getIBlock() + index / inodepack;
Buffer buffer = fs.getDisk().read(inodeBlock);
inode = new InodeStruct(buffer, fs, index, inodesize, inodepack);
table.put(hashkey, inode);
}
inode.refcount++;
return inode;
}
When a file is closed, its inode is released. The refcount field used in the code above and below should not be confused with the inode's link count. The refcount field is used to track the number of references to the inode in memory. The inode's link count is used to track the number of references in the file system. The release() method recycles the in-memory data structure. Another level, which calls this release() method, handles recycling the inode in the disk data structure. public void release(InodeStruct inode) {
if (inode.refcount == 1) {
Integer hashkey
= new Integer(inode.fs.getDisk().hashCode() ^ inode.index);
table.remove(hashkey);
}
inode.refcount--;
}
|
|||||||||||||||||||||||||||||
Last update 01/24/05
Copyright © Gerald Dueck
[=]