root / hw / virtio-9p-xattr.c @ 70fc55eb
History | View | Annotate | Download (3.7 kB)
1 |
/*
|
---|---|
2 |
* Virtio 9p xattr callback
|
3 |
*
|
4 |
* Copyright IBM, Corp. 2010
|
5 |
*
|
6 |
* Authors:
|
7 |
* Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
8 |
*
|
9 |
* This work is licensed under the terms of the GNU GPL, version 2. See
|
10 |
* the COPYING file in the top-level directory.
|
11 |
*
|
12 |
*/
|
13 |
|
14 |
#include "virtio.h" |
15 |
#include "virtio-9p.h" |
16 |
#include "file-op-9p.h" |
17 |
#include "virtio-9p-xattr.h" |
18 |
|
19 |
|
20 |
static XattrOperations *get_xattr_operations(XattrOperations **h,
|
21 |
const char *name) |
22 |
{ |
23 |
XattrOperations *xops; |
24 |
for (xops = *(h)++; xops != NULL; xops = *(h)++) { |
25 |
if (!strncmp(name, xops->name, strlen(xops->name))) {
|
26 |
return xops;
|
27 |
} |
28 |
} |
29 |
return NULL; |
30 |
} |
31 |
|
32 |
ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, |
33 |
const char *name, void *value, size_t size) |
34 |
{ |
35 |
XattrOperations *xops = get_xattr_operations(ctx->xops, name); |
36 |
if (xops) {
|
37 |
return xops->getxattr(ctx, path, name, value, size);
|
38 |
} |
39 |
errno = -EOPNOTSUPP; |
40 |
return -1; |
41 |
} |
42 |
|
43 |
ssize_t pt_listxattr(FsContext *ctx, const char *path, |
44 |
char *name, void *value, size_t size) |
45 |
{ |
46 |
int name_size = strlen(name) + 1; |
47 |
if (!value) {
|
48 |
return name_size;
|
49 |
} |
50 |
|
51 |
if (size < name_size) {
|
52 |
errno = ERANGE; |
53 |
return -1; |
54 |
} |
55 |
|
56 |
strncpy(value, name, name_size); |
57 |
return name_size;
|
58 |
} |
59 |
|
60 |
|
61 |
/*
|
62 |
* Get the list and pass to each layer to find out whether
|
63 |
* to send the data or not
|
64 |
*/
|
65 |
ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, |
66 |
void *value, size_t vsize)
|
67 |
{ |
68 |
ssize_t size = 0;
|
69 |
void *ovalue = value;
|
70 |
XattrOperations *xops; |
71 |
char *orig_value, *orig_value_start;
|
72 |
ssize_t xattr_len, parsed_len = 0, attr_len;
|
73 |
|
74 |
/* Get the actual len */
|
75 |
xattr_len = llistxattr(rpath(ctx, path), value, 0);
|
76 |
|
77 |
/* Now fetch the xattr and find the actual size */
|
78 |
orig_value = qemu_malloc(xattr_len); |
79 |
xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len); |
80 |
|
81 |
/* store the orig pointer */
|
82 |
orig_value_start = orig_value; |
83 |
while (xattr_len > parsed_len) {
|
84 |
xops = get_xattr_operations(ctx->xops, orig_value); |
85 |
if (!xops) {
|
86 |
goto next_entry;
|
87 |
} |
88 |
|
89 |
if (!value) {
|
90 |
size += xops->listxattr(ctx, path, orig_value, value, vsize); |
91 |
} else {
|
92 |
size = xops->listxattr(ctx, path, orig_value, value, vsize); |
93 |
if (size < 0) { |
94 |
goto err_out;
|
95 |
} |
96 |
value += size; |
97 |
vsize -= size; |
98 |
} |
99 |
next_entry:
|
100 |
/* Got the next entry */
|
101 |
attr_len = strlen(orig_value) + 1;
|
102 |
parsed_len += attr_len; |
103 |
orig_value += attr_len; |
104 |
} |
105 |
if (value) {
|
106 |
size = value - ovalue; |
107 |
} |
108 |
|
109 |
err_out:
|
110 |
qemu_free(orig_value_start); |
111 |
return size;
|
112 |
} |
113 |
|
114 |
int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, |
115 |
void *value, size_t size, int flags) |
116 |
{ |
117 |
XattrOperations *xops = get_xattr_operations(ctx->xops, name); |
118 |
if (xops) {
|
119 |
return xops->setxattr(ctx, path, name, value, size, flags);
|
120 |
} |
121 |
errno = -EOPNOTSUPP; |
122 |
return -1; |
123 |
|
124 |
} |
125 |
|
126 |
int v9fs_remove_xattr(FsContext *ctx,
|
127 |
const char *path, const char *name) |
128 |
{ |
129 |
XattrOperations *xops = get_xattr_operations(ctx->xops, name); |
130 |
if (xops) {
|
131 |
return xops->removexattr(ctx, path, name);
|
132 |
} |
133 |
errno = -EOPNOTSUPP; |
134 |
return -1; |
135 |
|
136 |
} |
137 |
|
138 |
XattrOperations *mapped_xattr_ops[] = { |
139 |
&mapped_user_xattr, |
140 |
&mapped_pacl_xattr, |
141 |
&mapped_dacl_xattr, |
142 |
NULL,
|
143 |
}; |
144 |
|
145 |
XattrOperations *passthrough_xattr_ops[] = { |
146 |
&passthrough_user_xattr, |
147 |
&passthrough_acl_xattr, |
148 |
NULL,
|
149 |
}; |
150 |
|
151 |
/* for .user none model should be same as passthrough */
|
152 |
XattrOperations *none_xattr_ops[] = { |
153 |
&passthrough_user_xattr, |
154 |
&none_acl_xattr, |
155 |
NULL,
|
156 |
}; |