10fd16957SHans de Goede // SPDX-License-Identifier: MIT
20fd16957SHans de Goede /*
30fd16957SHans de Goede * VirtualBox Guest Shared Folders support: Virtual File System.
40fd16957SHans de Goede *
50fd16957SHans de Goede * Module initialization/finalization
60fd16957SHans de Goede * File system registration/deregistration
70fd16957SHans de Goede * Superblock reading
80fd16957SHans de Goede * Few utility functions
90fd16957SHans de Goede *
100fd16957SHans de Goede * Copyright (C) 2006-2018 Oracle Corporation
110fd16957SHans de Goede */
120fd16957SHans de Goede
130fd16957SHans de Goede #include <linux/idr.h>
140fd16957SHans de Goede #include <linux/fs_parser.h>
150fd16957SHans de Goede #include <linux/magic.h>
160fd16957SHans de Goede #include <linux/module.h>
170fd16957SHans de Goede #include <linux/nls.h>
180fd16957SHans de Goede #include <linux/statfs.h>
190fd16957SHans de Goede #include <linux/vbox_utils.h>
200fd16957SHans de Goede #include "vfsmod.h"
210fd16957SHans de Goede
220fd16957SHans de Goede #define VBOXSF_SUPER_MAGIC 0x786f4256 /* 'VBox' little endian */
230fd16957SHans de Goede
24*5d01a4ecSBrahmajit Das static const unsigned char VBSF_MOUNT_SIGNATURE[4] = { '\000', '\377', '\376',
25*5d01a4ecSBrahmajit Das '\375' };
260fd16957SHans de Goede
270fd16957SHans de Goede static int follow_symlinks;
280fd16957SHans de Goede module_param(follow_symlinks, int, 0444);
290fd16957SHans de Goede MODULE_PARM_DESC(follow_symlinks,
300fd16957SHans de Goede "Let host resolve symlinks rather than showing them");
310fd16957SHans de Goede
320fd16957SHans de Goede static DEFINE_IDA(vboxsf_bdi_ida);
330fd16957SHans de Goede static DEFINE_MUTEX(vboxsf_setup_mutex);
340fd16957SHans de Goede static bool vboxsf_setup_done;
350fd16957SHans de Goede static struct super_operations vboxsf_super_ops; /* forward declaration */
360fd16957SHans de Goede static struct kmem_cache *vboxsf_inode_cachep;
370fd16957SHans de Goede
380fd16957SHans de Goede static char * const vboxsf_default_nls = CONFIG_NLS_DEFAULT;
390fd16957SHans de Goede
400fd16957SHans de Goede enum { opt_nls, opt_uid, opt_gid, opt_ttl, opt_dmode, opt_fmode,
410fd16957SHans de Goede opt_dmask, opt_fmask };
420fd16957SHans de Goede
430fd16957SHans de Goede static const struct fs_parameter_spec vboxsf_fs_parameters[] = {
440fd16957SHans de Goede fsparam_string ("nls", opt_nls),
450fd16957SHans de Goede fsparam_u32 ("uid", opt_uid),
460fd16957SHans de Goede fsparam_u32 ("gid", opt_gid),
470fd16957SHans de Goede fsparam_u32 ("ttl", opt_ttl),
480fd16957SHans de Goede fsparam_u32oct ("dmode", opt_dmode),
490fd16957SHans de Goede fsparam_u32oct ("fmode", opt_fmode),
500fd16957SHans de Goede fsparam_u32oct ("dmask", opt_dmask),
510fd16957SHans de Goede fsparam_u32oct ("fmask", opt_fmask),
520fd16957SHans de Goede {}
530fd16957SHans de Goede };
vboxsf_parse_param(struct fs_context * fc,struct fs_parameter * param)540fd16957SHans de Goede
550fd16957SHans de Goede static int vboxsf_parse_param(struct fs_context *fc, struct fs_parameter *param)
560fd16957SHans de Goede {
570fd16957SHans de Goede struct vboxsf_fs_context *ctx = fc->fs_private;
580fd16957SHans de Goede struct fs_parse_result result;
590fd16957SHans de Goede kuid_t uid;
600fd16957SHans de Goede kgid_t gid;
610fd16957SHans de Goede int opt;
620fd16957SHans de Goede
630fd16957SHans de Goede opt = fs_parse(fc, vboxsf_fs_parameters, param, &result);
640fd16957SHans de Goede if (opt < 0)
650fd16957SHans de Goede return opt;
660fd16957SHans de Goede
670fd16957SHans de Goede switch (opt) {
680fd16957SHans de Goede case opt_nls:
690fd16957SHans de Goede if (ctx->nls_name || fc->purpose != FS_CONTEXT_FOR_MOUNT) {
700fd16957SHans de Goede vbg_err("vboxsf: Cannot reconfigure nls option\n");
710fd16957SHans de Goede return -EINVAL;
720fd16957SHans de Goede }
730fd16957SHans de Goede ctx->nls_name = param->string;
740fd16957SHans de Goede param->string = NULL;
750fd16957SHans de Goede break;
760fd16957SHans de Goede case opt_uid:
770fd16957SHans de Goede uid = make_kuid(current_user_ns(), result.uint_32);
780fd16957SHans de Goede if (!uid_valid(uid))
790fd16957SHans de Goede return -EINVAL;
800fd16957SHans de Goede ctx->o.uid = uid;
810fd16957SHans de Goede break;
820fd16957SHans de Goede case opt_gid:
830fd16957SHans de Goede gid = make_kgid(current_user_ns(), result.uint_32);
840fd16957SHans de Goede if (!gid_valid(gid))
850fd16957SHans de Goede return -EINVAL;
860fd16957SHans de Goede ctx->o.gid = gid;
870fd16957SHans de Goede break;
880fd16957SHans de Goede case opt_ttl:
890fd16957SHans de Goede ctx->o.ttl = msecs_to_jiffies(result.uint_32);
900fd16957SHans de Goede break;
910fd16957SHans de Goede case opt_dmode:
920fd16957SHans de Goede if (result.uint_32 & ~0777)
930fd16957SHans de Goede return -EINVAL;
940fd16957SHans de Goede ctx->o.dmode = result.uint_32;
950fd16957SHans de Goede ctx->o.dmode_set = true;
960fd16957SHans de Goede break;
970fd16957SHans de Goede case opt_fmode:
980fd16957SHans de Goede if (result.uint_32 & ~0777)
990fd16957SHans de Goede return -EINVAL;
1000fd16957SHans de Goede ctx->o.fmode = result.uint_32;
1010fd16957SHans de Goede ctx->o.fmode_set = true;
1020fd16957SHans de Goede break;
1030fd16957SHans de Goede case opt_dmask:
1040fd16957SHans de Goede if (result.uint_32 & ~07777)
1050fd16957SHans de Goede return -EINVAL;
1060fd16957SHans de Goede ctx->o.dmask = result.uint_32;
1070fd16957SHans de Goede break;
1080fd16957SHans de Goede case opt_fmask:
1090fd16957SHans de Goede if (result.uint_32 & ~07777)
1100fd16957SHans de Goede return -EINVAL;
1110fd16957SHans de Goede ctx->o.fmask = result.uint_32;
1120fd16957SHans de Goede break;
1130fd16957SHans de Goede default:
1140fd16957SHans de Goede return -EINVAL;
1150fd16957SHans de Goede }
1160fd16957SHans de Goede
1170fd16957SHans de Goede return 0;
1180fd16957SHans de Goede }
vboxsf_fill_super(struct super_block * sb,struct fs_context * fc)1190fd16957SHans de Goede
1200fd16957SHans de Goede static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)
1210fd16957SHans de Goede {
1220fd16957SHans de Goede struct vboxsf_fs_context *ctx = fc->fs_private;
1230fd16957SHans de Goede struct shfl_string *folder_name, root_path;
1240fd16957SHans de Goede struct vboxsf_sbi *sbi;
1250fd16957SHans de Goede struct dentry *droot;
1260fd16957SHans de Goede struct inode *iroot;
1270fd16957SHans de Goede char *nls_name;
1280fd16957SHans de Goede size_t size;
1290fd16957SHans de Goede int err;
1300fd16957SHans de Goede
1310fd16957SHans de Goede if (!fc->source)
1320fd16957SHans de Goede return -EINVAL;
1330fd16957SHans de Goede
1340fd16957SHans de Goede sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
1350fd16957SHans de Goede if (!sbi)
1360fd16957SHans de Goede return -ENOMEM;
1370fd16957SHans de Goede
1380fd16957SHans de Goede sbi->o = ctx->o;
1390fd16957SHans de Goede idr_init(&sbi->ino_idr);
1400fd16957SHans de Goede spin_lock_init(&sbi->ino_idr_lock);
1410fd16957SHans de Goede sbi->next_generation = 1;
1420fd16957SHans de Goede sbi->bdi_id = -1;
1430fd16957SHans de Goede
1440fd16957SHans de Goede /* Load nls if not utf8 */
1450fd16957SHans de Goede nls_name = ctx->nls_name ? ctx->nls_name : vboxsf_default_nls;
1460fd16957SHans de Goede if (strcmp(nls_name, "utf8") != 0) {
1470fd16957SHans de Goede if (nls_name == vboxsf_default_nls)
1480fd16957SHans de Goede sbi->nls = load_nls_default();
1490fd16957SHans de Goede else
1500fd16957SHans de Goede sbi->nls = load_nls(nls_name);
1510fd16957SHans de Goede
1520fd16957SHans de Goede if (!sbi->nls) {
1530fd16957SHans de Goede vbg_err("vboxsf: Count not load '%s' nls\n", nls_name);
1540fd16957SHans de Goede err = -EINVAL;
15555fabde8SChristophe JAILLET goto fail_destroy_idr;
1560fd16957SHans de Goede }
1570fd16957SHans de Goede }
1580fd16957SHans de Goede
1590fd16957SHans de Goede sbi->bdi_id = ida_simple_get(&vboxsf_bdi_ida, 0, 0, GFP_KERNEL);
1600fd16957SHans de Goede if (sbi->bdi_id < 0) {
1610fd16957SHans de Goede err = sbi->bdi_id;
1620fd16957SHans de Goede goto fail_free;
1630fd16957SHans de Goede }
1640fd16957SHans de Goede
165156c7573SChristoph Hellwig err = super_setup_bdi_name(sb, "vboxsf-%d", sbi->bdi_id);
1660fd16957SHans de Goede if (err)
1670fd16957SHans de Goede goto fail_free;
16855b2598eSChristoph Hellwig sb->s_bdi->ra_pages = 0;
16955b2598eSChristoph Hellwig sb->s_bdi->io_pages = 0;
1700fd16957SHans de Goede
1710fd16957SHans de Goede /* Turn source into a shfl_string and map the folder */
1720fd16957SHans de Goede size = strlen(fc->source) + 1;
1730fd16957SHans de Goede folder_name = kmalloc(SHFLSTRING_HEADER_SIZE + size, GFP_KERNEL);
1740fd16957SHans de Goede if (!folder_name) {
1750fd16957SHans de Goede err = -ENOMEM;
1760fd16957SHans de Goede goto fail_free;
1770fd16957SHans de Goede }
1780fd16957SHans de Goede folder_name->size = size;
1790fd16957SHans de Goede folder_name->length = size - 1;
180883f8fe8SAzeem Shaikh strscpy(folder_name->string.utf8, fc->source, size);
1810fd16957SHans de Goede err = vboxsf_map_folder(folder_name, &sbi->root);
1820fd16957SHans de Goede kfree(folder_name);
1830fd16957SHans de Goede if (err) {
1840fd16957SHans de Goede vbg_err("vboxsf: Host rejected mount of '%s' with error %d\n",
1850fd16957SHans de Goede fc->source, err);
1860fd16957SHans de Goede goto fail_free;
1870fd16957SHans de Goede }
1880fd16957SHans de Goede
1890fd16957SHans de Goede root_path.length = 1;
1900fd16957SHans de Goede root_path.size = 2;
1910fd16957SHans de Goede root_path.string.utf8[0] = '/';
1920fd16957SHans de Goede root_path.string.utf8[1] = 0;
1930fd16957SHans de Goede err = vboxsf_stat(sbi, &root_path, &sbi->root_info);
1940fd16957SHans de Goede if (err)
1950fd16957SHans de Goede goto fail_unmap;
1960fd16957SHans de Goede
1970fd16957SHans de Goede sb->s_magic = VBOXSF_SUPER_MAGIC;
1980fd16957SHans de Goede sb->s_blocksize = 1024;
1990fd16957SHans de Goede sb->s_maxbytes = MAX_LFS_FILESIZE;
2000fd16957SHans de Goede sb->s_op = &vboxsf_super_ops;
2010fd16957SHans de Goede sb->s_d_op = &vboxsf_dentry_ops;
2020fd16957SHans de Goede
2030fd16957SHans de Goede iroot = iget_locked(sb, 0);
2040fd16957SHans de Goede if (!iroot) {
2050fd16957SHans de Goede err = -ENOMEM;
2060fd16957SHans de Goede goto fail_unmap;
2070fd16957SHans de Goede }
208e98f93e7SAl Viro vboxsf_init_inode(sbi, iroot, &sbi->root_info, false);
2090fd16957SHans de Goede unlock_new_inode(iroot);
2100fd16957SHans de Goede
2110fd16957SHans de Goede droot = d_make_root(iroot);
2120fd16957SHans de Goede if (!droot) {
2130fd16957SHans de Goede err = -ENOMEM;
2140fd16957SHans de Goede goto fail_unmap;
2150fd16957SHans de Goede }
2160fd16957SHans de Goede
2170fd16957SHans de Goede sb->s_root = droot;
2180fd16957SHans de Goede sb->s_fs_info = sbi;
2190fd16957SHans de Goede return 0;
2200fd16957SHans de Goede
2210fd16957SHans de Goede fail_unmap:
2220fd16957SHans de Goede vboxsf_unmap_folder(sbi->root);
2230fd16957SHans de Goede fail_free:
2240fd16957SHans de Goede if (sbi->bdi_id >= 0)
2250fd16957SHans de Goede ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
2260fd16957SHans de Goede if (sbi->nls)
2270fd16957SHans de Goede unload_nls(sbi->nls);
22855fabde8SChristophe JAILLET fail_destroy_idr:
2290fd16957SHans de Goede idr_destroy(&sbi->ino_idr);
2300fd16957SHans de Goede kfree(sbi);
2310fd16957SHans de Goede return err;
2320fd16957SHans de Goede }
vboxsf_inode_init_once(void * data)2330fd16957SHans de Goede
2340fd16957SHans de Goede static void vboxsf_inode_init_once(void *data)
2350fd16957SHans de Goede {
2360fd16957SHans de Goede struct vboxsf_inode *sf_i = data;
2370fd16957SHans de Goede
2380fd16957SHans de Goede mutex_init(&sf_i->handle_list_mutex);
2390fd16957SHans de Goede inode_init_once(&sf_i->vfs_inode);
2400fd16957SHans de Goede }
vboxsf_alloc_inode(struct super_block * sb)2410fd16957SHans de Goede
2420fd16957SHans de Goede static struct inode *vboxsf_alloc_inode(struct super_block *sb)
2430fd16957SHans de Goede {
2440fd16957SHans de Goede struct vboxsf_inode *sf_i;
2450fd16957SHans de Goede
246fd60b288SMuchun Song sf_i = alloc_inode_sb(sb, vboxsf_inode_cachep, GFP_NOFS);
2470fd16957SHans de Goede if (!sf_i)
2480fd16957SHans de Goede return NULL;
2490fd16957SHans de Goede
2500fd16957SHans de Goede sf_i->force_restat = 0;
2510fd16957SHans de Goede INIT_LIST_HEAD(&sf_i->handle_list);
2520fd16957SHans de Goede
2530fd16957SHans de Goede return &sf_i->vfs_inode;
2540fd16957SHans de Goede }
vboxsf_free_inode(struct inode * inode)2550fd16957SHans de Goede
2560fd16957SHans de Goede static void vboxsf_free_inode(struct inode *inode)
2570fd16957SHans de Goede {
2580fd16957SHans de Goede struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
2590fd16957SHans de Goede unsigned long flags;
2600fd16957SHans de Goede
2610fd16957SHans de Goede spin_lock_irqsave(&sbi->ino_idr_lock, flags);
2620fd16957SHans de Goede idr_remove(&sbi->ino_idr, inode->i_ino);
2630fd16957SHans de Goede spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
2640fd16957SHans de Goede kmem_cache_free(vboxsf_inode_cachep, VBOXSF_I(inode));
2650fd16957SHans de Goede }
vboxsf_put_super(struct super_block * sb)2660fd16957SHans de Goede
2670fd16957SHans de Goede static void vboxsf_put_super(struct super_block *sb)
2680fd16957SHans de Goede {
2690fd16957SHans de Goede struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);
2700fd16957SHans de Goede
2710fd16957SHans de Goede vboxsf_unmap_folder(sbi->root);
2720fd16957SHans de Goede if (sbi->bdi_id >= 0)
2730fd16957SHans de Goede ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
2740fd16957SHans de Goede if (sbi->nls)
2750fd16957SHans de Goede unload_nls(sbi->nls);
2760fd16957SHans de Goede
2770fd16957SHans de Goede /*
2780fd16957SHans de Goede * vboxsf_free_inode uses the idr, make sure all delayed rcu free
2790fd16957SHans de Goede * inodes are flushed.
2800fd16957SHans de Goede */
2810fd16957SHans de Goede rcu_barrier();
2820fd16957SHans de Goede idr_destroy(&sbi->ino_idr);
2830fd16957SHans de Goede kfree(sbi);
2840fd16957SHans de Goede }
vboxsf_statfs(struct dentry * dentry,struct kstatfs * stat)2850fd16957SHans de Goede
2860fd16957SHans de Goede static int vboxsf_statfs(struct dentry *dentry, struct kstatfs *stat)
2870fd16957SHans de Goede {
2880fd16957SHans de Goede struct super_block *sb = dentry->d_sb;
2890fd16957SHans de Goede struct shfl_volinfo shfl_volinfo;
2900fd16957SHans de Goede struct vboxsf_sbi *sbi;
2910fd16957SHans de Goede u32 buf_len;
2920fd16957SHans de Goede int err;
2930fd16957SHans de Goede
2940fd16957SHans de Goede sbi = VBOXSF_SBI(sb);
2950fd16957SHans de Goede buf_len = sizeof(shfl_volinfo);
2960fd16957SHans de Goede err = vboxsf_fsinfo(sbi->root, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
2970fd16957SHans de Goede &buf_len, &shfl_volinfo);
2980fd16957SHans de Goede if (err)
2990fd16957SHans de Goede return err;
3000fd16957SHans de Goede
3010fd16957SHans de Goede stat->f_type = VBOXSF_SUPER_MAGIC;
3020fd16957SHans de Goede stat->f_bsize = shfl_volinfo.bytes_per_allocation_unit;
3030fd16957SHans de Goede
3040fd16957SHans de Goede do_div(shfl_volinfo.total_allocation_bytes,
3050fd16957SHans de Goede shfl_volinfo.bytes_per_allocation_unit);
3060fd16957SHans de Goede stat->f_blocks = shfl_volinfo.total_allocation_bytes;
3070fd16957SHans de Goede
3080fd16957SHans de Goede do_div(shfl_volinfo.available_allocation_bytes,
3090fd16957SHans de Goede shfl_volinfo.bytes_per_allocation_unit);
3100fd16957SHans de Goede stat->f_bfree = shfl_volinfo.available_allocation_bytes;
3110fd16957SHans de Goede stat->f_bavail = shfl_volinfo.available_allocation_bytes;
3120fd16957SHans de Goede
3130fd16957SHans de Goede stat->f_files = 1000;
3140fd16957SHans de Goede /*
3150fd16957SHans de Goede * Don't return 0 here since the guest may then think that it is not
3160fd16957SHans de Goede * possible to create any more files.
3170fd16957SHans de Goede */
3180fd16957SHans de Goede stat->f_ffree = 1000000;
3190fd16957SHans de Goede stat->f_fsid.val[0] = 0;
3200fd16957SHans de Goede stat->f_fsid.val[1] = 0;
3210fd16957SHans de Goede stat->f_namelen = 255;
3220fd16957SHans de Goede return 0;
3230fd16957SHans de Goede }
3240fd16957SHans de Goede
3250fd16957SHans de Goede static struct super_operations vboxsf_super_ops = {
3260fd16957SHans de Goede .alloc_inode = vboxsf_alloc_inode,
3270fd16957SHans de Goede .free_inode = vboxsf_free_inode,
3280fd16957SHans de Goede .put_super = vboxsf_put_super,
3290fd16957SHans de Goede .statfs = vboxsf_statfs,
3300fd16957SHans de Goede };
vboxsf_setup(void)3310fd16957SHans de Goede
3320fd16957SHans de Goede static int vboxsf_setup(void)
3330fd16957SHans de Goede {
3340fd16957SHans de Goede int err;
3350fd16957SHans de Goede
3360fd16957SHans de Goede mutex_lock(&vboxsf_setup_mutex);
3370fd16957SHans de Goede
3380fd16957SHans de Goede if (vboxsf_setup_done)
3390fd16957SHans de Goede goto success;
3400fd16957SHans de Goede
3410fd16957SHans de Goede vboxsf_inode_cachep =
3420fd16957SHans de Goede kmem_cache_create("vboxsf_inode_cache",
3430fd16957SHans de Goede sizeof(struct vboxsf_inode), 0,
3440fd16957SHans de Goede (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD |
3450fd16957SHans de Goede SLAB_ACCOUNT),
3460fd16957SHans de Goede vboxsf_inode_init_once);
3470fd16957SHans de Goede if (!vboxsf_inode_cachep) {
3480fd16957SHans de Goede err = -ENOMEM;
3490fd16957SHans de Goede goto fail_nomem;
3500fd16957SHans de Goede }
3510fd16957SHans de Goede
3520fd16957SHans de Goede err = vboxsf_connect();
3530fd16957SHans de Goede if (err) {
3540fd16957SHans de Goede vbg_err("vboxsf: err %d connecting to guest PCI-device\n", err);
3550fd16957SHans de Goede vbg_err("vboxsf: make sure you are inside a VirtualBox VM\n");
3560fd16957SHans de Goede vbg_err("vboxsf: and check dmesg for vboxguest errors\n");
3570fd16957SHans de Goede goto fail_free_cache;
3580fd16957SHans de Goede }
3590fd16957SHans de Goede
3600fd16957SHans de Goede err = vboxsf_set_utf8();
3610fd16957SHans de Goede if (err) {
3620fd16957SHans de Goede vbg_err("vboxsf_setutf8 error %d\n", err);
3630fd16957SHans de Goede goto fail_disconnect;
3640fd16957SHans de Goede }
3650fd16957SHans de Goede
3660fd16957SHans de Goede if (!follow_symlinks) {
3670fd16957SHans de Goede err = vboxsf_set_symlinks();
3680fd16957SHans de Goede if (err)
3690fd16957SHans de Goede vbg_warn("vboxsf: Unable to show symlinks: %d\n", err);
3700fd16957SHans de Goede }
3710fd16957SHans de Goede
3720fd16957SHans de Goede vboxsf_setup_done = true;
3730fd16957SHans de Goede success:
3740fd16957SHans de Goede mutex_unlock(&vboxsf_setup_mutex);
3750fd16957SHans de Goede return 0;
3760fd16957SHans de Goede
3770fd16957SHans de Goede fail_disconnect:
3780fd16957SHans de Goede vboxsf_disconnect();
3790fd16957SHans de Goede fail_free_cache:
3800fd16957SHans de Goede kmem_cache_destroy(vboxsf_inode_cachep);
3810fd16957SHans de Goede fail_nomem:
3820fd16957SHans de Goede mutex_unlock(&vboxsf_setup_mutex);
3830fd16957SHans de Goede return err;
3840fd16957SHans de Goede }
vboxsf_parse_monolithic(struct fs_context * fc,void * data)3850fd16957SHans de Goede
3860fd16957SHans de Goede static int vboxsf_parse_monolithic(struct fs_context *fc, void *data)
3870fd16957SHans de Goede {
3889b3b353eSLinus Torvalds if (data && !memcmp(data, VBSF_MOUNT_SIGNATURE, 4)) {
3890fd16957SHans de Goede vbg_err("vboxsf: Old binary mount data not supported, remove obsolete mount.vboxsf and/or update your VBoxService.\n");
3900fd16957SHans de Goede return -EINVAL;
3910fd16957SHans de Goede }
3920fd16957SHans de Goede
3930fd16957SHans de Goede return generic_parse_monolithic(fc, data);
3940fd16957SHans de Goede }
vboxsf_get_tree(struct fs_context * fc)3950fd16957SHans de Goede
3960fd16957SHans de Goede static int vboxsf_get_tree(struct fs_context *fc)
3970fd16957SHans de Goede {
3980fd16957SHans de Goede int err;
3990fd16957SHans de Goede
4000fd16957SHans de Goede err = vboxsf_setup();
4010fd16957SHans de Goede if (err)
4020fd16957SHans de Goede return err;
4030fd16957SHans de Goede
4040fd16957SHans de Goede return get_tree_nodev(fc, vboxsf_fill_super);
4050fd16957SHans de Goede }
vboxsf_reconfigure(struct fs_context * fc)4060fd16957SHans de Goede
4070fd16957SHans de Goede static int vboxsf_reconfigure(struct fs_context *fc)
4080fd16957SHans de Goede {
4090fd16957SHans de Goede struct vboxsf_sbi *sbi = VBOXSF_SBI(fc->root->d_sb);
4100fd16957SHans de Goede struct vboxsf_fs_context *ctx = fc->fs_private;
4110fd16957SHans de Goede struct inode *iroot = fc->root->d_sb->s_root->d_inode;
4120fd16957SHans de Goede
4130fd16957SHans de Goede /* Apply changed options to the root inode */
4140fd16957SHans de Goede sbi->o = ctx->o;
415e98f93e7SAl Viro vboxsf_init_inode(sbi, iroot, &sbi->root_info, true);
4160fd16957SHans de Goede
4170fd16957SHans de Goede return 0;
4180fd16957SHans de Goede }
vboxsf_free_fc(struct fs_context * fc)4190fd16957SHans de Goede
4200fd16957SHans de Goede static void vboxsf_free_fc(struct fs_context *fc)
4210fd16957SHans de Goede {
4220fd16957SHans de Goede struct vboxsf_fs_context *ctx = fc->fs_private;
4230fd16957SHans de Goede
4240fd16957SHans de Goede kfree(ctx->nls_name);
4250fd16957SHans de Goede kfree(ctx);
4260fd16957SHans de Goede }
4270fd16957SHans de Goede
4280fd16957SHans de Goede static const struct fs_context_operations vboxsf_context_ops = {
4290fd16957SHans de Goede .free = vboxsf_free_fc,
4300fd16957SHans de Goede .parse_param = vboxsf_parse_param,
4310fd16957SHans de Goede .parse_monolithic = vboxsf_parse_monolithic,
4320fd16957SHans de Goede .get_tree = vboxsf_get_tree,
4330fd16957SHans de Goede .reconfigure = vboxsf_reconfigure,
4340fd16957SHans de Goede };
vboxsf_init_fs_context(struct fs_context * fc)4350fd16957SHans de Goede
4360fd16957SHans de Goede static int vboxsf_init_fs_context(struct fs_context *fc)
4370fd16957SHans de Goede {
4380fd16957SHans de Goede struct vboxsf_fs_context *ctx;
4390fd16957SHans de Goede
4400fd16957SHans de Goede ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
4410fd16957SHans de Goede if (!ctx)
4420fd16957SHans de Goede return -ENOMEM;
4430fd16957SHans de Goede
4440fd16957SHans de Goede current_uid_gid(&ctx->o.uid, &ctx->o.gid);
4450fd16957SHans de Goede
4460fd16957SHans de Goede fc->fs_private = ctx;
4470fd16957SHans de Goede fc->ops = &vboxsf_context_ops;
4480fd16957SHans de Goede return 0;
4490fd16957SHans de Goede }
4500fd16957SHans de Goede
4510fd16957SHans de Goede static struct file_system_type vboxsf_fs_type = {
4520fd16957SHans de Goede .owner = THIS_MODULE,
4530fd16957SHans de Goede .name = "vboxsf",
4540fd16957SHans de Goede .init_fs_context = vboxsf_init_fs_context,
4550fd16957SHans de Goede .kill_sb = kill_anon_super
4560fd16957SHans de Goede };
4570fd16957SHans de Goede
vboxsf_init(void)4580fd16957SHans de Goede /* Module initialization/finalization handlers */
4590fd16957SHans de Goede static int __init vboxsf_init(void)
4600fd16957SHans de Goede {
4610fd16957SHans de Goede return register_filesystem(&vboxsf_fs_type);
4620fd16957SHans de Goede }
vboxsf_fini(void)4630fd16957SHans de Goede
4640fd16957SHans de Goede static void __exit vboxsf_fini(void)
4650fd16957SHans de Goede {
4660fd16957SHans de Goede unregister_filesystem(&vboxsf_fs_type);
4670fd16957SHans de Goede
4680fd16957SHans de Goede mutex_lock(&vboxsf_setup_mutex);
4690fd16957SHans de Goede if (vboxsf_setup_done) {
4700fd16957SHans de Goede vboxsf_disconnect();
4710fd16957SHans de Goede /*
4720fd16957SHans de Goede * Make sure all delayed rcu free inodes are flushed
4730fd16957SHans de Goede * before we destroy the cache.
4740fd16957SHans de Goede */
4750fd16957SHans de Goede rcu_barrier();
4760fd16957SHans de Goede kmem_cache_destroy(vboxsf_inode_cachep);
4770fd16957SHans de Goede }
4780fd16957SHans de Goede mutex_unlock(&vboxsf_setup_mutex);
4790fd16957SHans de Goede }
4800fd16957SHans de Goede
4810fd16957SHans de Goede module_init(vboxsf_init);
4820fd16957SHans de Goede module_exit(vboxsf_fini);
4830fd16957SHans de Goede
4840fd16957SHans de Goede MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access");
4850fd16957SHans de Goede MODULE_AUTHOR("Oracle Corporation");
4860fd16957SHans de Goede MODULE_LICENSE("GPL v2");
4870fd16957SHans de Goede MODULE_ALIAS_FS("vboxsf");
488