static void umount_usb_path(disk_info_t *disks_info, int port, const char *dev_name, int do_spindown) { disk_info_t *follow_disk; partition_info_t *follow_partition; if (!disks_info) return; for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next) { if (port != 0) { if (follow_disk->port_root != port) continue; } if (dev_name && follow_disk->device) { if (strcmp(follow_disk->device, dev_name) != 0) continue; } for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next) umount_dev(follow_partition->device); umount_dev_all(follow_disk->device); if (do_spindown) spindown_hdd(follow_disk->device); } }
asmlinkage int sys_umount(char * name, int flags) { struct dentry * dentry; int retval; if (!capable(CAP_SYS_ADMIN)) return -EPERM; lock_kernel(); dentry = namei(name); retval = PTR_ERR(dentry); if (!IS_ERR(dentry)) { struct inode * inode = dentry->d_inode; kdev_t dev = inode->i_rdev; retval = 0; if (S_ISBLK(inode->i_mode)) { if (IS_NODEV(inode)) retval = -EACCES; } else { struct super_block *sb = inode->i_sb; retval = -EINVAL; if (sb && inode == sb->s_root->d_inode) { dev = sb->s_dev; retval = 0; } } dput(dentry); if (!retval) retval = umount_dev(dev, flags); } unlock_kernel(); return retval; }