/** * <Ring 1> Do some preparation. * *****************************************************************************/ PRIVATE void init_fs() { int i; /* f_desc_table[] */ for (i = 0; i < NR_FILE_DESC; i++) memset(&f_desc_table[i], 0, sizeof(struct file_desc)); /* inode_table[] */ for (i = 0; i < NR_INODE; i++) memset(&inode_table[i], 0, sizeof(struct inode)); /* super_block[] */ struct super_block * sb = super_block; for (; sb < &super_block[NR_SUPER_BLOCK]; sb++) sb->sb_dev = NO_DEV; /* open the device: hard disk */ MESSAGE driver_msg; driver_msg.type = DEV_OPEN; driver_msg.DEVICE = MINOR(ROOT_DEV); assert(dd_map[MAJOR(ROOT_DEV)].driver_nr != INVALID_DRIVER); send_recv(BOTH, dd_map[MAJOR(ROOT_DEV)].driver_nr, &driver_msg); /* make FS */ mkfs(); /* load super block of ROOT */ read_super_block(ROOT_DEV); sb = get_super_block(ROOT_DEV); assert(sb->magic == MAGIC_V1); root_inode = get_inode(ROOT_DEV, ROOT_INODE); }
int mount_root_fs(void) { char buf[32] = { 0 }; ssize_t ret = 0; driver = get_blk_driver("ATA disk"); if (!driver) { printk("There is no ATA disk driver!\n"); return -1; } if (driver->op->open()) { printk("Couldn't open disk\n"); return -1; } set_mount_point("/", "minix", driver); read_super_block("minix", "/"); printk("rootfs mount finished\n"); ret = vfs_read("/dir_a/dir_b/foobar.txt", buf, sizeof(buf) - 1); printk("/dir_a/dir_b/foobar.txt's size is %d bytes and data is %s", ret, buf); return 0; }
/***************************************************************************** 读取i节点结构到内存 *****************************************************************************/ struct m_inode *iget(uint super_block_id, uint ino) { struct m_super_block msb; uint blkno, blkoff; struct buf *bp; struct m_inode *mip; printl(__FILE__, __LINE__, "iget(): super_block_id-%d ino-0x%X\n", super_block_id, ino); if(read_super_block(super_block_id, &msb)) { printl(__FILE__, __LINE__, "iget(): invalid super_block_id\n"); return NULL; } if(ino == 0 || ino >= msb.s_ninodes) { printl(__FILE__, __LINE__, "iget(): invalid ino\n"); return NULL; } blkno = (ino - 1) / IPB; blkoff = ((ino - 1) % IPB) * sizeof(struct d_inode); if((bp = bget(super_block_id, msb.firstinodezone + blkno)) == NULL) { printl(__FILE__, __LINE__, "iget(): invalid struct buf *bp\n"); return NULL; } if((mip = (struct m_inode *)calloc(1, sizeof(struct m_inode))) == NULL) { printl(__FILE__, __LINE__, "iget(): invalid struct m_inode *mip\n"); brelse(bp); return NULL; } mip->super_block_id = super_block_id; mip->ino = ino; memcpy((char *)mip, bp->data + blkoff, sizeof(struct d_inode)); brelse(bp); return mip; }
void mount_root( void ) { int i; struct m_super_block *p; if( 64 != sizeof( struct d_inode )) panic(" bad inode size!\n"); for( i=0; i< NR_FILE_DESC; i++ ) file_desc_table[i].fd_count = 0; for( p=super_block_table; p<super_block_table+NR_SUPER_BLOCK; p++ ) { memset( p, 0, sizeof(struct m_super_block) ); } read_super_block( ROOT_DEV ); if( !( p = get_super_block(ROOT_DEV)) ) panic("unable to mount root!\n"); read_block_table( p ); }
void set_defaults(void) { char param_value[LINE_MAX + 1]; get_param("INSTR_SLICE", param_value); instr_slice = atoi(param_value); int heads, tracks, sectors; char command[1000]; get_param("NUM_HEADS", param_value); heads = atoi(param_value); get_param("NUM_TRACKS", param_value); tracks = atoi(param_value); get_param("NUM_SECTORS", param_value); sectors = atoi(param_value); FILE* check = fopen("Sim_disk", "r"); if(check != NULL) { disk_file_pointer = fopen("Sim_disk", "rb+"); read_super_block(); init_cache(); fclose(check); } else { total_blocks_virtual_mem = (heads * tracks * sectors) / 8; blocks_in_track = total_blocks_virtual_mem / tracks; prev_track = 0; disk_block_data = (int *) malloc(total_blocks_virtual_mem * sizeof(int)); int i = 0; for (i = 0; i < total_blocks_virtual_mem; i++) disk_block_data[i] = -1; sprintf(command, "(dd if=/dev/zero of=Sim_disk bs=%dx%dx%db count=1) 2> /dev/zero", heads, tracks, sectors); system(command); disk_file_pointer = fopen("Sim_disk", "rb+"); init_super_block(); init_cache(); } }
/***************************************************************************** 释放i节点内容 *****************************************************************************/ void irelse(struct m_inode *mip) { struct m_super_block msb; uint blkno, blkoff; struct buf *bp; if(!(mip && mip->ino)) { printl(__FILE__, __LINE__, "irelse(): invalid inode\n"); return ; } printl(__FILE__, __LINE__, "irelse(): ino-0x%X\n", mip->ino); if(mip->flag == UPD) { if(read_super_block(mip->super_block_id, &msb)) { printl(__FILE__, __LINE__, "irelse(): invalid super_block_id\n"); return ; } blkno = (mip->ino - 1) / IPB; blkoff = ((mip->ino - 1) % IPB) * sizeof(struct d_inode); if((bp = bget(mip->super_block_id, msb.firstinodezone + blkno)) == NULL) { printl(__FILE__, __LINE__, "irelse(): invalid struct buf *bp\n"); return ; } mip->i_mtime = get_seconds(); // 更新时间 memcpy(bp->data + blkoff, mip, sizeof(struct d_inode)); bp->flag = UPD; brelse(bp); } free(mip); }
// // a portion of this function, particularly the VFS interface portion, // was derived from minix or ext2's analog and evolved as the // prototype did. You should be able to tell which portion by looking // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // static struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent) { int size; struct inode *root_inode; kdev_t dev = s->s_dev; int j; extern int *blksize_size[]; struct reiserfs_transaction_handle th ; int old_format = 0; unsigned long blocks; int jinit_done = 0 ; struct reiserfs_iget4_args args ; int old_magic; struct reiserfs_super_block * rs; memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info)); if (parse_options ((char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) { return NULL; } if (blocks) { printk("reserfs: resize option for remount only\n"); return NULL; } if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)] != 0) { /* as blocksize is set for partition we use it */ size = blksize_size[MAJOR(dev)][MINOR(dev)]; } else { size = BLOCK_SIZE; set_blocksize (s->s_dev, BLOCK_SIZE); } /* read block (64-th 1k block), which can contain reiserfs super block */ if (read_super_block (s, size, REISERFS_DISK_OFFSET_IN_BYTES)) { // try old format (undistributed bitmap, super block in 8-th 1k block of a device) if (read_super_block (s, size, REISERFS_OLD_DISK_OFFSET_IN_BYTES)) goto error; else old_format = 1; } rs = SB_DISK_SUPER_BLOCK (s); s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s); s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ; if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { printk ("reiserfs_read_super: unable to read bitmap\n"); goto error; } #ifdef CONFIG_REISERFS_CHECK printk("reiserfs:warning: CONFIG_REISERFS_CHECK is set ON\n"); printk("reiserfs:warning: - it is slow mode for debugging.\n"); #endif // set_device_ro(s->s_dev, 1) ; if (journal_init(s)) { printk("reiserfs_read_super: unable to initialize journal space\n") ; goto error ; } else { jinit_done = 1 ; /* once this is set, journal_release must be called ** if we error out of the mount */ } if (reread_meta_blocks(s)) { printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ; goto error ; } if (replay_only (s)) goto error; if (is_read_only(s->s_dev) && !(s->s_flags & MS_RDONLY)) { printk("clm-7000: Detected readonly device, marking FS readonly\n") ; s->s_flags |= MS_RDONLY ; } args.objectid = REISERFS_ROOT_PARENT_OBJECTID ; root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args)); if (!root_inode) { printk ("reiserfs_read_super: get root inode failed\n"); goto error; } s->s_root = d_alloc_root(root_inode); if (!s->s_root) { iput(root_inode); goto error; } // define and initialize hash function s->u.reiserfs_sb.s_hash_function = hash_function (s); if (s->u.reiserfs_sb.s_hash_function == NULL) { dput(s->s_root) ; s->s_root = NULL ; goto error ; } rs = SB_DISK_SUPER_BLOCK (s); old_magic = strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, strlen ( REISER2FS_SUPER_MAGIC_STRING)); if (!old_magic) set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties)); else set_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties)); if (!(s->s_flags & MS_RDONLY)) { journal_begin(&th, s, 1) ; reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ; set_sb_state( rs, REISERFS_ERROR_FS ); if ( old_magic ) { // filesystem created under 3.5.x found if (convert_reiserfs (s)) { reiserfs_warning("reiserfs: converting 3.5.x filesystem to the new format\n") ; // after this 3.5.x will not be able to mount this partition memcpy (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, sizeof (REISER2FS_SUPER_MAGIC_STRING)); reiserfs_convert_objectid_map_v1(s) ; set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties)); clear_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties)); } else { reiserfs_warning("reiserfs: using 3.5.x disk format\n") ; } } journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); journal_end(&th, s, 1) ; /* look for files which were to be removed in previous session */ finish_unfinished (s); s->s_dirt = 0; } else { if ( old_magic ) { reiserfs_warning("reiserfs: using 3.5.x disk format\n") ; } } // mark hash in super block: it could be unset. overwrite should be ok set_sb_hash_function_code( rs, function2code(s->u.reiserfs_sb.s_hash_function ) ); handle_attrs( s ); reiserfs_proc_info_init( s ); reiserfs_proc_register( s, "version", reiserfs_version_in_proc ); reiserfs_proc_register( s, "super", reiserfs_super_in_proc ); reiserfs_proc_register( s, "per-level", reiserfs_per_level_in_proc ); reiserfs_proc_register( s, "bitmap", reiserfs_bitmap_in_proc ); reiserfs_proc_register( s, "on-disk-super", reiserfs_on_disk_super_in_proc ); reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc ); reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc ); init_waitqueue_head (&(s->u.reiserfs_sb.s_wait)); printk("%s\n", reiserfs_get_version_string()) ; return s; error: if (jinit_done) { /* kill the commit thread, free journal ram */ journal_release_error(NULL, s) ; } if (SB_DISK_SUPER_BLOCK (s)) { for (j = 0; j < SB_BMAP_NR (s); j ++) { if (SB_AP_BITMAP (s)) brelse (SB_AP_BITMAP (s)[j]); } if (SB_AP_BITMAP (s)) reiserfs_kfree (SB_AP_BITMAP (s), sizeof (struct buffer_head *) * SB_BMAP_NR (s), s); } if (SB_BUFFER_WITH_SB (s)) brelse(SB_BUFFER_WITH_SB (s)); return NULL; }
/* * Common code for mount and mountroot */ static int reiserfs_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { int error, old_format = 0; struct reiserfs_mount *rmp; struct reiserfs_sb_info *sbi; struct reiserfs_super_block *rs; struct cdev *dev; struct g_consumer *cp; struct bufobj *bo; //ronly = (mp->mnt_flag & MNT_RDONLY) != 0; dev = devvp->v_rdev; dev_ref(dev); DROP_GIANT(); g_topology_lock(); error = g_vfs_open(devvp, &cp, "reiserfs", /* read-only */ 0); g_topology_unlock(); PICKUP_GIANT(); VOP_UNLOCK(devvp, 0); if (error) { dev_rel(dev); return (error); } bo = &devvp->v_bufobj; bo->bo_private = cp; bo->bo_ops = g_vfs_bufops; if (devvp->v_rdev->si_iosize_max != 0) mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max; if (mp->mnt_iosize_max > MAXPHYS) mp->mnt_iosize_max = MAXPHYS; rmp = NULL; sbi = NULL; /* rmp contains any information about this specific mount */ rmp = malloc(sizeof *rmp, M_REISERFSMNT, M_WAITOK | M_ZERO); if (!rmp) { error = (ENOMEM); goto out; } sbi = malloc(sizeof *sbi, M_REISERFSMNT, M_WAITOK | M_ZERO); if (!sbi) { error = (ENOMEM); goto out; } rmp->rm_reiserfs = sbi; rmp->rm_mountp = mp; rmp->rm_devvp = devvp; rmp->rm_dev = dev; rmp->rm_bo = &devvp->v_bufobj; rmp->rm_cp = cp; /* Set default values for options: non-aggressive tails */ REISERFS_SB(sbi)->s_mount_opt = (1 << REISERFS_SMALLTAIL); REISERFS_SB(sbi)->s_rd_only = 1; REISERFS_SB(sbi)->s_devvp = devvp; /* Read the super block */ if ((error = read_super_block(rmp, REISERFS_OLD_DISK_OFFSET)) == 0) { /* The read process succeeded, it's an old format */ old_format = 1; } else if ((error = read_super_block(rmp, REISERFS_DISK_OFFSET)) != 0) { reiserfs_log(LOG_ERR, "can not find a ReiserFS filesystem\n"); goto out; } rs = SB_DISK_SUPER_BLOCK(sbi); /* * Let's do basic sanity check to verify that underlying device is * not smaller than the filesystem. If the check fails then abort and * scream, because bad stuff will happen otherwise. */ #if 0 if (s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs) * sb_blocksize(rs)) { reiserfs_log(LOG_ERR, "reiserfs: filesystem cannot be mounted because it is " "bigger than the device.\n"); reiserfs_log(LOG_ERR, "reiserfs: you may need to run fsck " "rr may be you forgot to reboot after fdisk when it " "told you to.\n"); goto out; } #endif /* * XXX This is from the original Linux code, but why affecting 2 values * to the same variable? */ sbi->s_mount_state = SB_REISERFS_STATE(sbi); sbi->s_mount_state = REISERFS_VALID_FS; if ((error = (old_format ? read_old_bitmaps(rmp) : read_bitmaps(rmp)))) { reiserfs_log(LOG_ERR, "unable to read bitmap\n"); goto out; } /* Make data=ordered the default */ if (!reiserfs_data_log(sbi) && !reiserfs_data_ordered(sbi) && !reiserfs_data_writeback(sbi)) { REISERFS_SB(sbi)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED); } if (reiserfs_data_log(sbi)) { reiserfs_log(LOG_INFO, "using journaled data mode\n"); } else if (reiserfs_data_ordered(sbi)) { reiserfs_log(LOG_INFO, "using ordered data mode\n"); } else { reiserfs_log(LOG_INFO, "using writeback data mode\n"); } /* TODO Not yet supported */ #if 0 if(journal_init(sbi, jdev_name, old_format, commit_max_age)) { reiserfs_log(LOG_ERR, "unable to initialize journal space\n"); goto out; } else { jinit_done = 1 ; /* once this is set, journal_release must be called if we error out of the mount */ } if (reread_meta_blocks(sbi)) { reiserfs_log(LOG_ERR, "unable to reread meta blocks after journal init\n"); goto out; } #endif /* Define and initialize hash function */ sbi->s_hash_function = hash_function(rmp); if (sbi->s_hash_function == NULL) { reiserfs_log(LOG_ERR, "couldn't determined hash function\n"); error = (EINVAL); goto out; } if (is_reiserfs_3_5(rs) || (is_reiserfs_jr(rs) && SB_VERSION(sbi) == REISERFS_VERSION_1)) bit_set(&(sbi->s_properties), REISERFS_3_5); else bit_set(&(sbi->s_properties), REISERFS_3_6); mp->mnt_data = rmp; mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; MNT_ILOCK(mp); mp->mnt_flag |= MNT_LOCAL; mp->mnt_kern_flag |= MNTK_MPSAFE; MNT_IUNLOCK(mp); #if defined(si_mountpoint) devvp->v_rdev->si_mountpoint = mp; #endif return (0); out: reiserfs_log(LOG_INFO, "*** error during mount ***\n"); if (sbi) { if (SB_AP_BITMAP(sbi)) { int i; for (i = 0; i < SB_BMAP_NR(sbi); i++) { if (!SB_AP_BITMAP(sbi)[i].bp_data) break; free(SB_AP_BITMAP(sbi)[i].bp_data, M_REISERFSMNT); } free(SB_AP_BITMAP(sbi), M_REISERFSMNT); } if (sbi->s_rs) { free(sbi->s_rs, M_REISERFSMNT); sbi->s_rs = NULL; } } if (cp != NULL) { DROP_GIANT(); g_topology_lock(); g_vfs_close(cp); g_topology_unlock(); PICKUP_GIANT(); } if (sbi) free(sbi, M_REISERFSMNT); if (rmp) free(rmp, M_REISERFSMNT); dev_rel(dev); return (error); }
static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec) { /* Check for the types of filesystems we know how to check */ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { /* * Some system images do not have tune2fs for licensing reasons * Detect these and skip reserve blocks. */ if (access(TUNE2FS_BIN, X_OK)) { ERROR("Not running %s on %s (executable not in system image)\n", TUNE2FS_BIN, blk_device); } else { INFO("Running %s on %s\n", TUNE2FS_BIN, blk_device); int status = 0; int ret = 0; unsigned long reserved_blocks = 0; int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)); if (fd >= 0) { struct ext4_super_block sb; ret = read_super_block(fd, &sb); if (ret < 0) { ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno)); goto out; } reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb); unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02; if (reserved_threshold < reserved_blocks) { WARNING("Reserved blocks %lu is too large\n", reserved_blocks); reserved_blocks = reserved_threshold; } if (ext4_r_blocks_count(&sb) == reserved_blocks) { INFO("Have reserved same blocks\n"); goto out; } } else { ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno)); return; } char buf[16] = {0}; snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks); char *tune2fs_argv[] = { TUNE2FS_BIN, buf, blk_device, }; ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv, &status, true, LOG_KLOG | LOG_FILE, true, NULL, NULL, 0); if (ret < 0) { /* No need to check for error in fork, we can't really handle it now */ ERROR("Failed trying to run %s\n", TUNE2FS_BIN); } out: close(fd); } } }
static int do_quota(char *blk_device, char *fs_type, struct fstab_rec *rec) { int force_check = 0; if (!strcmp(fs_type, "ext4")) { /* * Some system images do not have tune2fs for licensing reasons * Detect these and skip reserve blocks. */ if (access(TUNE2FS_BIN, X_OK)) { ERROR("Not running %s on %s (executable not in system image)\n", TUNE2FS_BIN, blk_device); } else { char* arg1 = NULL; char* arg2 = NULL; int status = 0; int ret = 0; int fd = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)); if (fd >= 0) { struct ext4_super_block sb; ret = read_super_block(fd, &sb); if (ret < 0) { ERROR("Can't read '%s' super block: %s\n", blk_device, strerror(errno)); goto out; } int has_quota = (sb.s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0; int want_quota = fs_mgr_is_quota(rec) != 0; if (has_quota == want_quota) { INFO("Requested quota status is match on %s\n", blk_device); goto out; } else if (want_quota) { INFO("Enabling quota on %s\n", blk_device); arg1 = "-Oquota"; arg2 = "-Qusrquota,grpquota"; force_check = 1; } else { INFO("Disabling quota on %s\n", blk_device); arg1 = "-Q^usrquota,^grpquota"; arg2 = "-O^quota"; } } else { ERROR("Failed to open '%s': %s\n", blk_device, strerror(errno)); return force_check; } char *tune2fs_argv[] = { TUNE2FS_BIN, arg1, arg2, blk_device, }; ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), tune2fs_argv, &status, true, LOG_KLOG | LOG_FILE, true, NULL, NULL, 0); if (ret < 0) { /* No need to check for error in fork, we can't really handle it now */ ERROR("Failed trying to run %s\n", TUNE2FS_BIN); } out: close(fd); } } return force_check; }
static int ext2_load_linux(int fd,int index, const unsigned char *path) { struct ext2_inode *ext2_raw_inode; ext2_dirent *de; unsigned char *bh; int i; unsigned int inode; int find = 1; unsigned char s[EXT2_NAME_LEN]; unsigned char pathname[EXT2_NAME_LEN], *pathnameptr; unsigned char *directoryname; int showdir, lookupdir; showdir = 0; lookupdir = 0; bh = 0; if(read_super_block(fd,index)) return -1; if((path[0]==0) || (path[strlen(path)-1] == '/')) lookupdir = 1; strncpy(pathname,path,sizeof(pathname)); pathnameptr = pathname; for(inode = EXT2_ROOT_INO; find; ) { for(i = 0; pathnameptr[i] && pathnameptr[i] != '/'; i++); pathnameptr[i] = 0; directoryname = (unsigned char *)pathnameptr; pathnameptr = (unsigned char *)(pathnameptr + i + 1); if(!strlen(directoryname) && lookupdir) showdir = 1; if(ext2_get_inode(fd, inode, &ext2_raw_inode)) { printf("load EXT2_ROOT_INO error"); return -1; } if(!bh) bh = (unsigned char *)malloc(sb_block_size + ext2_raw_inode->i_size); if(!bh) { printf("Error in allocting memory for file content!\n"); return -1; } if(ext2_read_file(fd, bh, ext2_raw_inode->i_size, 0, ext2_raw_inode) != ext2_raw_inode->i_size) return -1; de = (ext2_dirent *)bh; find = 0; for ( ; ((unsigned char *) de < bh + ext2_raw_inode->i_size) && (de->rec_len > 0) && (de->name_len > 0); de = ext2_next_entry(de)) { strncpy(s,de->name,de->name_len); s[de->name_len]='\0';//*(de->name+de->name_len)='\0'; #ifdef DEBUG_IDE printf("entry:name=%s,inode=%d,rec_len=%d,name_len=%d,file_type=%d\n",s,de->inode,de->rec_len,de->name_len,de->file_type); #endif if(showdir) printf("%s%s",s,((de->file_type)&2)?"/ ":" "); if (!ext2_entrycmp(directoryname, de->name, de->name_len)) { if(de->file_type == EXT2_FT_REG_FILE) { if (ext2_get_inode(fd, de->inode, &the_inode)) { printf("load EXT2_ROOT_INO error"); free(bh); return -1; } free(bh); return 0; } find = 1; inode = de->inode; break; } } if(!find) { free(bh); if(!lookupdir) printf("Not find the file or directory!\n"); else printf("\n"); return -1; } } return -1; }
static int find_superblock(caddr_t devstr) { int cg = 0; int retval = 0; int first; int found; calcsb_t style; struct fs proto; /* * Check the superblock, looking for alternates if necessary. * In more-recent times, some UFS instances get created with * only the first ten and last ten superblock backups. Since * if we can't get the necessary information from any of those, * the odds are also against us for the ones in between, we'll * just look at those twenty to save time. */ if (!read_super_block(1) || !checksb(1)) { if (bflag || preen) { retval = -1; goto finish; } for (style = MKFS_STYLE; style < MAX_SB_STYLES; style++) { if (reply("LOOK FOR ALTERNATE SUPERBLOCKS WITH %s", calcsb_names[style]) == 0) continue; first = 1; found = 0; if (!calcsb(style, devstr, fsreadfd, &proto)) { cg = proto.fs_ncg; continue; } if (debug) { (void) printf( "debug: calcsb(%s) gave fpg %d, cgoffset %d, ", calcsb_names[style], proto.fs_fpg, proto.fs_cgoffset); (void) printf("cgmask 0x%x, sblk %d, ncg %d\n", proto.fs_cgmask, proto.fs_sblkno, proto.fs_ncg); } for (cg = 0; cg < proto.fs_ncg; cg++) { bflag = fsbtodb(&proto, cgsblock(&proto, cg)); if (debug) (void) printf( "debug: trying block %lld\n", (longlong_t)bflag); if (read_super_block(0) && checksb(0)) { (void) printf( "FOUND ALTERNATE SUPERBLOCK %d WITH %s\n", bflag, calcsb_names[style]); if (reply( "USE ALTERNATE SUPERBLOCK") == 1) { found = 1; break; } } if (first && (cg >= 9)) { first = 0; if (proto.fs_ncg <= 9) cg = proto.fs_ncg; else if (proto.fs_ncg <= 19) cg = 9; else cg = proto.fs_ncg - 10; } } if (found) break; } /* * Didn't find one? Try to fake it. */ if (style >= MAX_SB_STYLES) { pwarn("SEARCH FOR ALTERNATE SUPERBLOCKS FAILED.\n"); for (style = MKFS_STYLE; style < MAX_SB_STYLES; style++) { if (reply("USE GENERIC SUPERBLOCK FROM %s", calcsb_names[style]) == 1 && calcsb(style, devstr, fsreadfd, &sblock)) { break; } /* * We got something from mkfs/newfs, so use it. */ if (style < MAX_SB_STYLES) proto.fs_ncg = sblock.fs_ncg; bflag = 0; } } /* * Still no luck? Tell the user they're on their own. */ if (style >= MAX_SB_STYLES) { pwarn("SEARCH FOR ALTERNATE SUPERBLOCKS FAILED. " "YOU MUST USE THE -o b OPTION\n" "TO FSCK TO SPECIFY THE LOCATION OF A VALID " "ALTERNATE SUPERBLOCK TO\n" "SUPPLY NEEDED INFORMATION; SEE fsck(1M).\n"); bflag = 0; retval = -1; goto finish; } /* * Need to make sure a human really wants us to use * this. -y mode could've gotten us this far, so * we need to ask something that has to be answered * in the negative. * * Note that we can't get here when preening. */ if (!found) { pwarn("CALCULATED GENERIC SUPERBLOCK WITH %s\n", calcsb_names[style]); } else { pwarn("FOUND ALTERNATE SUPERBLOCK AT %d USING %s\n", bflag, calcsb_names[style]); } pwarn("If filesystem was created with manually-specified "); pwarn("geometry, using\nauto-discovered superblock may "); pwarn("result in irrecoverable damage to\nfilesystem and "); pwarn("user data.\n"); if (reply("CANCEL FILESYSTEM CHECK") == 1) { if (cg >= 0) { pwarn("Please verify that the indicated block " "contains a proper\nsuperblock for the " "filesystem (see fsdb(1M)).\n"); if (yflag) pwarn("\nFSCK was running in YES " "mode. If you wish to run in " "that mode using\nthe alternate " "superblock, run " "`fsck -y -o b=%d %s'.\n", bflag, devstr); } retval = -1; goto finish; } /* * Pretend we found it as an alternate, so everything * gets updated when we clean up at the end. */ if (!found) { havesb = 1; sblk.b_bno = fsbtodb(&sblock, cgsblock(&sblock, 0)); bwrite(fswritefd, (caddr_t)&sblock, SBLOCK, SBSIZE); write_altsb(fswritefd); } } finish: return (retval); }
/* * Roll the embedded log, if any, and set up the global variables * islog and islogok. */ static int logsetup(caddr_t devstr) { void *buf; extent_block_t *ebp; ml_unit_t *ul; ml_odunit_t *ud; void *ud_buf; int badlog; islog = islogok = 0; if (bflag != 0) return (1); /* can't roll log while alternate sb specified */ /* * Roll the log, if any. A bad sb implies we'll be using * an alternate sb as far as logging goes, so just fail back * to the caller if we can't read the default sb. Suppress * complaints, because the caller will be reading the same * superblock again and running full verification on it, so * whatever is bad will be reported then. */ sblock.fs_logbno = 0; badlog = 0; if (!read_super_block(0)) return (1); /* * Roll the log in 3 cases: * 1. If it's unmounted (mount_point == NULL) and it's not marked * as fully rolled (sblock.fs_rolled != FS_ALL_ROLLED) * 2. If it's mounted and anything other than a sanity * check fsck (mflag) is being done, as we have the current * super block. Note, only a sanity check is done for * root/usr at boot. If a roll were done then the expensive * ufs_flush() gets called, leading to a slower boot. * 3. If anything other then a sanity check (mflag) is being done * to a mounted filesystem while it is in read-only state * (e.g. root during early boot stages) we have to detect this * and have to roll the log as well. NB. the read-only mount * will flip fs_clean from FSLOG to FSSTABLE and marks the * log as FS_NEED_ROLL. */ if (sblock.fs_logbno && (((mount_point == NULL) && (sblock.fs_rolled != FS_ALL_ROLLED)) || ((mount_point != NULL) && !mflag))) { int roll_log_err = 0; if (sblock.fs_ronly && (sblock.fs_clean == FSSTABLE) && (sblock.fs_state + sblock.fs_time == FSOKAY)) { /* * roll the log without a mount */ flush_fs(); } if (sblock.fs_clean == FSLOG && (sblock.fs_state + sblock.fs_time == FSOKAY)) { if (rl_roll_log(devstr) != RL_SUCCESS) roll_log_err = 1; } if (roll_log_err) { (void) printf("Can't roll the log for %s.\n", devstr); /* * There are two cases where we want to set * an error code and return: * - We're preening * - We're not on a live root and the user * chose *not* to ignore the log * Otherwise, we want to mark the log as bad * and continue to check the filesystem. This * has the side effect of destroying the log. */ if (preen || (!hotroot && reply( "DISCARDING THE LOG MAY DISCARD PENDING TRANSACTIONS.\n" "DISCARD THE LOG AND CONTINUE") == 0)) { exitstat = EXERRFATAL; return (0); } ++badlog; } } /* Logging UFS may be enabled */ if (sblock.fs_logbno) { ++islog; /* log is not okay; check the fs */ if (FSOKAY != (sblock.fs_state + sblock.fs_time)) return (1); /* * If logging or (stable and mounted) then continue */ if (!((sblock.fs_clean == FSLOG) || (sblock.fs_clean == FSSTABLE) && (mount_point != NULL))) return (1); /* get the log allocation block */ buf = malloc(dev_bsize); if (buf == NULL) { return (1); } ud_buf = malloc(dev_bsize); if (ud_buf == NULL) { free(buf); return (1); } (void) fsck_bread(fsreadfd, buf, logbtodb(&sblock, sblock.fs_logbno), dev_bsize); ebp = (extent_block_t *)buf; /* log allocation block is not okay; check the fs */ if (ebp->type != LUFS_EXTENTS) { free(buf); free(ud_buf); return (1); } /* get the log state block(s) */ if (fsck_bread(fsreadfd, ud_buf, (logbtodb(&sblock, ebp->extents[0].pbno)), dev_bsize)) { (void) fsck_bread(fsreadfd, ud_buf, (logbtodb(&sblock, ebp->extents[0].pbno)) + 1, dev_bsize); } ud = (ml_odunit_t *)ud_buf; ul = (ml_unit_t *)malloc(sizeof (*ul)); if (ul == NULL) { free(buf); free(ud_buf); return (1); } ul->un_ondisk = *ud; /* log state is okay; don't need to check the fs */ if ((ul->un_chksum == ul->un_head_ident + ul->un_tail_ident) && (ul->un_version == LUFS_VERSION_LATEST) && (ul->un_badlog == 0) && (!badlog)) { ++islogok; } free(ud_buf); free(buf); free(ul); } return (1); }
struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent) { int size; struct inode *root_inode; kdev_t dev = s->s_dev; int j; extern int *blksize_size[]; struct reiserfs_transaction_handle th ; int old_format = 0; unsigned long blocks; int jinit_done = 0 ; memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info)); if (parse_options ((char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) { s->s_dev = 0; return NULL; } if (blocks) { printk("reserfs: resize option for remount only\n"); return NULL; } MOD_INC_USE_COUNT; lock_super (s); if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)] != 0) { /* as blocksize is set for partition we use it */ size = blksize_size[MAJOR(dev)][MINOR(dev)]; } else { size = BLOCK_SIZE; set_blocksize (s->s_dev, BLOCK_SIZE); } /* read block, containing reiserfs super block (it is stored at REISERFS_FIRST_BLOCK-th 1K block) */ if (read_super_block (s, size)) { if(read_old_super_block(s,size)) goto error; else old_format = 1; } s->u.reiserfs_sb.s_mount_state = le16_to_cpu (SB_DISK_SUPER_BLOCK (s)->s_state); /* journal victim */ s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ; /* reiserfs can not be mounted when it propably contains errors */ #if 0 /* journal victim */ if (le16_to_cpu (SB_DISK_SUPER_BLOCK (s)->s_state) != REISERFS_VALID_FS) { printk ("reiserfs_read_super: mounting unchecked fs, run reiserfsck first\n"); goto error; } #endif if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { printk ("reiserfs_read_super: unable to read bitmap\n"); goto error; } if (journal_init(s)) { printk("reiserfs_read_super: unable to initialize journal space\n") ; goto error ; } else { jinit_done = 1 ; /* once this is set, journal_release must be called ** if we error out of the mount */ } if (reread_meta_blocks(s)) { printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ; goto error ; } if (replay_only (s)) goto error; /*s->s_op = &reiserfs_sops;*/ /* get root directory inode */ store_key (s, &root_key); root_inode = iget (s, root_key.k_objectid); forget_key (s, &root_key); if (!root_inode) { printk ("reiserfs_read_super: get root inode failed\n"); goto error; } s->s_root = d_alloc_root(root_inode, NULL); if (!s->s_root) { iput(root_inode); goto error; } if (!(s->s_flags & MS_RDONLY)) { SB_DISK_SUPER_BLOCK (s)->s_state = cpu_to_le16 (REISERFS_ERROR_FS); /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */ journal_begin(&th, s, 1) ; journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); journal_end(&th, s, 1) ; s->s_dirt = 0; } /*s->u.reiserfs_sb.unpreserve = dont_preserve (s) ? 0 : unpreserve;*/ /* we have to do this to make journal writes work correctly */ SB_BUFFER_WITH_SB(s)->b_end_io = reiserfs_end_buffer_io_sync ; unlock_super (s); print_credits() ; printk("%s\n", reiserfs_get_version_string()) ; return s; error: if (jinit_done) { /* kill the commit thread, free journal ram */ journal_release_error(NULL, s) ; } if (SB_DISK_SUPER_BLOCK (s)) { for (j = 0; j < le16_to_cpu (SB_DISK_SUPER_BLOCK (s)->s_bmap_nr); j ++) { if (SB_AP_BITMAP (s)) brelse (SB_AP_BITMAP (s)[j]); /* if (SB_AP_CAUTIOUS_BITMAP (s)) brelse (SB_AP_CAUTIOUS_BITMAP (s)[j]); */ } if (SB_AP_BITMAP (s)) reiserfs_kfree (SB_AP_BITMAP (s), sizeof (struct buffer_head *) * SB_BMAP_NR (s), s); /* if (SB_AP_CAUTIOUS_BITMAP (s)) reiserfs_kfree (SB_AP_CAUTIOUS_BITMAP (s), sizeof (struct buffer_head *) * SB_BMAP_NR (s), s); */ } if (SB_BUFFER_WITH_SB (s)) brelse(SB_BUFFER_WITH_SB (s)); s->s_dev = 0; unlock_super(s); MOD_DEC_USE_COUNT; return NULL; }