Example #1
0
static int find_partition(BlockBackend *blk, int partition,
                          off_t *offset, off_t *size)
{
    struct partition_record mbr[4];
    uint8_t data[512];
    int i;
    int ext_partnum = 4;
    int ret;

    if ((ret = blk_read(blk, 0, data, 1)) < 0) {
        error_report("error while reading: %s", strerror(-ret));
        exit(EXIT_FAILURE);
    }

    if (data[510] != 0x55 || data[511] != 0xaa) {
        return -EINVAL;
    }

    for (i = 0; i < 4; i++) {
        read_partition(&data[446 + 16 * i], &mbr[i]);

        if (!mbr[i].system || !mbr[i].nb_sectors_abs) {
            continue;
        }

        if (mbr[i].system == 0xF || mbr[i].system == 0x5) {
            struct partition_record ext[4];
            uint8_t data1[512];
            int j;

            if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) {
                error_report("error while reading: %s", strerror(-ret));
                exit(EXIT_FAILURE);
            }

            for (j = 0; j < 4; j++) {
                read_partition(&data1[446 + 16 * j], &ext[j]);
                if (!ext[j].system || !ext[j].nb_sectors_abs) {
                    continue;
                }

                if ((ext_partnum + j + 1) == partition) {
                    *offset = (uint64_t)ext[j].start_sector_abs << 9;
                    *size = (uint64_t)ext[j].nb_sectors_abs << 9;
                    return 0;
                }
            }
            ext_partnum += 4;
        } else if ((i + 1) == partition) {
            *offset = (uint64_t)mbr[i].start_sector_abs << 9;
            *size = (uint64_t)mbr[i].nb_sectors_abs << 9;
            return 0;
        }
    }

    return -ENOENT;
}
Example #2
0
static int read_superblock(struct filesys *fs)
{
	struct superblock *sb = fs->sb;

	/* read superblock and verify */
	if(blk_read(fs->bdev, 1, 1, sb) == -1) {
		printf("failed to read superblock\n");
		return -EIO;
	}
	if(sb->magic != MAGIC) {
		printf("invalid magic\n");
		return -EINVAL;
	}
	if(sb->ver > FS_VER) {
		printf("invalid version: %d\n", sb->ver);
		return -EINVAL;
	}
	if(sb->blksize != BLKSZ) {
		printf("invalid block size: %d\n", sb->blksize);
		return -EINVAL;
	}

	/* allocate and populate in-memory bitmaps */
	if(!(sb->ibm = malloc(sb->ibm_count * sb->blksize))) {
		return -ENOMEM;
	}
	if(blk_read(fs->bdev, sb->ibm_start, sb->ibm_count, sb->ibm) == -1) {
		printf("failed to read inode bitmap\n");
		free(sb->ibm);
		return -EIO;
	}
	if(!(sb->bm = malloc(sb->bm_count * sb->blksize))) {
		free(sb->ibm);
		return -ENOMEM;
	}
	if(blk_read(fs->bdev, sb->bm_start, sb->bm_count, sb->bm) == -1) {
		printf("failed to read block bitmap\n");
		free(sb->ibm);
		free(sb->bm);
		return -EIO;
	}

	/* read the root inode */
	if(!(sb->root = malloc(sizeof *sb->root))) {
		free(sb->ibm);
		free(sb->bm);
		return -ENOMEM;
	}
	if(get_inode(fs, sb->root_ino, sb->root) == -1) {
		printf("failed to read root inode\n");
		return -1;
	}

	return 0;
}
Example #3
0
int blk_verify_fingerprint(uint64_t fingerprint, char *data, size_t length)
{
	win_reset();

	memcpy(gbuf, data, length);
	gbuf_end=gbuf+length;
	gcp=gbuf;
	blk_free(&blk);
	if(!blk && !(blk=blk_alloc())) return -1;
	blk->length=0;
	blk->fingerprint=0;

	// FIX THIS: blk_read should return 1 when it has a block.
	// But, if the block is too small (because the end of the file
	// happened), it returns 0, and blks_generate treats it as having found
	// a final block.
	// So, here the return of blk_read is ignored and we look at the
	// position of gcp instead.
	blk_read();
//printf("%d %d\n", blk->length, length);
//printf("%016"PRIX64" %016"PRIX64" ",
//	blk->fingerprint, fingerprint);
//printf("%s\n", blk->fingerprint==fingerprint?"yes":"no");
	if(gcp==gbuf_end
	  && blk->fingerprint==fingerprint)
		return 1;
	return 0;
}
Example #4
0
File: rabin.c Project: EmisFR/burp
// The server uses this for verification.
int blk_read_verify(struct blk *blk_to_verify)
{
	if(!win)
	{
		rconf_init(&rconf);
		if(!(win=win_alloc(&rconf))) return -1;
	}

	gbuf=blk_to_verify->data;
	gbuf_end=gbuf+blk_to_verify->length;
	gcp=gbuf;
	if(!blk && !(blk=blk_alloc())) return -1;
	blk->length=0;
	blk->fingerprint=0;

	// FIX THIS: blk_read should return 1 when it has a block.
	// But, if the block is too small (because the end of the file
	// happened), it returns 0, and blks_generate treats it as having found
	// a final block.
	// So, here the return of blk_read is ignored and we look at the
	// position of gcp instead.
	blk_read();
	if(gcp==gbuf_end
	  && blk->fingerprint==blk_to_verify->fingerprint)
		return 1;
	return 0;
}
Example #5
0
static void load_kernel(const char *name, const char *devname)
{
  int i;

  tmp = (void *)0x02040000;

  (void)blk_read(tmp, 512 * 1024, devname, 0);

  /* disable all IRQ */
  for (i = LC823450_IRQ_NMI + 1; i < NR_IRQS; i++)
    {
      up_disable_irq(i);
    }

  /* clear pending IRQ */
  putreg32(0xffffffff, NVIC_IRQ0_31_CLRPEND);
  putreg32(0xffffffff, NVIC_IRQ32_63_CLRPEND);
  putreg32(0xffffffff, NVIC_IRQ64_95_CLRPEND);

  _info("start %s\n", name);

  __asm__ __volatile__
    (
     "ldr r0, =tmp\n"
     "ldr r1, [r0, #0]\n" /* r1 = 0x02040000 */
     "ldr sp, [r1, #0]\n" /* set sp */
     "ldr pc, [r1, #4]"   /* set pc, start nuttx */
     );

}
Example #6
0
static int addlink(struct filesys *fs, struct inode *target, struct inode *node, const char *name)
{
	struct dir_entry ent, *data;
	int i, boffs, bidx, len;

	if(!(target->mode & S_IFDIR)) {
		return -ENOTDIR;
	}
	if(node->mode & S_IFDIR) {
		return -EPERM;
	}
	/* TODO check that the link does not already exist (EEXIST) */

	if((len = strlen(name)) > NAME_MAX) {
		return -ENAMETOOLONG;
	}
	ent.ino = node->ino;
	memcpy(ent.name, name, len + 1);

	/* find a place to put it */
	if(!(data = malloc(BLKSZ))) {
		return -ENOMEM;
	}

	boffs = 0;
	while((bidx = get_file_block(fs, target, boffs)) > 0) {
		/* read the block, and search for an empty entry */
		blk_read(fs->bdev, bidx, 1, data);

		/* for all directory entries in this block... */
		for(i=0; i<BLK_DIRENT; i++) {
			if(data[i].ino == 0) {
				/* found empty */
				memcpy(data + i, &ent, sizeof ent);
				goto success;
			}
		}
		boffs++;
	}

	/* didn't find any free entries amongst our blocks, allocate a new one */
	if(!(bidx = alloc_file_block(fs, target, boffs))) {
		free(data);
		return -ENOSPC;
	}
	/* zero-fill the new block and add the first entry */
	memset(data, 0, BLKSZ);
	*data = ent;

success:
	/* write to disk */
	blk_write(fs->bdev, bidx, 1, data);
	node->nlink++;	/* increase reference count */

	free(data);
	return 0;
}
Example #7
0
//*****************mount****************
int8_t cnmount(void)
{
	blk_read(BLOCKID_SUPER, &superblk_cache);
	blk_read(BLOCKID_BLOCK_BITMAP, &block_bm_cache);
	blk_read(BLOCKID_INODE_BITMAP, &inode_bm_cache);

	fs.superblk = (superblock*)&superblk_cache;
	if(fs.superblk->magic == FS_MAGIC && fs.superblk->state == VALID_FS) {
		fs.state = VFS_GOOD;
		fs.superblk->state = ERROR_FS;
	} else
	{
		fs.state = VFS_BLANK;
	}
	memset(fd_tbl, 0, sizeof(fd_entry)*1024);
	memset(fd_bm, 0, sizeof(uint8_t)*MAX_FD/8);
	strcpy(cwd_str,"/");
	cwd = cnopendir("/");
	return 0;
}
Example #8
0
//******** llread *******************
//Reads a complete file from its inode data
int8_t llread(inode* inode_ptr, block* buf)
{
	uint32_t* s_ind = calloc(1, sizeof(block));
	for(uint8_t i = 0; i < MIN(inode_ptr->blocks,8); i++)
	{
		blk_read(inode_ptr->data0[i], buf);
		buf++;
	}

	if(inode_ptr->blocks > 8)
	{
		blk_read(inode_ptr->data1, (block*)s_ind);
		for(uint32_t j = 0; j < inode_ptr->blocks - 8; j++)
		{
			blk_read(s_ind[j], buf);
			buf++;
		}
	}
	free(s_ind);
	return 0;
}
Example #9
0
/* copy the requested inode from the disk, into the buffer passed in the last arg */
static int get_inode(struct filesys *fs, int ino, struct inode *inode)
{
	struct inode *buf = malloc(BLKSZ);
	assert(buf);

	if(blk_read(fs->bdev, fs->sb->itbl_start + ino / BLK_INODES, 1, buf) == -1) {
		free(buf);
		return -1;
	}
	memcpy(inode, buf + ino % BLK_INODES, sizeof *inode);
	free(buf);
	return 0;
}
Example #10
0
File: rabin.c Project: EmisFR/burp
static int blk_read_to_list(struct sbuf *sb, struct blist *blist)
{
	if(!blk_read()) return 0;

	// Got something.
	if(first)
	{
		sb->protocol2->bstart=blk;
		first=0;
	}
	if(!sb->protocol2->bsighead)
	{
		sb->protocol2->bsighead=blk;
	}
	blist_add_blk(blist, blk);
	blk=NULL;
	return 1;
}
int main(int argc, char *argv[]) {
        char *s_device = "\0";
	char ch;
	char *optstr = "d:0:1:2:3:s:";

	while( -1 != (ch=getopt(argc,argv,optstr))) {
		switch(ch) {
			case 's':           
				s_device = optarg;
				printf("option: -s : %s\n", s_device); 
				break;
			case 'd':
				debug = atoi(optarg);
				printf("option: -d : %d\n", debug); 
				break;
			case '?':
				printf("unrecognized option: %c\n",optopt);
				break;
			default:
				printf("error?  condition unaccounted for?\n");
				break;

		}
	}

	if (debug > 1) {
		printf("\nEPSPD version 1.5 (2009-0m-dd)");
		printf("\nDebug level: %d", debug);
	}
	setSerial(s_device);
	
	/*
	 *	Up.. time to go (Clunk, ..(wait), Clunk, Clunk)
	 */
	 
	printf("\nEPSPD: Starting EPSP disk services on %s", s_device);
	printf("\n");
	
	while(1) {
		blk_read(epsp_port, dataMsg, 256);
	}
	
	return(1);
}
Example #12
0
static ssize_t ext2_pread(struct inode *i, void *buf, size_t len, off_t off)
{
	size_t first_block, last_block, num_blk, x;
	struct buffer *bh;
	ssize_t copied;

	if ( off + len > i->i_size )
		len = i->i_size - off;

	first_block = off / i->i_sb->s_blocksize;
	last_block = (off + len) / i->i_sb->s_blocksize;
	num_blk = last_block - first_block;
	dprintk("EXT2: pread %lu @ %lu: blocks %lu - %lu\n",
		len, off, first_block, last_block);

	BUG_ON(last_block >= EXT2_NDIR_BLOCKS);

	for(copied = 0, x = first_block; x <= last_block; x++) {
		size_t clen, coff;

		bh = blk_read(i->i_sb->s_dev, i->u.ext2.block[x]);
		if ( NULL == bh )
			return copied;

		coff = off & (i->i_sb->s_blocksize - 1);
		clen = (coff + len > i->i_sb->s_blocksize) ? 
				i->i_sb->s_blocksize - coff : len;
		dprintk("EXT2: got block %lu, copy %lu bytes at %lu\n",
			i->u.ext2.block[x], clen, coff);
		if ( copy_to_user(buf, bh->b_buf + coff, clen) < 0 ) {
			blk_free(bh);
			return -1; /* EFAULT */
		}
		copied += clen;
		len -= clen;
		off += clen;

		blk_free(bh);
	}

	return copied;
}
Example #13
0
static void fs_init(addr_t start_addr, uint len)
{
	struct buf *super;
	start = start_addr;
	length = len;

	// Set the blk layer
	blk_set(start);

	// Set the inode layer
	// Block #0 is bootblock
	// Block #1 is superblock
	superblock = blk_read(1);
	// Block #2 is where the inode bitmap starts
	blk_nr_t inodes_blk_nr =
		2 + 
		(super->nr_inodes * sizeof(struct dinode) 
		+ sizeof(buf_blk_t) - 1) / sizeof(buf_blk_t);
	ino_set(2, inodes_blk_nr);
}
Example #14
0
TEST(blockdev, BlockdevCanReadWrite)
{
	TEST_ASSERT_TRUE(blockdev_attach() == 0);
	block* test_write_blk = (block*)malloc(BLOCK_SIZE);
	uint32_t* wblk_32 = (uint32_t*)test_write_blk;
	wblk_32[0] = 0xDEADBEEF;
	wblk_32[45] = 0xFEEDBEEF;
	TEST_ASSERT_TRUE(blk_write(1234, test_write_blk) == 0);
	free(test_write_blk);
	TEST_ASSERT_TRUE(blockdev_detach() == 0);

	TEST_ASSERT_TRUE(blockdev_attach() == 0);
	block* test_read_blk = (block*)malloc(BLOCK_SIZE);
	TEST_ASSERT_TRUE(blk_read(1234, test_read_blk) == 0);
	uint32_t* rblk_32 = (uint32_t*)test_read_blk;
	TEST_ASSERT_TRUE(rblk_32[0] == 0xDEADBEEF);
	TEST_ASSERT_TRUE(rblk_32[45] == 0xFEEDBEEF);
	free(test_read_blk);
	TEST_ASSERT_TRUE(blockdev_detach() == 0);
}
Example #15
0
static int check_diskformat(void)
{
  int ret;

#ifdef CONFIG_FS_EVFAT
  struct evfat_format_s fmt = EVFAT_FORMAT_INITIALIZER;

  /* load MBR */

  ret = blk_read(copybuf, sizeof(copybuf), "/dev/mtdblock0p2", 0);

  if (ret < 0)
    {
      return 0;
    }

  /* If part2 has MBR signature, this eMMC was formated by PC.
   * This means the set is just after writing IPL2.
   */

  if (copybuf[510] != 0x55 || copybuf[511] != 0xaa)
    {
      return 0;
    }

  ret = mkevfatfs(CONFIG_MTD_CP_DEVPATH, &fmt);
#endif

  _info("FORMAT content partition : %d\n", ret);

  memset(copybuf, 0, sizeof(copybuf));
  ret = blk_write(copybuf, 512, CONFIG_MTD_ETC_DEVPATH, 0);
  _info("clear /etc : %d\n", ret);
  ret = blk_write(copybuf, 512, CONFIG_MTD_SYSTEM_DEVPATH, 0);
  _info("clear /system : %d\n", ret);
  ret = blk_write(copybuf, 512, CONFIG_MTD_CACHE_DEVPATH, 0);
  _info("clear /cache : %d\n", ret);

  return 1;
}
Example #16
0
static dev_t find_rootfs(void)
{
	dev_t dev = 0;
	int i, num_dev, partid;
	struct partition *plist, *p;
	struct superblock *sb = malloc(BLKSZ);
	char name[16];

	assert(sb);

	num_dev = ata_num_devices();
	for(i=0; i<num_dev; i++) {
		plist = p = get_part_list(i);

		partid = 0;
		while(p) {
			if(get_part_type(p) == PART_TYPE) {
				/* found the correct partition, now read the superblock
				 * and make sure it's got the correct magic id
				 */
				blk_read(i, p->start_sect / 2 + 1, BLKSZ, sb);

				if(sb->magic == MAGIC) {
					sprintf(name, "ata%dp%d", i, partid);
					printf("found root: %s\n", name);
					dev = bdev_by_name(name);
					break;
				}
			}
			p = p->next;
			partid++;
		}
		free_part_list(plist);
		if(dev) break;
	}

	free(sb);
	return dev;
}
Example #17
0
/* Lookup a name in an inode */
static struct inode *ext2_lookup(struct inode *i, const char *n, size_t nlen)
{
	struct ext2_dir_entry_2 *dir;
	struct buffer *bh;
	ino_t inum;
	int x, y;
	char *j;

	y = EXT2_NDIR_BLOCKS < i->i_blocks ? EXT2_NDIR_BLOCKS : i->i_blocks;

	for(x = 0; x < y; x++) {
		/* pre-allocation ?? */
		if ( i->u.ext2.block[x] == 0 )
			continue;

		/* Read the block */
		bh = blk_read(i->i_sb->s_dev, i->u.ext2.block[x]);
		if ( NULL == bh )
			return NULL;

		/* Search for the item */
		for(j = bh->b_buf; j < (bh->b_buf + bh->b_len); ) {
			dir = (struct ext2_dir_entry_2 *)j;
			dprintk("EXT2: dentry: %.*s\n",
				dir->name_len, dir->name);
			if ( (dir->name_len == nlen) &&
				!memcmp(dir->name, n, nlen) ) {
				inum = dir->inode;
				blk_free(bh);
				return iget(i->i_sb, inum);
			}
			j += dir->rec_len;
		}

		blk_free(bh);
	}

	return NULL;
}
Example #18
0
//****** realloc_fs_blocks*****************
//Allocates at least "blocks_needed" blocks for this file
int8_t realloc_fs_blocks(inode* inode, uint32_t blocks_needed)
{
	uint32_t* s_ind = calloc(1, sizeof(block));
	if(blocks_needed > inode->blocks)
	{
		if(inode->blocks <= 8)
		{
			for(; inode->blocks < MIN(8,blocks_needed); inode->blocks++)
			{
				inode->data0[inode->blocks] = reserve_block();
			}
		}

		if(inode->blocks < blocks_needed) //still not enough after allocating direct
		{
			//Determine if a single indirect block has been allocated
			if(inode->data1 == 0)
			{
				inode->data1 = reserve_block();
			}
			else
			{
				blk_read(inode->data1,(block*)s_ind);
			}
			//Allocate the blocks and save in the indirect block
			for(;inode->blocks < blocks_needed; inode->blocks++)
			{
				s_ind[inode->blocks-8] = reserve_block();
			}
			blk_write(inode->data1,(block*)s_ind);
		}

	}
	free(s_ind);
	return 0;
}
/* UDC ISR function */
void INT_UDC(void)
{
    uint32_t txstat, rxstat;
    int tmp, ep_num;
    
    /* read what caused UDC irq */
    uint32_t intsrc = INT2FLAG & 0x7fffff;
    
    if (intsrc & (1<<1)) /* setup interrupt */
    {
        setup_received();
    }
    else if (intsrc & (1<<2)) /* ep0 in interrupt */
    {
        txstat = TX0STAT; /* read clears flags */
        
        /* TODO handle errors */
        if (txstat & (1<<18)) /* check TxACK flag */
        {
            if (ctrlep[DIR_IN].cnt >= 0)
            {
                /* we still have data to send (or ZLP) */
                ctr_write();
            }
            else
            {
                /* final ack received */
                usb_core_transfer_complete(0,                   /* ep */
                                           USB_DIR_IN,          /* dir */
                                           0,                   /* status */
                                           ctrlep[DIR_IN].len); /* length */
                
                /* release semaphore for blocking transfer */
                if (ctrlep[DIR_IN].block)
                    semaphore_release(&ctrlep[DIR_IN].complete);
            }
        }
    }
    else if (intsrc & (1<<3)) /* ep0 out interrupt */
    {
        rxstat = RX0STAT;

        /* TODO handle errors */
        if (rxstat & (1<<18)) /* RxACK */
        {
            if (ctrlep[DIR_OUT].cnt > 0)
                ctr_read();
            else
                usb_core_transfer_complete(0,                    /* ep */
                                           USB_DIR_OUT,          /* dir */
                                           0,                    /* status */
                                           ctrlep[DIR_OUT].len); /* length */                
        }
    }
    else if (intsrc & (1<<4)) /* usb reset */
    {
        usb_drv_init();
    }
    else if (intsrc & (1<<5)) /* usb resume */
    {
        TX0CON |= (1<<0); /* TxClr */
        TX0CON &= ~(1<<0);
        RX0CON |= (1<<1); /* RxClr */
        RX0CON &= (1<<1);
    }
    else if (intsrc & (1<<6)) /* usb suspend */
    {
    }
    else if (intsrc & (1<<7)) /* usb connect */
    {
    }
    else
    {
        /* lets figure out which ep generated irq */
        tmp = intsrc >> 7;
        for (ep_num=1; ep_num < 15; ep_num++)
        {
            tmp >>= ep_num;
            if (tmp & 0x01)
                break;
        }
        
        if (intsrc & ((1<<8)|(1<<11)|(1<<14)|(1<<17)|(1<<20)))
        {
            /* bulk out */
            rxstat = BOUT_RXSTAT(ep_num);
            
            /* TODO handle errors */
            if (rxstat & (1<<18)) /* RxACK */
            {
                if (endpoints[ep_num].cnt > 0)
                    blk_read(ep_num);
                else
                    usb_core_transfer_complete(ep_num,               /* ep */
                                               USB_DIR_OUT,          /* dir */
                                               0,                    /* status */
                                               endpoints[ep_num].len); /* length */                
            }
        }
        else if (intsrc & ((1<<9)|(1<<12)|(1<<15)|(1<<18)|(1<<21)))
        {
            /* bulk in */
            txstat = BIN_TXSTAT(ep_num);
            
            /* TODO handle errors */
            if (txstat & (1<<18)) /* check TxACK flag */
            {
                if (endpoints[ep_num].cnt >= 0)
                {
                    /* we still have data to send (or ZLP) */
                    blk_write(ep_num);
                }
                else
                {
                    /* final ack received */
                    usb_core_transfer_complete(ep_num,                   /* ep */
                                               USB_DIR_IN,          /* dir */
                                               0,                   /* status */
                                               endpoints[ep_num].len); /* length */
                
                    /* release semaphore for blocking transfer */
                    if (endpoints[ep_num].block)
                        semaphore_release(&endpoints[ep_num].complete);
                }
            }
        }
        else if (intsrc & ((1<<10)|(1<13)|(1<<16)|(1<<19)|(1<<22)))
        {
            /* int in */
            txstat = IIN_TXSTAT(ep_num);

            /* TODO handle errors */
            if (txstat & (1<<18)) /* check TxACK flag */
            {
                if (endpoints[ep_num].cnt >= 0)
                {
                    /* we still have data to send (or ZLP) */
                    int_write(ep_num);
                }
                else
                {
                    /* final ack received */
                    usb_core_transfer_complete(ep_num,                   /* ep */
                                               USB_DIR_IN,          /* dir */
                                               0,                   /* status */
                                               endpoints[ep_num].len); /* length */
                
                    /* release semaphore for blocking transfer */
                    if (endpoints[ep_num].block)
                        semaphore_release(&endpoints[ep_num].complete);
                }
            }
        }
    }
}
Example #20
0
static int ext2_get_super(struct super *sb)
{
	struct ext2_super_block *s;
	struct buffer *bh;
	int db_count, i;

	/* Set blocksize for the device */
	if ( blk_set_blocksize(sb->s_dev, EXT2_MIN_BLOCK_SIZE) ) {
		printk("EXT2: Unable to set blocksize %d\n",
			EXT2_MIN_BLOCK_SIZE);
		return -1;
	}

	/* Read in the super block */
	bh = blk_read(sb->s_dev, 1);
	if ( NULL == bh ) {
		printk("EXT2: %s: unable to read super\n",
			sb->s_dev->name);
		return -1;
	}

	s = (struct ext2_super_block *)bh->b_buf;

	/* Check the super block */
	if ( s->s_magic != EXT2_SUPER_MAGIC ) {
		printk("EXT2: Bad voodoo magic on superblock!\n");
		goto err;
	}

	if ( s->s_log_block_size ) {
		printk("EXT2: only 1KB blocksize supported\n");
		goto err;
	}

	/* Fill in the superblock structures */
	sb->s_blocksize = EXT2_MIN_BLOCK_SIZE;
	sb->s_ops = &ext2_superops;

	/* Fill in custom structures */
	sb->u.ext2.s_sbh = bh;
	sb->u.ext2.s_es = s;
	sb->u.ext2.s_inodes_per_block = sb->s_blocksize / s->s_inode_size;
	sb->u.ext2.s_blocks_per_group = s->s_blocks_per_group;
	sb->u.ext2.s_inodes_per_group = s->s_inodes_per_group;
	sb->u.ext2.s_itb_per_group = s->s_inodes_per_group / 
					sb->u.ext2.s_inodes_per_block;
	sb->u.ext2.s_desc_per_block = sb->s_blocksize / 
					sizeof(struct ext2_group_desc);
	sb->u.ext2.s_groups_count = (s->s_blocks_count - 
					s->s_first_data_block + 
					(sb->u.ext2.s_blocks_per_group-1)) /
					sb->u.ext2.s_blocks_per_group;

	/* Read in the group descriptors */
	db_count = (sb->u.ext2.s_groups_count +
		sb->u.ext2.s_desc_per_block - 1) / sb->u.ext2.s_desc_per_block;
	sb->u.ext2.s_group_desc = kmalloc(db_count * sizeof(struct buffer *));
	for(i = 0; i < db_count; i++) {
		int j;
		sb->u.ext2.s_group_desc[i] = blk_read(sb->s_dev, i + 2);
		if ( !sb->u.ext2.s_group_desc[i] ) {
			printk("EXT2: unable to read group descriptors\n");
			for(j = 0; j < i; j++)
				blk_free(sb->u.ext2.s_group_desc[i]);
			goto err;
		}
	}

	/* Lookup root inode */
	sb->s_root = iget(sb, EXT2_ROOT_INO);
	if ( NULL == sb->s_root ) {
		printk("EXT2: get root inode failed\n");
		goto err;
	}

	return 0;
err:
	blk_free(bh);
	return -1;
}
Example #21
0
static int file_block(struct filesys *fs, struct inode *node, int boffs, int allocate)
{
	int res, idx, node_dirty = 0;
	blkid *barr;

	/* out of bounds */
	if(boffs < 0 || boffs >= MAX_DIND) {
		return 0;
	}

	/* is it a direct block ? */
	if(boffs < NDIRBLK) {
		if(!(res = node->blk[boffs]) && allocate) {
			res = node->blk[boffs] = alloc_block(fs);
			if(res) {
				zero_block(fs, res);
				/* also write back the modified inode */
				put_inode(fs, node);
			}
		}
		return res;
	}

	barr = malloc(fs->sb->blksize);
	assert(barr);

	/* is it an indirect block ? */
	if(boffs < MAX_IND) {
		int ind_dirty = 0;

		if(node->ind) {
			/* read the indirect block */
			blk_read(fs->bdev, node->ind, 1, barr);
		} else {
			/* does not exist... try to allocate if requested */
			if(!allocate || !(node->ind = alloc_block(fs))) {
				res = 0;
				goto end;
			}

			/* allocated a block clear the buffer, and invalidate everything */
			memset(barr, 0, sizeof fs->sb->blksize);
			node_dirty = 1;
			ind_dirty = 1;
		}

		idx = boffs - NDIRBLK;

		if(!(res = barr[idx])) {
			if(allocate && (res = barr[idx] = alloc_block(fs))) {
				ind_dirty = 1;
			}
		}

		/* write back the indirect block if needed */
		if(ind_dirty) {
			blk_write(fs->bdev, node->ind, 1, barr);
		}
		goto end;
	}

	/* TODO check/rewrite this */
#if 0
	/* is it a double-indirect block ? */
	if(boffs < MAX_DIND) {
		/* first read the dind block and find the index of the ind block */
		if(!node->dind) {
			if(allocate) {
				/* allocate and zero-out the double indirect block */
				res = node->dind = alloc_block(fs);
				if(res) {
					zero_block(fs, res);
				}
			} else {
				res = 0;
				goto end;
			}
		}
		blk_read(fd->bdev, node->dind, 1, barr);
		idx = (boffs - MAX_IND) / BLK_BLKID;

		/* then read the ind block and find the index of the block */
		if(!barr[idx]) {
			res = 0;
			goto end;
		}
		blk_read(fd->bdev, barr[idx], 1, barr);
		res = barr[(boffs - MAX_IND) % BLK_BLKID];
	}
#endif

end:
	if(node_dirty) {
		put_inode(fs, node);
	}
	free(barr);
	return res;
}
Example #22
0
/* Fill in an inode structure for iget */
static int ext2_read_inode(struct inode *i)
{
	unsigned long block_group;
	unsigned long group_desc, desc;
	unsigned long offset, block;
	struct ext2_group_desc *gdp;
	struct ext2_inode *raw_inode;
	struct buffer *b;

	/* 1. Check inode number */
	if ( i->i_ino > i->i_sb->u.ext2.s_es->s_inodes_count ) {
		printk("EXT2: bad inode %lu\n", i->i_ino);
		return -1;
	}

	/* 2. Calculate block group number */
	block_group = (i->i_ino - 1) / i->i_sb->u.ext2.s_inodes_per_group;
	if ( block_group >= i->i_sb->u.ext2.s_groups_count ) {
		printk("EXT2: Bad group %lu\n", block_group);
		return -1;
	}
	
	/* 3. Obtain block group descriptor */
	group_desc = block_group / i->i_sb->u.ext2.s_desc_per_block;
	desc = block_group % i->i_sb->u.ext2.s_desc_per_block;
	b = i->i_sb->u.ext2.s_group_desc[group_desc];
	gdp = (struct ext2_group_desc *)b->b_buf;
	
	/* 4. Obtain correct block from inode table */
	block = gdp[desc].bg_inode_table + 
		((i->i_ino - 1) / i->i_sb->u.ext2.s_inodes_per_block);
	if ( !(b=blk_read(i->i_sb->s_dev, block)) ) {
		printk("EXT2: Unable to read inode block - inode=%lu, block=%lu\n",
			i->i_ino, block);
		return -1;
	}

	/* 5. Obtain the inode pointer */
	offset = (i->i_ino - 1) * i->i_sb->u.ext2.s_es->s_inode_size;
	offset &= (i->i_sb->s_blocksize - 1);
	raw_inode = (struct ext2_inode *)(b->b_buf + offset);
	
	/* 6. Copy the inode */
	dprintk("Inode %lu mode %o\n", i->i_ino, raw_inode->i_mode);
	switch(raw_inode->i_mode & S_IFMT) {
	case S_IFDIR:
		i->i_iop = &ext2_dir_iop;
		break;
	case S_IFREG:
		i->i_iop = &ext2_reg_iop;
		break;
	default:
		printk("EXT2: Unsupported file type: 0%o\n",
			raw_inode->i_mode);
		blk_free(b);
		return -1;
	}

	i->i_mode = raw_inode->i_mode;
	i->i_uid = raw_inode->i_uid;
	i->i_gid = raw_inode->i_gid;
	i->i_size = raw_inode->i_size;
	i->i_nlink = raw_inode->i_links_count;
	i->i_blocks = raw_inode->i_blocks;

	for(block = 0; block < EXT2_N_BLOCKS; block++) {
		i->u.ext2.block[block] = raw_inode->i_block[block];
	}

	/* Finish up */
	blk_free(b);
	return 0;
}
Example #23
0
static int get_config(int num, char *buf)
{
  int ret;
  ret = blk_read(buf, 512, CONFIG_MTD_CONFIG_DEVPATH, num * 512);
  return ret;
}