]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - ubuntu/vbox/vboxsf/lnkops.c
UBUNTU: SAUCE: vbox -- remove .readlink assignment
[mirror_ubuntu-zesty-kernel.git] / ubuntu / vbox / vboxsf / lnkops.c
CommitLineData
39adb5c3
TG
1/** @file
2 *
3 * vboxsf -- VirtualBox Guest Additions for Linux:
4 * Operations for symbolic links.
5 */
6
7/*
8 * Copyright (C) 2010-2016 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "vfsmod.h"
20
21#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
22
23# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
24# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
25static const char *sf_follow_link(struct dentry *dentry, void **cookie)
26# else
27static void *sf_follow_link(struct dentry *dentry, struct nameidata *nd)
28# endif
29{
30 struct inode *inode = dentry->d_inode;
31 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
32 struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
33 int error = -ENOMEM;
34 char *path = (char*)get_zeroed_page(GFP_KERNEL);
35 int rc;
36
37 if (path)
38 {
39 error = 0;
40 rc = VbglR0SfReadLink(&client_handle, &sf_g->map, sf_i->path, PATH_MAX, path);
41 if (RT_FAILURE(rc))
42 {
43 LogFunc(("VbglR0SfReadLink failed, caller=%s, rc=%Rrc\n", __func__, rc));
44 free_page((unsigned long)path);
45 error = -EPROTO;
46 }
47 }
48# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
49 return error ? ERR_PTR(error) : (*cookie = path);
50# else
51 nd_set_link(nd, error ? ERR_PTR(error) : path);
52 return NULL;
53# endif
54}
55
56# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
57static void sf_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
58{
59 char *page = nd_get_link(nd);
60 if (!IS_ERR(page))
61 free_page((unsigned long)page);
62}
63# endif
64
65# else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) */
66static const char *sf_get_link(struct dentry *dentry, struct inode *inode,
67 struct delayed_call *done)
68{
69 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
70 struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
71 char *path;
72 int rc;
73
74 if (!dentry)
75 return ERR_PTR(-ECHILD);
76 path = kzalloc(PAGE_SIZE, GFP_KERNEL);
77 if (!path)
78 return ERR_PTR(-ENOMEM);
79 rc = VbglR0SfReadLink(&client_handle, &sf_g->map, sf_i->path, PATH_MAX, path);
80 if (RT_FAILURE(rc))
81 {
82 LogFunc(("VbglR0SfReadLink failed, caller=%s, rc=%Rrc\n", __func__, rc));
83 kfree(path);
84 return ERR_PTR(-EPROTO);
85 }
86 set_delayed_call(done, kfree_link, path);
87 return path;
88}
89# endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) */
90
91struct inode_operations sf_lnk_iops =
92{
39adb5c3
TG
93# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
94 .get_link = sf_get_link
95# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
96 .follow_link = sf_follow_link,
97 .put_link = free_page_put_link,
98# else
99 .follow_link = sf_follow_link,
100 .put_link = sf_put_link
101# endif
102};
103
104#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */