Esempio n. 1
0
/**
 * <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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
File: super.c Progetto: qpig/sfs
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 );
}
Esempio n. 5
0
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();
    }
}
Esempio n. 6
0
/*****************************************************************************
 释放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);
}
Esempio n. 7
0
//
// 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;
}
Esempio n. 8
0
/*
 * 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);
}
Esempio n. 9
0
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);
        }
    }
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
/*
 * 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);
}
Esempio n. 14
0
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;
}