static int do_umount(kdev_t dev,int unmount_root) { struct super_block * sb; int retval; if (dev==ROOT_DEV && !unmount_root) { /* * Special case for "unmounting" root. We just try to remount * it readonly, and sync() the device. */ if (!(sb=get_super(dev))) return -ENOENT; if (!(sb->s_flags & MS_RDONLY)) { /* * Make sure all quotas are turned off on this device we need to mount * it readonly so no more writes by the quotasystem. * If later on the remount fails too bad there are no quotas running * anymore. Turn them on again by hand. */ quota_off(dev, -1); fsync_dev(dev); retval = do_remount_sb(sb, MS_RDONLY, 0); if (retval) return retval; } return 0; } if (!(sb=get_super(dev)) || !(sb->s_covered)) return -ENOENT; if (!sb->s_covered->i_mount) printk("VFS: umount(%s): mounted inode has i_mount=NULL\n", kdevname(dev)); /* * Before checking if the filesystem is still busy make sure the kernel * doesn't hold any quotafiles open on that device. If the umount fails * too bad there are no quotas running anymore. Turn them on again by hand. */ quota_off(dev, -1); if (!fs_may_umount(dev, sb->s_mounted)) return -EBUSY; sb->s_covered->i_mount = NULL; iput(sb->s_covered); sb->s_covered = NULL; iput(sb->s_mounted); sb->s_mounted = NULL; if (sb->s_op && sb->s_op->write_super && sb->s_dirt) sb->s_op->write_super(sb); put_super(dev); remove_vfsmnt(dev); return 0; }
static int do_umount(kdev_t dev) { register struct super_block *sb; register struct super_operations *sop; int retval = -ENOENT; if ((sb = get_super(dev))) { if (dev == ROOT_DEV) { /* Special case for "unmounting" root. We just try to remount * it readonly, and sync() the device. */ retval = 0; if (!(sb->s_flags & MS_RDONLY)) { fsync_dev(dev); retval = do_remount_sb(sb, MS_RDONLY, 0); } } else if (sb->s_covered) { if (!sb->s_covered->i_mount) panic("umount: i_mount=NULL\n"); if (!fs_may_umount(dev, sb->s_mounted)) retval = -EBUSY; else { retval = 0; sb->s_covered->i_mount = NULL; iput(sb->s_covered); sb->s_covered = NULL; iput(sb->s_mounted); sb->s_mounted = NULL; sop = sb->s_op; if (sop && sop->write_super && sb->s_dirt) sop->write_super(sb); put_super(dev); } } } return retval; }