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; }
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; }
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; }
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)); }
/* * 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; }
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)); }
/* * 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; }