static int umount_dev(kdev_t dev, int flags) { int retval; struct inode * inode = get_empty_inode(); retval = -ENOMEM; if (!inode) goto out; inode->i_rdev = dev; retval = -ENXIO; if (MAJOR(dev) >= MAX_BLKDEV) goto out_iput; fsync_dev(dev); down(&mount_sem); retval = do_umount(dev, 0, flags); if (!retval) { fsync_dev(dev); if (dev != ROOT_DEV) { blkdev_release(inode); put_unnamed_dev(dev); } } up(&mount_sem); out_iput: iput(inode); out: return retval; }
static int sys_umount(argstr_t *input) { argstr_t kstr; char *target; int ret; if (copy_from_user(&kstr, input, sizeof(kstr)) < 0) { curthr->kt_errno = EFAULT; return -1; } if (NULL == (target = user_strdup(&kstr))) { curthr->kt_errno = EINVAL; return -1; } ret = do_umount(target); kfree(target); if (ret) { curthr->kt_errno = -ret; return -1; } return 0; }
static void deinit(void) { struct device_t *iter, *tmp; if (hal_ctx) { libhal_ctx_shutdown(hal_ctx, (DBusError *)NULL); libhal_ctx_free(hal_ctx); } dbus_connection_unref(dbus_conn); iter = head; while (iter) { tmp = iter; if (!is_mounted(iter)) /* don't care to check the return values */ do_umount(iter); rmdir(iter->mountp); if (iter->should_remove_entry) remove_fstab_entry(iter); iter = iter->next; free_device(tmp); } if (pid_fd >= 0) if (close(pid_fd) < 0) /* releases lock */ syslog(LOG_ERR, "%s:%d: %s", __FILE__, __LINE__, strerror(errno)); closelog(); }
int sys_umount(char *name) { struct inode *inode; register struct inode *inodep; kdev_t dev; int retval; struct inode dummy_inode; if (!suser()) return -EPERM; retval = namei(name, &inode, 0, 0); if (retval) { retval = lnamei(name, &inode); if (retval) return retval; } inodep = inode; if (S_ISBLK(inodep->i_mode)) { dev = inodep->i_rdev; if (IS_NODEV(inodep)) { iput(inodep); return -EACCES; } } else { register struct super_block *sb = inodep->i_sb; if (!sb || inodep != sb->s_mounted) { iput(inodep); return -EINVAL; } dev = sb->s_dev; iput(inodep); memset(&dummy_inode, 0, sizeof(dummy_inode)); dummy_inode.i_rdev = dev; inodep = &dummy_inode; } if (MAJOR(dev) >= MAX_BLKDEV) { iput(inodep); return -ENXIO; } if (!(retval = do_umount(dev)) && dev != ROOT_DEV) { register struct file_operations *fops; fops = get_blkfops(MAJOR(dev)); if (fops && fops->release) fops->release(inodep, NULL); #ifdef NOT_YET if (MAJOR(dev) == UNNAMED_MAJOR) put_unnamed_dev(dev); #endif } if (inodep != &dummy_inode) iput(inodep); if (retval) return retval; fsync_dev(dev); return 0; }
long sys_umount(const char *name, size_t name_len) { struct inode * inode; dev_t dev; int retval, error; struct inode dummy_inode; struct file_operations * fops; error = verify_user_string(name, name_len); if (error) return error; //if (!suser()) // return -EPERM; retval = namei(name,&inode); if (retval) { retval = lnamei(name,&inode); if (retval) return retval; } if (S_ISBLK(inode->i_mode)) { dev = inode->i_rdev; if (IS_NODEV(inode)) { iput(inode); return -EACCES; } } else { if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) { iput(inode); return -EINVAL; } dev = inode->i_sb->s_dev; iput(inode); memset(&dummy_inode, 0, sizeof(dummy_inode)); dummy_inode.i_dev = dev; inode = &dummy_inode; } if (major(dev) >= MAX_BLKDEV) { iput(inode); return -ENXIO; } if (!(retval = do_umount(dev)) && dev != ROOT_DEV) { fops = get_blkfops(major(dev)); if (fops && fops->release) fops->release(inode,NULL); if (major(dev) == UNNAMED_MAJOR) put_unnamed_dev(dev); } if (inode != &dummy_inode) iput(inode); if (retval) return retval; //fsync_dev(dev); return 0; }
asmlinkage long sys_umount(struct super_block *mnt_sb, int flags) { struct vfsmount mnt; struct nameidata nd; int retval; mnt.mnt_sb = mnt_sb; mnt.mnt_root = mnt_sb->s_root; retval = do_umount(&mnt, flags); return retval; }
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; }
asmlinkage int sys_umount(char * name) { struct inode * inode; kdev_t dev; int retval; struct inode dummy_inode; if (!suser()) return -EPERM; retval = namei(name, &inode); if (retval) { retval = lnamei(name, &inode); if (retval) return retval; } if (S_ISBLK(inode->i_mode)) { dev = inode->i_rdev; if (IS_NODEV(inode)) { iput(inode); return -EACCES; } } else { if (!inode->i_sb || inode != inode->i_sb->s_mounted) { iput(inode); return -EINVAL; } dev = inode->i_sb->s_dev; iput(inode); memset(&dummy_inode, 0, sizeof(dummy_inode)); dummy_inode.i_rdev = dev; inode = &dummy_inode; } if (MAJOR(dev) >= MAX_BLKDEV) { iput(inode); return -ENXIO; } retval = do_umount(dev,0); if (!retval) { fsync_dev(dev); if (dev != ROOT_DEV) { blkdev_release (inode); if (MAJOR(dev) == UNNAMED_MAJOR) put_unnamed_dev(dev); } } if (inode != &dummy_inode) iput(inode); if (retval) return retval; fsync_dev(dev); return 0; }
int main (int argc, char **argv) { error_t err; err = argp_parse (&argp, argc, argv, 0, 0, &fstab_params); if (err) error (3, err, "parsing arguments"); /* Read the mtab file by default. */ if (! fstab_params.fstab_path) fstab_params.fstab_path = _PATH_MOUNTED; struct fstab *fstab = fstab_argp_create (&fstab_params, NULL, 0); if (! fstab) error (3, ENOMEM, "fstab creation"); if (targets) for (char *t = targets; t; t = argz_next (targets, targets_len, t)) { /* Figure out if t is the device or the mountpoint. */ struct fs *fs = fstab_find_mount (fstab, t); if (! fs) { fs = fstab_find_device (fstab, t); if (! fs) { /* As last resort, just assume it is the mountpoint. */ struct mntent m = { mnt_fsname: "", mnt_dir: t, mnt_type: "", mnt_opts: 0, mnt_freq: 0, mnt_passno: 0, }; err = fstab_add_mntent (fstab, &m, &fs); if (err) error (2, err, "could not find entry for: %s", t); } } if (fs) err |= do_umount (fs); }
void Mount::run_unmount(const QString& name) { QString location = ctab.location(name).location; if (location.length()) { State state = mounts.state(location, name); switch(state) { case mounted: if (do_umount(name)) { do_cryptdisk_stop(name); } break; case dm_started: do_cryptdisk_stop(name); break; } } }
int main(int argc, char** argv) { if(argc != 2) { fprintf(stderr, "dmg-mount <file>\n"); exit(EXIT_FAILURE); } setuid(0); if(strcmp(argv[1], "-u") == 0) { chmod("/mnt/dmg", 0755); do_umount(); } else { if(do_mount(argv[1]) == 0) chmod("/mnt/dmg", 0777); } exit(EXIT_SUCCESS); }
/* * The zgetdump main function */ int main(int argc, char *argv[]) { sig_handler_init(); opts_parse(argc, argv); switch (g.opts.action) { case ZG_ACTION_STDOUT: return do_stdout(); case ZG_ACTION_DUMP_INFO: return do_dump_info(); case ZG_ACTION_DEVICE_INFO: return do_device_info(); case ZG_ACTION_MOUNT: return do_mount(); case ZG_ACTION_UMOUNT: return do_umount(); } ABORT("Invalid action: %i", g.opts.action); }
/** * mnt_context_do_umount: * @cxt: mount context * * Umount filesystem by umount(2) or fork()+exec(/sbin/umount.type). * Unnecessary for mnt_context_umount(). * * See also mnt_context_disable_helpers(). * * WARNING: non-zero return code does not mean that umount(2) syscall or * umount.type helper wasn't successfully called. * * Check mnt_context_get_status() after error! * * Returns: 0 on success; * >0 in case of umount(2) error (returns syscall errno), * <0 in case of other errors. */ int mnt_context_do_umount(struct libmnt_context *cxt) { int rc; assert(cxt); assert(cxt->fs); assert(cxt->helper_exec_status == 1); assert(cxt->syscall_status == 1); assert((cxt->flags & MNT_FL_PREPARED)); assert((cxt->action == MNT_ACT_UMOUNT)); assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); rc = do_umount(cxt); if (rc) return rc; if (mnt_context_get_status(cxt) && !mnt_context_is_fake(cxt)) { /* * Umounted, do some post-umount operations * - remove loopdev * - refresh in-memory mtab stuff if remount rather than * umount has been performed */ if (mnt_context_is_loopdel(cxt) && !(cxt->mountflags & MS_REMOUNT)) rc = mnt_context_delete_loopdev(cxt); if (!mnt_context_is_nomtab(cxt) && mnt_context_get_status(cxt) && !cxt->helper && mnt_context_is_rdonly_umount(cxt) && (cxt->mountflags & MS_REMOUNT)) { /* use "remount" instead of "umount" in /etc/mtab */ if (!rc && cxt->update && cxt->mtab_writable) rc = mnt_update_set_fs(cxt->update, cxt->mountflags, NULL, cxt->fs); } } return rc; }
int main(int argc, char **argv) { int ch, keep, success, pathlen; time_t expire, now; char *host, *path; struct mtablist *mtab; expire = 0; host = path = NULL; success = keep = verbose = 0; while ((ch = getopt(argc, argv, "h:kp:ve:")) != -1) switch (ch) { case 'h': host = optarg; break; case 'e': expire = atoi(optarg); break; case 'k': keep = 1; break; case 'p': path = optarg; break; case 'v': verbose = 1; break; case '?': usage(); default: break; } argc -= optind; argv += optind; /* Default expiretime is one day */ if (expire == 0) expire = 86400; time(&now); /* Read PATH_MOUNTTAB. */ if (!read_mtab()) { if (verbose) warnx("no mounttab entries (%s does not exist)", PATH_MOUNTTAB); mtabhead = NULL; } if (host == NULL && path == NULL) { /* Check each entry and do any necessary unmount RPCs. */ for (mtab = mtabhead; mtab != NULL; mtab = mtab->mtab_next) { if (*mtab->mtab_host == '\0') continue; if (mtab->mtab_time + expire < now) { /* Clear expired entry. */ if (verbose) warnx("remove expired entry %s:%s", mtab->mtab_host, mtab->mtab_dirp); bzero(mtab->mtab_host, sizeof(mtab->mtab_host)); continue; } if (keep && is_mounted(mtab->mtab_host, mtab->mtab_dirp)) { if (verbose) warnx("skip entry %s:%s", mtab->mtab_host, mtab->mtab_dirp); continue; } if (do_umount(mtab->mtab_host, mtab->mtab_dirp)) { if (verbose) warnx("umount RPC for %s:%s succeeded", mtab->mtab_host, mtab->mtab_dirp); /* Remove all entries for this host + path. */ clean_mtab(mtab->mtab_host, mtab->mtab_dirp, verbose); } } success = 1; } else { if (host == NULL && path != NULL) /* Missing hostname. */ usage(); if (path == NULL) { /* Do a RPC UMNTALL for this specific host */ success = do_umntall(host); if (verbose && success) warnx("umntall RPC for %s succeeded", host); } else { /* Do a RPC UMNTALL for this specific mount */ for (pathlen = strlen(path); pathlen > 1 && path[pathlen - 1] == '/'; pathlen--) path[pathlen - 1] = '\0'; success = do_umount(host, path); if (verbose && success) warnx("umount RPC for %s:%s succeeded", host, path); } /* If successful, remove any corresponding mounttab entries. */ if (success) clean_mtab(host, path, verbose); } /* Write and unlink PATH_MOUNTTAB if necessary */ if (success) success = write_mtab(verbose); free_mtab(); exit (success ? 0 : 1); }
static uint32_t sys_umount(uint32_t arg[]) { const char *target = (const char *)arg[0]; return do_umount(target); }
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; }
static void close_umount(void) { SAFE_CLOSE(cleanup, fd); do_umount(); }
int do_mount(char *spec, char *dir, int mflag, char *opt) { // VERIFY(mflag == 0); vfs_t *vfs = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); if(vfs == NULL) return ENOMEM; VFS_INIT(vfs, zfs_vfsops, 0); VFS_HOLD(vfs); struct mounta uap = { .spec = spec, .dir = dir, .flags = mflag | MS_SYSSPACE, .fstype = "zfs-fuse", .dataptr = "", .datalen = 0, .optptr = opt, .optlen = strlen(opt) }; int ret; if ((ret = VFS_MOUNT(vfs, rootdir, &uap, kcred)) != 0) { kmem_free(vfs, sizeof(vfs_t)); return ret; } /* Actually, optptr is totally ignored by VFS_MOUNT. * So we are going to pass this with fuse_mount_options if possible */ if (fuse_mount_options == NULL) fuse_mount_options = ""; char real_opts[1024]; *real_opts = 0; if (*fuse_mount_options) strcat(real_opts,fuse_mount_options); // comes with a starting , if (*opt) sprintf(&real_opts[strlen(real_opts)],",%s",opt); #ifdef DEBUG atomic_inc_32(&mounted);; fprintf(stderr, "mounting %s\n", dir); #endif char *fuse_opts = NULL; int has_default_perm = 0; if (fuse_version() <= 27) { if(asprintf(&fuse_opts, FUSE_OPTIONS, spec, real_opts) == -1) { VERIFY(do_umount(vfs, B_FALSE) == 0); return ENOMEM; } } else { if(asprintf(&fuse_opts, FUSE_OPTIONS ",big_writes", spec, real_opts) == -1) { VERIFY(do_umount(vfs, B_FALSE) == 0); return ENOMEM; } } struct fuse_args args = FUSE_ARGS_INIT(0, NULL); if(fuse_opt_add_arg(&args, "") == -1 || fuse_opt_add_arg(&args, "-o") == -1 || fuse_opt_add_arg(&args, fuse_opts) == -1) { fuse_opt_free_args(&args); free(fuse_opts); VERIFY(do_umount(vfs, B_FALSE) == 0); return ENOMEM; } has_default_perm = detect_fuseoption(fuse_opts,"default_permissions"); free(fuse_opts); struct fuse_chan *ch = fuse_mount(dir, &args); if(ch == NULL) { VERIFY(do_umount(vfs, B_FALSE) == 0); return EIO; } if (has_default_perm) vfs->fuse_attribute = FUSE_VFS_HAS_DEFAULT_PERM; struct fuse_session *se = fuse_lowlevel_new(&args, &zfs_operations, sizeof(zfs_operations), vfs); fuse_opt_free_args(&args); if(se == NULL) { VERIFY(do_umount(vfs, B_FALSE) == 0); /* ZFSFUSE: FIXME?? */ fuse_unmount(dir,ch); return EIO; } fuse_session_add_chan(se, ch); if(zfsfuse_newfs(dir, ch) != 0) { fuse_session_destroy(se); fuse_unmount(dir,ch); return EIO; } return 0; }