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; }
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; }
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; }
// 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; }
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 */ ); }
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; }
//*****************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; }
//******** 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; }
/* 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; }
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); }
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; }
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); }
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); }
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; }
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; }
/* 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; }
//****** 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); } } } } }
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; }
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; }
/* 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; }
static int get_config(int num, char *buf) { int ret; ret = blk_read(buf, 512, CONFIG_MTD_CONFIG_DEVPATH, num * 512); return ret; }