Esempio n. 1
0
File: super.c Progetto: lithoxs/elks
void mount_root(void)
{
    register struct file_system_type **fs_type;
    register struct super_block *sb;
    struct inode *inode, d_inode;
    struct file filp;
    int retval;

  retry_floppy:
    memset(&filp, 0, sizeof(filp));
    filp.f_inode = &d_inode;
    filp.f_mode = ((root_mountflags & MS_RDONLY) ? 1 : 3);
    memset(&d_inode, 0, sizeof(d_inode));
    d_inode.i_rdev = ROOT_DEV;

    retval = blkdev_open(&d_inode, &filp);
    if (retval == -EROFS) {
	root_mountflags |= MS_RDONLY;
	filp.f_mode = 1;
	retval = blkdev_open(&d_inode, &filp);
    }

    for (fs_type = &file_systems[0]; *fs_type; fs_type++) {
	struct file_system_type *fp = *fs_type;
	if (retval)
	    break;

#ifdef BLOAT_FS
	if (!fp->requires_dev)
	    continue;
#endif

	sb = read_super(ROOT_DEV, fp->name, root_mountflags, NULL, 1);
	if (sb) {
	    inode = sb->s_mounted;
	    /* NOTE! it is logically used 4 times, not 1 */
	    inode->i_count += 3;
	    sb->s_covered = inode;
	    sb->s_flags = (unsigned short int) root_mountflags;
	    current->fs.pwd = current->fs.root = inode;
	    printk("VFS: Mounted root (%s filesystem)%s.\n",
		   fp->name, (sb->s_flags & MS_RDONLY) ? " readonly" : "");
	    return;
	}
    }

#ifdef CONFIG_BLK_DEV_BIOS
    if (ROOT_DEV == 0x0380) {
	if (filp.f_op->release)
	    filp.f_op->release(&d_inode, &filp);
	else
	    printk("Release not defined\n");
	printk("VFS: Insert root floppy and press ENTER\n");
	wait_for_keypress();
	goto retry_floppy;
    }
#endif

    panic("VFS: Unable to mount root fs on %s\n", kdevname(ROOT_DEV));
}
Esempio n. 2
0
int main( int argc,
	  char **argv)
{
    int rc = 0;
    int	c;
    int	debug_wait;
    HFILE	device_handle;
    int32	phys_block_size;

    if( argc != 2 ) {
	printf("usage: validfs <fs device> ...\n");
	exit(1);
    }

    rc = ujfs_open_device(argv[1], &device_handle, &phys_block_size, READONLY);
    if( rc != 0 ) {
	printf("open of device %s failed.\n", argv[1] );
	exit(1);
    }

    rc = read_super( device_handle );
    if( rc != 0 ) {
	printf("Failed reading superblock.\n");
	exit(rc);
    }

    rc = validfs( device_handle );

    if( rc == 0 && error == 0 ) {
	printf("XJFS filesystem %s looks GOOD!\n", argv[1]);
    }

    ujfs_close(device_handle);
    exit(rc);
}
Esempio n. 3
0
File: super.c Progetto: drewt/Telos
/*
 * do_mount() does the actual mounting after sys_mount has done the ugly
 * parameter parsing. When enough time has gone by, and everything uses the
 * new mount() parameters, sys_mount() can then be cleaned up.
 *
 * We cannot mount a filesystem if it has active, used, or dirty inodes.
 * We also have to flush all inode-data for this device, as the new mount
 * might need new info.
 */
static int do_mount(dev_t dev, const char * dir, const char * type, int flags,
		void * data)
{
	struct inode *dir_i;
	struct super_block *sb;
	int error;

	error = namei(dir, &dir_i);
	if (error)
		return error;
	if (dir_i->i_count != 1 || dir_i->i_mount) {
		iput(dir_i);
		return -EBUSY;
	}
	if (!S_ISDIR(dir_i->i_mode)) {
		iput(dir_i);
		return -EPERM;
	}
	//if (!fs_may_mount(dev)) {
	//	iput(dir_i);
	//	return -EBUSY;
	//}
	sb = read_super(dev, type, flags, data, 0);
	if (!sb || sb->s_covered) {
		iput(dir_i);
		return -EBUSY;
	}
	sb->s_covered = dir_i;
	dir_i->i_mount = sb->s_mounted;
	return 0; // we don't iput(dir_i) - see umount
}
Esempio n. 4
0
int fs_init(dev_t dev)
{
    fs_dev->f_op = dev_operations(dev);
    read_super();
    cache_init();

    /* register sys calls */
    SCALL_REGISTER(3, sys_read);
    SCALL_REGISTER(4, sys_write);
    SCALL_REGISTER(5, fs_open);
    SCALL_REGISTER(6, fs_close);
    SCALL_REGISTER(10, fs_unlink);
    SCALL_REGISTER(12, fs_chdir);
    SCALL_REGISTER(19, sys_lseek);
    SCALL_REGISTER(38, fs_rename);
    SCALL_REGISTER(39, fs_mkdir);
    SCALL_REGISTER(40, fs_rmdir);
    SCALL_REGISTER(141, fs_getdents);
    SCALL_REGISTER(200, sys_flush);

    /* register fs device */
    dev_register(DEV_FS, &ops);

    return OK;
}
Esempio n. 5
0
static void test_fs(int start)
{
	struct cramfs_inode *root;

	root = read_super();
	umask(0);
	euid = geteuid();
	stream.next_in = NULL;
	stream.avail_in = 0;
	inflateInit(&stream);
	expand_fs(extract_dir, root);
	inflateEnd(&stream);
	if (start_data != ~0UL) {
		if (start_data < (sizeof(struct cramfs_super) + start))
			errx(FSCK_EX_UNCORRECTED,
			     _("directory data start (%lu) < sizeof(struct cramfs_super) + start (%zu)"),
			     start_data, sizeof(struct cramfs_super) + start);
		if (end_dir != start_data)
			errx(FSCK_EX_UNCORRECTED,
			     _("directory data end (%lu) != file data start (%lu)"),
			     end_dir, start_data);
	}
	if (super.flags & CRAMFS_FLAG_FSID_VERSION_2)
		if (end_data > super.size)
			errx(FSCK_EX_UNCORRECTED, _("invalid file data offset"));

	iput(root);		/* free(root) */
}
Esempio n. 6
0
File: super.c Progetto: lithoxs/elks
int do_mount(kdev_t dev, char *dir, char *type, int flags, char *data)
{
    struct inode *dir_i;
    register struct inode *dirp;
    register struct super_block *sb;
    int error;

    if ((error = namei(dir, &dir_i, IS_DIR, 0)))
	return error;
    dirp = dir_i;
    if ((dirp->i_count != 1 || dirp->i_mount)
	|| (!fs_may_mount(dev))
	) {
 	goto BUSY;
    }
    sb = read_super(dev, type, flags, data, 0);
    if (!sb) {
	iput(dirp);
	return -EINVAL;
    }
    if (sb->s_covered) {
    BUSY:
	iput(dirp);
	return -EBUSY;
    }
    sb->s_covered = dirp;
    dirp->i_mount = sb->s_mounted;
    return 0;			/* we don't iput(dir_i) - see umount */
}
Esempio n. 7
0
/*===========================================================================*
 *				fs_readsuper_o				     *
 *===========================================================================*/
PUBLIC int fs_readsuper_o()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname 
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
 * so that the VFS knows that it has to find the vnode on which this FS 
 * process' partition is mounted on.
 */
  struct super_block *xp;
  struct inode *root_ip;
  int r = OK;
  phys_bytes ph;

  fs_dev = fs_m_in.REQ_DEV;

  /* Map the driver endpoint for this major */
  driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e =  fs_m_in.REQ_DRIVER_E;
  boottime = fs_m_in.REQ_BOOTTIME;
  vfs_slink_storage = fs_m_in.REQ_SLINK_STORAGE;

  /* Fill in the super block. */
  superblock.s_dev = fs_dev;		/* read_super() needs to know which dev */
  r = read_super(&superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock.s_dev = NO_DEV;
	return(r);
  }

  set_blocksize(superblock.s_block_size);
  
  /* Get the root inode of the mounted file system. */
  root_ip = NIL_INODE;		/* if 'r' not OK, make sure this is defined */
  if (r == OK) {
	if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NIL_INODE) 
		r = err_code;
  }
  
  if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
        put_inode(root_ip);
  	r = EINVAL;
  }

  if (r != OK) return r;
  superblock.s_rd_only = fs_m_in.REQ_READONLY;
  superblock.s_is_root = fs_m_in.REQ_ISROOT;
  
  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE = root_ip->i_size;

  /* Partition properties */
  fs_m_out.RES_MAXSIZE = superblock.s_max_size;
  fs_m_out.RES_BLOCKSIZE = superblock.s_block_size;
  
  return r;
}
Esempio n. 8
0
int orig_do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data) {
#endif
	struct dentry * dir_d;
	struct super_block * sb;
	struct vfsmount *vfsmnt;
	int error;
	
	error = -EACCES;
	if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
		goto out;

	/*
	 * Do the lookup first to force automounting.
	 */
	dir_d = namei(dir_name);
	error = PTR_ERR(dir_d);
	if (IS_ERR(dir_d))
		goto out;

	down(&mount_sem);
	error = -ENOTDIR;
	if (!S_ISDIR(dir_d->d_inode->i_mode))
		goto dput_and_out;

	error = -EBUSY;
	if (dir_d->d_covers != dir_d)
		goto dput_and_out;

	/*
	 * Note: If the superblock already exists,
	 * read_super just does a get_super().
	 */
	error = -EINVAL;
	sb = read_super(dev, type, flags, data, 0);
	if (!sb)
		goto dput_and_out;

	/*
	 * We may have slept while reading the super block, 
	 * so we check afterwards whether it's safe to mount.
	 */
	error = -EBUSY;
	if (!fs_may_mount(dev))
		goto dput_and_out;

	error = -ENOMEM;
	vfsmnt = add_vfsmnt(sb, dev_name, dir_name);
	if (vfsmnt) {
		d_mount(dget(dir_d), sb->s_root);
		error = 0;
	}

dput_and_out:
	dput(dir_d);
	up(&mount_sem);
out:
	return error;	
}
Esempio n. 9
0
File: super.c Progetto: drewt/Telos
void mount_root(void)
{
	struct super_block *sb;
	struct inode *inode;

	memset(super_blocks, 0, sizeof(super_blocks));
	if (!(sb = read_super(ROOT_DEV, ROOT_FS, root_mountflags, NULL, 1)))
		panic("VFS: unable to mount root");

	root_inode = inode = sb->s_mounted;
	inode->i_count += 3;
	sb->s_covered = inode;
}
Esempio n. 10
0
int main(int argc, char **argv)
{
	FILE *boot, *img;
	char boot_buf[512];
	short buf2[512];
	short blocks[256];
	struct inode inode;
	int i = 0;

	if (argc != 3) {
		fprintf(stderr, "install-boot boot.bin dev_name\n");
		exit(0);
	}

	boot = fopen(argv[1], "rb");
	if (boot == NULL) {
		fprintf(stderr, "File Open Error:%s", argv[3]);
		exit(0);
	}

	img = fopen(argv[2], "r+");
	if (img == NULL) {
		fprintf(stderr, "File Open Error:%s", argv[1]);
		exit(0);
	}

	fread(boot_buf, 512, 1, boot);
	fclose(boot);

	read_super(img);

	read_inode(img, 1, &inode);

	look_up(img, &inode, "boot");
	look_up(img, &inode, "kernel");

	memset(blocks, 0, 512);
	for (i = 0; i < 7; i++)
		blocks[i] = inode.i_zone[i];

	read_block(img, inode.i_zone[7], (char*) buf2);
	while (i * 1024 < inode.i_size) {
		blocks[i] = buf2[i - 7];
		i++;
	}

	fseek(img, 0, 0);
	fwrite(boot_buf, 1, 512, img);
	fwrite(blocks, 1, 512, img);
	fclose(img);
}
Esempio n. 11
0
File: fs.c Progetto: ren85/jos2006
// Initialize the file system
void
fs_init(void)
{
	static_assert(sizeof(struct File) == 256);

	// Find a JOS disk.  Use the second IDE disk (number 1) if available.
	if (ide_probe_disk1())
		ide_set_disk(1);
	else
		ide_set_disk(0);
	
	read_super();
	check_write_block();
	read_bitmap();
}
Esempio n. 12
0
/*===========================================================================*
 *				fs_inodewalker			     *
 *===========================================================================*/
int fs_inodewalker()
{
	/* Get the list of blocks in use by the system from the inode bitmap */
	printf("Inode Walker\n");
	printf("Getting super node from device %llu ...\n", fs_dev);
	type = IMAP;
	sb = get_super(fs_dev);
	read_super(sb);
	lsuper();
	init_global();
	imap_disk = alloc_bitmap(N_IMAP);
	printf("Loading inode bitmap from disk ...\n");
	get_bitmap(imap_disk, IMAP);
	printf(" done.\n");
	sleep(3);
	int *list_inodes = get_list_used(imap_disk, IMAP);
	free_bitmap(imap_disk);
	return 0;
}
Esempio n. 13
0
int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
{
	struct inode * dir_i;
	struct super_block * sb;
	struct vfsmount *vfsmnt;
	int error;

	if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
		return -EACCES;
		/*flags |= MS_RDONLY;*/
	error = namei(dir_name, &dir_i);
	if (error)
		return error;
	if (dir_i->i_count != 1 || dir_i->i_mount) {
		iput(dir_i);
		return -EBUSY;
	}
	if (!S_ISDIR(dir_i->i_mode)) {
		iput(dir_i);
		return -ENOTDIR;
	}
	if (!fs_may_mount(dev)) {
		iput(dir_i);
		return -EBUSY;
	}
	sb = read_super(dev,type,flags,data,0);
	if (!sb) {
		iput(dir_i);
		return -EINVAL;
	}
	if (sb->s_covered) {
		iput(dir_i);
		return -EBUSY;
	}
	vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
	if (vfsmnt) {
		vfsmnt->mnt_sb = sb;
		vfsmnt->mnt_flags = flags;
	}
	sb->s_covered = dir_i;
	dir_i->i_mount = sb->s_mounted;
	return 0;		/* we don't iput(dir_i) - see umount */
}
Esempio n. 14
0
/*===========================================================================*
 *				fs_zonewalker			     *
 *===========================================================================*/
int fs_zonewalker()
{
	/* Get the list of blocks used by the system from the zone bitmap */
	printf("Zone Walkder\n");
	printf("Getting super node from device %llu ...\n", fs_dev);
	type = ZMAP;
	sb = get_super(fs_dev);
	read_super(sb);
	lsuper();
	sleep(3);
	init_global();
	zmap_disk = alloc_bitmap(N_ZMAP);
	printf("Loading zone bitmap from disk ...\n");
	get_bitmap(zmap_disk, ZMAP);
	printf(" done.\n\n");
	sleep(3);
	//print_bitmap(zmap_disk);
	int* list = get_list_used(zmap_disk, ZMAP);
	free_bitmap(zmap_disk);
	return 0;
}
Esempio n. 15
0
fs_context* mount(io_backend* ctx)
{
    if (!ctx)
    {
        log().error("ffsp::mount(): invalid io backend");
        return nullptr;
    }

    auto fs = std::make_unique<fs_context>();
    fs->io_ctx = ctx;

    if (   !read_super(*fs)
        || !read_eb_usage(*fs)
        || !read_ino_map(*fs))
    {
        log().critical("ffsp::mount(): failed to read data from super erase block");
        return nullptr;
    }

    if (!read_cl_occupancy(*fs))
    {
        log().critical("ffsp::mount(): failed to read cluster occupancy data");
        return nullptr;
    }

    fs->summary_cache = summary_cache_init(*fs);
    fs->inode_cache = inode_cache_init(*fs);
    fs->gcinfo = gcinfo_init(*fs);

    size_t ino_bitmask_size = fs->nino / 8;
    fs->ino_status_map = new uint32_t[ino_bitmask_size / sizeof(uint32_t)];
    memset(fs->ino_status_map, 0, ino_bitmask_size);

    fs->buf = new char[fs->erasesize];

    return fs.release();
}
Esempio n. 16
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
PUBLIC int fs_readsuper()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back
 * so that the VFS knows that it has to find the vnode on which this FS
 * process' partition is mounted on.
 */
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r = OK;
  int readonly, isroot;
  u32_t mask;

  fs_dev    = fs_m_in.REQ_DEV;
  label_gid = fs_m_in.REQ_GRANT;
  label_len = fs_m_in.REQ_PATH_LEN;
  readonly  = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
  isroot    = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;

  if (label_len > sizeof(fs_dev_label))
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0,
		       (vir_bytes)fs_dev_label, label_len, D);
  if (r != OK) {
	printf("%s:%d fs_readsuper: safecopyfrom failed: %d\n",
	       __FILE__, __LINE__, r);
	return(EINVAL);
  }

  /* Map the driver label for this major. */
  bdev_driver(fs_dev, fs_dev_label);

  /* Open the device the file system lives on. */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) {
        return(EINVAL);
  }

  /* Fill in the super block. */
  STATICINIT(superblock, 1);
  if (!superblock)
	panic("Can't allocate memory for superblock.");
  superblock->s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(r);
  }

  if (superblock->s_rev_level != EXT2_GOOD_OLD_REV) {
	struct super_block *sp = superblock; /* just shorter name */
	mask = ~SUPPORTED_INCOMPAT_FEATURES;
	if (HAS_INCOMPAT_FEATURE(sp, mask)) {
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_COMPRESSION & mask))
			printf("ext2: fs compression is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_FILETYPE & mask))
			printf("ext2: fs in dir filetype is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_RECOVER & mask))
			printf("ext2: fs recovery is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_JOURNAL_DEV & mask))
			printf("ext2: fs journal dev is not supported by server\n");
		if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_META_BG & mask))
			printf("ext2: fs meta bg is not supported by server\n");
		return(EINVAL);
	}
	mask = ~SUPPORTED_RO_COMPAT_FEATURES;
	if (HAS_RO_COMPAT_FEATURE(sp, mask)) {
		if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_SPARSE_SUPER & mask)) {
			printf("ext2: sparse super is not supported by server, \
				remount read-only\n");
		}
		if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_LARGE_FILE & mask)) {
			printf("ext2: large files are not supported by server, \
				remount read-only\n");
		}
		if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_BTREE_DIR & mask)) {
			printf("ext2: dir's btree is not supported by server, \
				remount read-only\n");
		}
		return(EINVAL);
	}
  }

  if (superblock->s_state == EXT2_ERROR_FS) {
	printf("ext2: filesystem wasn't cleanly unmounted previous time\n");
        superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }


  set_blocksize(superblock->s_block_size,
  	superblock->s_blocks_count,
	superblock->s_free_blocks_count,
	major(fs_dev));

  /* Get the root inode of the mounted file system. */
  if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
	printf("ext2: couldn't get root inode\n");
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  if (root_ip != NULL && root_ip->i_mode == 0) {
	printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
	put_inode(root_ip);
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  if (root_ip != NULL && (root_ip->i_mode & I_TYPE) != I_DIRECTORY) {
	printf("%s:%d root inode has wrong type, it's not a DIR\n",
		 __FILE__, __LINE__);
	put_inode(root_ip);
	superblock->s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  superblock->s_rd_only = readonly;
  superblock->s_is_root = isroot;

  if (!readonly) {
	superblock->s_state = EXT2_ERROR_FS;
	superblock->s_mnt_count++;
	superblock->s_mtime = clock_time();
	write_super(superblock); /* Commit info, we just set above */
  }

  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  return(r);
}
Esempio n. 17
0
static void do_mount_root(void)
{
	struct file_system_type * fs_type;
	struct super_block * sb;
	struct vfsmount *vfsmnt;
	struct inode * inode, d_inode;
	struct file filp;
	int retval;
  
#ifdef CONFIG_ROOT_NFS
	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR)
		if (nfs_root_init(nfs_root_name, nfs_root_addrs) < 0) {
			printk(KERN_ERR "Root-NFS: Unable to contact NFS "
			    "server for root fs, using /dev/fd0 instead\n");
			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
		}
	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
		ROOT_DEV = 0;
		if ((fs_type = get_fs_type("nfs"))) {
			sb = &super_blocks[0];
			while (sb->s_dev) sb++;
			sb->s_dev = get_unnamed_dev();
			sb->s_flags = root_mountflags & ~MS_RDONLY;
			if (nfs_root_mount(sb) >= 0) {
				inode = sb->s_mounted;
				inode->i_count += 3 ;
				sb->s_covered = inode;
				sb->s_rd_only = 0;
				sb->s_dirt = 0;
				sb->s_type = fs_type;
				current->fs->pwd = inode;
				current->fs->root = inode;
				ROOT_DEV = sb->s_dev;
				printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
				vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
				if (!vfsmnt)
					panic("VFS: add_vfsmnt failed for NFS root.\n");
				vfsmnt->mnt_sb = sb;
				vfsmnt->mnt_flags = sb->s_flags;
				return;
			}
			sb->s_dev = 0;
		}
		if (!ROOT_DEV) {
			printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
		}
	}
#endif

#ifdef CONFIG_BLK_DEV_FD
	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
		floppy_eject();
		printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
		wait_for_keypress();
	}
#endif

	memset(&filp, 0, sizeof(filp));
	memset(&d_inode, 0, sizeof(d_inode));
	d_inode.i_rdev = ROOT_DEV;
	filp.f_inode = &d_inode;
	if ( root_mountflags & MS_RDONLY)
		filp.f_mode = 1; /* read only */
	else
		filp.f_mode = 3; /* read write */
	retval = blkdev_open(&d_inode, &filp);
	if (retval == -EROFS) {
		root_mountflags |= MS_RDONLY;
		filp.f_mode = 1;
		retval = blkdev_open(&d_inode, &filp);
	}
	if (retval)
	        /*
		 * Allow the user to distinguish between failed open
		 * and bad superblock on root device.
		 */
		printk("VFS: Cannot open root device %s\n",
		       kdevname(ROOT_DEV));
	else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
  		if (!fs_type->requires_dev)
  			continue;
  		sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
		if (sb) {
			inode = sb->s_mounted;
			inode->i_count += 3 ;	/* NOTE! it is logically used 4 times, not 1 */
			sb->s_covered = inode;
			sb->s_flags = root_mountflags;
			current->fs->pwd = inode;
			current->fs->root = inode;
			printk ("VFS: Mounted root (%s filesystem)%s.\n",
				fs_type->name,
				(sb->s_flags & MS_RDONLY) ? " readonly" : "");
			vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
			if (!vfsmnt)
				panic("VFS: add_vfsmnt failed for root fs");
			vfsmnt->mnt_sb = sb;
			vfsmnt->mnt_flags = root_mountflags;
			return;
		}
	}
	panic("VFS: Unable to mount root fs on %s",
		kdevname(ROOT_DEV));
}
Esempio n. 18
0
int main(int argc, char **argv)
{
	void *buf;
	size_t length;
	struct stat st;
	unsigned long crc_old, crc_new;
#ifdef INCLUDE_FS_TESTS
	struct cramfs_inode *root;
#endif /* INCLUDE_FS_TESTS */
	int c;			/* for getopt */
	int start = 0;

	if (argc)
		progname = argv[0];

	/* command line options */
	while ((c = getopt(argc, argv, "hx:v")) != EOF) {
		switch (c) {
		case 'h':
			usage(0);
		case 'x':
#ifdef INCLUDE_FS_TESTS
			opt_extract = 1;
			extract_dir = malloc(strlen(optarg) + 1);
			strcpy(extract_dir, optarg);
			break;
#else /*  not INCLUDE_FS_TESTS */
			fprintf(stderr, "%s: compiled without -x support\n",
				progname);
			exit(16);
#endif /* not INCLUDE_FS_TESTS */
		case 'v':
			opt_verbose++;
			break;
		}
	}

	if ((argc - optind) != 1)
		usage(16);
	filename = argv[optind];

	/* find the physical size of the file or block device */
	if (lstat(filename, &st) < 0) {
		perror(filename);
		exit(8);
	}
	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		perror(filename);
		exit(8);
	}
	if (S_ISBLK(st.st_mode)) {
		if (ioctl(fd, BLKGETSIZE, &length) < 0) {
			fprintf(stderr, "%s: warning--unable to determine filesystem size \n", filename);
			exit(4);
		}
		length = length * 512;
	}
	else if (S_ISREG(st.st_mode)) {
		length = st.st_size;
	}
	else {
		fprintf(stderr, "%s is not a block device or file\n", filename);
		exit(8);
	}

	if (length < sizeof(struct cramfs_super)) {
		fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename);
		exit(4);
	}

	if (S_ISBLK(st.st_mode)) {
		/* nasty because mmap of block devices fails */
		buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
		read(fd, buf, length);
	}
	else {
		/* nice and easy */
		buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
	}

	/* XXX - this could be cleaner... */
	if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) {
		start = 0;
		super = (struct cramfs_super *) buf;
	}
	else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) &&
		 ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC)))
	{
		start = PAD_SIZE;
		super = (struct cramfs_super *) (buf + PAD_SIZE);
	}
	else {
		fprintf(stderr, "%s: invalid cramfs--wrong magic\n", filename);
		exit(4);
	}

	if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) {
		/* length test */
		if (length < super->size) {
			fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename);
			exit(4);
		}
		else if (length > super->size) {
			fprintf(stderr, "%s: warning--file length too long, padded image?\n", filename);
		}

		/* CRC test */
		crc_old = super->fsid.crc;
		super->fsid.crc = crc32(0L, Z_NULL, 0);
		crc_new = crc32(0L, Z_NULL, 0);
		crc_new = crc32(crc_new, (unsigned char *) buf+start, super->size - start);
		if (crc_new != crc_old) {
			fprintf(stderr, "%s: invalid cramfs--crc error\n", filename);
			exit(4);
		}
	}
	else {
		fprintf(stderr, "%s: warning--old cramfs image, no CRC\n",
			filename);
	}

#ifdef INCLUDE_FS_TESTS
	super = (struct cramfs_super *) malloc(sizeof(struct cramfs_super));
	if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) {
		memcpy(super, buf, sizeof(struct cramfs_super));
	}
	else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) &&
		 ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC)))
	{
		memcpy(super, (buf + PAD_SIZE), sizeof(struct cramfs_super));
	}

	munmap(buf, length);

	/* file format test, uses fake "blocked" accesses */
	root = read_super();
	umask(0);
	euid = geteuid();
	if (!root) {
		fprintf(stderr, "%s: invalid cramfs--bad superblock\n",
			filename);
		exit(4);
	}
	stream.next_in = NULL;
	stream.avail_in = 0;
	inflateInit(&stream);

	if (!extract_dir) {
		extract_dir = "root";
	}

	expand_fs(strlen(extract_dir), extract_dir, root);
	inflateEnd(&stream);

	if (start_data != 1 << 28  && end_inode != start_data) {
		fprintf(stderr, "%s: invalid cramfs--directory data end (%ld) != file data start (%ld)\n", filename, end_inode, start_data);
		exit(4);
	}
	if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) {
		if (end_data > super->size) {
			fprintf(stderr, "%s: invalid cramfs--invalid file data offset\n", filename);
			exit(4);
		}
	}
#endif /* INCLUDE_FS_TESTS */

	exit(0);
}
Esempio n. 19
0
void __init mount_root(void)
{
	struct file_system_type * fs_type;
	struct super_block * sb;
	struct vfsmount *vfsmnt;
	struct inode * d_inode = NULL;
	struct file filp;
	int retval;

#ifdef CONFIG_ROOT_NFS
	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
		ROOT_DEV = 0;
		if ((fs_type = get_fs_type("nfs"))) {
			sb = get_empty_super(); /* "can't fail" */
			sb->s_dev = get_unnamed_dev();
			sb->s_flags = root_mountflags;
			sema_init(&sb->s_vfs_rename_sem,1);
			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
			if (vfsmnt) {
				if (nfs_root_mount(sb) >= 0) {
					sb->s_dirt = 0;
					sb->s_type = fs_type;
					current->fs->root = dget(sb->s_root);
					current->fs->pwd = dget(sb->s_root);
					ROOT_DEV = sb->s_dev;
			                printk (KERN_NOTICE "VFS: Mounted root (NFS filesystem)%s.\n", (sb->s_flags & MS_RDONLY) ? " readonly" : "");
					return;
				}
				remove_vfsmnt(sb->s_dev);
			}
			put_unnamed_dev(sb->s_dev);
			sb->s_dev = 0;
		}
		if (!ROOT_DEV) {
			printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
		}
	}
#endif

#ifdef CONFIG_BLK_DEV_FD
	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
#ifdef CONFIG_BLK_DEV_RAM	
		extern int rd_doload;
#endif		
		floppy_eject();
#ifndef CONFIG_BLK_DEV_RAM
		printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
#else
		/* rd_doload is 2 for a dual initrd/ramload setup */
		if(rd_doload==2)
			rd_load_secondary();
		else
#endif		
		{
			printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
			wait_for_keypress();
		}
	}
#endif

	memset(&filp, 0, sizeof(filp));
	d_inode = get_empty_inode();
	d_inode->i_rdev = ROOT_DEV;
	filp.f_dentry = NULL;
	if ( root_mountflags & MS_RDONLY)
		filp.f_mode = 1; /* read only */
	else
		filp.f_mode = 3; /* read write */
	retval = blkdev_open(d_inode, &filp);
	if (retval == -EROFS) {
		root_mountflags |= MS_RDONLY;
		filp.f_mode = 1;
		retval = blkdev_open(d_inode, &filp);
	}
	iput(d_inode);
	if (retval)
	        /*
		 * Allow the user to distinguish between failed open
		 * and bad superblock on root device.
		 */
		printk("VFS: Cannot open root device %s\n",
		       kdevname(ROOT_DEV));
	else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
  		if (!(fs_type->fs_flags & FS_REQUIRES_DEV))
  			continue;
  		sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,root_mount_data,1);
		if (sb) {
			sb->s_flags = root_mountflags;
			current->fs->root = dget(sb->s_root);
			current->fs->pwd = dget(sb->s_root);
			printk ("VFS: Mounted root (%s filesystem)%s.\n",
				fs_type->name,
				(sb->s_flags & MS_RDONLY) ? " readonly" : "");
			vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
			if (vfsmnt)
				return;
			panic("VFS: add_vfsmnt failed for root fs");
		}
	}
#ifdef CONFIG_EMPEG_DISPLAY
	display_bootfail();
#endif
	panic("VFS: Unable to mount root fs on %s",
		kdevname(ROOT_DEV));
}
Esempio n. 20
0
int guess_filesystem(int start_session)
{
    int ret = 0;

    read_super(start_session);

#undef _DEBUG
#ifdef _DEBUG
    /* buffer is defined */
    if (is_cdi())     printf("CD-I, ");
    if (is_cd_rtos()) printf("CD-RTOS, ");
    if (is_isofs())   printf("ISOFS, ");
    if (is_hs())      printf("HS, ");
    if (is_bridge())  printf("BRIDGE, ");
    if (is_xa())      printf("XA, ");
    if (is_cdtv())    printf("CDTV, ");
    puts("");
#endif

    /* filesystem */
    if (is_cdi() && is_cd_rtos() && !is_bridge() && !is_xa()) {
        return FS_INTERACTIVE;
    } else {	/* read sector 0 ONLY, when NO greenbook CD-I !!!! */

        read_super2(start_session);

#ifdef _DEBUG
	/* buffer2 is defined */
	if (is_photocd()) printf("PHOTO CD, ");
	if (is_hfs()) printf("HFS, ");
	if (is_ext2()) printf("EXT2 FS, ");
	puts("");
#endif
        if (is_hs())
	    ret |= FS_HIGH_SIERRA;
	else if (is_isofs()) {
	    if (is_cd_rtos() && is_bridge())
	        ret = FS_ISO_9660_INTERACTIVE;
	    else if (is_hfs())
	        ret = FS_ISO_HFS;
	    else
	        ret = FS_ISO_9660;
	    isofs_size = get_size();

	    read_super4(start_session);

#ifdef _DEBUG
	    /* buffer4 is defined */
	    if (is_bootable()) printf("BOOTABLE, ");
	    puts("");
#endif
	    if (is_bootable())
		ret |= BOOTABLE;

	    if (is_bridge() && is_xa() && is_isofs() && is_cd_rtos()) {
	        read_super5(start_session);

#ifdef _DEBUG
		/* buffer5 is defined */
		if (is_video_cdi()) printf("VIDEO-CDI, ");
		puts("");
#endif
		if (is_video_cdi())
		    ret |= VIDEOCDI;
	    }
	} else if (is_hfs())
	    ret |= FS_HFS;
	else if (is_ext2())
	    ret |= FS_EXT2;
	else {

	    read_super3(start_session);

#ifdef _DEBUG
	    /* buffer3 is defined */
	    if (is_ufs()) printf("UFS, ");
	    puts("");
#endif
	    if (is_ufs())
	        ret |= FS_UFS;
	    else
	        ret |= FS_UNKNOWN;
	}
    }
    /* other checks */
    if (is_xa())
        ret |= XA;
    if (is_photocd())
	ret |= PHOTO_CD;
    if (is_cdtv())
	ret |= CDTV;
    return ret;
}
Esempio n. 21
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
PUBLIC int fs_readsuper()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname 
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
 * so that the VFS knows that it has to find the vnode on which this FS 
 * process' partition is mounted on.
 */
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r;
  int readonly, isroot;

  fs_dev    = (dev_t) fs_m_in.REQ_DEV;
  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
  readonly  = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
  isroot    = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;

  if (label_len > sizeof(fs_dev_label))
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
		       (vir_bytes) fs_dev_label, label_len, D);
  if (r != OK) {
	printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
	return(EINVAL);
  }

  /* Map the driver label for this major. */
  bdev_driver(fs_dev, fs_dev_label);

  /* Open the device the file system lives on. */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) {
        return(EINVAL);
  }
  
  /* Fill in the super block. */
  superblock.s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(&superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(r);
  }

  /* Remember whether we were mounted cleanly so we know what to
   * do at unmount time
   */
  if(superblock.s_flags & MFSFLAG_CLEAN)
	cleanmount = 1;

  /* clean check: if rw and not clean, switch to readonly */
  if(!(superblock.s_flags & MFSFLAG_CLEAN) && !readonly) {
	if(bdev_close(fs_dev) != OK)
		panic("couldn't bdev_close after found unclean FS");
	readonly = 1;

	if (bdev_open(fs_dev, R_BIT) != OK) {
		panic("couldn't bdev_open after found unclean FS");
		return(EINVAL);
  	}
	printf("MFS: WARNING: FS 0x%x unclean, mounting readonly\n", fs_dev);
  }
  
  set_blocksize(&superblock);
  
  /* Get the root inode of the mounted file system. */
  if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
	printf("MFS: couldn't get root inode\n");
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }
  
  if(root_ip->i_mode == 0) {
	printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
	put_inode(root_ip);
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  superblock.s_rd_only = readonly;
  superblock.s_is_root = isroot;
  
  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  /* Mark it dirty */
  if(!superblock.s_rd_only) {
	  superblock.s_flags &= ~MFSFLAG_CLEAN;
	  if(write_super(&superblock) != OK)
		panic("mounting: couldn't write dirty superblock");
  }

  return(r);
}
Esempio n. 22
0
/*===========================================================================*
 *				cdprobe					     *
 *===========================================================================*/
PUBLIC int cdprobe(void)
{
#define CD_SECTOR	2048
#define AT_MAJOR	3
#define AT_MINORS	4
	int i, minors[AT_MINORS] = { 0, 5, 10, 15 }, dev = 0, found = 0;
	char pvd[CD_SECTOR];
	printf("\nLooking for boot CD. This may take a minute.\n"
		"Please ignore any error messages.\n\n");
	for(i = 0; i < AT_MINORS && !found; i++) {
		struct super_block probe_super;
		int r, minor;

		dev = (AT_MAJOR << MAJOR) | minors[i];

		/* Open device readonly. (This fails if the device
		 * is also writable, which a CD isn't.)
		 */
		if ((r = dev_open(dev, FS_PROC_NR, RO_BIT)) != OK) {
			continue;
		}

		if ((r = dev_io(DEV_READ, dev, FS_PROC_NR, pvd,
			16*CD_SECTOR, sizeof(pvd), 0)) != sizeof(pvd)) {
			dev_close(dev);
			continue;
		}
		dev_close(dev);

		/* Check PVD ID. */
		if (pvd[0] !=  1  || pvd[1] != 'C' || pvd[2] != 'D' ||
		   pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' || pvd[6] != 1 ||
		   strncmp(pvd + 40, "MINIX", 5)) {
		   	continue;
		   }

		/* 3. Both c0dXp1 and p2 should have a superblock. */
		for(minor = minors[i]+2; minor <= minors[i]+3; minor++) {
			dev = (AT_MAJOR << MAJOR) | minor;
			if ((r = dev_open(dev, FS_PROC_NR, R_BIT)) != OK) {
				break;
			}
			probe_super.s_dev = dev;
			r = read_super(&probe_super);
			dev_close(dev);
			if (r != OK) {
				break;
			}
		}

		if (minor > minors[i]+3) {
			/* Success? Then set dev to p1. */
			dev = (AT_MAJOR << MAJOR) | (minors[i]+2);
			found = 1;
			break;
		}
	}

	if (!found) return NO_DEV;

	return dev;
}
Esempio n. 23
0
/*===========================================================================*
 *				fs_readsuper				     *
 *===========================================================================*/
PUBLIC int fs_readsuper()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname 
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
 * so that the VFS knows that it has to find the vnode on which this FS 
 * process' partition is mounted on.
 */
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r;
  endpoint_t driver_e;
  int readonly, isroot;

  fs_dev    = (dev_t) fs_m_in.REQ_DEV;
  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
  readonly  = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0;
  isroot    = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0;

  if (label_len > sizeof(fs_dev_label))
	return(EINVAL);

  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
		       (vir_bytes) fs_dev_label, label_len, D);
  if (r != OK) {
	printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r);
	return(EINVAL);
  }

  r = ds_retrieve_label_endpt(fs_dev_label, &driver_e);
  if (r != OK) {
	printf("MFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n",
		__FILE__, __LINE__, fs_dev_label, r);
	return(EINVAL);
  }

  /* Map the driver endpoint for this major */
  bdev_driver(fs_dev, driver_e);

  /* Open the device the file system lives on. */
  if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) {
        return(EINVAL);
  }
  
  /* Fill in the super block. */
  superblock.s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(&superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(r);
  }

  set_blocksize(&superblock);
  
  /* Get the root inode of the mounted file system. */
  if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL)  {
	printf("MFS: couldn't get root inode\n");
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }
  
  if(root_ip->i_mode == 0) {
	printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__);
	put_inode(root_ip);
	superblock.s_dev = NO_DEV;
	bdev_close(fs_dev);
	return(EINVAL);
  }

  superblock.s_rd_only = readonly;
  superblock.s_is_root = isroot;
  
  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  fs_m_out.RES_CONREQS = 1;	/* We can handle only 1 request at a time */

  return(r);
}
Esempio n. 24
0
/*===========================================================================*
 *				do_mount				     *
 *===========================================================================*/
PUBLIC int do_mount()
{
/* Perform the mount(name, mfile, rd_only) system call. */

  register struct inode *rip, *root_ip;
  struct super_block *xp, *sp;
  dev_t dev;
  mode_t bits;
  int rdir, mdir;		/* TRUE iff {root|mount} file is dir */
  int i, r, found;
  struct fproc *tfp;

  /* Only the super-user may do MOUNT. */
  if (!super_user) return(EPERM);

  /* If 'name' is not for a block special file, return error. */
  if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
  if ( (dev = name_to_dev(user_path)) == NO_DEV) return(err_code);

  /* Scan super block table to see if dev already mounted & find a free slot.*/
  sp = NIL_SUPER;
  found = FALSE;
  for (xp = &super_block[0]; xp < &super_block[NR_SUPERS]; xp++) {
	if (xp->s_dev == dev)
	{
		/* is it mounted already? */
		found = TRUE;
		sp= xp;
		break;
	}
	if (xp->s_dev == NO_DEV) sp = xp;	/* record free slot */
  }
  if (found)
  {
	printf(
"do_mount: s_imount = 0x%x (%x, %d), s_isup = 0x%x (%x, %d), fp_rootdir = 0x%x\n",
		xp->s_imount, xp->s_imount->i_dev, xp->s_imount->i_num,
		xp->s_isup, xp->s_isup->i_dev, xp->s_isup->i_num,
		fproc[FS_PROC_NR].fp_rootdir);
	/* It is possible that we have an old root lying around that 
	 * needs to be remounted.
	 */
	if (xp->s_imount != xp->s_isup ||
		xp->s_isup == fproc[FS_PROC_NR].fp_rootdir)
	{
		/* Normally, s_imount refers to the mount point. For a root
		 * filesystem, s_imount is equal to the root inode. We assume
		 * that the root of FS is always the real root. If the two
		 * inodes are different or if the root of FS is equal two the
		 * root of the filesystem we found, we found a filesystem that
		 * is in use.
		 */
		return(EBUSY);	/* already mounted */
	}

	if (root_dev == xp->s_dev)
	{
		panic("fs", "inconsistency remounting old root",
			NO_NUM);
	}

	/* Now get the inode of the file to be mounted on. */
	if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
		return(err_code);
	}

	if ( (rip = eat_path(user_path)) == NIL_INODE) {
		return(err_code);
	}

	r = OK;

	/* It may not be special. */
	bits = rip->i_mode & I_TYPE;
	if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL)
		r = ENOTDIR;

	/* Get the root inode of the mounted file system. */
	root_ip= sp->s_isup;

	/* File types of 'rip' and 'root_ip' may not conflict. */
	if (r == OK) {
		mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY); 
						/* TRUE iff dir */
		rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY);
		if (!mdir && rdir) r = EISDIR;
	}

	/* If error, return the mount point. */
	if (r != OK) {
		put_inode(rip);
		return(r);
	}

	/* Nothing else can go wrong.  Perform the mount. */
	rip->i_mount = I_MOUNT;	/* this bit says the inode is
				 * mounted on
				 */
	put_inode(sp->s_imount);
	sp->s_imount = rip;
	sp->s_rd_only = m_in.rd_only;
	allow_newroot= 0;		/* The root is now fixed */
	return(OK);
  }
  if (sp == NIL_SUPER) return(ENFILE);	/* no super block available */

  /* Open the device the file system lives on. */
  if (dev_open(dev, who_e, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK) 
  	return(EINVAL);

  /* Make the cache forget about blocks it has open on the filesystem */
  (void) do_sync();
  invalidate(dev);

  /* Fill in the super block. */
  sp->s_dev = dev;		/* read_super() needs to know which dev */
  r = read_super(sp);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	dev_close(dev);
	sp->s_dev = NO_DEV;
	return(r);
  }

  /* Now get the inode of the file to be mounted on. */
  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
	dev_close(dev);
	sp->s_dev = NO_DEV;
	return(err_code);
  }

  if (strcmp(user_path, "/") == 0 && allow_newroot)
  {
	printf("Replacing root\n");

	/* Get the root inode of the mounted file system. */
	if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code;
	if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
		r = EINVAL;
	}

	/* If error, return the super block and both inodes; release the
	 * maps.
	 */
	if (r != OK) {
		put_inode(root_ip);
		(void) do_sync();
		invalidate(dev);
		dev_close(dev);
		sp->s_dev = NO_DEV;
		return(r);
	}

	/* Nothing else can go wrong.  Perform the mount. */
	sp->s_imount = root_ip;
	dup_inode(root_ip);
	sp->s_isup = root_ip;
	sp->s_rd_only = m_in.rd_only;
	root_dev= dev;

	/* Replace all root and working directories */
	for (i= 0, tfp= fproc; i<NR_PROCS; i++, tfp++)
	{
		if (tfp->fp_pid == PID_FREE)
			continue;
		if (tfp->fp_rootdir == NULL)
			panic("fs", "do_mount: null rootdir", i);
		put_inode(tfp->fp_rootdir);
		dup_inode(root_ip);
		tfp->fp_rootdir= root_ip;

		if (tfp->fp_workdir == NULL)
			panic("fs", "do_mount: null workdir", i);
		put_inode(tfp->fp_workdir);
		dup_inode(root_ip);
		tfp->fp_workdir= root_ip;
	}

	/* Leave the old filesystem lying around. */
	return(OK);
  }

  if ( (rip = eat_path(user_path)) == NIL_INODE) {
	dev_close(dev);
	sp->s_dev = NO_DEV;
	return(err_code);
  }

  /* It may not be busy. */
  r = OK;
  if (rip->i_count > 1) r = EBUSY;

  /* It may not be special. */
  bits = rip->i_mode & I_TYPE;
  if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL) r = ENOTDIR;

  /* Get the root inode of the mounted file system. */
  root_ip = NIL_INODE;		/* if 'r' not OK, make sure this is defined */
  if (r == OK) {
	if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code;
  }
  if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
  	r = EINVAL;
  }

  /* File types of 'rip' and 'root_ip' may not conflict. */
  if (r == OK) {
	mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY);  /* TRUE iff dir */
	rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY);
	if (!mdir && rdir) r = EISDIR;
  }

  /* If error, return the super block and both inodes; release the maps. */
  if (r != OK) {
	put_inode(rip);
	put_inode(root_ip);
	(void) do_sync();
	invalidate(dev);
	dev_close(dev);
	sp->s_dev = NO_DEV;
	return(r);
  }

  /* Nothing else can go wrong.  Perform the mount. */
  rip->i_mount = I_MOUNT;	/* this bit says the inode is mounted on */
  sp->s_imount = rip;
  sp->s_isup = root_ip;
  sp->s_rd_only = m_in.rd_only;
  allow_newroot= 0;		/* The root is now fixed */
  return(OK);
}
Esempio n. 25
0
/*===========================================================================*
 *				fs_readsuper_s				     *
 *===========================================================================*/
PUBLIC int fs_readsuper_s()
{
/* This function reads the superblock of the partition, gets the root inode
 * and sends back the details of them. Note, that the FS process does not
 * know the index of the vmnt object which refers to it, whenever the pathname 
 * lookup leaves a partition an ELEAVEMOUNT error is transferred back 
 * so that the VFS knows that it has to find the vnode on which this FS 
 * process' partition is mounted on.
 */
  struct super_block *xp;
  struct inode *root_ip;
  cp_grant_id_t label_gid;
  size_t label_len;
  int r = OK;
  unsigned long tasknr;
  endpoint_t driver_e;

  fs_dev = fs_m_in.REQ_DEV;

  label_gid= fs_m_in.REQ_GRANT2;
  label_len= fs_m_in.REQ_PATH_LEN;

  if (label_len > sizeof(fs_dev_label))
  {
	printf("mfs:fs_readsuper: label too long\n");
	return EINVAL;
  }

  r= sys_safecopyfrom(fs_m_in.m_source, label_gid, 0, (vir_bytes)fs_dev_label,
	label_len, D);
  if (r != OK)
  {
	printf("mfs:fs_readsuper: safecopyfrom failed: %d\n", r);
	return EINVAL;
  }

  r= ds_retrieve_u32(fs_dev_label, &tasknr);
  if (r != OK)
  {
	printf("mfs:fs_readsuper: ds_retrieve_u32 failed for '%s': %d\n",
		fs_dev_label, r);
	return EINVAL;
  }

  driver_e= tasknr;

  /* Map the driver endpoint for this major */
  driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e =  driver_e;
  use_getuptime2= TRUE;				/* Should be removed with old
						 * getuptime call.
						 */
  vfs_slink_storage = (char *)0xdeadbeef;	/* Should be removed together
						 * with old lookup code.
						 */;

  /* Open the device the file system lives on. */
  if (dev_open(driver_e, fs_dev, driver_e,
	fs_m_in.REQ_READONLY ? R_BIT : (R_BIT|W_BIT)) != OK) {
        return(EINVAL);
  }
  
  /* Fill in the super block. */
  superblock.s_dev = fs_dev;	/* read_super() needs to know which dev */
  r = read_super(&superblock);

  /* Is it recognized as a Minix filesystem? */
  if (r != OK) {
	superblock.s_dev = NO_DEV;
  	dev_close(driver_e, fs_dev);
	return(r);
  }

  set_blocksize(superblock.s_block_size);
  
  /* Get the root inode of the mounted file system. */
  if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NIL_INODE)  {
	printf("MFS: couldn't get root inode?!\n");
	superblock.s_dev = NO_DEV;
  	dev_close(driver_e, fs_dev);
	return EINVAL;
  }
  
  if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
	printf("MFS: zero mode for root inode?!\n");
        put_inode(root_ip);
	superblock.s_dev = NO_DEV;
  	dev_close(driver_e, fs_dev);
  	return EINVAL;
  }

  superblock.s_rd_only = fs_m_in.REQ_READONLY;
  superblock.s_is_root = fs_m_in.REQ_ISROOT;
  
  /* Root inode properties */
  fs_m_out.RES_INODE_NR = root_ip->i_num;
  fs_m_out.RES_MODE = root_ip->i_mode;
  fs_m_out.RES_FILE_SIZE = root_ip->i_size;
  fs_m_out.RES_UID = root_ip->i_uid;
  fs_m_out.RES_GID = root_ip->i_gid;

  return r;
}
Esempio n. 26
0
int grsIntFrag()
{

  printf("\n======================================================\n");
    printf("\n System Call Invoked : grsIntFrag \n");

  struct super_block* sp;
  unsigned int in_numbs[100] = {0};
  struct inode *rip;
  block_t start_block;		/* first bit block */
  block_t block;
  bit_t map_bits;		/* how many bits are there in the bit map? */
  short bit_blocks;		/* how many blocks are there in the bit map? */
  bit_t origin = 1;			/* number of bit to start searching at */
  int c = 0, n = 0, d = 0, count =0, j=0, frag_cnt =0 , scale =0;

  unsigned word, bcount;
  struct buf *bp;
  bitchunk_t *wptr, *wlim, k;
  bit_t i, b;
  
  sp = get_super(fs_dev);
  c = read_super(sp);  
  printf("The block sz currently in use : %d\n",sp->s_block_size);
  if(sp->s_log_zone_size == 0)
  {
	printf("One block/zone on this filesystem. So no external fragmentation\n");
	return 0;
  }
  start_block = START_BLOCK;
  map_bits = (bit_t) (sp->s_ninodes + 1);
  bit_blocks = sp->s_imap_blocks;
  
    /* Locate the starting place. */
  block = (block_t) (origin / FS_BITS_PER_BLOCK(sp->s_block_size));
  word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
  
  bcount = bit_blocks;
while(bcount > 0)  
{
    bp = get_block(sp->s_dev, start_block + block, NORMAL);
   assert(bp);
    wlim = &bp->b_bitmap[FS_BITMAP_CHUNKS(sp->s_block_size)];

    /* Iterate over the words in block. */
    for (wptr = &bp->b_bitmap[word]; wptr < wlim; wptr++) 
    {

      /* Does this word contain a free bit? */
      if (*wptr == (bitchunk_t) 0) continue;
	  
	  k = (bitchunk_t) conv4(sp->s_native, (int) *wptr);

      for (i = 0; i < 8*sizeof(k); ++i) 
      {
        /* Bit number from the start of the bit map. */
        b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
            + (wptr - &bp->b_bitmap[0]) * FS_BITCHUNK_BITS
            + i;

        /* Don't count bits beyond the end of the map. */
        if (b >= map_bits) {
          break;
        } 
        if ((k & (1 << i)) == 1) {
          in_numbs[n++] = b;
        }
      }	
      if (b >= map_bits) break;
   }
   ++block;
   word = 0;
   --bcount;	
}

  for(n=0;in_numbs[n]!=0;n++)
  {
	rip = get_inode(fs_dev, in_numbs[n]);
	scale = rip->i_sp->s_log_zone_size;
	for(j=0;j<7;j++)
	{
	    b = (block_t)rip->i_zone[7] << scale;
	    bp = get_block(rip->i_dev,b,NORMAL);
	    count = (rip->i_sp->s_block_size)/32;
	    for(d=0;d<count;d++)
	    {
		if(bp->b_v1_ind[d] == NO_ZONE)
		{
			frag_cnt = get_internal_frag(bp->b_v1_ind[d],scale);
		}
	    }		
	  }
  }
  print_internal_frag_report();
  return 0;

  printf("\n======================================================\n");
}