Пример #1
0
asmlinkage int sunos_nfs_mount(char *dir_name, int linux_flags, void *data)
{
	int  ret = -ENODEV, error;
	int  server_fd;
	char *the_name;
	struct nfs_mount_data linux_nfs_mount;
	struct sunos_nfs_mount_args *sunos_mount = data;
	dev_t dev;

	error = verify_area(VERIFY_READ, data, sizeof (struct sunos_nfs_mount_args));
	if (error)
		return error;
	/* Ok, here comes the fun part: Linux's nfs mount needs a
	 * socket connection to the server, but SunOS mount does not
	 * require this, so we use the information on the destination
	 * address to create a socket and bind it to a reserved
	 * port on this system
	 */
	server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (server_fd < 0)
		return -ENXIO;

	if (!sunos_nfs_get_server_fd (server_fd, sunos_mount->addr)){
		sys_close (server_fd);
		return -ENXIO;
	}

	/* Now, bind it to a locally reserved port */
	linux_nfs_mount.version  = NFS_MOUNT_VERSION;
	linux_nfs_mount.flags    = sunos_mount->flags;
	linux_nfs_mount.addr     = *sunos_mount->addr;
	linux_nfs_mount.root     = *sunos_mount->fh;
	linux_nfs_mount.fd       = server_fd;
	
	linux_nfs_mount.rsize    = get_default (sunos_mount->rsize, 8192);
	linux_nfs_mount.wsize    = get_default (sunos_mount->wsize, 8192);
	linux_nfs_mount.timeo    = get_default (sunos_mount->timeo, 10);
	linux_nfs_mount.retrans  = sunos_mount->retrans;
	
	linux_nfs_mount.acregmin = sunos_mount->acregmin;
	linux_nfs_mount.acregmax = sunos_mount->acregmax;
	linux_nfs_mount.acdirmin = sunos_mount->acdirmin;
	linux_nfs_mount.acdirmax = sunos_mount->acdirmax;

	if (getname (sunos_mount->hostname, &the_name))
		return -EFAULT;

	strncpy (linux_nfs_mount.hostname, the_name, 254);
	linux_nfs_mount.hostname [255] = 0;
	putname (the_name);

	dev = get_unnamed_dev ();
	
	ret = do_mount (dev, "", dir_name, "nfs", linux_flags, &linux_nfs_mount);
	if (ret)
	    put_unnamed_dev(dev);

	return ret;
}
Пример #2
0
static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags)
{
	kdev_t dev;
	int retval;
	struct procfs_args tmp;

	retval = verify_area(VERIFY_READ, args, sizeof(*args));
	if (retval)
		return retval;
	memcpy_fromfs(&tmp, args, sizeof(tmp));
	dev = get_unnamed_dev();
	if (!dev)
		return -ENODEV;
	retval = do_mount(dev, "", dirname, "proc", flags, NULL);
	if (retval)
		put_unnamed_dev(dev);
	return retval;
}
Пример #3
0
static long unpacked_mount(const char *dev_name, const char *dir_name,
		const char *type, unsigned long flags, const void *data)
{
	struct file_system_type *fstype;
	struct inode *inode;
	struct file_operations *fops;
	dev_t dev;
	int error;

	if (flags & MS_REMOUNT) {
		return do_remount(dir_name, flags, data);
	}
	flags &= MS_MOUNT_MASK;
	if (!type || !(fstype = get_fs_type(type)))
		return -ENODEV;

	if (fstype->requires_dev) {
		if (!dev_name)
			return -ENOTBLK;
		error = namei(dev_name, &inode);
		if (error)
			return error;
		if (!S_ISBLK(inode->i_mode))
			return -ENOTBLK;
		dev = inode->i_rdev;
	} else {
		if (!(dev = get_unnamed_dev()))
			return -EMFILE;
		inode = NULL;
	}
	fops = get_blkfops(major(dev));
	if (fops && fops->open) {
		if ((error = fops->open(inode, NULL))) {
			iput(inode);
			return error;
		}
	}
	error = do_mount(dev, dir_name, type, flags, NULL);
	if (error && fops && fops->release)
		fops->release(inode, NULL);
	iput(inode);
	return error;
}
Пример #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));
}
Пример #5
0
/*
 * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to
 * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
 *
 * data is a (void *) that can point to any structure up to
 * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
 * information (or be NULL).
 *
 * NOTE! As old versions of mount() didn't use this setup, the flags
 * has to have a special 16-bit magic number in the hight word:
 * 0xC0ED. If this magic word isn't present, the flags and data info
 * isn't used, as the syscall assumes we are talking to an older
 * version that didn't understand them.
 */
asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
	unsigned long new_flags, void * data)
{
	struct file_system_type * fstype;
	struct inode * inode;
	struct file_operations * fops;
	kdev_t dev;
	int retval;
	const char * t;
	unsigned long flags = 0;
	unsigned long page = 0;

	if (!suser())
		return -EPERM;
	if ((new_flags &
	     (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
		retval = copy_mount_options (data, &page);
		if (retval < 0)
			return retval;
		retval = do_remount(dir_name,
				    new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
				    (char *) page);
		free_page(page);
		return retval;
	}
	retval = copy_mount_options (type, &page);
	if (retval < 0)
		return retval;
	fstype = get_fs_type((char *) page);
	free_page(page);
	if (!fstype)		
		return -ENODEV;
	t = fstype->name;
	fops = NULL;
	if (fstype->requires_dev) {
		retval = namei(dev_name, &inode);
		if (retval)
			return retval;
		if (!S_ISBLK(inode->i_mode)) {
			iput(inode);
			return -ENOTBLK;
		}
		if (IS_NODEV(inode)) {
			iput(inode);
			return -EACCES;
		}
		dev = inode->i_rdev;
		if (MAJOR(dev) >= MAX_BLKDEV) {
			iput(inode);
			return -ENXIO;
		}
		fops = get_blkfops(MAJOR(dev));
		if (!fops) {
			iput(inode);
			return -ENOTBLK;
		}
		if (fops->open) {
			struct file dummy;	/* allows read-write or read-only flag */
			memset(&dummy, 0, sizeof(dummy));
			dummy.f_inode = inode;
			dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
			retval = fops->open(inode, &dummy);
			if (retval) {
				iput(inode);
				return retval;
			}
		}

	} else {
		if (!(dev = get_unnamed_dev()))
			return -EMFILE;
		inode = NULL;
	}
	page = 0;
	if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
		flags = new_flags & ~MS_MGC_MSK;
		retval = copy_mount_options(data, &page);
		if (retval < 0) {
			iput(inode);
			return retval;
		}
	}
	retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
	free_page(page);
	if (retval && fops && fops->release)
		fops->release(inode, NULL);
	iput(inode);
	return retval;
}
Пример #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));
}
Пример #7
0
/*
 * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to
 * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
 *
 * data is a (void *) that can point to any structure up to
 * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
 * information (or be NULL).
 *
 * NOTE! As old versions of mount() didn't use this setup, the flags
 * have to have a special 16-bit magic number in the high word:
 * 0xC0ED. If this magic word isn't present, the flags and data info
 * aren't used, as the syscall assumes we are talking to an older
 * version that didn't understand them.
 */
asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
	unsigned long new_flags, void * data)
{
	struct file_system_type * fstype;
	struct dentry * dentry = NULL;
	struct inode * inode = NULL;
	kdev_t dev;
	int retval = -EPERM;
	unsigned long flags = 0;
	unsigned long page = 0;
	struct file dummy;	/* allows read-write or read-only flag */

	lock_kernel();
	if (!capable(CAP_SYS_ADMIN))
		goto out;
	if ((new_flags &
	     (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
		retval = copy_mount_options (data, &page);
		if (retval < 0)
			goto out;
		retval = do_remount(dir_name,
				    new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
				    (char *) page);
		free_mount_page(page);
		goto out;
	}

	retval = copy_mount_options (type, &page);
	if (retval < 0)
		goto out;
	fstype = get_fs_type((char *) page);
	free_mount_page(page);
	retval = -ENODEV;
	if (!fstype)		
		goto out;

	memset(&dummy, 0, sizeof(dummy));
	if (fstype->fs_flags & FS_REQUIRES_DEV) {
		dentry = namei(dev_name);
		retval = PTR_ERR(dentry);
		if (IS_ERR(dentry))
			goto out;

		inode = dentry->d_inode;
		retval = -ENOTBLK;
		if (!S_ISBLK(inode->i_mode))
			goto dput_and_out;

		retval = -EACCES;
		if (IS_NODEV(inode))
			goto dput_and_out;

		dev = inode->i_rdev;
		retval = -ENXIO;
		if (MAJOR(dev) >= MAX_BLKDEV)
			goto dput_and_out;

		retval = -ENOTBLK;
		dummy.f_op = get_blkfops(MAJOR(dev));
		if (!dummy.f_op)
			goto dput_and_out;

		if (dummy.f_op->open) {
			dummy.f_dentry = dentry;
			dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
			retval = dummy.f_op->open(inode, &dummy);
			if (retval)
				goto dput_and_out;
		}

	} else {
		retval = -EMFILE;
		if (!(dev = get_unnamed_dev()))
			goto out;
	}

	page = 0;
	if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
		flags = new_flags & ~MS_MGC_MSK;
		retval = copy_mount_options(data, &page);
		if (retval < 0)
			goto clean_up;
	}
	retval = do_mount(dev, dev_name, dir_name, fstype->name, flags,
				(void *) page);
	free_mount_page(page);
	if (retval)
		goto clean_up;

dput_and_out:
	dput(dentry);
out:
	unlock_kernel();
	return retval;

clean_up:
	if (dummy.f_op) {
		if (dummy.f_op->release)
			dummy.f_op->release(inode, NULL);
	} else
		put_unnamed_dev(dev);
	goto dput_and_out;
}