xref: /openbmc/linux/fs/vboxsf/file.c (revision e0d77d0f38aa60ca61b3ce6e60d64fad2aa0853d)
10fd16957SHans de Goede // SPDX-License-Identifier: MIT
20fd16957SHans de Goede /*
30fd16957SHans de Goede  * VirtualBox Guest Shared Folders support: Regular file inode and file ops.
40fd16957SHans de Goede  *
50fd16957SHans de Goede  * Copyright (C) 2006-2018 Oracle Corporation
60fd16957SHans de Goede  */
70fd16957SHans de Goede 
80fd16957SHans de Goede #include <linux/mm.h>
90fd16957SHans de Goede #include <linux/page-flags.h>
100fd16957SHans de Goede #include <linux/pagemap.h>
110fd16957SHans de Goede #include <linux/highmem.h>
120fd16957SHans de Goede #include <linux/sizes.h>
130fd16957SHans de Goede #include "vfsmod.h"
140fd16957SHans de Goede 
150fd16957SHans de Goede struct vboxsf_handle {
160fd16957SHans de Goede 	u64 handle;
170fd16957SHans de Goede 	u32 root;
180fd16957SHans de Goede 	u32 access_flags;
190fd16957SHans de Goede 	struct kref refcount;
200fd16957SHans de Goede 	struct list_head head;
210fd16957SHans de Goede };
220fd16957SHans de Goede 
vboxsf_create_sf_handle(struct inode * inode,u64 handle,u32 access_flags)2302f840f9SHans de Goede struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode,
2402f840f9SHans de Goede 					      u64 handle, u32 access_flags)
250fd16957SHans de Goede {
260fd16957SHans de Goede 	struct vboxsf_inode *sf_i = VBOXSF_I(inode);
2702f840f9SHans de Goede 	struct vboxsf_handle *sf_handle;
2802f840f9SHans de Goede 
2902f840f9SHans de Goede 	sf_handle = kmalloc(sizeof(*sf_handle), GFP_KERNEL);
3002f840f9SHans de Goede 	if (!sf_handle)
3102f840f9SHans de Goede 		return ERR_PTR(-ENOMEM);
3202f840f9SHans de Goede 
3302f840f9SHans de Goede 	/* the host may have given us different attr then requested */
3402f840f9SHans de Goede 	sf_i->force_restat = 1;
3502f840f9SHans de Goede 
3602f840f9SHans de Goede 	/* init our handle struct and add it to the inode's handles list */
3702f840f9SHans de Goede 	sf_handle->handle = handle;
3802f840f9SHans de Goede 	sf_handle->root = VBOXSF_SBI(inode->i_sb)->root;
3902f840f9SHans de Goede 	sf_handle->access_flags = access_flags;
4002f840f9SHans de Goede 	kref_init(&sf_handle->refcount);
4102f840f9SHans de Goede 
4202f840f9SHans de Goede 	mutex_lock(&sf_i->handle_list_mutex);
4302f840f9SHans de Goede 	list_add(&sf_handle->head, &sf_i->handle_list);
4402f840f9SHans de Goede 	mutex_unlock(&sf_i->handle_list_mutex);
4502f840f9SHans de Goede 
4602f840f9SHans de Goede 	return sf_handle;
4702f840f9SHans de Goede }
4802f840f9SHans de Goede 
vboxsf_file_open(struct inode * inode,struct file * file)4902f840f9SHans de Goede static int vboxsf_file_open(struct inode *inode, struct file *file)
5002f840f9SHans de Goede {
5102f840f9SHans de Goede 	struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
520fd16957SHans de Goede 	struct shfl_createparms params = {};
530fd16957SHans de Goede 	struct vboxsf_handle *sf_handle;
540fd16957SHans de Goede 	u32 access_flags = 0;
550fd16957SHans de Goede 	int err;
560fd16957SHans de Goede 
570fd16957SHans de Goede 	/*
580fd16957SHans de Goede 	 * We check the value of params.handle afterwards to find out if
590fd16957SHans de Goede 	 * the call succeeded or failed, as the API does not seem to cleanly
600fd16957SHans de Goede 	 * distinguish error and informational messages.
610fd16957SHans de Goede 	 *
620fd16957SHans de Goede 	 * Furthermore, we must set params.handle to SHFL_HANDLE_NIL to
630fd16957SHans de Goede 	 * make the shared folders host service use our mode parameter.
640fd16957SHans de Goede 	 */
650fd16957SHans de Goede 	params.handle = SHFL_HANDLE_NIL;
660fd16957SHans de Goede 	if (file->f_flags & O_CREAT) {
670fd16957SHans de Goede 		params.create_flags |= SHFL_CF_ACT_CREATE_IF_NEW;
680fd16957SHans de Goede 		/*
690fd16957SHans de Goede 		 * We ignore O_EXCL, as the Linux kernel seems to call create
700fd16957SHans de Goede 		 * beforehand itself, so O_EXCL should always fail.
710fd16957SHans de Goede 		 */
720fd16957SHans de Goede 		if (file->f_flags & O_TRUNC)
730fd16957SHans de Goede 			params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
740fd16957SHans de Goede 		else
750fd16957SHans de Goede 			params.create_flags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
760fd16957SHans de Goede 	} else {
770fd16957SHans de Goede 		params.create_flags |= SHFL_CF_ACT_FAIL_IF_NEW;
780fd16957SHans de Goede 		if (file->f_flags & O_TRUNC)
790fd16957SHans de Goede 			params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
800fd16957SHans de Goede 	}
810fd16957SHans de Goede 
820fd16957SHans de Goede 	switch (file->f_flags & O_ACCMODE) {
830fd16957SHans de Goede 	case O_RDONLY:
840fd16957SHans de Goede 		access_flags |= SHFL_CF_ACCESS_READ;
850fd16957SHans de Goede 		break;
860fd16957SHans de Goede 
870fd16957SHans de Goede 	case O_WRONLY:
880fd16957SHans de Goede 		access_flags |= SHFL_CF_ACCESS_WRITE;
890fd16957SHans de Goede 		break;
900fd16957SHans de Goede 
910fd16957SHans de Goede 	case O_RDWR:
920fd16957SHans de Goede 		access_flags |= SHFL_CF_ACCESS_READWRITE;
930fd16957SHans de Goede 		break;
940fd16957SHans de Goede 
950fd16957SHans de Goede 	default:
960fd16957SHans de Goede 		WARN_ON(1);
970fd16957SHans de Goede 	}
980fd16957SHans de Goede 
990fd16957SHans de Goede 	if (file->f_flags & O_APPEND)
1000fd16957SHans de Goede 		access_flags |= SHFL_CF_ACCESS_APPEND;
1010fd16957SHans de Goede 
1020fd16957SHans de Goede 	params.create_flags |= access_flags;
1030fd16957SHans de Goede 	params.info.attr.mode = inode->i_mode;
1040fd16957SHans de Goede 
1050fd16957SHans de Goede 	err = vboxsf_create_at_dentry(file_dentry(file), &params);
1060fd16957SHans de Goede 	if (err == 0 && params.handle == SHFL_HANDLE_NIL)
1070fd16957SHans de Goede 		err = (params.result == SHFL_FILE_EXISTS) ? -EEXIST : -ENOENT;
10802f840f9SHans de Goede 	if (err)
1090fd16957SHans de Goede 		return err;
11002f840f9SHans de Goede 
11102f840f9SHans de Goede 	sf_handle = vboxsf_create_sf_handle(inode, params.handle, access_flags);
11202f840f9SHans de Goede 	if (IS_ERR(sf_handle)) {
11302f840f9SHans de Goede 		vboxsf_close(sbi->root, params.handle);
11402f840f9SHans de Goede 		return PTR_ERR(sf_handle);
1150fd16957SHans de Goede 	}
1160fd16957SHans de Goede 
1170fd16957SHans de Goede 	file->private_data = sf_handle;
1180fd16957SHans de Goede 	return 0;
1190fd16957SHans de Goede }
1200fd16957SHans de Goede 
vboxsf_handle_release(struct kref * refcount)1210fd16957SHans de Goede static void vboxsf_handle_release(struct kref *refcount)
1220fd16957SHans de Goede {
1230fd16957SHans de Goede 	struct vboxsf_handle *sf_handle =
1240fd16957SHans de Goede 		container_of(refcount, struct vboxsf_handle, refcount);
1250fd16957SHans de Goede 
1260fd16957SHans de Goede 	vboxsf_close(sf_handle->root, sf_handle->handle);
1270fd16957SHans de Goede 	kfree(sf_handle);
1280fd16957SHans de Goede }
1290fd16957SHans de Goede 
vboxsf_release_sf_handle(struct inode * inode,struct vboxsf_handle * sf_handle)13002f840f9SHans de Goede void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle)
1310fd16957SHans de Goede {
1320fd16957SHans de Goede 	struct vboxsf_inode *sf_i = VBOXSF_I(inode);
1330fd16957SHans de Goede 
1340fd16957SHans de Goede 	mutex_lock(&sf_i->handle_list_mutex);
1350fd16957SHans de Goede 	list_del(&sf_handle->head);
1360fd16957SHans de Goede 	mutex_unlock(&sf_i->handle_list_mutex);
1370fd16957SHans de Goede 
1380fd16957SHans de Goede 	kref_put(&sf_handle->refcount, vboxsf_handle_release);
13902f840f9SHans de Goede }
14002f840f9SHans de Goede 
vboxsf_file_release(struct inode * inode,struct file * file)14102f840f9SHans de Goede static int vboxsf_file_release(struct inode *inode, struct file *file)
14202f840f9SHans de Goede {
14302f840f9SHans de Goede 	/*
14402f840f9SHans de Goede 	 * When a file is closed on our (the guest) side, we want any subsequent
14502f840f9SHans de Goede 	 * accesses done on the host side to see all changes done from our side.
14602f840f9SHans de Goede 	 */
14702f840f9SHans de Goede 	filemap_write_and_wait(inode->i_mapping);
14802f840f9SHans de Goede 
14902f840f9SHans de Goede 	vboxsf_release_sf_handle(inode, file->private_data);
1500fd16957SHans de Goede 	return 0;
1510fd16957SHans de Goede }
1520fd16957SHans de Goede 
1530fd16957SHans de Goede /*
1540fd16957SHans de Goede  * Write back dirty pages now, because there may not be any suitable
1550fd16957SHans de Goede  * open files later
1560fd16957SHans de Goede  */
vboxsf_vma_close(struct vm_area_struct * vma)1570fd16957SHans de Goede static void vboxsf_vma_close(struct vm_area_struct *vma)
1580fd16957SHans de Goede {
1590fd16957SHans de Goede 	filemap_write_and_wait(vma->vm_file->f_mapping);
1600fd16957SHans de Goede }
1610fd16957SHans de Goede 
1620fd16957SHans de Goede static const struct vm_operations_struct vboxsf_file_vm_ops = {
1630fd16957SHans de Goede 	.close		= vboxsf_vma_close,
1640fd16957SHans de Goede 	.fault		= filemap_fault,
1650fd16957SHans de Goede 	.map_pages	= filemap_map_pages,
1660fd16957SHans de Goede };
1670fd16957SHans de Goede 
vboxsf_file_mmap(struct file * file,struct vm_area_struct * vma)1680fd16957SHans de Goede static int vboxsf_file_mmap(struct file *file, struct vm_area_struct *vma)
1690fd16957SHans de Goede {
1700fd16957SHans de Goede 	int err;
1710fd16957SHans de Goede 
1720fd16957SHans de Goede 	err = generic_file_mmap(file, vma);
1730fd16957SHans de Goede 	if (!err)
1740fd16957SHans de Goede 		vma->vm_ops = &vboxsf_file_vm_ops;
1750fd16957SHans de Goede 
1760fd16957SHans de Goede 	return err;
1770fd16957SHans de Goede }
1780fd16957SHans de Goede 
1790fd16957SHans de Goede /*
1800fd16957SHans de Goede  * Note that since we are accessing files on the host's filesystem, files
1810fd16957SHans de Goede  * may always be changed underneath us by the host!
1820fd16957SHans de Goede  *
1830fd16957SHans de Goede  * The vboxsf API between the guest and the host does not offer any functions
1840fd16957SHans de Goede  * to deal with this. There is no inode-generation to check for changes, no
1850fd16957SHans de Goede  * events / callback on changes and no way to lock files.
1860fd16957SHans de Goede  *
1870fd16957SHans de Goede  * To avoid returning stale data when a file gets *opened* on our (the guest)
1880fd16957SHans de Goede  * side, we do a "stat" on the host side, then compare the mtime with the
1890fd16957SHans de Goede  * last known mtime and invalidate the page-cache if they differ.
1900fd16957SHans de Goede  * This is done from vboxsf_inode_revalidate().
1910fd16957SHans de Goede  *
1920fd16957SHans de Goede  * When reads are done through the read_iter fop, it is possible to do
1930fd16957SHans de Goede  * further cache revalidation then, there are 3 options to deal with this:
1940fd16957SHans de Goede  *
1950fd16957SHans de Goede  * 1)  Rely solely on the revalidation done at open time
1960fd16957SHans de Goede  * 2)  Do another "stat" and compare mtime again. Unfortunately the vboxsf
1970fd16957SHans de Goede  *     host API does not allow stat on handles, so we would need to use
1980fd16957SHans de Goede  *     file->f_path.dentry and the stat will then fail if the file was unlinked
1990fd16957SHans de Goede  *     or renamed (and there is no thing like NFS' silly-rename). So we get:
2000fd16957SHans de Goede  * 2a) "stat" and compare mtime, on stat failure invalidate the cache
2010fd16957SHans de Goede  * 2b) "stat" and compare mtime, on stat failure do nothing
2020fd16957SHans de Goede  * 3)  Simply always call invalidate_inode_pages2_range on the range of the read
2030fd16957SHans de Goede  *
2040fd16957SHans de Goede  * Currently we are keeping things KISS and using option 1. this allows
2050fd16957SHans de Goede  * directly using generic_file_read_iter without wrapping it.
2060fd16957SHans de Goede  *
2070fd16957SHans de Goede  * This means that only data written on the host side before open() on
2080fd16957SHans de Goede  * the guest side is guaranteed to be seen by the guest. If necessary
2090fd16957SHans de Goede  * we may provide other read-cache strategies in the future and make this
2100fd16957SHans de Goede  * configurable through a mount option.
2110fd16957SHans de Goede  */
2120fd16957SHans de Goede const struct file_operations vboxsf_reg_fops = {
2130fd16957SHans de Goede 	.llseek = generic_file_llseek,
2140fd16957SHans de Goede 	.read_iter = generic_file_read_iter,
2150fd16957SHans de Goede 	.write_iter = generic_file_write_iter,
2160fd16957SHans de Goede 	.mmap = vboxsf_file_mmap,
2170fd16957SHans de Goede 	.open = vboxsf_file_open,
2180fd16957SHans de Goede 	.release = vboxsf_file_release,
2190fd16957SHans de Goede 	.fsync = noop_fsync,
2202cb1e089SDavid Howells 	.splice_read = filemap_splice_read,
221*9872ab5bSJeff Layton 	.setlease = simple_nosetlease,
2220fd16957SHans de Goede };
2230fd16957SHans de Goede 
2240fd16957SHans de Goede const struct inode_operations vboxsf_reg_iops = {
2250fd16957SHans de Goede 	.getattr = vboxsf_getattr,
2260fd16957SHans de Goede 	.setattr = vboxsf_setattr
2270fd16957SHans de Goede };
2280fd16957SHans de Goede 
vboxsf_read_folio(struct file * file,struct folio * folio)2294b4db9b4SMatthew Wilcox (Oracle) static int vboxsf_read_folio(struct file *file, struct folio *folio)
2300fd16957SHans de Goede {
2314b4db9b4SMatthew Wilcox (Oracle) 	struct page *page = &folio->page;
2320fd16957SHans de Goede 	struct vboxsf_handle *sf_handle = file->private_data;
2330fd16957SHans de Goede 	loff_t off = page_offset(page);
2340fd16957SHans de Goede 	u32 nread = PAGE_SIZE;
2350fd16957SHans de Goede 	u8 *buf;
2360fd16957SHans de Goede 	int err;
2370fd16957SHans de Goede 
2380fd16957SHans de Goede 	buf = kmap(page);
2390fd16957SHans de Goede 
2400fd16957SHans de Goede 	err = vboxsf_read(sf_handle->root, sf_handle->handle, off, &nread, buf);
2410fd16957SHans de Goede 	if (err == 0) {
2420fd16957SHans de Goede 		memset(&buf[nread], 0, PAGE_SIZE - nread);
2430fd16957SHans de Goede 		flush_dcache_page(page);
2440fd16957SHans de Goede 		SetPageUptodate(page);
2450fd16957SHans de Goede 	} else {
2460fd16957SHans de Goede 		SetPageError(page);
2470fd16957SHans de Goede 	}
2480fd16957SHans de Goede 
2490fd16957SHans de Goede 	kunmap(page);
2500fd16957SHans de Goede 	unlock_page(page);
2510fd16957SHans de Goede 	return err;
2520fd16957SHans de Goede }
2530fd16957SHans de Goede 
vboxsf_get_write_handle(struct vboxsf_inode * sf_i)2540fd16957SHans de Goede static struct vboxsf_handle *vboxsf_get_write_handle(struct vboxsf_inode *sf_i)
2550fd16957SHans de Goede {
2560fd16957SHans de Goede 	struct vboxsf_handle *h, *sf_handle = NULL;
2570fd16957SHans de Goede 
2580fd16957SHans de Goede 	mutex_lock(&sf_i->handle_list_mutex);
2590fd16957SHans de Goede 	list_for_each_entry(h, &sf_i->handle_list, head) {
2600fd16957SHans de Goede 		if (h->access_flags == SHFL_CF_ACCESS_WRITE ||
2610fd16957SHans de Goede 		    h->access_flags == SHFL_CF_ACCESS_READWRITE) {
2620fd16957SHans de Goede 			kref_get(&h->refcount);
2630fd16957SHans de Goede 			sf_handle = h;
2640fd16957SHans de Goede 			break;
2650fd16957SHans de Goede 		}
2660fd16957SHans de Goede 	}
2670fd16957SHans de Goede 	mutex_unlock(&sf_i->handle_list_mutex);
2680fd16957SHans de Goede 
2690fd16957SHans de Goede 	return sf_handle;
2700fd16957SHans de Goede }
2710fd16957SHans de Goede 
vboxsf_writepage(struct page * page,struct writeback_control * wbc)2720fd16957SHans de Goede static int vboxsf_writepage(struct page *page, struct writeback_control *wbc)
2730fd16957SHans de Goede {
2740fd16957SHans de Goede 	struct inode *inode = page->mapping->host;
2750fd16957SHans de Goede 	struct vboxsf_inode *sf_i = VBOXSF_I(inode);
2760fd16957SHans de Goede 	struct vboxsf_handle *sf_handle;
2770fd16957SHans de Goede 	loff_t off = page_offset(page);
2780fd16957SHans de Goede 	loff_t size = i_size_read(inode);
2790fd16957SHans de Goede 	u32 nwrite = PAGE_SIZE;
2800fd16957SHans de Goede 	u8 *buf;
2810fd16957SHans de Goede 	int err;
2820fd16957SHans de Goede 
2830fd16957SHans de Goede 	if (off + PAGE_SIZE > size)
2840fd16957SHans de Goede 		nwrite = size & ~PAGE_MASK;
2850fd16957SHans de Goede 
2860fd16957SHans de Goede 	sf_handle = vboxsf_get_write_handle(sf_i);
2870fd16957SHans de Goede 	if (!sf_handle)
2880fd16957SHans de Goede 		return -EBADF;
2890fd16957SHans de Goede 
2900fd16957SHans de Goede 	buf = kmap(page);
2910fd16957SHans de Goede 	err = vboxsf_write(sf_handle->root, sf_handle->handle,
2920fd16957SHans de Goede 			   off, &nwrite, buf);
2930fd16957SHans de Goede 	kunmap(page);
2940fd16957SHans de Goede 
2950fd16957SHans de Goede 	kref_put(&sf_handle->refcount, vboxsf_handle_release);
2960fd16957SHans de Goede 
2970fd16957SHans de Goede 	if (err == 0) {
2980fd16957SHans de Goede 		ClearPageError(page);
2990fd16957SHans de Goede 		/* mtime changed */
3000fd16957SHans de Goede 		sf_i->force_restat = 1;
3010fd16957SHans de Goede 	} else {
3020fd16957SHans de Goede 		ClearPageUptodate(page);
3030fd16957SHans de Goede 	}
3040fd16957SHans de Goede 
3050fd16957SHans de Goede 	unlock_page(page);
3060fd16957SHans de Goede 	return err;
3070fd16957SHans de Goede }
3080fd16957SHans de Goede 
vboxsf_write_end(struct file * file,struct address_space * mapping,loff_t pos,unsigned int len,unsigned int copied,struct page * page,void * fsdata)3090fd16957SHans de Goede static int vboxsf_write_end(struct file *file, struct address_space *mapping,
3100fd16957SHans de Goede 			    loff_t pos, unsigned int len, unsigned int copied,
3110fd16957SHans de Goede 			    struct page *page, void *fsdata)
3120fd16957SHans de Goede {
3130fd16957SHans de Goede 	struct inode *inode = mapping->host;
3140fd16957SHans de Goede 	struct vboxsf_handle *sf_handle = file->private_data;
3150fd16957SHans de Goede 	unsigned int from = pos & ~PAGE_MASK;
3160fd16957SHans de Goede 	u32 nwritten = len;
3170fd16957SHans de Goede 	u8 *buf;
3180fd16957SHans de Goede 	int err;
3190fd16957SHans de Goede 
3200fd16957SHans de Goede 	/* zero the stale part of the page if we did a short copy */
3210fd16957SHans de Goede 	if (!PageUptodate(page) && copied < len)
3220fd16957SHans de Goede 		zero_user(page, from + copied, len - copied);
3230fd16957SHans de Goede 
3240fd16957SHans de Goede 	buf = kmap(page);
3250fd16957SHans de Goede 	err = vboxsf_write(sf_handle->root, sf_handle->handle,
3260fd16957SHans de Goede 			   pos, &nwritten, buf + from);
3270fd16957SHans de Goede 	kunmap(page);
3280fd16957SHans de Goede 
3290fd16957SHans de Goede 	if (err) {
3300fd16957SHans de Goede 		nwritten = 0;
3310fd16957SHans de Goede 		goto out;
3320fd16957SHans de Goede 	}
3330fd16957SHans de Goede 
3340fd16957SHans de Goede 	/* mtime changed */
3350fd16957SHans de Goede 	VBOXSF_I(inode)->force_restat = 1;
3360fd16957SHans de Goede 
3370fd16957SHans de Goede 	if (!PageUptodate(page) && nwritten == PAGE_SIZE)
3380fd16957SHans de Goede 		SetPageUptodate(page);
3390fd16957SHans de Goede 
3400fd16957SHans de Goede 	pos += nwritten;
3410fd16957SHans de Goede 	if (pos > inode->i_size)
3420fd16957SHans de Goede 		i_size_write(inode, pos);
3430fd16957SHans de Goede 
3440fd16957SHans de Goede out:
3450fd16957SHans de Goede 	unlock_page(page);
3460fd16957SHans de Goede 	put_page(page);
3470fd16957SHans de Goede 
3480fd16957SHans de Goede 	return nwritten;
3490fd16957SHans de Goede }
3500fd16957SHans de Goede 
3510fd16957SHans de Goede /*
3520fd16957SHans de Goede  * Note simple_write_begin does not read the page from disk on partial writes
3530fd16957SHans de Goede  * this is ok since vboxsf_write_end only writes the written parts of the
3540fd16957SHans de Goede  * page and it does not call SetPageUptodate for partial writes.
3550fd16957SHans de Goede  */
3560fd16957SHans de Goede const struct address_space_operations vboxsf_reg_aops = {
3574b4db9b4SMatthew Wilcox (Oracle) 	.read_folio = vboxsf_read_folio,
3580fd16957SHans de Goede 	.writepage = vboxsf_writepage,
359187c82cbSMatthew Wilcox (Oracle) 	.dirty_folio = filemap_dirty_folio,
3600fd16957SHans de Goede 	.write_begin = simple_write_begin,
3610fd16957SHans de Goede 	.write_end = vboxsf_write_end,
3620fd16957SHans de Goede };
3630fd16957SHans de Goede 
vboxsf_get_link(struct dentry * dentry,struct inode * inode,struct delayed_call * done)3640fd16957SHans de Goede static const char *vboxsf_get_link(struct dentry *dentry, struct inode *inode,
3650fd16957SHans de Goede 				   struct delayed_call *done)
3660fd16957SHans de Goede {
3670fd16957SHans de Goede 	struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
3680fd16957SHans de Goede 	struct shfl_string *path;
3690fd16957SHans de Goede 	char *link;
3700fd16957SHans de Goede 	int err;
3710fd16957SHans de Goede 
3720fd16957SHans de Goede 	if (!dentry)
3730fd16957SHans de Goede 		return ERR_PTR(-ECHILD);
3740fd16957SHans de Goede 
3750fd16957SHans de Goede 	path = vboxsf_path_from_dentry(sbi, dentry);
3760fd16957SHans de Goede 	if (IS_ERR(path))
3770fd16957SHans de Goede 		return ERR_CAST(path);
3780fd16957SHans de Goede 
3790fd16957SHans de Goede 	link = kzalloc(PATH_MAX, GFP_KERNEL);
3800fd16957SHans de Goede 	if (!link) {
3810fd16957SHans de Goede 		__putname(path);
3820fd16957SHans de Goede 		return ERR_PTR(-ENOMEM);
3830fd16957SHans de Goede 	}
3840fd16957SHans de Goede 
3850fd16957SHans de Goede 	err = vboxsf_readlink(sbi->root, path, PATH_MAX, link);
3860fd16957SHans de Goede 	__putname(path);
3870fd16957SHans de Goede 	if (err) {
3880fd16957SHans de Goede 		kfree(link);
3890fd16957SHans de Goede 		return ERR_PTR(err);
3900fd16957SHans de Goede 	}
3910fd16957SHans de Goede 
3920fd16957SHans de Goede 	set_delayed_call(done, kfree_link, link);
3930fd16957SHans de Goede 	return link;
3940fd16957SHans de Goede }
3950fd16957SHans de Goede 
3960fd16957SHans de Goede const struct inode_operations vboxsf_lnk_iops = {
3970fd16957SHans de Goede 	.get_link = vboxsf_get_link
3980fd16957SHans de Goede };
399