aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2015-10-04 13:18:52 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-11-13 20:34:33 -0500
commite409de992e3ea3674393465f07cc71c948edd87a (patch)
treee650f63fbb38fb48cef2fd24f10651ea5765d5ff
parentd9a82a04033f87bbd06efb29f78c0170a38154a8 (diff)
9p: xattr simplifications
Now that the xattr handler is passed to the xattr handler operations, we can use the same get and set operations for the user, trusted, and security xattr namespaces. In those namespaces, we can access the full attribute name by "reattaching" the name prefix the vfs has skipped for us. Add a xattr_full_name helper to make this obvious in the code. For the "system.posix_acl_access" and "system.posix_acl_default" attributes, handler->prefix is the full attribute name; the suffix is the empty string. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Ron Minnich <rminnich@sandia.gov> Cc: Latchesar Ionkov <lucho@ionkov.net> Cc: v9fs-developer@lists.sourceforge.net Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/9p/Makefile5
-rw-r--r--fs/9p/acl.c51
-rw-r--r--fs/9p/xattr.c42
-rw-r--r--fs/9p/xattr.h3
-rw-r--r--fs/9p/xattr_security.c82
-rw-r--r--fs/9p/xattr_trusted.c82
-rw-r--r--fs/9p/xattr_user.c82
-rw-r--r--fs/xattr.c24
-rw-r--r--include/linux/xattr.h18
9 files changed, 83 insertions, 306 deletions
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index ff7be98f84f2..9619ccadd2fc 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -10,10 +10,7 @@ obj-$(CONFIG_9P_FS) := 9p.o
10 vfs_dentry.o \ 10 vfs_dentry.o \
11 v9fs.o \ 11 v9fs.o \
12 fid.o \ 12 fid.o \
13 xattr.o \ 13 xattr.o
14 xattr_user.o \
15 xattr_trusted.o
16 14
179p-$(CONFIG_9P_FSCACHE) += cache.o 159p-$(CONFIG_9P_FSCACHE) += cache.o
189p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o 169p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
199p-$(CONFIG_9P_FS_SECURITY) += xattr_security.o
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index e6fe82462043..a7e28890f5ef 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -212,31 +212,12 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep,
212 return 0; 212 return 0;
213} 213}
214 214
215static int v9fs_remote_get_acl(struct dentry *dentry, const char *name,
216 void *buffer, size_t size, int type)
217{
218 char *full_name;
219
220 switch (type) {
221 case ACL_TYPE_ACCESS:
222 full_name = POSIX_ACL_XATTR_ACCESS;
223 break;
224 case ACL_TYPE_DEFAULT:
225 full_name = POSIX_ACL_XATTR_DEFAULT;
226 break;
227 default:
228 BUG();
229 }
230 return v9fs_xattr_get(dentry, full_name, buffer, size);
231}
232
233static int v9fs_xattr_get_acl(const struct xattr_handler *handler, 215static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
234 struct dentry *dentry, const char *name, 216 struct dentry *dentry, const char *name,
235 void *buffer, size_t size) 217 void *buffer, size_t size)
236{ 218{
237 struct v9fs_session_info *v9ses; 219 struct v9fs_session_info *v9ses;
238 struct posix_acl *acl; 220 struct posix_acl *acl;
239 int type = handler->flags;
240 int error; 221 int error;
241 222
242 if (strcmp(name, "") != 0) 223 if (strcmp(name, "") != 0)
@@ -247,9 +228,9 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
247 * We allow set/get/list of acl when access=client is not specified 228 * We allow set/get/list of acl when access=client is not specified
248 */ 229 */
249 if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) 230 if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
250 return v9fs_remote_get_acl(dentry, name, buffer, size, type); 231 return v9fs_xattr_get(dentry, handler->prefix, buffer, size);
251 232
252 acl = v9fs_get_cached_acl(d_inode(dentry), type); 233 acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags);
253 if (IS_ERR(acl)) 234 if (IS_ERR(acl))
254 return PTR_ERR(acl); 235 return PTR_ERR(acl);
255 if (acl == NULL) 236 if (acl == NULL)
@@ -260,26 +241,6 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
260 return error; 241 return error;
261} 242}
262 243
263static int v9fs_remote_set_acl(struct dentry *dentry, const char *name,
264 const void *value, size_t size,
265 int flags, int type)
266{
267 char *full_name;
268
269 switch (type) {
270 case ACL_TYPE_ACCESS:
271 full_name = POSIX_ACL_XATTR_ACCESS;
272 break;
273 case ACL_TYPE_DEFAULT:
274 full_name = POSIX_ACL_XATTR_DEFAULT;
275 break;
276 default:
277 BUG();
278 }
279 return v9fs_xattr_set(dentry, full_name, value, size, flags);
280}
281
282
283static int v9fs_xattr_set_acl(const struct xattr_handler *handler, 244static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
284 struct dentry *dentry, const char *name, 245 struct dentry *dentry, const char *name,
285 const void *value, size_t size, int flags) 246 const void *value, size_t size, int flags)
@@ -298,8 +259,8 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
298 * xattr value. We leave it to the server to validate 259 * xattr value. We leave it to the server to validate
299 */ 260 */
300 if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) 261 if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
301 return v9fs_remote_set_acl(dentry, name, 262 return v9fs_xattr_set(dentry, handler->prefix, value, size,
302 value, size, flags, handler->flags); 263 flags);
303 264
304 if (S_ISLNK(inode->i_mode)) 265 if (S_ISLNK(inode->i_mode))
305 return -EOPNOTSUPP; 266 return -EOPNOTSUPP;
@@ -320,7 +281,6 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
320 281
321 switch (handler->flags) { 282 switch (handler->flags) {
322 case ACL_TYPE_ACCESS: 283 case ACL_TYPE_ACCESS:
323 name = POSIX_ACL_XATTR_ACCESS;
324 if (acl) { 284 if (acl) {
325 umode_t mode = inode->i_mode; 285 umode_t mode = inode->i_mode;
326 retval = posix_acl_equiv_mode(acl, &mode); 286 retval = posix_acl_equiv_mode(acl, &mode);
@@ -351,7 +311,6 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
351 } 311 }
352 break; 312 break;
353 case ACL_TYPE_DEFAULT: 313 case ACL_TYPE_DEFAULT:
354 name = POSIX_ACL_XATTR_DEFAULT;
355 if (!S_ISDIR(inode->i_mode)) { 314 if (!S_ISDIR(inode->i_mode)) {
356 retval = acl ? -EINVAL : 0; 315 retval = acl ? -EINVAL : 0;
357 goto err_out; 316 goto err_out;
@@ -360,7 +319,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
360 default: 319 default:
361 BUG(); 320 BUG();
362 } 321 }
363 retval = v9fs_xattr_set(dentry, name, value, size, flags); 322 retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags);
364 if (!retval) 323 if (!retval)
365 set_cached_acl(inode, handler->flags, acl); 324 set_cached_acl(inode, handler->flags, acl);
366err_out: 325err_out:
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index 0cf44b6cccd6..e3d026ac382e 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -137,6 +137,48 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
137 return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); 137 return v9fs_xattr_get(dentry, NULL, buffer, buffer_size);
138} 138}
139 139
140static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
141 struct dentry *dentry, const char *name,
142 void *buffer, size_t size)
143{
144 const char *full_name = xattr_full_name(handler, name);
145
146 if (strcmp(name, "") == 0)
147 return -EINVAL;
148 return v9fs_xattr_get(dentry, full_name, buffer, size);
149}
150
151static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
152 struct dentry *dentry, const char *name,
153 const void *value, size_t size, int flags)
154{
155 const char *full_name = xattr_full_name(handler, name);
156
157 if (strcmp(name, "") == 0)
158 return -EINVAL;
159 return v9fs_xattr_set(dentry, full_name, value, size, flags);
160}
161
162static struct xattr_handler v9fs_xattr_user_handler = {
163 .prefix = XATTR_USER_PREFIX,
164 .get = v9fs_xattr_handler_get,
165 .set = v9fs_xattr_handler_set,
166};
167
168static struct xattr_handler v9fs_xattr_trusted_handler = {
169 .prefix = XATTR_TRUSTED_PREFIX,
170 .get = v9fs_xattr_handler_get,
171 .set = v9fs_xattr_handler_set,
172};
173
174#ifdef CONFIG_9P_FS_SECURITY
175static struct xattr_handler v9fs_xattr_security_handler = {
176 .prefix = XATTR_SECURITY_PREFIX,
177 .get = v9fs_xattr_handler_get,
178 .set = v9fs_xattr_handler_set,
179};
180#endif
181
140const struct xattr_handler *v9fs_xattr_handlers[] = { 182const struct xattr_handler *v9fs_xattr_handlers[] = {
141 &v9fs_xattr_user_handler, 183 &v9fs_xattr_user_handler,
142 &v9fs_xattr_trusted_handler, 184 &v9fs_xattr_trusted_handler,
diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h
index d3e2ea3840be..c63c3bea5de5 100644
--- a/fs/9p/xattr.h
+++ b/fs/9p/xattr.h
@@ -19,9 +19,6 @@
19#include <net/9p/client.h> 19#include <net/9p/client.h>
20 20
21extern const struct xattr_handler *v9fs_xattr_handlers[]; 21extern const struct xattr_handler *v9fs_xattr_handlers[];
22extern struct xattr_handler v9fs_xattr_user_handler;
23extern struct xattr_handler v9fs_xattr_trusted_handler;
24extern struct xattr_handler v9fs_xattr_security_handler;
25extern const struct xattr_handler v9fs_xattr_acl_access_handler; 22extern const struct xattr_handler v9fs_xattr_acl_access_handler;
26extern const struct xattr_handler v9fs_xattr_acl_default_handler; 23extern const struct xattr_handler v9fs_xattr_acl_default_handler;
27 24
diff --git a/fs/9p/xattr_security.c b/fs/9p/xattr_security.c
deleted file mode 100644
index c0a470add13c..000000000000
--- a/fs/9p/xattr_security.c
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * Copyright IBM Corporation, 2010
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14
15
16#include <linux/module.h>
17#include <linux/string.h>
18#include <linux/fs.h>
19#include <linux/slab.h>
20#include "xattr.h"
21
22static int v9fs_xattr_security_get(const struct xattr_handler *handler,
23 struct dentry *dentry, const char *name,
24 void *buffer, size_t size)
25{
26 int retval;
27 char *full_name;
28 size_t name_len;
29 size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
30
31 if (name == NULL)
32 return -EINVAL;
33
34 if (strcmp(name, "") == 0)
35 return -EINVAL;
36
37 name_len = strlen(name);
38 full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
39 if (!full_name)
40 return -ENOMEM;
41 memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
42 memcpy(full_name+prefix_len, name, name_len);
43 full_name[prefix_len + name_len] = '\0';
44
45 retval = v9fs_xattr_get(dentry, full_name, buffer, size);
46 kfree(full_name);
47 return retval;
48}
49
50static int v9fs_xattr_security_set(const struct xattr_handler *handler,
51 struct dentry *dentry, const char *name,
52 const void *value, size_t size, int flags)
53{
54 int retval;
55 char *full_name;
56 size_t name_len;
57 size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
58
59 if (name == NULL)
60 return -EINVAL;
61
62 if (strcmp(name, "") == 0)
63 return -EINVAL;
64
65 name_len = strlen(name);
66 full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
67 if (!full_name)
68 return -ENOMEM;
69 memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
70 memcpy(full_name + prefix_len, name, name_len);
71 full_name[prefix_len + name_len] = '\0';
72
73 retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
74 kfree(full_name);
75 return retval;
76}
77
78struct xattr_handler v9fs_xattr_security_handler = {
79 .prefix = XATTR_SECURITY_PREFIX,
80 .get = v9fs_xattr_security_get,
81 .set = v9fs_xattr_security_set,
82};
diff --git a/fs/9p/xattr_trusted.c b/fs/9p/xattr_trusted.c
deleted file mode 100644
index b888a4eecd1a..000000000000
--- a/fs/9p/xattr_trusted.c
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * Copyright IBM Corporation, 2010
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14
15
16#include <linux/module.h>
17#include <linux/string.h>
18#include <linux/fs.h>
19#include <linux/slab.h>
20#include "xattr.h"
21
22static int v9fs_xattr_trusted_get(const struct xattr_handler *handler,
23 struct dentry *dentry, const char *name,
24 void *buffer, size_t size)
25{
26 int retval;
27 char *full_name;
28 size_t name_len;
29 size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
30
31 if (name == NULL)
32 return -EINVAL;
33
34 if (strcmp(name, "") == 0)
35 return -EINVAL;
36
37 name_len = strlen(name);
38 full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
39 if (!full_name)
40 return -ENOMEM;
41 memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
42 memcpy(full_name+prefix_len, name, name_len);
43 full_name[prefix_len + name_len] = '\0';
44
45 retval = v9fs_xattr_get(dentry, full_name, buffer, size);
46 kfree(full_name);
47 return retval;
48}
49
50static int v9fs_xattr_trusted_set(const struct xattr_handler *handler,
51 struct dentry *dentry, const char *name,
52 const void *value, size_t size, int flags)
53{
54 int retval;
55 char *full_name;
56 size_t name_len;
57 size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
58
59 if (name == NULL)
60 return -EINVAL;
61
62 if (strcmp(name, "") == 0)
63 return -EINVAL;
64
65 name_len = strlen(name);
66 full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
67 if (!full_name)
68 return -ENOMEM;
69 memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
70 memcpy(full_name + prefix_len, name, name_len);
71 full_name[prefix_len + name_len] = '\0';
72
73 retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
74 kfree(full_name);
75 return retval;
76}
77
78struct xattr_handler v9fs_xattr_trusted_handler = {
79 .prefix = XATTR_TRUSTED_PREFIX,
80 .get = v9fs_xattr_trusted_get,
81 .set = v9fs_xattr_trusted_set,
82};
diff --git a/fs/9p/xattr_user.c b/fs/9p/xattr_user.c
deleted file mode 100644
index 06f136cbe264..000000000000
--- a/fs/9p/xattr_user.c
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 * Copyright IBM Corporation, 2010
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14
15
16#include <linux/module.h>
17#include <linux/string.h>
18#include <linux/fs.h>
19#include <linux/slab.h>
20#include "xattr.h"
21
22static int v9fs_xattr_user_get(const struct xattr_handler *handler,
23 struct dentry *dentry, const char *name,
24 void *buffer, size_t size)
25{
26 int retval;
27 char *full_name;
28 size_t name_len;
29 size_t prefix_len = XATTR_USER_PREFIX_LEN;
30
31 if (name == NULL)
32 return -EINVAL;
33
34 if (strcmp(name, "") == 0)
35 return -EINVAL;
36
37 name_len = strlen(name);
38 full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
39 if (!full_name)
40 return -ENOMEM;
41 memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
42 memcpy(full_name+prefix_len, name, name_len);
43 full_name[prefix_len + name_len] = '\0';
44
45 retval = v9fs_xattr_get(dentry, full_name, buffer, size);
46 kfree(full_name);
47 return retval;
48}
49
50static int v9fs_xattr_user_set(const struct xattr_handler *handler,
51 struct dentry *dentry, const char *name,
52 const void *value, size_t size, int flags)
53{
54 int retval;
55 char *full_name;
56 size_t name_len;
57 size_t prefix_len = XATTR_USER_PREFIX_LEN;
58
59 if (name == NULL)
60 return -EINVAL;
61
62 if (strcmp(name, "") == 0)
63 return -EINVAL;
64
65 name_len = strlen(name);
66 full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
67 if (!full_name)
68 return -ENOMEM;
69 memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
70 memcpy(full_name + prefix_len, name, name_len);
71 full_name[prefix_len + name_len] = '\0';
72
73 retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
74 kfree(full_name);
75 return retval;
76}
77
78struct xattr_handler v9fs_xattr_user_handler = {
79 .prefix = XATTR_USER_PREFIX,
80 .get = v9fs_xattr_user_get,
81 .set = v9fs_xattr_user_set,
82};
diff --git a/fs/xattr.c b/fs/xattr.c
index 44377b6f6001..9b932b95d74e 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -790,6 +790,30 @@ EXPORT_SYMBOL(generic_listxattr);
790EXPORT_SYMBOL(generic_setxattr); 790EXPORT_SYMBOL(generic_setxattr);
791EXPORT_SYMBOL(generic_removexattr); 791EXPORT_SYMBOL(generic_removexattr);
792 792
793/**
794 * xattr_full_name - Compute full attribute name from suffix
795 *
796 * @handler: handler of the xattr_handler operation
797 * @name: name passed to the xattr_handler operation
798 *
799 * The get and set xattr handler operations are called with the remainder of
800 * the attribute name after skipping the handler's prefix: for example, "foo"
801 * is passed to the get operation of a handler with prefix "user." to get
802 * attribute "user.foo". The full name is still "there" in the name though.
803 *
804 * Note: the list xattr handler operation when called from the vfs is passed a
805 * NULL name; some file systems use this operation internally, with varying
806 * semantics.
807 */
808const char *xattr_full_name(const struct xattr_handler *handler,
809 const char *name)
810{
811 size_t prefix_len = strlen(handler->prefix);
812
813 return name - prefix_len;
814}
815EXPORT_SYMBOL(xattr_full_name);
816
793/* 817/*
794 * Allocate new xattr and copy in the value; but leave the name to callers. 818 * Allocate new xattr and copy in the value; but leave the name to callers.
795 */ 819 */
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 91b0a68d38dc..89474b9d260c 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -21,15 +21,19 @@ struct dentry;
21 21
22struct xattr_handler { 22struct xattr_handler {
23 const char *prefix; 23 const char *prefix;
24 int flags; /* fs private flags passed back to the handlers */ 24 int flags; /* fs private flags */
25 size_t (*list)(struct dentry *dentry, char *list, size_t list_size, 25 size_t (*list)(const struct xattr_handler *, struct dentry *dentry,
26 const char *name, size_t name_len, int handler_flags); 26 char *list, size_t list_size, const char *name,
27 int (*get)(struct dentry *dentry, const char *name, void *buffer, 27 size_t name_len);
28 size_t size, int handler_flags); 28 int (*get)(const struct xattr_handler *, struct dentry *dentry,
29 int (*set)(struct dentry *dentry, const char *name, const void *buffer, 29 const char *name, void *buffer, size_t size);
30 size_t size, int flags, int handler_flags); 30 int (*set)(const struct xattr_handler *, struct dentry *dentry,
31 const char *name, const void *buffer, size_t size,
32 int flags);
31}; 33};
32 34
35const char *xattr_full_name(const struct xattr_handler *, const char *);
36
33struct xattr { 37struct xattr {
34 const char *name; 38 const char *name;
35 void *value; 39 void *value;