This repository has been archived by the owner on Jun 29, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsymlink.c
70 lines (61 loc) · 1.72 KB
/
symlink.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// SPDX-License-Identifier: GPL-2.0
/*
* linux/fs/apfs/symlink.c
*
* Copyright (C) 2018 Ernesto A. Fernández <[email protected]>
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include "apfs.h"
#include "message.h"
#include "xattr.h"
/**
* apfs_get_link - Follow a symbolic link
* @dentry: dentry for the link
* @inode: inode for the link
* @done: delayed call to free the returned buffer after use
*
* Returns a pointer to a buffer containing the target path, or an appropriate
* error pointer in case of failure.
*/
static const char *apfs_get_link(struct dentry *dentry, struct inode *inode,
struct delayed_call *done)
{
struct super_block *sb = inode->i_sb;
char *target, *err;
int size;
if (!dentry)
return ERR_PTR(-ECHILD);
size = apfs_xattr_get(inode, APFS_XATTR_NAME_SYMLINK,
NULL /* buffer */, 0 /* size */);
if (size < 0) /* TODO: return a better error code */
return ERR_PTR(size);
target = kmalloc(size, GFP_KERNEL);
if (!target)
return ERR_PTR(-ENOMEM);
size = apfs_xattr_get(inode, APFS_XATTR_NAME_SYMLINK, target, size);
if (size < 0) {
err = ERR_PTR(size);
goto fail;
}
if (size == 0 || *(target + size - 1) != 0) {
/* Target path must be NULL-terminated */
apfs_alert(sb, "bad link target in inode 0x%llx",
(unsigned long long) inode->i_ino);
err = ERR_PTR(-EFSCORRUPTED);
goto fail;
}
set_delayed_call(done, kfree_link, target);
return target;
fail:
kfree(target);
return err;
}
const struct inode_operations apfs_symlink_inode_operations = {
.get_link = apfs_get_link,
.getattr = apfs_getattr,
.listxattr = apfs_listxattr,
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) /* Now this is the default */
.readlink = generic_readlink,
#endif
};