Beispiel #1
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;	
}
Beispiel #2
0
int change_root(kdev_t new_root_dev,const char *put_old)
{
	kdev_t old_root_dev;
	struct vfsmount *vfsmnt;
	struct inode *old_root,*old_pwd,*inode;
	unsigned long old_fs;
	int error;

	old_root = current->fs->root;
	old_pwd = current->fs->pwd;
	old_root_dev = ROOT_DEV;
	if (!fs_may_mount(new_root_dev)) {
		printk(KERN_CRIT "New root is busy. Staying in initrd.\n");
		return -EBUSY;
	}
	ROOT_DEV = new_root_dev;
	do_mount_root();
	old_fs = get_fs();
	set_fs(get_ds());
        error = namei(put_old,&inode);
	if (error) inode = NULL;
	set_fs(old_fs);
	if (!error && (inode->i_count != 1 || inode->i_mount)) error = -EBUSY;
	if (!error && !S_ISDIR(inode->i_mode)) error = -ENOTDIR;
	iput(old_root); /* current->fs->root */
	iput(old_pwd); /* current->fs->pwd */
	if (error) {
		int umount_error;

		if (inode) iput(inode);
		printk(KERN_NOTICE "Trying to unmount old root ... ");
		old_root->i_mount = old_root;
			/* does this belong into do_mount_root ? */
		umount_error = do_umount(old_root_dev,1);
		if (umount_error) printk(KERN_ERR "error %d\n",umount_error);
		else {
			printk(KERN_NOTICE "okay\n");
			invalidate_buffers(old_root_dev);
		}
		return umount_error ? error : 0;
	}
	iput(old_root); /* sb->s_covered */
	remove_vfsmnt(old_root_dev);
	vfsmnt = add_vfsmnt(old_root_dev,"old_rootfs",put_old);
	if (!vfsmnt) printk(KERN_CRIT "Trouble: add_vfsmnt failed\n");
	else {
		vfsmnt->mnt_sb = old_root->i_sb;
		vfsmnt->mnt_sb->s_covered = inode;
		vfsmnt->mnt_flags = vfsmnt->mnt_sb->s_flags;
	}
	inode->i_mount = old_root;
	return 0;
}
Beispiel #3
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 */
}
Beispiel #4
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));
}
Beispiel #5
0
int __init change_root(kdev_t new_root_dev,const char *put_old)
{
	kdev_t old_root_dev;
	struct vfsmount *vfsmnt;
	struct dentry *old_root,*old_pwd,*dir_d = NULL;
	int error;

	old_root = current->fs->root;
	old_pwd = current->fs->pwd;
	old_root_dev = ROOT_DEV;
	if (!fs_may_mount(new_root_dev)) {
		printk(KERN_CRIT "New root is busy. Staying in initrd.\n");
		return -EBUSY;
	}
	ROOT_DEV = new_root_dev;
	mount_root();
	dput(old_root);
	dput(old_pwd);
#if 1
	shrink_dcache();
	printk("change_root: old root has d_count=%d\n", old_root->d_count);
#endif
	/*
	 * Get the new mount directory
	 */
	dir_d = lookup_dentry(put_old, NULL, 1);
	if (IS_ERR(dir_d)) {
		error = PTR_ERR(dir_d);
	} else if (!dir_d->d_inode) {
		dput(dir_d);
		error = -ENOENT;
	} else {
		error = 0;
	}
	if (!error && dir_d->d_covers != dir_d) {
		dput(dir_d);
		error = -EBUSY;
	}
	if (!error && !S_ISDIR(dir_d->d_inode->i_mode)) {
		dput(dir_d);
		error = -ENOTDIR;
	}
	if (error) {
		int umount_error;

		printk(KERN_NOTICE "Trying to unmount old root ... ");
		umount_error = do_umount(old_root_dev,1, 0);
		if (!umount_error) {
			printk("okay\n");
			/* special: the old device driver is going to be
			   a ramdisk and the point of this call is to free its
			   protected memory (even if dirty). */
			destroy_buffers(old_root_dev);
			return 0;
		}
		printk(KERN_ERR "error %d\n",umount_error);
		return error;
	}
	remove_vfsmnt(old_root_dev);
	vfsmnt = add_vfsmnt(old_root->d_sb, "/dev/root.old", put_old);
	if (vfsmnt) {
		d_mount(dir_d,old_root);
		return 0;
	}
	printk(KERN_CRIT "Trouble: add_vfsmnt failed\n");
	return -ENOMEM;
}
Beispiel #6
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));
}