aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;