Exemplo n.º 1
0
int do_umount(vfs_t *vfs, boolean_t force)
{
	VFS_SYNC(vfs, 0, kcred);

	int ret = VFS_UNMOUNT(vfs, force ? MS_FORCE : 0, kcred);
	if(ret != 0)
		return ret;

	ASSERT(force || vfs->vfs_count == 1);
	VFS_RELE(vfs);

#ifdef DEBUG
	fprintf(stderr, "mounted filesystems: %i\n", atomic_dec_32_nv(&mounted));
#endif

	return 0;
}
Exemplo n.º 2
0
STATIC void
linvfs_put_super(
	struct super_block	*sb)
{
	vfs_t			*vfsp = LINVFS_GET_VFS(sb);
	int			error;

	linvfs_stop_syncd(vfsp);
	VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
	if (!error)
		VFS_UNMOUNT(vfsp, 0, NULL, error);
	if (error) {
		printk("XFS unmount got error %d\n", error);
		printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
		return;
	}

	vfs_deallocate(vfsp);
}
Exemplo n.º 3
0
void
vnlayer_put_super(struct super_block *super_p)
{
    int err;
    CALL_DATA_T cd;

    ASSERT_KERNEL_LOCKED();
    ASSERT_SB_LOCKED(super_p);

    mdki_linux_init_call_data(&cd);
    err = VFS_UNMOUNT(SBTOVFS(super_p), &cd);
    mdki_linux_destroy_call_data(&cd);

    if (err != 0) {
        VFS_LOG(SBTOVFS(super_p), VFS_LOG_ERR,
                "Linux file system interface doesn't let vnode/vfs reject unmounts: error %d\n", err);
    }
    return /* mdki_errno_unix_to_linux(err)*/;
}
Exemplo n.º 4
0
void
vnlayer_put_super(struct super_block *super_p)
{
    int err;
    CRED_T *cred;

    ASSERT_KERNEL_LOCKED();
    ASSERT_SB_LOCKED(super_p);

    cred = MDKI_GET_UCRED();
    err = VFS_UNMOUNT(SBTOVFS(super_p), cred);
    MDKI_CRFREE(cred);

    if (err != 0) {
        VFS_LOG(SBTOVFS(super_p), VFS_LOG_ERR,
                "Linux file system interface doesn't let vnode/vfs reject unmounts: error %d\n", err);
    }
    return /* mdki_errno_unix_to_linux(err)*/;
}
Exemplo n.º 5
0
STATIC int
linvfs_fill_super(
	struct super_block	*sb,
	void			*data,
	int			silent)
{
	vnode_t			*rootvp;
	struct vfs		*vfsp = vfs_allocate();
	struct xfs_mount_args	*args = xfs_args_allocate(sb);
	struct kstatfs		statvfs;
	int			error;

	vfsp->vfs_super = sb;
	LINVFS_SET_VFS(sb, vfsp);
	if (sb->s_flags & MS_RDONLY)
		vfsp->vfs_flag |= VFS_RDONLY;
	bhv_insert_all_vfsops(vfsp);

	VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
	if (error) {
		bhv_remove_all_vfsops(vfsp, 1);
		goto fail_vfsop;
	}

	sb_min_blocksize(sb, BBSIZE);
	sb->s_export_op = &linvfs_export_ops;
	sb->s_qcop = &linvfs_qops;
	sb->s_op = &linvfs_sops;

	VFS_MOUNT(vfsp, args, NULL, error);
	if (error) {
		bhv_remove_all_vfsops(vfsp, 1);
		goto fail_vfsop;
	}

	VFS_STATVFS(vfsp, &statvfs, NULL, error);
	if (error)
		goto fail_unmount;

	sb->s_dirt = 1;
	sb->s_magic = statvfs.f_type;
	sb->s_blocksize = statvfs.f_bsize;
	sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
	sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
	set_posix_acl_flag(sb);

	VFS_ROOT(vfsp, &rootvp, error);
	if (error)
		goto fail_unmount;

	sb->s_root = d_alloc_root(LINVFS_GET_IP(rootvp));
	if (!sb->s_root)
		goto fail_vnrele;
	if (is_bad_inode(sb->s_root->d_inode))
		goto fail_vnrele;
	if (linvfs_start_syncd(vfsp))
		goto fail_vnrele;
	vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);

	kmem_free(args, sizeof(*args));
	return 0;

fail_vnrele:
	if (sb->s_root) {
		dput(sb->s_root);
		sb->s_root = NULL;
	} else {
		VN_RELE(rootvp);
	}

fail_unmount:
	VFS_UNMOUNT(vfsp, 0, NULL, error);

fail_vfsop:
	vfs_deallocate(vfsp);
	kmem_free(args, sizeof(*args));
	return -error;
}
Exemplo n.º 6
0
int
vnlayer_fill_super(
    SUPER_T *super_p,
    void *data_p,
    int silent
)
{
    INODE_T *ino_p;
    VNODE_T *rootvp;
    VATTR_T va;
    VFS_T *vfsp;
    int err = 0;
    CALL_DATA_T cd;

    ASSERT_KERNEL_LOCKED();             /* sys_mount() */
    ASSERT_SB_MOUNT_LOCKED_W(super_p);

    /* can't assert on mount_sem, we don't have access to it. */

    if (vnlayer_vfs_opvec == NULL) {
        MDKI_VFS_LOG(VFS_LOG_ERR,
                     "%s: VFS operation not set yet "
                     "(no file system module loaded?)\n", __func__);
        err = -ENODATA;
        goto return_NULL;
    }

    if (MDKI_INOISOURS(vnlayer_get_urdir_inode())) {
        /* can't handle this case */
        MDKI_VFS_LOG(VFS_LOG_ERR,
                    "%s: can't handle mounts inside setview.\n", __func__);
        err = -EINVAL;
        goto return_NULL;
    }

    /*
     * The only fields we have coming in are s_type and s_flags.
     */
    /* Verify this */

    super_p->s_blocksize = MVFS_DEF_BLKSIZE;
    super_p->s_blocksize_bits = MVFS_DEF_BLKSIZE_BITS;
    super_p->s_maxbytes = MVFS_DEF_MAX_FILESIZE;
    super_p->s_op = &mvfs_super_ops;
    super_p->s_export_op = &vnlayer_export_ops;
    super_p->dq_op = NULL;
    super_p->s_magic = MVFS_SUPER_MAGIC;

    /*
     * XXX This module is currently restricted to one client file system
     * type at a time, as registered via the vnlayer_vfs_opvec.
     */
    vfsp = KMEM_ALLOC(sizeof(*vfsp), KM_SLEEP);
    if (vfsp == NULL) {
        MDKI_VFS_LOG(VFS_LOG_ERR, "%s failed: no memory\n", __func__);
        SET_SBTOVFS(super_p, NULL);
        err = -ENOMEM;
        goto return_NULL;
    }
    BZERO(vfsp, sizeof(*vfsp));
    SET_VFSTOSB(vfsp, super_p);
    SET_SBTOVFS(super_p, vfsp);
    vfsp->vfs_op = vnlayer_vfs_opvec;
    /* XXX fill in more of vfsp (flag?) */
    if (super_p->s_flags & MS_RDONLY)
        vfsp->vfs_flag |= VFS_RDONLY;
    if (super_p->s_flags & MS_NOSUID)
        vfsp->vfs_flag |= VFS_NOSUID;

    err = vnlayer_linux_mount(vfsp, data_p);

    if (err) {
        goto bailout;
    }

    /*
     * Now create our dentry and set that up in the superblock.  Get
     * the inode from the vnode at the root of the file system, and
     * attach it to a new dentry.
     */
    mdki_linux_init_call_data(&cd);
    err = VFS_ROOT(SBTOVFS(super_p), &rootvp);
    if (err) {
        err = mdki_errno_unix_to_linux(err);
        (void) VFS_UNMOUNT(vfsp,&cd);
        mdki_linux_destroy_call_data(&cd);
        goto bailout;
    }

    ino_p = VTOI(rootvp);

#ifdef CONFIG_FS_POSIX_ACL
    /* If the system supports ACLs, we set the flag in the superblock
     * depending on the ability of the underlying filesystem
     */
    if (vfsp->vfs_flag & VFS_POSIXACL) {
	super_p->s_flags |= MS_POSIXACL;
    }
#endif
    /*
     * Call getattr() to prime this inode with real attributes via the
     * callback to mdki_linux_vattr_pullup()
     */
    VATTR_NULL(&va);
    /* ignore error code, we're committed */
    (void) VOP_GETATTR(rootvp, &va, 0, &cd);

    /* This will allocate a dentry with a name of /, which is
     * what Linux uses in all filesystem roots.  The dentry is
     * also not put on the hash chains because Linux does not
     * hash file system roots.  It finds them through the super
     * blocks.
     */
    super_p->s_root = VNODE_D_ALLOC_ROOT(ino_p);
    if (super_p->s_root) {
        if (VFSTOSB(vnlayer_looproot_vp->v_vfsp) == super_p) {
            /* loopback names are done with regular dentry ops */
            MDKI_SET_DOPS(super_p->s_root, &vnode_dentry_ops);
        } else {
            /*
             * setview names come in via VOB mounts, they're marked
             * with setview dentry ops
             */
            MDKI_SET_DOPS(super_p->s_root, &vnode_setview_dentry_ops);
        }
        super_p->s_root->d_fsdata = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
        atomic_set(&super_p->s_root->d_count, 1);
#endif
        /* d_alloc_root assumes that the caller will take care of
         * bumping the inode count for the dentry.  So we will oblige
         */
        igrab(ino_p);
    } else {
        VN_RELE(rootvp);
        (void) VFS_UNMOUNT(vfsp,&cd);
        mdki_linux_destroy_call_data(&cd);
        err = -ENOMEM;
        goto bailout;
    }
    mdki_linux_destroy_call_data(&cd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
    super_p->s_dirt = 1;            /* we want to be called on
                                       write_super/sync() */
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)
    /* write back is delegated to the undelying fs */
    super_p->s_bdi = &noop_backing_dev_info;
#endif
    /*
     * release reference on rootvp--super block holds appropriate
     * references now
     */
    VN_RELE(rootvp);
    return(0);

  bailout:
    MDKI_VFS_LOG(VFS_LOG_ERR,
                 "%s failed: error %d\n", __func__,
                 vnlayer_errno_linux_to_unix(err));
    SET_SBTOVFS(super_p, NULL);
    KMEM_FREE(vfsp, sizeof(*vfsp));
  return_NULL:
    return(err);
}