Untitled

 avatar
unknown
c_cpp
a year ago
3.2 kB
5
Indexable
int inode_iget(const struct unixfilesystem *fs, int inumber,
        struct inode *inp) {

    int inode_num = DISKIMG_SECTOR_SIZE / sizeof(struct inode);
    
	int sector = (inumber - 1) / inode_num; // Get sector (starts from index 1)
	int offset = (inumber - 1) % inode_num; // Get offset (block in sector)

	struct inode cur_inodes[inode_num]; // Helper variable to keep sector

    int dfd = fs->dfd;
	int error_code = diskimg_readsector(dfd, sector + INODE_START_SECTOR, cur_inodes);
	if(error_code < 0) {
        fprintf(stderr, "inode_iget(inumber=%d) cannot read inumber, "
            "returning -1\n", inumber);
        return -1;
    }
	
	*inp = *(cur_inodes + offset); // Get block in sector
    return 0;
}

int inode_indexlookup(const struct unixfilesystem *fs, struct inode *inp,
        int fileBlockIndex) {
    
	if((inp->i_mode & ILARG) == 0) { // Small mode
		int index = *(inp->i_addr + fileBlockIndex); // Just get directly
        if (index == 0) {
            fprintf(stderr, "inode_indexlookup(fileBlockIndex=%d) tried to read an index out of range, "
            "returning -1\n", fileBlockIndex);
            return -1;
        }
        return index;
    }

    int dfd = fs->dfd;

    int num_addr = DISKIMG_SECTOR_SIZE / sizeof(uint16_t);
	int indir_addr_num = SINGLE_LENGTH * num_addr;

	if(fileBlockIndex < indir_addr_num) { // Need only a singly-indirect block
        uint16_t addrs[num_addr];
        int sector = fileBlockIndex / num_addr;
		int offset = fileBlockIndex % num_addr;
		
		int error = diskimg_readsector(dfd, *(inp->i_addr + sector), addrs);
		if(error < 0) {
            return -1;
        }

		int index = *(addrs + offset);
        if (index == 0) {
            fprintf(stderr, "inode_indexlookup(fileBlockIndex=%d) tried to read an index out of range, "
            "returning -1\n", fileBlockIndex);
            return -1;
        }

        return index;
	} else {
    	uint16_t single_addrs[num_addr]; // Information for singly-indirect blocks
		int blockNum_in_double = fileBlockIndex - indir_addr_num;
		int single_offset = blockNum_in_double / num_addr;

		int error = diskimg_readsector(dfd, inp->i_addr[SINGLE_LENGTH], single_addrs);
		if(error < 0) {
            fprintf(stderr, "inode_indexlookup(fileBlockIndex=%d) encountered error while reading first layer sector, "
            "returning -1\n", fileBlockIndex);
             return -1;
        }

        uint16_t double_addrs[num_addr]; // Information for doubly-indirect blocks
		int double_sector = single_addrs[single_offset];
		int double_offset = blockNum_in_double % num_addr;

		error = diskimg_readsector(dfd, double_sector, double_addrs);
		if(error < 0) {
            fprintf(stderr, "inode_indexlookup(fileBlockIndex=%d) encountered error while reading second layer sector, "
            "returning -1\n", fileBlockIndex);
            return -1;
        }

		int index = *(double_addrs + double_offset);
        if (index == 0) {
            fprintf(stderr, "inode_indexlookup(fileBlockIndex=%d) tried to read an index out of range, "
            "returning -1\n", fileBlockIndex);
            return -1;
        }

        return index;
	}	

    return 0;
}
Editor is loading...
Leave a Comment