Beispiel #1
0
/**
 * Allocate a bit in inode-map.
 *
 * @param dev  In which device the inode-map is located.
 *
 * @return  I-node nr.
 *****************************************************************************/
PRIVATE int alloc_imap_bit(int dev)
{
    int inode_nr = 0;
    int i, j, k;

    int imap_blk0_nr = 1 + 1; /* 1 boot sector & 1 super block */
    struct super_block * sb = get_super_block(dev);

    for (i = 0; i < sb->nr_imap_sects; i++) {
        RD_SECT(dev, imap_blk0_nr + i);

        for (j = 0; j < SECTOR_SIZE; j++) {
            /* skip `11111111' bytes */
            if (fsbuf[j] == 0xFF)
                continue;
            /* skip `1' bits */
            for (k = 0; ((fsbuf[j] >> k) & 1) != 0; k++) {}
            /* i: sector index; j: byte index; k: bit index */
            inode_nr = (i * SECTOR_SIZE + j) * 8 + k;
            fsbuf[j] |= (1 << k);
            /* write the bit to imap */
            WR_SECT(dev, imap_blk0_nr + i);
            break;
        }

        return inode_nr;
    }

    /* no free bit in imap */
    panic("inode-map is probably full.\n");

    return 0;
}
Beispiel #2
0
Datei: open.c Projekt: Zach41/OS
PRIVATE int alloc_imap_bit(int dev) {
    int inode_nr = 0;

    int i, j, k;
    int imap_blk0_nr = 2;
    assert(dev == ROOT_DEV);
    struct super_block *sb = get_super_block(dev);

    
    for (i=0; i<sb -> nr_imap_sects; i++) {
	RD_SECT(dev, imap_blk0_nr+i);

	for (j=0; j<SECTOR_SIZE; j++) {
	    if (fsbuf[j] == 0xFF)
		continue;
	    for (k=0; (fsbuf[j] & (1<<k))!=0; k++)
		;
	    inode_nr = (i*SECTOR_SIZE + j)*8 + k;
	    fsbuf[j] |= (1<<k);

	    WR_SECT(dev, imap_blk0_nr+i);

	    return inode_nr;
	}
    }

    panic("Inode map is full.\n");

    return 0;
}
Beispiel #3
0
PRIVATE int alloc_imap_bit(int dev)
{
    int inode_nr = 0;
    int imap_blk0_nr = 1 + 1; // boot sector + super block
    struct super_block *sb = get_super_block(dev);

    for (int i = 0; i < sb->nr_imap_sects; i++) { // 逐扇区遍历 inode map
        RD_SECT(dev, imap_blk0_nr + i);

        for (int j = 0; j < SECTOR_SIZE; j++) { // 逐字节
            /* 跳过已经使用的(1:使用;0:未使用) */
            if (fsbuf[j] == 0xFF)
                continue;

            int k = 0;
            for (k = 0; ((fsbuf[j] >> k) & 1) != 0; k++); // 逐位(一位代表一个 inode)

            inode_nr = (i * SECTOR_SIZE + j) * 8 + k;
            fsbuf[j] |= (1 << k);

            /* 将更新后的 inode map 写入磁盘 */
            WR_SECT(dev, imap_blk0_nr + i);
            break;
        }

        return inode_nr;
    }

    panic("inode-map is probably full.\n");

    return 0;
}
Beispiel #4
0
/**
 * Write a new entry into the directory.
 * 
 * @param dir_inode  I-node of the directory.
 * @param inode_nr   I-node nr of the new file.
 * @param filename   Filename of the new file.
 *****************************************************************************/
PRIVATE void new_dir_entry(struct inode * dir_inode, int inode_nr, char * filename)
{
	/* struct super_block * sb = get_super_block(dir_inode->i_dev); */

	/* write the dir_entry */
	int dir_blk0_nr = dir_inode->i_start_sect;
	/* printl("n_1st_sect:0x%x, dir_blk0_nr:0x%x\n", */
	/*        sb->n_1st_sect, dir_blk0_nr); */
	int nr_dir_blks = (dir_inode->i_size + SECTOR_SIZE) / SECTOR_SIZE;
	int nr_dir_entries =
		dir_inode->i_size / DIR_ENTRY_SIZE; /**
						     * including unused slots
						     * (the file has been
						     * deleted but the slot
						     * is still there)
						     */
	int m = 0;
	struct dir_entry * pde;
	struct dir_entry * new_de = 0;

	int i, j;
	for (i = 0; i < nr_dir_blks; i++) {
		RD_SECT(dir_inode->i_dev, dir_blk0_nr + i);

		pde = (struct dir_entry *)fsbuf;
		for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) {
			if (++m > nr_dir_entries)
				break;

			if (pde->inode_nr == 0) { /* it's a free slot */
				new_de = pde;
				break;
			}
		}
		if (m > nr_dir_entries ||/* all entries have been iterated or */
		    new_de)              /* free slot is found */
			break;
	}
	/* printm("FS::in create_file: nr_dir_blks:%d, i:%d\n", nr_dir_blks, i); */
	if (!new_de) {		/* reached the end of the dir */
		new_de = pde;
		dir_inode->i_size += DIR_ENTRY_SIZE;
	}
	new_de->inode_nr = inode_nr;
	strcpy(new_de->name, filename);

	/* write dir block -- ROOT dir block */
	WR_SECT(dir_inode->i_dev, dir_blk0_nr + i);

	/* update dir inode */
	sync_inode(dir_inode);
}
Beispiel #5
0
//when inode is changed , write it to disk
void sync_inode(struct inode *p)
{
    struct inode *pinode;
    struct super_block * get_super_block(int dev);
    struct super_block *sb = get_super_block(p->i_dev);
    int blk_nr = 2+sb->nr_imap_sects + sb->nr_smap_sects+ ((p->i_num-1)/(SECTOR_SIZE /INODE_SIZE));//inode_nr==0 is not used
    RD_SECT(p->i_dev, blk_nr);
    pinode = (struct inode *)((t_8*)fsbuf + ((p->i_num-1)%(SECTOR_SIZE/INODE_SIZE)) *INODE_SIZE);

    pinode->i_mode = p->i_mode;
    pinode->i_size = p->i_size;
    pinode->i_start_sect = p->i_start_sect;
    pinode->i_nr_sects = p->i_nr_sects;
    WR_SECT(p->i_dev, blk_nr);
}
Beispiel #6
0
/**
 * Allocate a bit in sector-map.
 *
 * @param dev  In which device the sector-map is located.
 * @param nr_sects_to_alloc  How many sectors are allocated.
 *
 * @return  The 1st sector nr allocated.
 *****************************************************************************/
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc)
{
    /* int nr_sects_to_alloc = NR_DEFAULT_FILE_SECTS; */

    int i; /* sector index */
    int j; /* byte index */
    int k; /* bit index */

    struct super_block * sb = get_super_block(dev);

    int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects;
    int free_sect_nr = 0;

    for (i = 0; i < sb->nr_smap_sects; i++) {
        /* smap_blk0_nr + i :
        					     current sect nr. */
        RD_SECT(dev, smap_blk0_nr + i);

        /* byte offset in current sect */
        for (j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++) {
            k = 0;
            if (!free_sect_nr) {
                /* loop until a free bit is found */
                if (fsbuf[j] == 0xFF) continue;
                for (; ((fsbuf[j] >> k) & 1) != 0; k++) {}
                free_sect_nr = (i * SECTOR_SIZE + j) * 8 +
                               k - 1 + sb->n_1st_sect;
            }

            for (; k < 8; k++) { /* repeat till enough bits are set */
                assert(((fsbuf[j] >> k) & 1) == 0);
                fsbuf[j] |= (1 << k);
                if (--nr_sects_to_alloc == 0)
                    break;
            }
        }

        if (free_sect_nr) /* free bit found, write the bits to smap */
            WR_SECT(dev, smap_blk0_nr + i);

        if (nr_sects_to_alloc == 0)
            break;
    }

    assert(nr_sects_to_alloc == 0);

    return free_sect_nr;
}
Beispiel #7
0
/**
 * <Ring 1> Write the inode back to the disk. Commonly invoked as soon as the
 *          inode is changed.
 * 
 * @param p I-node ptr.
 *****************************************************************************/
PUBLIC void sync_inode(struct inode * p)
{
	struct inode * pinode;
	struct super_block * sb = get_super_block(p->i_dev);
	int blk_nr = 1 + 1 + sb->nr_imap_sects + sb->nr_smap_sects +
		((p->i_num - 1) / (SECTOR_SIZE / INODE_SIZE));
	RD_SECT(p->i_dev, blk_nr);
	pinode = (struct inode*)((u8*)fsbuf +
				 (((p->i_num - 1) % (SECTOR_SIZE / INODE_SIZE))
				  * INODE_SIZE));
	pinode->i_mode = p->i_mode;
	pinode->i_size = p->i_size;
	pinode->i_start_sect = p->i_start_sect;
	pinode->i_nr_sects = p->i_nr_sects;
	WR_SECT(p->i_dev, blk_nr);
}
Beispiel #8
0
PRIVATE void new_dir_entry(struct inode *dir_inode, int inode_nr, char *filename)
{
    /* write the dir_entry */
    int dir_blk0_nr = dir_inode->i_start_sect;                         // 目录文件的起始扇区
    int nr_dir_blks = (dir_inode->i_size + SECTOR_SIZE) / SECTOR_SIZE; // 目录文件所占扇区数
    int nr_dir_entries = dir_inode->i_size / DIR_ENTRY_SIZE;           // 目录项数
    int m = 0;
    struct dir_entry *pde;
    struct dir_entry *new_de = 0;

    int i;
    for (i = 0; i < nr_dir_blks; i++) { // 逐扇区
        RD_SECT(dir_inode->i_dev, dir_blk0_nr + i);

        pde = (struct dir_entry *)fsbuf;
        for (int j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++, pde++) { // 逐目录项
            if (++m > nr_dir_entries)
                break;

            if (pde->inode_nr == 0) { /* it's a free slot */
                new_de = pde;
                break;
            }
        }

        if (m > nr_dir_entries || // all entries have been iterated or */
            new_de)               // free slot is found */
            break;
    }
    
    if (!new_de) { /* reached the end of the dir */
        new_de = pde;
        dir_inode->i_size += DIR_ENTRY_SIZE;
    }
    new_de->inode_nr = inode_nr;
    strcpy(new_de->name, filename);

    /* write dir block -- ROOT dir block */
    WR_SECT(dir_inode->i_dev, dir_blk0_nr + i);

    /* update dir inode */
    sync_inode(dir_inode);
}
Beispiel #9
0
/**************************************************************************************************
 * 					alloc_smap_bit
 **************************************************************************************************
 * Allocate a bit in sector-map.
 *
 * @param dev			In which device the sector-map is located.
 * @param nr_sects_to_alloc	How many sectors are allocated.
 *
 * @return	The 1st sector nr allocated.
 *************************************************************************************************/
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc){
	int i, j, k;	/* i: sector index	j: byte index	k: bit index */
	int nr_free_sect	= 0;

	struct super_block* sb	= get_super_block(dev);
	int nr_smap_blk0	= 1 + 1 + sb->nr_imap_sects;

	for(i=0; i<sb->nr_smap_sects; i++){
		RD_SECT(dev, nr_smap_blk0 + i);

		for(j=0; j<SECTOR_SIZE && nr_sects_to_alloc > 0; j++){
			k = 0;
			if(!nr_free_sect){
				/* loop untill a free bit is found. */
				if(fsbuf[j] == 0xff){
					continue;
				}
				for(; ((fsbuf[j] >> k) & 1) != 0; k++){}

				nr_free_sect = (i * SECTOR_SIZE + j) * 8 + k - 1 + sb->n_1st_sect;
			}
			/* repeat till enough bits are set */
			for(; k < 8; k++){
				assert(((fsbuf[j] >> k) & 1) == 0);
				fsbuf[j] |= (1 << k);
				if(--nr_sects_to_alloc == 0){
					break;
				}
			}
		}
		/* free bit was found, write the bit to smap */
		if(nr_free_sect){
			WR_SECT(dev, nr_smap_blk0 + i);
		}

		if(nr_sects_to_alloc == 0){
			break;
		}
	}
	assert(nr_sects_to_alloc == 0);

	return nr_free_sect;
}
Beispiel #10
0
Datei: open.c Projekt: Zach41/OS
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc) {
    int i, j, k;
    assert(dev == ROOT_DEV);
    assert(nr_sects_to_alloc == NR_DEFAULT_FILE_SECTS);
    struct super_block* sb = get_super_block(dev);
    assert(sb -> nr_smap_sects);
    int smap_blk0_nr = 2 + sb -> nr_imap_sects;
    int free_sect_nr = 0;
    
    for (i=0; i<sb -> nr_smap_sects; i++) {
	RD_SECT(dev, smap_blk0_nr + i);

	for (j=0; j<SECTOR_SIZE && nr_sects_to_alloc>0; j++) {
	    k = 0;
	    if(!free_sect_nr) {
		/* 找到第一个空闲的扇区 */
		/* 由于文件最大长度固定,并不需要考虑空洞,找到就可以了 */
		if (fsbuf[j] == 0xFF)
		    continue;
		for(; (fsbuf[j] & (1<<k)) != 0; k++)
		    ;
		free_sect_nr = (i*SECTOR_SIZE + j) * 8 + k - 1 + sb -> n_1st_sect;
	    }

	    for(; k<8; k++) {
		assert(((fsbuf[j] >> k) & 1) == 0);
		fsbuf[j] |= 1<<k;
		if (--nr_sects_to_alloc == 0)
		    break;
	    }
	}
	if (free_sect_nr)
	    WR_SECT(dev, smap_blk0_nr+i);
	if (nr_sects_to_alloc == 0)
	    break;
    }

    if (nr_sects_to_alloc != 0) {
	panic("Don't have enough space.\n");
    }

    return free_sect_nr;
}
Beispiel #11
0
/**************************************************************************************************
 * 					new_dir_entry
 **************************************************************************************************
 * Write a new entry into the directory.
 *
 * @param dir_inode	Inode of the directory.
 * @param nr_inode	Inode nr of the new file.
 * @param filename	File name of the new file.
 *************************************************************************************************/
PRIVATE void new_dir_entry(struct inode* dir_inode, int nr_inode, char* filename){
	/* Write the dir_entry */
	int nr_dir_blk0	= dir_inode->i_start_sect;
	int nr_dir_blks	= (dir_inode->i_size + SECTOR_SIZE) / SECTOR_SIZE;
	/* including unused slots (the file has been deleted but the slot is still there) */
	int nr_dir_entries = dir_inode->i_size / DIR_ENTRY_SIZE;

	int m = 0;
	int i, j;
	struct dir_entry* pde;
	struct dir_entry* new_de = 0;

	for(i=0; i<nr_dir_blks; i++){
		RD_SECT(dir_inode->i_dev, nr_dir_blk0 + i);

		pde = (struct dir_entry*) fsbuf;
		for(j=0; j<SECTOR_SIZE / DIR_ENTRY_SIZE; j++, pde++){
			if(++m > nr_dir_entries){
				break;
			}
			if(pde->inode_nr == 0){	/* it's a free slot */
				new_de = pde;
				break;
			}
		}
		if(m > nr_dir_entries || new_de){/* all entries have been iterated or */
			break;			/* free slot is found */
		}
	}
	if(!new_de){				/* reached the end of the dir */
		new_de = pde;
		dir_inode->i_size += DIR_ENTRY_SIZE;
	}
	new_de->inode_nr = nr_inode;
	strcpy(new_de->name, filename);

	/* Write dir block -- ROOT dir block */
	WR_SECT(dir_inode->i_dev, nr_dir_blk0 + i);

	/* update dir inode */
	sync_inode(dir_inode);
}
Beispiel #12
0
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc)
{
    struct super_block *sb = get_super_block(dev);
    int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; // boot sector + super block + inode map
    int free_sect_nr = 0; // 空闲 sector 起始号

    for (int i = 0; i < sb->nr_smap_sects; i++) { // 逐扇区遍历 sector map
        RD_SECT(dev, smap_blk0_nr + i);

        for (int j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++) { // 逐字节
            int k = 0;
            if (!free_sect_nr) {
                if (fsbuf[j] == 0xFF)
                    continue;
                for (; ((fsbuf[j] >> k) & 1) != 0; k++); // 逐位(一位代表一个扇区)

                free_sect_nr = (i * SECTOR_SIZE + j) * 8
                             + k - 1 + sb->n_1st_sect;
            }

            for (; k < 8; k++) {
                assert(((fsbuf[j] >> k) & 1) == 0);
                fsbuf[j] |= (1 << k);
                if (--nr_sects_to_alloc == 0)
                    break;
            }
        }

        /* 将更新后的 sector map 扇区写入磁盘 */
        if (free_sect_nr)
            WR_SECT(dev, smap_blk0_nr + i);

        if (nr_sects_to_alloc == 0)
            break;
    }

    assert(nr_sects_to_alloc == 0);

    return free_sect_nr;
}
Beispiel #13
0
Datei: open.c Projekt: Zach41/OS
/* dir_inode: root_node */
PRIVATE void new_dir_entry(struct inode* dir_inode, int inode_nr, char* filename) {
    int dir_blk0_nr = dir_inode -> i_start_sect;
    int nr_dir_blks = (dir_inode -> i_size + SECTOR_SIZE) / SECTOR_SIZE;
    int nr_dir_entries = dir_inode -> i_size / DIR_ENTRY_SIZE;

    int i, j;
    int m = 0;
    struct dir_entry* p_dir_entry;
    struct dir_entry* new_entry = 0;

    for(i=0; i<nr_dir_blks; i++) {
	RD_SECT(dir_inode -> i_dev, dir_blk0_nr + i);
	p_dir_entry = (struct dir_entry*)fsbuf;

	for (j = 0; j<SECTOR_SIZE / DIR_ENTRY_SIZE; j++, p_dir_entry++) {
	    if (++m > nr_dir_entries)
		break;

	    if (p_dir_entry -> inode_nr == 0) {
		/* 之前被删除的文件留下来的entry */
		/* 如果文件删除了,dir_inode -> i_size不会改变 */
		new_entry = p_dir_entry;
		break;
	    }
	}
	if (m > nr_dir_entries || new_entry)
	    break;
    }
    if (!new_entry) {
	new_entry = p_dir_entry;
	dir_inode -> i_size += DIR_ENTRY_SIZE;
    }

    new_entry -> inode_nr = inode_nr;
    strcpy(new_entry -> name, filename);

    WR_SECT(dir_inode -> i_dev, dir_blk0_nr+i);

    sync_inode(dir_inode);
}
Beispiel #14
0
/**
 * Allocate a bit in sector-map.
 * 
 * @param dev  In which device the sector-map is located.
 * @param nr_sects_to_alloc  How many sectors are allocated.
 * @param i_zone the zone of the inode
 * 
 * @return  The 1st sector nr allocated.
 *****************************************************************************/
PRIVATE int alloc_bit(int dev)
{
	int i; /* sector index */
	int j; /* byte index */
	int k; /* bit index */

	struct super_block * sb = get_super_block(dev);

	int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects;
	int flag_bit_alloc = 0;
	int bit_alloc = 0;
	for (i = 0; i < sb->nr_smap_sects; i++) { /* smap_blk0_nr + i :
						     current sect nr. */
		RD_SECT(dev, smap_blk0_nr + i);

		/* byte offset in current sect */
		for (j = 0; j < SECTOR_SIZE ; j++) {
			/* loop until a free bit is found */
			if (fsbuf[j] != 0xFF) {
				k = 0;
				for (; ((fsbuf[j] >> k) & 1) != 0; k++) {}

				assert(((fsbuf[j] >> k) & 1) == 0);
				fsbuf[j] |= (1 << k);
				flag_bit_alloc = 1;
				//1 byte = 8 bit ~ stand for 8 sector
				bit_alloc = i * SECTOR_SIZE * 8
							+ j * 8
							+ k - 1
							+ sb->n_1st_sect;
				break;
			}
		}

		if (flag_bit_alloc) {
			/* free bit found, write the bits to smap */
			WR_SECT(dev, smap_blk0_nr + i);
			break;
		}
	}
Beispiel #15
0
/**
 * Remove a file.
 *
 * @note We clear the i-node in inode_array[] although it is not really needed.
 *       We don't clear the data bytes so the file is recoverable.
 * 
 * @return On success, zero is returned.  On error, -1 is returned.
 *****************************************************************************/
PUBLIC int do_unlink()
{
	char pathname[MAX_PATH];

	/* get parameters from the message */
	int name_len = fs_msg.NAME_LEN;	/* length of filename */
	int src = fs_msg.source;	/* caller proc nr. */
	assert(name_len < MAX_PATH);
	phys_copy((void*)va2la(TASK_FS, pathname),
		  (void*)va2la(src, fs_msg.PATHNAME),
		  name_len);
	pathname[name_len] = 0;

	if (strcmp(pathname , "/") == 0) {
		printl("FS:do_unlink():: cannot unlink the root\n");
		return -1;
	}

	int inode_nr = search_file(pathname);
	if (inode_nr == INVALID_INODE) {	/* file not found */
		printl("FS::do_unlink():: search_file() returns "
			"invalid inode: %s\n", pathname);
		return -1;
	}

	char filename[MAX_PATH];
	struct inode * dir_inode;
	if (strip_path(filename, pathname, &dir_inode) != 0)
		return -1;

	struct inode * pin = get_inode(dir_inode->i_dev, inode_nr);

	if (pin->i_mode != I_REGULAR) { /* can only remove regular files */
		printl("cannot remove file %s, because "
		       "it is not a regular file.\n",
		       pathname);
		return -1;
	}

	if (pin->i_cnt > 1) {	/* the file was opened */
		printl("cannot remove file %s, because pin->i_cnt is %d.\n",
		       pathname, pin->i_cnt);
		return -1;
	}

	struct super_block * sb = get_super_block(pin->i_dev);

	/*************************/
	/* free the bit in i-map */
	/*************************/
	int byte_idx = inode_nr / 8;
	int bit_idx = inode_nr % 8;
	assert(byte_idx < SECTOR_SIZE);	/* we have only one i-map sector */
	/* read sector 2 (skip bootsect and superblk): */
	RD_SECT(pin->i_dev, 2);
	assert(fsbuf[byte_idx % SECTOR_SIZE] & (1 << bit_idx));
	fsbuf[byte_idx % SECTOR_SIZE] &= ~(1 << bit_idx);
	WR_SECT(pin->i_dev, 2);

	/**************************/
	/* free the bits in s-map */
	/**************************/
	/*
	 *           bit_idx: bit idx in the entire i-map
	 *     ... ____|____
	 *                  \        .-- byte_cnt: how many bytes between
	 *                   \      |              the first and last byte
	 *        +-+-+-+-+-+-+-+-+ V +-+-+-+-+-+-+-+-+
	 *    ... | | | | | |*|*|*|...|*|*|*|*| | | | |
	 *        +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
	 *         0 1 2 3 4 5 6 7     0 1 2 3 4 5 6 7
	 *  ...__/
	 *      byte_idx: byte idx in the entire i-map
	 */
	bit_idx  = pin->i_start_sect - sb->n_1st_sect + 1;
	byte_idx = bit_idx / 8;
	int bits_left = pin->i_nr_sects;
	int byte_cnt = (bits_left - (8 - (bit_idx % 8))) / 8;

	/* current sector nr. */
	int s = 2  /* 2: bootsect + superblk */
		+ sb->nr_imap_sects + byte_idx / SECTOR_SIZE;

	RD_SECT(pin->i_dev, s);

	int i;
	/* clear the first byte */
	for (i = bit_idx % 8; (i < 8) && bits_left; i++,bits_left--) {
		//assert((fsbuf[byte_idx % SECTOR_SIZE] >> i & 1) == 1);
		fsbuf[byte_idx % SECTOR_SIZE] &= ~(1 << i);
	}

	/* clear bytes from the second byte to the second to last */
	int k;
	i = (byte_idx % SECTOR_SIZE) + 1;	/* the second byte */
	for (k = 0; k < byte_cnt; k++,i++,bits_left-=8) {
		if (i == SECTOR_SIZE) {
			i = 0;
			WR_SECT(pin->i_dev, s);
			RD_SECT(pin->i_dev, ++s);
		}
		//assert(fsbuf[i] == 0xFF);
		fsbuf[i] = 0;
	}

	/* clear the last byte */
	if (i == SECTOR_SIZE) {
		i = 0;
		WR_SECT(pin->i_dev, s);
		RD_SECT(pin->i_dev, ++s);
	}
	unsigned char mask = ~((unsigned char)(~0) << bits_left);
	//assert((fsbuf[i] & mask) == mask);
	fsbuf[i] &= (~0) << bits_left;
	WR_SECT(pin->i_dev, s);

	/***************************/
	/* clear the i-node itself */
	/***************************/
	pin->i_mode = 0;
	pin->i_size = 0;
	pin->i_start_sect = 0;
	pin->i_nr_sects = 0;
	sync_inode(pin);
	/* release slot in inode_table[] */
	put_inode(pin);

	/************************************************/
	/* set the inode-nr to 0 in the directory entry */
	/************************************************/
	int dir_blk0_nr = dir_inode->i_start_sect;
	int nr_dir_blks = (dir_inode->i_size + SECTOR_SIZE) / SECTOR_SIZE;
	int nr_dir_entries =
		dir_inode->i_size / DIR_ENTRY_SIZE; /* including unused slots
						     * (the file has been
						     * deleted but the slot
						     * is still there)
						     */
	int m = 0;
	struct dir_entry * pde = 0;
	int flg = 0;
	int dir_size = 0;

	for (i = 0; i < nr_dir_blks; i++) {
		RD_SECT(dir_inode->i_dev, dir_blk0_nr + i);

		pde = (struct dir_entry *)fsbuf;
		int j;
		for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) {
			if (++m > nr_dir_entries)
				break;

			if (pde->inode_nr == inode_nr) {
				/* pde->inode_nr = 0; */
				memset(pde, 0, DIR_ENTRY_SIZE);
				WR_SECT(dir_inode->i_dev, dir_blk0_nr + i);
				flg = 1;
				break;
			}

			if (pde->inode_nr != INVALID_INODE)
				dir_size += DIR_ENTRY_SIZE;
		}

		if (m > nr_dir_entries || /* all entries have been iterated OR */
		    flg) /* file is found */
			break;
	}
	assert(flg);
	if (m == nr_dir_entries) { /* the file is the last one in the dir */
		dir_inode->i_size = dir_size;
		sync_inode(dir_inode);
	}

	return 0;
}
Beispiel #16
0
/**************************************************************************************************
 * 					mkfs
 **************************************************************************************************
 * <Ring 1> Make an available bzOS FS in the disk. It will
 * 	- Write a super block to sector 1.
 * 	- Create three special files: dev_tty0, dev_tty1, dev_tty2.
 * 	- Create the inode map.
 * 	- Create the sector map.
 * 	- Create the inodes of the files.
 * 	- Create '/', the root directory.
 *************************************************************************************************/
PRIVATE void mkfs(){
	MESSAGE	driver_msg;
	int i, j;
	int bits_per_sect	= SECTOR_SIZE * 8;

	/* get the geometry of ROOTDEV */
	struct part_info geo;
	driver_msg.type		= DEV_IOCTL;
	driver_msg.DEVICE	= MINOR(ROOT_DEV);
	driver_msg.REQUEST	= DIOCTL_GET_GEO;
	driver_msg.BUF		= &geo;
	driver_msg.PROC_NR	= TASK_FS;
	
	assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);

	send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

	printl("{FS} dev size: %x sectors\n", geo.size);

	/******************************************************************************************
	 * Super Block
	 *****************************************************************************************/
	struct super_block sb;
	sb.magic		= MAGIC_V1;

	sb.nr_inodes		= bits_per_sect;
	sb.nr_inode_sects	= sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
	sb.nr_sects		= geo.size;	/* partition size */
	sb.nr_imap_sects	= 1;
	sb.nr_smap_sects	= sb.nr_sects / bits_per_sect + 1;
	sb.n_1st_sect		= 1 + 1 + /* boot sector & super block */
				  sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
	sb.root_inode		= ROOT_INODE;
	sb.inode_size		= INODE_SIZE;
	
	struct inode x;
	sb.inode_isize_off	= (int)&x.i_size - (int)&x;
	sb.inode_start_off	= (int)&x.i_start_sect - (int)&x;

	sb.dir_ent_size		= DIR_ENTRY_SIZE;
	
	struct dir_entry de;
	sb.dir_ent_inode_off	= (int)&de.inode_nr - (int)&de;
	sb.dir_ent_fname_off	= (int)&de.name - (int)&de;

	memset(fsbuf, 0x90, SECTOR_SIZE);
	memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);
	/* write the super block using fsbuf */
	WR_SECT(ROOT_DEV, 1);
	/* 这里全是字节偏移量,后面加上00,然后* 2,其实就是(扇区*扇区字节大小) */
	printl("{FS} devbase: %x00, sb: %x00, imap: %x00, smap: %x00\n"
		"        inodes: %x00, 1st_sector: %x00\n",
		geo.base * 2,
		(geo.base + 1) * 2,
		(geo.base + 2) * 2,
		(geo.base + 2 + sb.nr_imap_sects) * 2,
		(geo.base + 2 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
		(geo.base + sb.n_1st_sect) *2
		);

	/******************************************************************************************
	 * inode map
	 *****************************************************************************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	/* there are NR_CONSOLES character devices here */
	for(i=0; i<NR_CONSOLES + 2; i++){
		fsbuf[0] |= 1 << i;
	}

	assert(fsbuf[0] == 0x1f);/**
				  * 0001 1111:
				  * bit 0: reserved.
				  * bit 1: the first inode, which indicates '/'.
				  * bit 2: /dev_tty0
				  * bit 3: /dev_tty1
				  * bit 4: /dev_tty2
				  */
	WR_SECT(ROOT_DEV, 2);

	/******************************************************************************************
	 * sector map
	 *****************************************************************************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	int nr_sects	= NR_DEFAULT_FILE_SECTS + 1;	/* bit 0 is reserved, root directory */
	for(i=0; i<nr_sects / 8; i++){			/* Notify this division */
		fsbuf[i] = 0xff;
	}
	for(j=0; j<nr_sects % 8; j++){
		fsbuf[i] |= (1 << j);
	}

	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

	/* zeromemory the rest sector-map */
	memset(fsbuf, 0, SECTOR_SIZE);
	for(i=1; i<sb.nr_smap_sects; i++){
		WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);
	}
	/******************************************************************************************
	 * inodes
	 *****************************************************************************************/
	/* inode of '/' */
	memset(fsbuf, 0, SECTOR_SIZE);
	struct inode* pi	= (struct inode*) fsbuf;
	pi->i_mode		= I_DIRECTORY;
	pi->i_size		= DIR_ENTRY_SIZE * 4;/* 4 files:
						      * '.'.
						      * 'dev_tty0', 'dev_tty1', 'dev_tty2'
						      */
	pi->i_start_sect	= sb.n_1st_sect;
	pi->i_nr_sects		= NR_DEFAULT_FILE_SECTS;
	/* inode of '/dev_tty0~2' */
	for(i=0; i<NR_CONSOLES; i++){
		pi		= (struct inode*) (fsbuf + (INODE_SIZE * (i + 1)));
		pi->i_mode	= I_CHAR_SPECIAL;
		pi->i_size	= 0;
		pi->i_start_sect= MAKE_DEV(DEV_CHAR_TTY, i);
		pi->i_nr_sects	= 0;
	}
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);
	/******************************************************************************************
	 * '/'
	 *****************************************************************************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	struct dir_entry* pde	= (struct dir_entry*)fsbuf;
	pde->inode_nr		= 1;
	strcpy(pde->name, ".");

	/* dir entries of '/dev_tty0~2' */
	for(i=0; i<NR_CONSOLES; i++){
		pde ++;
		pde->inode_nr	= i + 2;
		sprintf(pde->name, "dev_tty%d", i);	/* do not use 'vsprintf' */
	}
	WR_SECT(ROOT_DEV, sb.n_1st_sect);

}
Beispiel #17
0
/**
 * <Ring 1> Make a available Orange'S FS in the disk. It will
 *          - Write a super block to sector 1.
 *          - Create three special files: dev_tty0, dev_tty1, dev_tty2
 *          - Create the inode map
 *          - Create the sector map
 *          - Create the inodes of the files
 *          - Create `/', the root directory
 *****************************************************************************/
PRIVATE void mkfs()
{
	MESSAGE driver_msg;
	int i, j;

	int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */

	/* get the geometry of ROOTDEV */
	struct part_info geo;
	driver_msg.type		= DEV_IOCTL;
	driver_msg.DEVICE	= MINOR(ROOT_DEV);
	driver_msg.REQUEST	= DIOCTL_GET_GEO;
	driver_msg.BUF		= &geo;
	driver_msg.PROC_NR	= TASK_FS;
	assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
	send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

	printl("dev size: 0x%x sectors\n", geo.size);

	/************************/
	/*      super block     */
	/************************/
	struct super_block sb;
	sb.magic	  = MAGIC_V1;
	sb.nr_inodes	  = bits_per_sect;
	sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
	sb.nr_sects	  = geo.size; /* partition size in sector */
	sb.nr_imap_sects  = 1;
	sb.nr_smap_sects  = sb.nr_sects / bits_per_sect + 1;
	sb.n_1st_sect	  = 1 + 1 +   /* boot sector & super block */
		sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
	sb.root_inode	  = ROOT_INODE;
	sb.inode_size	  = INODE_SIZE;
	struct inode x;
	sb.inode_isize_off= (int)&x.i_size - (int)&x;
	sb.inode_start_off= (int)&x.i_start_sect - (int)&x;
	sb.dir_ent_size	  = DIR_ENTRY_SIZE;
	struct dir_entry de;
	sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de;
	sb.dir_ent_fname_off = (int)&de.name - (int)&de;

	memset(fsbuf, 0x90, SECTOR_SIZE);
	memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);

	/* write the super block */
	WR_SECT(ROOT_DEV, 1);

	printl("devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n"
	       "        inodes:0x%x00, 1st_sector:0x%x00\n", 
	       geo.base * 2,
	       (geo.base + 1) * 2,
	       (geo.base + 1 + 1) * 2,
	       (geo.base + 1 + 1 + sb.nr_imap_sects) * 2,
	       (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
	       (geo.base + sb.n_1st_sect) * 2);

	/************************/
	/*       inode map      */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	for (i = 0; i < (NR_CONSOLES + 2); i++)
		fsbuf[0] |= 1 << i;

	assert(fsbuf[0] == 0x1F);/* 0001 1111 : 
				  *    | ||||
				  *    | |||`--- bit 0 : reserved
				  *    | ||`---- bit 1 : the first inode,
				  *    | ||              which indicates `/'
				  *    | |`----- bit 2 : /dev_tty0
				  *    | `------ bit 3 : /dev_tty1
				  *    `-------- bit 4 : /dev_tty2
				  */
	WR_SECT(ROOT_DEV, 2);

	/************************/
	/*      secter map      */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
	/*             ~~~~~~~~~~~~~~~~~~~|~   |
	 *                                |    `--- bit 0 is reserved
	 *                                `-------- for `/'
	 */
	for (i = 0; i < nr_sects / 8; i++)
		fsbuf[i] = 0xFF;

	for (j = 0; j < nr_sects % 8; j++)
		fsbuf[i] |= (1 << j);

	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

	/* zeromemory the rest sector-map */
	memset(fsbuf, 0, SECTOR_SIZE);
	for (i = 1; i < sb.nr_smap_sects; i++)
		WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

	/************************/
	/*       inodes         */
	/************************/
	/* inode of `/' */
	memset(fsbuf, 0, SECTOR_SIZE);
	struct inode * pi = (struct inode*)fsbuf;
	pi->i_mode = I_DIRECTORY;
	pi->i_size = DIR_ENTRY_SIZE * 4; /* 4 files:
					  * `.',
					  * `dev_tty0', `dev_tty1', `dev_tty2',
					  */
	pi->i_start_sect = sb.n_1st_sect;
	pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
	/* inode of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1)));
		pi->i_mode = I_CHAR_SPECIAL;
		pi->i_size = 0;
		pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
		pi->i_nr_sects = 0;
	}
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

	/************************/
	/*          `/'         */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	struct dir_entry * pde = (struct dir_entry *)fsbuf;

	pde->inode_nr = 1;
	strcpy(pde->name, ".");

	/* dir entries of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pde++;
		pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
		sprintf(pde->name, "dev_tty%d", i);
	}
	WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Beispiel #18
0
Datei: fs.c Projekt: qpig/sfs
static void mkfs()
{
	int i;
	MESSAGE driver_msg;

	PART_INFO geo;
	driver_msg.type = DEV_IOCTL;
	driver_msg.DEVICE = MINOR(ROOT_DEV);
	driver_msg.REQUEST = DIOCTL_GET_GEO;
	driver_msg.BUF = &geo;
	driver_msg.PROC_NR = TASK_FS;
	send_recv( BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg );

	printk("dev size: 0x%x sectors\n", geo.size );

	//super block
	struct d_super_block sb;
	sb.magic = MAGIC_V1;
	sb.first_block_table_sect = FIRST_BLOCK_TABLE ;
	sb.root_inode = ROOT_INODE ;
	sb.zone_mete_sects = ZONE_METE_SECTS;
	sb.zone_data_sects = ZONE_DATA_SECTS;

	struct buffer_head bh ;
	bh.pdata = (void *)kmalloc( SECTOR_SIZE );
	bh.dev = ROOT_DEV;
	bh.blocknr = FIRST_SUPER_BLOCK;
	bh.size = 1;
	memset( bh.pdata, 0x60, SECTOR_SIZE * 2 );
	memcpy( bh.pdata, &sb, sizeof(struct d_super_block) );
	WR_SECT( &bh );

	printk("devbase: 0x%x00, sb:0x%x00, btable:0x%x00, first zone:0x%x00, "
		   "first_zone_mete: 0x%x00, first_zone_data: 0x%x00	\n",
			geo.base * 2,
			(geo.base +2) * 2,
			(geo.base +4) * 2,
			(geo.base +6) * 2,
			(geo.base +6) * 2,
			(geo.base +6 +ZONE_METE_SECTS) *2 );

	//block table
	memset( bh.pdata, 0, SECTOR_SIZE * 2 );
	struct d_block_table_entry bt;
	for( i=0; i<NR_BLOCK_TABLE_ENTRY; i++ )
	{
		bt.block_size = 1 << i;
		if( i == 0 )
		{
			bt.first_inode_num = 1;
		}
		else
		{
			struct d_block_table_entry *pbt = (struct d_block_table_entry *)bh.pdata;
			bt.first_inode_num = pbt[i-1].first_inode_num +pbt[i-1].inode_count ;
		}
		bt.free_inode_num = bt.first_inode_num ;
		bt.inode_count = ZONE_DATA_SECTS / bt.block_size;
		bt.start_imap_nr = ZONE_ALL_SECTS * i + FIRST_ZONE;
		bt.start_itable_nr = bt.start_imap_nr + ZONE_IMAP_SECTS;
		bt.start_data_nr = bt.start_imap_nr + ZONE_METE_SECTS;
		bt.dev = ROOT_DEV;
		memcpy( bh.pdata + i * sizeof(struct d_block_table_entry) , &bt, sizeof(struct d_block_table_entry) );
	}
	bh.blocknr = FIRST_BLOCK_TABLE ;
	WR_SECT( &bh );

	//imap
	memset( bh.pdata, 0, SECTOR_SIZE );
	for( i=0; i< (NR_CONSOLES +2); i++ )
		((u8 *)(bh.pdata))[0] |= 1<< i;
	assert( ((u8 *)(bh.pdata))[0] == 0x1f );
	bh.blocknr = FIRST_ZONE ;
	bh.size = 0;
	WR_SECT( &bh );
	memset( bh.pdata, 0, SECTOR_SIZE );
	((u8 *)(bh.pdata))[0] = 0xff;
	bh.blocknr = bt.start_imap_nr ;
	bh.size = 0;
	WR_SECT( &bh );

	memset( bh.pdata, 0, SECTOR_SIZE );
	for( i=1; i<bt.inode_count/SECTOR_SIZE + 1; i++ )
	{
		bh.blocknr = FIRST_ZONE + i;
		WR_SECT( &bh );
	}

	//inodes
	memset( bh.pdata, 0, SECTOR_SIZE );
	struct d_inode *pi = (struct d_inode *)bh.pdata;
	pi->mode = I_DIRECTORY;
	pi->size = 0;
	pi->start_data_sect = FIRST_ZONE + ZONE_METE_SECTS ;
	pi->next_inode_id = 0;
	pi->nlinks = 1;
	pi->bitmap = 1;
	memcpy( pi->name, "/", sizeof("/") );

	for( i=0; i<NR_CONSOLES; i++ )
	{
		pi++;
		pi->mode = I_CHAR_SPECIAL;
		pi->size = 0;
		pi->start_data_sect = MAKE_DEV( DEV_CHAR_TTY, i);
		pi->next_inode_id = 0;
		pi->nlinks = 1;
		pi->bitmap = 0;
		sprintf( pi->name, "dev_tty%d", i+1 );
	}
	bh.blocknr = FIRST_ZONE + ZONE_IMAP_SECTS ;
	WR_SECT( &bh );

	memset( bh.pdata, 0, SECTOR_SIZE );
	char *names[] ={
		"hello",
		"ls",
		"cat",
		"touch",
		"write",
		"mkdir",
		"rm"
	};
	const int cmd_cnt = 5;
	pi = (struct d_inode *)bh.pdata;
	for( i=0; i<cmd_cnt; i++ )
	{
		pi->mode = I_REGULAR;
		pi->size = 6;
		pi->start_data_sect = bt.start_data_nr + i*bt.block_size ;
		pi->next_inode_id = 0;
		pi->nlinks = 1;
		pi->bitmap = 0;
		sprintf( pi->name, names[i] );
		pi++;
	}
	bh.blocknr = bt.start_itable_nr;
	WR_SECT( &bh );
	//memset( bh.pdata, 0x99, SECTOR_SIZE );
	//bh.blocknr = bt.start_data_nr;
	//WR_SECT( &bh );

	//d_bree_node  of "/"
	memset( bh.pdata, 0, SECTOR_SIZE );
	bh.blocknr = FIRST_ZONE + ZONE_METE_SECTS ;
	struct d_name_value_pair kv_pair[] ={
		{ ".", 1 },
		{ "..", 1 },
		{ "dev_tty1", 2 },
		{ "dev_tty2", 3 },
		{ "dev_tty3", 4 },
		{ names[0], bt.first_inode_num },
		{ names[1], bt.first_inode_num + 1},
		{ names[2], bt.first_inode_num + 2},
		{ names[3], bt.first_inode_num + 3},
		{ names[4], bt.first_inode_num + 4},
		/*
		{ names[5], bt.first_inode_num + 5},
		{ names[6], bt.first_inode_num + 6},
		*/
	};
	btree_new_root( &bh, kv_pair, sizeof(kv_pair)/sizeof(kv_pair[0]) );
	WR_SECT( &bh );

	kfree( bh.pdata );
}
Beispiel #19
0
PRIVATE void mkfs()
{
    MESSAGE driver_msg;
    int bits_per_sect = SECTOR_SIZE * 8;

    struct part_info geo;
    driver_msg.type = DEV_IOCTL;
    driver_msg.DEVICE = MINOR(ROOT_DEV);
    driver_msg.REQUEST = DIOCTL_GET_GEO;
    driver_msg.BUF = &geo;
    driver_msg.PROC_NR = TASK_FS;
    assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
    send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

    printl("dev base: 0x%x, dev size: 0x%x sectors\n", geo.base, geo.size);

    /***********************/
    /*     super block     */
    /***********************/
    struct super_block sb;
    sb.magic = MAGIC_V1;
    sb.nr_inodes = bits_per_sect;
    sb.nr_sects = geo.size;
    sb.nr_imap_sects = 1;
    sb.nr_smap_sects = sb.nr_sects / bits_per_sect + 1;
    sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
    sb.n_1st_sect = 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
    sb.root_inode = ROOT_INODE;
    sb.inode_size = INODE_SIZE;
    sb.inode_isize_off = offsetof(struct inode, i_size);
    sb.inode_start_off = offsetof(struct inode, i_start_sect);
    sb.dir_ent_size = DIR_ENTRY_SIZE;
    sb.dir_ent_inode_off = offsetof(struct dir_entry, inode_nr);
    sb.dir_ent_fname_off = offsetof(struct dir_entry, name);

    memset(fsbuf, 0x90, SECTOR_SIZE);
    memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);

    WR_SECT(ROOT_DEV, 1); // write the super block

    printl(
        "devbase: 0x%x00, sb: 0x%x00, imap: 0x%x00, smap: 0x%x00\n"
        "     inodes: 0x%x00, 1st_sector: 0x%x00\n", 
        geo.base * 2,
        (geo.base + 1) * 2,
        (geo.base + 1 + 1) * 2,
        (geo.base + 1 + 1 + sb.nr_imap_sects) * 2,
        (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
        (geo.base + sb.n_1st_sect) * 2
    );

    /***********************/
    /*      inode Map      */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    for (int i = 0; i < (NR_CONSOLES + 3); i++)
        fsbuf[0] |= 1 << i;

    assert(fsbuf[0] == 0x3F); /* 0011 1111
                               *   || |||`- bit 0 : reserved
                               *   || ||`-- bit 1 : the frist inode which indicates '/'
                               *   || |`--- bit 2 : /dev_tty0
                               *   || `---- bit 3 : /dev_tty1
                               *   |`------ bit 4 : /dev_tty2
                               *   `------- bit 5 : /cmd.tar
                               */
    WR_SECT(ROOT_DEV, 2);

    /***********************/
    /*      sector Map     */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    int nr_sects = NR_DEFAULT_FILE_SECTS + 1;

    int i;
    for (i = 0; i < nr_sects / 8; i++)
        fsbuf[i] = 0xFF;

    for (int j = 0; j < nr_sects % 8; j++)
        fsbuf[i] |= (1 << i);

    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

    memset(fsbuf, 0x0, SECTOR_SIZE);
    for (int i = 1; i < sb.nr_smap_sects; i++)
        WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

    /* cmd.tar */
    int bit_offset = INSTALL_START_SECT - sb.n_1st_sect + 1; // sect M <-> bit (M - sb.n_1stsect + 1)
    int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8);
    int bit_left = INSTALL_NR_SECTS;
    int cur_sect = bit_offset / (SECTOR_SIZE * 8);
    RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
    while (bit_left) {
        int byte_off = bit_off_in_sect / 8;
        /* this line is ineffecient in a loop, but I don't care */
        fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8);
        bit_left--;
        bit_off_in_sect++;
        if (bit_off_in_sect == (SECTOR_SIZE * 8)) {
            WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
            cur_sect++;
            RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
            bit_off_in_sect = 0;
        }
    }
    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);

    /***********************/
    /*        inodes       */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    struct inode *pi = (struct inode *)fsbuf;
    pi->i_mode = I_DIRECTORY;
    pi->i_size = DIR_ENTRY_SIZE * 5; // 5 files
    pi->i_start_sect = sb.n_1st_sect;
    pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
    
    for (int i = 0; i < NR_CONSOLES; i++) {
        pi = (struct inode *)(fsbuf + (INODE_SIZE * (i + 1)));
        pi->i_mode = I_CHAR_SPECIAL;
        pi->i_size = 0;
        pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
        pi->i_nr_sects = 0;
    }
    /* inode of `/cmd.tar' */
    pi = (struct inode*)(fsbuf + (INODE_SIZE * (NR_CONSOLES + 1)));
    pi->i_mode = I_REGULAR;
    pi->i_size = INSTALL_NR_SECTS * SECTOR_SIZE;
    pi->i_start_sect = INSTALL_START_SECT;
    pi->i_nr_sects = INSTALL_NR_SECTS;
    WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

    /***********************/
    /*         '/'         */
    /***********************/
    memset(fsbuf, 0x0, SECTOR_SIZE);
    struct dir_entry *pde = (struct dir_entry *)fsbuf;

    pde->inode_nr = 1;
    strcpy(pde->name, ".");

    for (int i = 0; i < NR_CONSOLES; i++) {
        pde++;
        pde->inode_nr = i + 2;
        sprintf(pde->name, "dev_tty%d", i);
    }
    (++pde)->inode_nr = NR_CONSOLES + 2;
    strcpy(pde->name, "cmd.tar");
    WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Beispiel #20
0
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  alloc_zone
 *  Description:  alloc zone
 *  @param dev :  In which device the sector-map is located.
 *  @param alloc_start: the start sect of the buf
 *  @param alloc_nr:	the amount of the sect of the buf
 *  @param i_zone: the	zone of the inode
 *	@return:			the amount of allocated zones
 * =====================================================================================
 */
PRIVATE	int
alloc_zone (int dev, int alloc_start, int alloc_nr, zone_t * i_zone)
{
	int i;
	int flag_no_zone = 0;
	int nr_sect = alloc_start + alloc_nr;

	if (alloc_start < NR_DIRECT_ZONE) {
		//the sectors are only in the direct zone
		int flag_direct_zone = 1;

		//asumpt the amount of the sect is less than direct zone
		int direct_alloc_nr = alloc_nr;
		if (nr_sect > NR_DIRECT_ZONE) {
			//the amount of sects is less than the direct zone
			flag_direct_zone = 0;
			direct_alloc_nr = NR_DIRECT_ZONE - alloc_start;
			alloc_nr -= direct_alloc_nr;
		}
		for (i = 0; i < direct_alloc_nr; i++) {
			if (NO_ZONE == i_zone[alloc_start + i]) {
				alloc_sect(dev, &i_zone[alloc_start + i]);
			}
		}
		if (flag_direct_zone) {
			return nr_sect - alloc_start;
		}
	}

	//the first level indirect zone
	zone_t sectors[NR_ZONE_PER_SECT];

	if (alloc_start < NR_SECOND_LEVEL_ZONE) {
		int second_level_start = NR_DIRECT_ZONE;
		if (alloc_start > second_level_start) {
			second_level_start = alloc_start;
		}

		//the sectors are only reach the second level
		int flag_second_level = 1;
		int second_alloc_nr = alloc_nr;
		if (nr_sect > NR_SECOND_LEVEL_ZONE) {
			//the amount of sects is less than the second level zone
			flag_second_level = 0;
			second_alloc_nr = NR_SECOND_LEVEL_ZONE - second_level_start;
			alloc_nr -= second_alloc_nr;
		}

		//get the begin and end in second level zone
		second_level_start -= NR_DIRECT_ZONE;

		//if the inode has second level zone
		flag_no_zone = 0;
		if (NO_ZONE == i_zone[SECOND_LEVEL_ZONE]) {
			//the second level zone is not available yet
			alloc_sect(dev, &i_zone[SECOND_LEVEL_ZONE]);
			flag_no_zone = 1;
		}

		RD_SECT(dev, i_zone[SECOND_LEVEL_ZONE]);
		memcpy((void *)sectors,
				(void *)fsbuf,
				NR_SECT_PER_SECOND_LEVEL_ZONE * sizeof(int) );

		if (flag_no_zone) {
			for (i = 0; i < NR_SECT_PER_SECOND_LEVEL_ZONE; i++) {
				sectors[i] = NO_ZONE;
			}
		}

		for (i = 0; i < second_alloc_nr; i++) {
			if (NO_ZONE == sectors[second_level_start + i]) {
				alloc_sect(dev, &sectors[second_level_start + i]);
			}
		}

		//sync to disk
		memcpy((void *)fsbuf,
				(void *)sectors,
				NR_SECT_PER_SECOND_LEVEL_ZONE * sizeof(int) );
		WR_SECT(dev, i_zone[SECOND_LEVEL_ZONE]);

		//if the zones only reach second level
		if (flag_second_level) {
			return nr_sect - alloc_start;
		}
	} 

	if (alloc_start < NR_THIRD_LEVEL_ZONE) {
		//less than the third level indirect zone
		int third_level_start = NR_SECOND_LEVEL_ZONE;
		if (alloc_start > third_level_start) {
			third_level_start = alloc_start;
		}
		//the sectors are only reach the third level
		int flag_third_level = 1;
		int third_alloc_nr = alloc_nr;
		if (nr_sect > NR_THIRD_LEVEL_ZONE) {
			//the amount of sects is less than the third level zone
			flag_third_level = 0;
			third_alloc_nr = NR_THIRD_LEVEL_ZONE - third_level_start;
			alloc_nr -= third_alloc_nr;
		}

		//get the start and end in third level zone
		third_level_start -= NR_SECOND_LEVEL_ZONE;

		//if the inode has third level zone
		flag_no_zone = 0;
		if (NO_ZONE == i_zone[THIRD_LEVEL_ZONE]) {
			//the third level zone is not available yet
			alloc_sect(dev, &i_zone[THIRD_LEVEL_ZONE]);
			flag_no_zone = 1;
		}

		RD_SECT(dev, i_zone[THIRD_LEVEL_ZONE]);
		memcpy((void *)sectors,
				(void *)fsbuf,
				NR_ZONE_PER_SECT * sizeof(int) );

		if (flag_no_zone) {
			for (i = 0; i < NR_ZONE_PER_SECT; i++) {
				sectors[i] = NO_ZONE;
			}
		}

		int current_second_level_zone = NO_ZONE;
		zone_t current_zones[NR_ZONE_PER_SECT];
		for (i = 0; i < third_alloc_nr; i++) {
			int second_level_index	=
				(third_level_start + i) /
				NR_SECT_PER_SECOND_LEVEL_ZONE;
			int third_level_index = 
				(third_level_start + i) % 
				NR_SECT_PER_SECOND_LEVEL_ZONE;

			if (NO_ZONE == current_second_level_zone
					|| current_second_level_zone != second_level_index){

				if (NO_ZONE != current_second_level_zone) {
					//the previous zone is done for writing
					//sync to disk
					memcpy((void *)fsbuf,
							(void *)current_zones,
							NR_ZONE_PER_SECT * sizeof(int) );
					WR_SECT(dev, current_second_level_zone);
				}

				//the second level zone is a slot
				flag_no_zone = 0;
				if (NO_ZONE == sectors[second_level_index]) {
					flag_no_zone = 1;
					alloc_sect(dev, &sectors[second_level_index]);
				}
				current_second_level_zone = sectors[second_level_index];

				RD_SECT(dev, sectors[second_level_index]);
				memcpy((void *)current_zones,
						(void *)fsbuf,
						NR_ZONE_PER_SECT * sizeof(int) );

				//if the second level zone is a slot, get to init
				if (flag_no_zone) {
					for (i = 0; i < NR_ZONE_PER_SECT; i++) {
						current_zones[i] = NO_ZONE;
					}
				}
			}
			if (NO_ZONE == current_zones[third_level_index]) {
				alloc_sect(dev, &current_zones[third_level_index]);
			}
		}

		//sync the rest second level zone to disk
		if (NO_ZONE != current_second_level_zone) {
			//the previous zone is done for writing
			//sync to disk
			memcpy((void *)fsbuf,
					(void *)current_zones,
					NR_ZONE_PER_SECT * sizeof(int) );
			WR_SECT(dev, current_second_level_zone);
		}

		//sync to disk
		memcpy((void *)fsbuf,
				(void *)sectors,
				NR_ZONE_PER_SECT * sizeof(int) );
		WR_SECT(dev, i_zone[THIRD_LEVEL_ZONE]);

		//if the zones only reach third level
		if (flag_third_level) {
			return nr_sect - alloc_start;
		}
		
	}

	if (nr_sect > NR_THIRD_LEVEL_ZONE) {
		//do not support zones larger than third level
		panic("file is too large");
	}

	return -1;
}		/* -----  end of function alloc_zone  ----- */
Beispiel #21
0
/**
 * <Ring 1> This routine handles the DEV_LOG message.
 * 
 * @param p  Ptr to the MESSAGE.
 *****************************************************************************/
PUBLIC int disklog(char * logstr)
{
	int device = root_inode->i_dev;
	struct super_block * sb = get_super_block(device);
	int nr_log_blk0_nr = sb->nr_sects - NR_SECTS_FOR_LOG; /* 0x9D41-0x800=0x9541 */

	static int pos = 0;
	if (!pos) { /* first time invoking this routine */

#ifdef SET_LOG_SECT_SMAP_AT_STARTUP
		/*
		 * set sector-map so that other files cannot use the log sectors
		 */

		int bits_per_sect = SECTOR_SIZE * 8; /* 4096 */

		int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; /* 3 */
		int sect_nr  = smap_blk0_nr + nr_log_blk0_nr / bits_per_sect; /* 3+9=12 */
		int byte_off = (nr_log_blk0_nr % bits_per_sect) / 8; /* 168 */
		int bit_off  = (nr_log_blk0_nr % bits_per_sect) % 8; /* 1 */
		int sect_cnt = NR_SECTS_FOR_LOG / bits_per_sect + 2; /* 1 */
		int bits_left= NR_SECTS_FOR_LOG; /* 2048 */

		int i;
		for (i = 0; i < sect_cnt; i++) {
			RD_SECT(device, sect_nr + i); /* RD_SECT(?, 12) */

			for (; byte_off < SECTOR_SIZE && bits_left > 0; byte_off++) {
				for (; bit_off < 8; bit_off++) { /* repeat till enough bits are set */
					assert(((fsbuf[byte_off] >> bit_off) & 1) == 0);
					fsbuf[byte_off] |= (1 << bit_off);
					if (--bits_left  == 0)
						break;
				}
				bit_off = 0;
			}
			byte_off = 0;
			bit_off = 0;

			WR_SECT(device, sect_nr + i);

			if (bits_left == 0)
				break;
		}
		assert(bits_left == 0);
#endif /* SET_LOG_SECT_SMAP_AT_STARTUP */

		pos = 0x40;

#ifdef MEMSET_LOG_SECTS
		/* write padding stuff to log sectors */
		int chunk = min(MAX_IO_BYTES, FSBUF_SIZE >> SECTOR_SIZE_SHIFT);
		assert(chunk == 256);
		int sects_left = NR_SECTS_FOR_LOG;
		for (i = nr_log_blk0_nr;
		     i < nr_log_blk0_nr + NR_SECTS_FOR_LOG;
		     i += chunk) {
			memset(fsbuf, 0x20, chunk*SECTOR_SIZE);
			rw_sector(DEV_WRITE,
				  device,
				  i * SECTOR_SIZE,
				  chunk * SECTOR_SIZE,
				  TASK_FS,
				  fsbuf);
			sects_left -= chunk;
		}
		if (sects_left != 0)
			panic("sects_left should be 0, current: %d.", sects_left);
#endif /* MEMSET_LOG_SECTS */
	}
Beispiel #22
0
void mkfs()
{
	MESSAGE driver_msg;
	int i, j;

	int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */
	
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	fsbuf = (u8 *)memman_alloc(memman,FSBUF_SIZE);

	/* get the geometry of ROOTDEV */
	struct part_info geo;
	//driver_msg.type		= DEV_IOCTL;
	//driver_msg.DEVICE	= MINOR(ROOT_DEV);
	//driver_msg.REQUEST	= DIOCTL_GET_GEO;
	//driver_msg.BUF		= &geo;
	//driver_msg.PROC_NR	= 0; //TASK_FS
	//hd_ioctl(&driver_msg);
	geo.size = 20097;
	
	debug("dev size: 0x%x sectors", geo.size);

	/************************/
	/*      super block     */
	/************************/
	struct super_block sb;
	sb.magic	  = MAGIC_V1;
	sb.nr_inodes	  = bits_per_sect;  //512 * 8 = 4096个i_node
	sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;  //i_node所占用的扇区数=4096 * 32 / 512 = 32
	sb.nr_sects	  = geo.size; /* partition size in sector, 这个分区总共有多少个扇区 */
	sb.nr_imap_sects  = 1; //inode-map所占用的扇区数
	sb.nr_smap_sects  = sb.nr_sects / bits_per_sect + 1; //secotr-map所占用的扇区数
	sb.n_1st_sect	  = 1 + 1 +   /* boot sector & super block */
						sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects; //数据区的第一个扇区编号
	sb.root_inode	  = ROOT_INODE;  //root directory占用的inode编号
	sb.inode_size	  = INODE_SIZE; 
	struct inode x;
	sb.inode_isize_off= (int)&x.i_size - (int)&x; //i_size在i-node结构中的偏移
	sb.inode_start_off= (int)&x.i_start_sect - (int)&x; //start_sect在i-node结构中的偏移
	sb.dir_ent_size	  = DIR_ENTRY_SIZE; //DIR_ENTRY结构的大小
	struct dir_entry de;
	sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de; //inode_nr在dir_entry中的偏移
	sb.dir_ent_fname_off = (int)&de.name - (int)&de; //name在dir_entry中的偏移

	memset1(fsbuf, 0x90, SECTOR_SIZE);
	memcpy1(fsbuf, &sb,  SUPER_BLOCK_SIZE);
	
	debug("sb.n_1st_sect = %d",sb.n_1st_sect);
	
	/* write the super block */
	WR_SECT(ROOT_DEV, 1);

	/************************/
	/*       inode map      */
	/************************/
	memset1(fsbuf, 0, SECTOR_SIZE);
	for (i = 0; i < (NR_CONSOLES + 2); i++)
		fsbuf[0] |= 1 << i;

	assert(fsbuf[0] == 0x1F);/* 0001 1111 : 
	//			  *    | ||||
	//			  *    | |||`--- bit 0 : reserved
	//			  *    | ||`---- bit 1 : the first inode,
	//			  *    | ||              which indicates `/'
	//			  *    | |`----- bit 2 : /dev_tty0
	//			  *    | `------ bit 3 : /dev_tty1
	//			  *    `-------- bit 4 : /dev_tty2
	//			  */
	WR_SECT(ROOT_DEV, 2);

	/************************/
	/*      secter map      */
	/************************/
	memset1(fsbuf, 0, SECTOR_SIZE);
	int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
	/*             ~~~~~~~~~~~~~~~~~~~|~   |
	 *                                |    `--- bit 0 is reserved
	 *                                `-------- for `/'
	 */
	for (i = 0; i < nr_sects / 8; i++)
		fsbuf[i] = 0xFF;

	for (j = 0; j < nr_sects % 8; j++)
		fsbuf[i] |= (1 << j);

	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

	/* zeromemory the rest sector-map */
	memset1(fsbuf, 0, SECTOR_SIZE);
	for (i = 1; i < sb.nr_smap_sects; i++)
		WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

	/************************/
	/*       inodes         */
	/************************/
	/* inode of `/' */
	memset1(fsbuf, 0, SECTOR_SIZE);
	struct inode * pi = (struct inode*)fsbuf;
	pi->i_mode = I_DIRECTORY;
	pi->i_size = DIR_ENTRY_SIZE * 4; /* 4 files:
					  * `.',
					  * `dev_tty0', `dev_tty1', `dev_tty2',
					  */
	pi->i_start_sect = sb.n_1st_sect;
	pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
	/* inode of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1)));
		pi->i_mode = I_CHAR_SPECIAL;
		pi->i_size = 0;
		pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
		debug("pi->i_start_sect = %d",MAKE_DEV(DEV_CHAR_TTY, i));
		pi->i_nr_sects = 0;
	}
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

	/************************/
	/*          `/'         */
	/************************/
	memset1(fsbuf, 0, SECTOR_SIZE);
	struct dir_entry * pde = (struct dir_entry *)fsbuf;

	pde->inode_nr = 1;
	strcpy(pde->name, ".");

	/* dir entries of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pde++;
		pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
		
		sprintf(pde->name, "dev_tty%d", i);
		
		debug("pde->inode_nr = %d",pde->inode_nr);
		debug("pde->name = %s",pde->name);
	}
	WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Beispiel #23
0
/**
 * <Ring 1> Make a available Orange'S FS in the disk. It will
 *          - Write a super block to sector 1.
 *          - Create three special files: dev_tty0, dev_tty1, dev_tty2
 *          - Create a file cmd.tar
 *          - Create the inode map
 *          - Create the sector map
 *          - Create the inodes of the files
 *          - Create `/', the root directory
 *****************************************************************************/
PRIVATE void mkfs()
{
	MESSAGE driver_msg;
	int i, j;

	/************************/
	/*      super block     */
	/************************/
	/* get the geometry of ROOTDEV */
	struct part_info geo;
	driver_msg.type		= DEV_IOCTL;
	driver_msg.DEVICE	= MINOR(ROOT_DEV);
	driver_msg.REQUEST	= DIOCTL_GET_GEO;
	driver_msg.BUF		= &geo;
	driver_msg.PROC_NR	= TASK_FS;
	assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER);
	send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg);

	printl("{FS} dev size: 0x%x sectors\n", geo.size);

	int bits_per_sect = SECTOR_SIZE * 8; /* 8 bits per byte */
	/* generate a super block */
	struct super_block sb;
	sb.magic	  = MAGIC_V1; /* 0x111 */
	sb.nr_inodes	  = bits_per_sect;
	sb.nr_inode_sects = sb.nr_inodes * INODE_SIZE / SECTOR_SIZE;
	sb.nr_sects	  = geo.size; /* partition size in sector */
	sb.nr_imap_sects  = 1;
	sb.nr_smap_sects  = sb.nr_sects / bits_per_sect + 1;
	sb.n_1st_sect	  = 1 + 1 +   /* boot sector & super block */
		sb.nr_imap_sects + sb.nr_smap_sects + sb.nr_inode_sects;
	sb.root_inode	  = ROOT_INODE;
	sb.inode_size	  = INODE_SIZE;
	struct inode x;
	sb.inode_isize_off= (int)&x.i_size - (int)&x;
	sb.inode_start_off= (int)&x.i_start_sect - (int)&x;
	sb.dir_ent_size	  = DIR_ENTRY_SIZE;
	struct dir_entry de;
	sb.dir_ent_inode_off = (int)&de.inode_nr - (int)&de;
	sb.dir_ent_fname_off = (int)&de.name - (int)&de;

	memset(fsbuf, 0x90, SECTOR_SIZE);
	memcpy(fsbuf, &sb, SUPER_BLOCK_SIZE);

	/* write the super block */
	WR_SECT(ROOT_DEV, 1);

	printl("{FS} devbase:0x%x00, sb:0x%x00, imap:0x%x00, smap:0x%x00\n"
	       "        inodes:0x%x00, 1st_sector:0x%x00\n", 
	       geo.base * 2,
	       (geo.base + 1) * 2,
	       (geo.base + 1 + 1) * 2,
	       (geo.base + 1 + 1 + sb.nr_imap_sects) * 2,
	       (geo.base + 1 + 1 + sb.nr_imap_sects + sb.nr_smap_sects) * 2,
	       (geo.base + sb.n_1st_sect) * 2);

	/************************/
	/*       inode map      */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	for (i = 0; i < (NR_CONSOLES + 3); i++)
		fsbuf[0] |= 1 << i;

	assert(fsbuf[0] == 0x3F);/* 0011 1111 :
				  *   || ||||
				  *   || |||`--- bit 0 : reserved
				  *   || ||`---- bit 1 : the first inode,
				  *   || ||              which indicates `/'
				  *   || |`----- bit 2 : /dev_tty0
				  *   || `------ bit 3 : /dev_tty1
				  *   |`-------- bit 4 : /dev_tty2
				  *   `--------- bit 5 : /cmd.tar
				  */
	WR_SECT(ROOT_DEV, 2);

	/************************/
	/*      secter map      */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	int nr_sects = NR_DEFAULT_FILE_SECTS + 1;
	/*             ~~~~~~~~~~~~~~~~~~~|~   |
	 *                                |    `--- bit 0 is reserved
	 *                                `-------- for `/'
	 */
	for (i = 0; i < nr_sects / 8; i++)
		fsbuf[i] = 0xFF;

	for (j = 0; j < nr_sects % 8; j++)
		fsbuf[i] |= (1 << j);

	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects);

	/* zeromemory the rest sector-map */
	memset(fsbuf, 0, SECTOR_SIZE);
	for (i = 1; i < sb.nr_smap_sects; i++)
		WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + i);

	/* cmd.tar */
	/* make sure it'll not be overwritten by the disk log */
	assert(INSTALL_START_SECT + INSTALL_NR_SECTS < 
	       sb.nr_sects - NR_SECTS_FOR_LOG);
	int bit_offset = INSTALL_START_SECT -
		sb.n_1st_sect + 1; /* sect M <-> bit (M - sb.n_1stsect + 1) */
	int bit_off_in_sect = bit_offset % (SECTOR_SIZE * 8);
	int bit_left = INSTALL_NR_SECTS;
	int cur_sect = bit_offset / (SECTOR_SIZE * 8);
	RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
	while (bit_left) {
		int byte_off = bit_off_in_sect / 8;
		/* this line is ineffecient in a loop, but I don't care */
		fsbuf[byte_off] |= 1 << (bit_off_in_sect % 8);
		bit_left--;
		bit_off_in_sect++;
		if (bit_off_in_sect == (SECTOR_SIZE * 8)) {
			WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
			cur_sect++;
			RD_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);
			bit_off_in_sect = 0;
		}
	}
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + cur_sect);

	/************************/
	/*       inodes         */
	/************************/
	/* inode of `/' */
	memset(fsbuf, 0, SECTOR_SIZE);
	struct inode * pi = (struct inode*)fsbuf;
	pi->i_mode = I_DIRECTORY;
	pi->i_size = DIR_ENTRY_SIZE * 5; /* 5 files:
					  * `.',
					  * `dev_tty0', `dev_tty1', `dev_tty2',
					  * `cmd.tar'
					  */
	pi->i_start_sect = sb.n_1st_sect;
	pi->i_nr_sects = NR_DEFAULT_FILE_SECTS;
	/* inode of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pi = (struct inode*)(fsbuf + (INODE_SIZE * (i + 1)));
		pi->i_mode = I_CHAR_SPECIAL;
		pi->i_size = 0;
		pi->i_start_sect = MAKE_DEV(DEV_CHAR_TTY, i);
		pi->i_nr_sects = 0;
	}
	/* inode of `/cmd.tar' */
	pi = (struct inode*)(fsbuf + (INODE_SIZE * (NR_CONSOLES + 1)));
	pi->i_mode = I_REGULAR;
	pi->i_size = INSTALL_NR_SECTS * SECTOR_SIZE;
	pi->i_start_sect = INSTALL_START_SECT;
	pi->i_nr_sects = INSTALL_NR_SECTS;
	WR_SECT(ROOT_DEV, 2 + sb.nr_imap_sects + sb.nr_smap_sects);

	/************************/
	/*          `/'         */
	/************************/
	memset(fsbuf, 0, SECTOR_SIZE);
	struct dir_entry * pde = (struct dir_entry *)fsbuf;

	pde->inode_nr = 1;
	strcpy(pde->name, ".");

	/* dir entries of `/dev_tty0~2' */
	for (i = 0; i < NR_CONSOLES; i++) {
		pde++;
		pde->inode_nr = i + 2; /* dev_tty0's inode_nr is 2 */
		sprintf(pde->name, "dev_tty%d", i);
	}
	(++pde)->inode_nr = NR_CONSOLES + 2;
	sprintf(pde->name, "cmd.tar", i);
	WR_SECT(ROOT_DEV, sb.n_1st_sect);
}
Beispiel #24
0
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  rdwt_zones
 *  Description:  read of write the buf to the zones
 *  @param pos:	  the current position in the file
 *  @param buf_len:		the length of the buf
 *  @param src:			the source of the buf
 *  @param buf:			the buf should be read or written
 *  @param i_nr_sects:	the current amount of the sects of the file
 *  @param i_zone:		the i_zone of this inode
 *  @param mode:		READ or WRITE
 *  @return :			how many bytes writed or read
 * =====================================================================================
 */
PRIVATE int
rdwt_zones ( int pos, int len, int src, char * buf, struct inode * pin, int mode)
{
	//check if the mode is right
	assert(WRITE == mode || READ == mode);

	int i;
	int align = 0;
	int pos_end = pos + len;

	//larger than file in read mode
	if (READ == mode) {
		if (pos > pin->i_size) {
			//read start is larger than the file, get nothing
			return 0;
		} else if (pos_end > pin->i_size) {
			//read end is larger than the file, just end at the EOF
			len -= (pos_end - pin->i_size);
			pos_end = pin->i_size;
		}
	}

	//how many sects does the buf need to take
	int nr_sect_start = pos >> SECTOR_SIZE_SHIFT;
	int nr_rw_sect = len >> SECTOR_SIZE_SHIFT;
	int off = pos_end % SECTOR_SIZE;

	//if the buf is not n * SECTOR_SIZE, just give one more sector
	if (off > 0) {
		nr_rw_sect ++;
	}

	int nr_sect = nr_sect_start + nr_rw_sect;

	//if the sects in the file is not enough
	if (nr_sect > pin->i_nr_sects) {
		//allocate the sectors that needed
		assert(WRITE == mode);
		u32 zone_amount = alloc_zone(pin->i_dev, pin->i_nr_sects, nr_sect - pin->i_nr_sects, pin->i_zone);
		assert(nr_sect - pin->i_nr_sects == zone_amount);
		pin->i_nr_sects += zone_amount;
	}

	if (nr_sect_start < NR_DIRECT_ZONE) {
		//the sectors are only in the direct zone
		int flag_direct_zone = 1;

		//asumpt the amount of the sect is less than direct zone
		int direct_nr_rw_sect = nr_rw_sect;
		if (nr_sect > NR_DIRECT_ZONE) {
			//the amount of sects is more than the direct zone
			flag_direct_zone = 0;
			direct_nr_rw_sect = NR_DIRECT_ZONE - nr_sect_start;
			nr_rw_sect -= direct_nr_rw_sect;
		}
		for (i = 0; i < direct_nr_rw_sect; i++, align++) {
			if (WRITE == mode) {
  				phys_copy((void*)va2la(TASK_FS, fsbuf),
						(void*)va2la(src, buf + align * SECTOR_SIZE),
						SECTOR_SIZE);
				WR_SECT(pin->i_dev, pin->i_zone[nr_sect_start + i]);
			} else if (READ == mode) {
				RD_SECT(pin->i_dev, pin->i_zone[nr_sect_start + i]);
				phys_copy((void*)va2la(src, buf + align * SECTOR_SIZE),
						(void*)va2la(TASK_FS, fsbuf),
						SECTOR_SIZE);
			}
		}
		if (flag_direct_zone) {
			return len;
		}
	}

	//the first level indirect zone
	zone_t sectors[NR_ZONE_PER_SECT];

	if (nr_sect_start < NR_SECOND_LEVEL_ZONE) {
		int second_level_start = NR_DIRECT_ZONE;
		if (nr_sect_start > second_level_start) {
			second_level_start = nr_sect_start;
		}
		//the sectors are only reach the second level
		int flag_second_level = 1;
		int second_nr_rw_sect = nr_rw_sect;
		if (nr_sect > NR_SECOND_LEVEL_ZONE) {
			//the amount of sects is more than the second level zone
			flag_second_level = 0;
			second_nr_rw_sect = NR_SECOND_LEVEL_ZONE - second_level_start;
			nr_rw_sect -= second_nr_rw_sect;
		}

		//get the begin and end in second level zone
		second_level_start -= NR_DIRECT_ZONE;

		RD_SECT(pin->i_dev, pin->i_zone[SECOND_LEVEL_ZONE]);
		memcpy((void *)sectors,
				(void *)fsbuf,
				NR_ZONE_PER_SECT * sizeof(int) );

		for (i = 0; i < second_nr_rw_sect; i++, align++) {
            if (WRITE == mode) {
                phys_copy((void*)va2la(TASK_FS, fsbuf),
                        (void*)va2la(src, buf + align * SECTOR_SIZE),
                        SECTOR_SIZE);
                WR_SECT(pin->i_dev, sectors[second_level_start + i]);
            } else if(READ == mode) {
                RD_SECT(pin->i_dev, sectors[second_level_start + i]);
                phys_copy((void*)va2la(src, buf + align * SECTOR_SIZE),
                        (void*)va2la(TASK_FS, fsbuf),
                        SECTOR_SIZE);
            }

		}

		//if the zones only reach second level
		if (flag_second_level) {
			return len;
		}
	} 

	if (nr_sect_start < NR_THIRD_LEVEL_ZONE) {
		//less than the third level indirect zone
		int third_level_start = NR_SECOND_LEVEL_ZONE;
		if (nr_sect_start > third_level_start) {
			third_level_start = nr_sect_start;
		}
		//the sectors are only reach the third level
		int flag_third_level = 1;
		int third_nr_rw_sect = nr_rw_sect;
		if (nr_sect > NR_THIRD_LEVEL_ZONE) {
			//the amount of sects is more than the third level zone
			flag_third_level = 0;
			third_nr_rw_sect = NR_THIRD_LEVEL_ZONE - third_level_start;
			nr_rw_sect -= third_nr_rw_sect;
		}

		//get the start and end in third level zone
		third_level_start -= NR_SECOND_LEVEL_ZONE;

		RD_SECT(pin->i_dev, pin->i_zone[THIRD_LEVEL_ZONE]);
		memcpy((void *)sectors,
				(void *)fsbuf,
				NR_ZONE_PER_SECT * sizeof(int) );

		int current_second_level_zone = NO_ZONE;
		zone_t current_zones[NR_ZONE_PER_SECT];
		for (i = 0; i < third_nr_rw_sect; i++, align++) {
			int second_level_index	=
				(third_level_start + i) /
				NR_SECT_PER_SECOND_LEVEL_ZONE;
			int third_level_index = 
				(third_level_start + i) %
				NR_SECT_PER_SECOND_LEVEL_ZONE;

			if (NO_ZONE == current_second_level_zone
					|| current_second_level_zone != sectors[second_level_index]){
				RD_SECT(pin->i_dev, sectors[second_level_index]);
				memcpy((void *)current_zones,
						(void *)fsbuf,
						NR_ZONE_PER_SECT * sizeof(int) );
			}

			//record the current second level zone for compare in next time
			//to comfirm if that the current second level zone is finished
			current_second_level_zone = sectors[second_level_index];

            if (WRITE == mode) {
                phys_copy((void*)va2la(TASK_FS, fsbuf),
                        (void*)va2la(src, buf + align * SECTOR_SIZE),
                        SECTOR_SIZE);
                WR_SECT(pin->i_dev, current_zones[third_level_index]);
            } else if(READ == mode) {
                RD_SECT(pin->i_dev, current_zones[third_level_index]);
                phys_copy((void*)va2la(src, buf + align * SECTOR_SIZE),
                        (void*)va2la(TASK_FS, fsbuf),
                        SECTOR_SIZE);
            }

		}

		//if the zones only reach third level
		if (flag_third_level) {
			return len;
		}
	}

	if (nr_sect > NR_THIRD_LEVEL_ZONE) {
		//do not support zones larger than third level
		panic("buf is too large");
	}

	return -1;
}		/* -----  end of function rdwt_zones  ----- */
Beispiel #25
0
/**
 * Allocate a bit in sector-map.
 * 
 * @param dev  In which device the sector-map is located.
 * @param nr_sects_to_alloc  How many sectors are allocated.
 * 
 * @return  The 1st sector nr allocated.
 *****************************************************************************/
PRIVATE int alloc_smap_bit(int dev, int nr_sects_to_alloc)
{
	/* int nr_sects_to_alloc = NR_DEFAULT_FILE_SECTS; */

	int i; /* sector index */
	int j; /* byte index */
	int k; /* bit index */

	struct super_block * sb = get_super_block(dev);

	int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects;
	int free_sect_nr = 0;

	for (i = 0; i < sb->nr_smap_sects; i++) { /* smap_blk0_nr + i :
						     current sect nr. */
		RD_SECT(dev, smap_blk0_nr + i);

		/* byte offset in current sect */
		for (j = 0; j < SECTOR_SIZE && nr_sects_to_alloc > 0; j++) {
			k = 0;
			if (!free_sect_nr) {
				/* loop until a free bit is found */
				if (fsbuf[j] == 0xFF) continue;
				for (; ((fsbuf[j] >> k) & 1) != 0; k++) {}
				free_sect_nr = (i * SECTOR_SIZE + j) * 8 + k - 1 + sb->n_1st_sect;
				if (free_sect_nr + nr_sects_to_alloc > sb->nr_sects) {
					/* FIXME: instead of halting the system,
					 *        telling the caller to handle this
					 *        will be better
					 */
					panic("disk is full");
				}
			}

			for (; k < 8; k++) { /* repeat till enough bits are set */
				assert(nr_sects_to_alloc > 0);

				/*
				 * this assert will fail if the disk is full
				 * (we would be overwriting "cmd.tar" to
				 *  create the new file)
				 *
				 * for example, if we have a 80MB hard disk,
				 * we may not be able to create more than 14
				 * regulare files
				 *
				 * @see doc/README::"cmd.tar" for details
				 */
				assert(((fsbuf[j] >> k) & 1) == 0);

				fsbuf[j] |= (1 << k);
				if (--nr_sects_to_alloc == 0)
					break;
			}
		}

		if (free_sect_nr) /* free bit found, write the bits to smap */
			WR_SECT(dev, smap_blk0_nr + i);

		if (nr_sects_to_alloc == 0)
			break;
	}

	assert(nr_sects_to_alloc == 0);

	return free_sect_nr;
}