]>
Commit | Line | Data |
---|---|---|
fc22118d AK |
1 | /* |
2 | * Virtio 9p xattr callback | |
3 | * | |
4 | * Copyright IBM, Corp. 2010 | |
5 | * | |
6 | * Authors: | |
7 | * Aneesh Kumar K.V <[email protected]> | |
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); | |
0562c674 KK |
76 | if (xattr_len <= 0) { |
77 | return xattr_len; | |
78 | } | |
fc22118d AK |
79 | |
80 | /* Now fetch the xattr and find the actual size */ | |
81 | orig_value = qemu_malloc(xattr_len); | |
82 | xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len); | |
83 | ||
84 | /* store the orig pointer */ | |
85 | orig_value_start = orig_value; | |
86 | while (xattr_len > parsed_len) { | |
87 | xops = get_xattr_operations(ctx->xops, orig_value); | |
88 | if (!xops) { | |
89 | goto next_entry; | |
90 | } | |
91 | ||
92 | if (!value) { | |
93 | size += xops->listxattr(ctx, path, orig_value, value, vsize); | |
94 | } else { | |
95 | size = xops->listxattr(ctx, path, orig_value, value, vsize); | |
96 | if (size < 0) { | |
97 | goto err_out; | |
98 | } | |
99 | value += size; | |
100 | vsize -= size; | |
101 | } | |
102 | next_entry: | |
103 | /* Got the next entry */ | |
104 | attr_len = strlen(orig_value) + 1; | |
105 | parsed_len += attr_len; | |
106 | orig_value += attr_len; | |
107 | } | |
108 | if (value) { | |
109 | size = value - ovalue; | |
110 | } | |
111 | ||
112 | err_out: | |
113 | qemu_free(orig_value_start); | |
114 | return size; | |
115 | } | |
116 | ||
117 | int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, | |
118 | void *value, size_t size, int flags) | |
119 | { | |
120 | XattrOperations *xops = get_xattr_operations(ctx->xops, name); | |
121 | if (xops) { | |
122 | return xops->setxattr(ctx, path, name, value, size, flags); | |
123 | } | |
124 | errno = -EOPNOTSUPP; | |
125 | return -1; | |
126 | ||
127 | } | |
128 | ||
129 | int v9fs_remove_xattr(FsContext *ctx, | |
130 | const char *path, const char *name) | |
131 | { | |
132 | XattrOperations *xops = get_xattr_operations(ctx->xops, name); | |
133 | if (xops) { | |
134 | return xops->removexattr(ctx, path, name); | |
135 | } | |
136 | errno = -EOPNOTSUPP; | |
137 | return -1; | |
138 | ||
139 | } | |
140 | ||
141 | XattrOperations *mapped_xattr_ops[] = { | |
142 | &mapped_user_xattr, | |
70fc55eb AK |
143 | &mapped_pacl_xattr, |
144 | &mapped_dacl_xattr, | |
fc22118d AK |
145 | NULL, |
146 | }; | |
147 | ||
148 | XattrOperations *passthrough_xattr_ops[] = { | |
149 | &passthrough_user_xattr, | |
70fc55eb | 150 | &passthrough_acl_xattr, |
fc22118d AK |
151 | NULL, |
152 | }; | |
153 | ||
154 | /* for .user none model should be same as passthrough */ | |
155 | XattrOperations *none_xattr_ops[] = { | |
156 | &passthrough_user_xattr, | |
70fc55eb | 157 | &none_acl_xattr, |
fc22118d AK |
158 | NULL, |
159 | }; |