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