]>
Commit | Line | Data |
---|---|---|
d3e3b7ea DH |
1 | /* Extended attribute handling for AFS. We use xattrs to get and set metadata |
2 | * instead of providing pioctl(). | |
3 | * | |
4 | * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. | |
5 | * Written by David Howells ([email protected]) | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public Licence | |
9 | * as published by the Free Software Foundation; either version | |
10 | * 2 of the Licence, or (at your option) any later version. | |
11 | */ | |
12 | ||
13 | #include <linux/slab.h> | |
14 | #include <linux/fs.h> | |
15 | #include <linux/xattr.h> | |
16 | #include "internal.h" | |
17 | ||
18 | static const char afs_xattr_list[] = | |
19 | "afs.cell\0" | |
20 | "afs.fid\0" | |
21 | "afs.volume"; | |
22 | ||
23 | /* | |
24 | * Retrieve a list of the supported xattrs. | |
25 | */ | |
26 | ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |
27 | { | |
28 | if (size == 0) | |
29 | return sizeof(afs_xattr_list); | |
30 | if (size < sizeof(afs_xattr_list)) | |
31 | return -ERANGE; | |
32 | memcpy(buffer, afs_xattr_list, sizeof(afs_xattr_list)); | |
33 | return sizeof(afs_xattr_list); | |
34 | } | |
35 | ||
36 | /* | |
37 | * Get the name of the cell on which a file resides. | |
38 | */ | |
39 | static int afs_xattr_get_cell(const struct xattr_handler *handler, | |
40 | struct dentry *dentry, | |
41 | struct inode *inode, const char *name, | |
42 | void *buffer, size_t size) | |
43 | { | |
44 | struct afs_vnode *vnode = AFS_FS_I(inode); | |
45 | struct afs_cell *cell = vnode->volume->cell; | |
46 | size_t namelen; | |
47 | ||
989782dc | 48 | namelen = cell->name_len; |
d3e3b7ea DH |
49 | if (size == 0) |
50 | return namelen; | |
51 | if (namelen > size) | |
52 | return -ERANGE; | |
53 | memcpy(buffer, cell->name, size); | |
54 | return namelen; | |
55 | } | |
56 | ||
57 | static const struct xattr_handler afs_xattr_afs_cell_handler = { | |
58 | .name = "afs.cell", | |
59 | .get = afs_xattr_get_cell, | |
60 | }; | |
61 | ||
62 | /* | |
63 | * Get the volume ID, vnode ID and vnode uniquifier of a file as a sequence of | |
64 | * hex numbers separated by colons. | |
65 | */ | |
66 | static int afs_xattr_get_fid(const struct xattr_handler *handler, | |
67 | struct dentry *dentry, | |
68 | struct inode *inode, const char *name, | |
69 | void *buffer, size_t size) | |
70 | { | |
71 | struct afs_vnode *vnode = AFS_FS_I(inode); | |
72 | char text[8 + 1 + 8 + 1 + 8 + 1]; | |
73 | size_t len; | |
74 | ||
3b6492df | 75 | len = sprintf(text, "%llx:%llx:%x", |
d3e3b7ea DH |
76 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); |
77 | if (size == 0) | |
78 | return len; | |
79 | if (len > size) | |
80 | return -ERANGE; | |
81 | memcpy(buffer, text, len); | |
82 | return len; | |
83 | } | |
84 | ||
85 | static const struct xattr_handler afs_xattr_afs_fid_handler = { | |
86 | .name = "afs.fid", | |
87 | .get = afs_xattr_get_fid, | |
88 | }; | |
89 | ||
90 | /* | |
91 | * Get the name of the volume on which a file resides. | |
92 | */ | |
93 | static int afs_xattr_get_volume(const struct xattr_handler *handler, | |
94 | struct dentry *dentry, | |
95 | struct inode *inode, const char *name, | |
96 | void *buffer, size_t size) | |
97 | { | |
98 | struct afs_vnode *vnode = AFS_FS_I(inode); | |
d2ddc776 | 99 | const char *volname = vnode->volume->name; |
d3e3b7ea DH |
100 | size_t namelen; |
101 | ||
102 | namelen = strlen(volname); | |
103 | if (size == 0) | |
104 | return namelen; | |
105 | if (namelen > size) | |
106 | return -ERANGE; | |
107 | memcpy(buffer, volname, size); | |
108 | return namelen; | |
109 | } | |
110 | ||
111 | static const struct xattr_handler afs_xattr_afs_volume_handler = { | |
112 | .name = "afs.volume", | |
113 | .get = afs_xattr_get_volume, | |
114 | }; | |
115 | ||
116 | const struct xattr_handler *afs_xattr_handlers[] = { | |
117 | &afs_xattr_afs_cell_handler, | |
118 | &afs_xattr_afs_fid_handler, | |
119 | &afs_xattr_afs_volume_handler, | |
120 | NULL | |
121 | }; |