4 Extended attribute handling.
6 Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
7 Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
10 #include <linux/slab.h>
11 #include <linux/smp_lock.h>
12 #include <linux/file.h>
13 #include <linux/xattr.h>
14 #include <linux/namei.h>
15 #include <linux/security.h>
16 #include <asm/uaccess.h>
19 * Extended attribute memory allocation wrappers, originally
20 * based on the Intermezzo PRESTO_ALLOC/PRESTO_FREE macros.
21 * Values larger than a page are uncommon - extended attributes
22 * are supposed to be small chunks of metadata, and it is quite
23 * unusual to have very many extended attributes, so lists tend
24 * to be quite short as well. The 64K upper limit is derived
25 * from the extended attribute size limit used by XFS.
26 * Intentionally allow zero @size for value/list size requests.
29 xattr_alloc(size_t size
, size_t limit
)
34 return ERR_PTR(-E2BIG
);
36 if (!size
) /* size request, no buffer is needed */
39 ptr
= kmalloc((unsigned long) size
, GFP_KERNEL
);
41 return ERR_PTR(-ENOMEM
);
46 xattr_free(void *ptr
, size_t size
)
48 if (size
) /* for a size request, no buffer was needed */
53 * Extended attribute SET operations
56 setxattr(struct dentry
*d
, char *name
, void *value
, size_t size
, int flags
)
60 char kname
[XATTR_NAME_MAX
+ 1];
62 if (flags
& ~(XATTR_CREATE
|XATTR_REPLACE
))
65 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
66 if (error
== 0 || error
== sizeof(kname
))
71 kvalue
= xattr_alloc(size
, XATTR_SIZE_MAX
);
73 return PTR_ERR(kvalue
);
75 if (size
> 0 && copy_from_user(kvalue
, value
, size
)) {
76 xattr_free(kvalue
, size
);
81 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->setxattr
) {
82 down(&d
->d_inode
->i_sem
);
83 error
= security_inode_setxattr(d
, kname
, kvalue
, size
, flags
);
86 error
= d
->d_inode
->i_op
->setxattr(d
, kname
, kvalue
, size
, flags
);
88 security_inode_post_setxattr(d
, kname
, kvalue
, size
, flags
);
90 up(&d
->d_inode
->i_sem
);
92 xattr_free(kvalue
, size
);
97 sys_setxattr(char *path
, char *name
, void *value
, size_t size
, int flags
)
102 error
= user_path_walk(path
, &nd
);
105 error
= setxattr(nd
.dentry
, name
, value
, size
, flags
);
111 sys_lsetxattr(char *path
, char *name
, void *value
, size_t size
, int flags
)
116 error
= user_path_walk_link(path
, &nd
);
119 error
= setxattr(nd
.dentry
, name
, value
, size
, flags
);
125 sys_fsetxattr(int fd
, char *name
, void *value
, size_t size
, int flags
)
133 error
= setxattr(f
->f_dentry
, name
, value
, size
, flags
);
139 * Extended attribute GET operations
142 getxattr(struct dentry
*d
, char *name
, void *value
, size_t size
)
146 char kname
[XATTR_NAME_MAX
+ 1];
148 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
149 if (error
== 0 || error
== sizeof(kname
))
154 kvalue
= xattr_alloc(size
, XATTR_SIZE_MAX
);
156 return PTR_ERR(kvalue
);
159 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->getxattr
) {
160 error
= security_inode_getxattr(d
, kname
);
163 error
= d
->d_inode
->i_op
->getxattr(d
, kname
, kvalue
, size
);
166 if (kvalue
&& error
> 0)
167 if (copy_to_user(value
, kvalue
, error
))
170 xattr_free(kvalue
, size
);
175 sys_getxattr(char *path
, char *name
, void *value
, size_t size
)
180 error
= user_path_walk(path
, &nd
);
183 error
= getxattr(nd
.dentry
, name
, value
, size
);
189 sys_lgetxattr(char *path
, char *name
, void *value
, size_t size
)
194 error
= user_path_walk_link(path
, &nd
);
197 error
= getxattr(nd
.dentry
, name
, value
, size
);
203 sys_fgetxattr(int fd
, char *name
, void *value
, size_t size
)
206 ssize_t error
= -EBADF
;
211 error
= getxattr(f
->f_dentry
, name
, value
, size
);
217 * Extended attribute LIST operations
220 listxattr(struct dentry
*d
, char *list
, size_t size
)
225 klist
= (char *)xattr_alloc(size
, XATTR_LIST_MAX
);
227 return PTR_ERR(klist
);
230 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->listxattr
) {
231 error
= security_inode_listxattr(d
);
234 error
= d
->d_inode
->i_op
->listxattr(d
, klist
, size
);
237 if (klist
&& error
> 0)
238 if (copy_to_user(list
, klist
, error
))
241 xattr_free(klist
, size
);
246 sys_listxattr(char *path
, char *list
, size_t size
)
251 error
= user_path_walk(path
, &nd
);
254 error
= listxattr(nd
.dentry
, list
, size
);
260 sys_llistxattr(char *path
, char *list
, size_t size
)
265 error
= user_path_walk_link(path
, &nd
);
268 error
= listxattr(nd
.dentry
, list
, size
);
274 sys_flistxattr(int fd
, char *list
, size_t size
)
277 ssize_t error
= -EBADF
;
282 error
= listxattr(f
->f_dentry
, list
, size
);
288 * Extended attribute REMOVE operations
291 removexattr(struct dentry
*d
, char *name
)
294 char kname
[XATTR_NAME_MAX
+ 1];
296 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
297 if (error
== 0 || error
== sizeof(kname
))
303 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->removexattr
) {
304 error
= security_inode_removexattr(d
, kname
);
307 down(&d
->d_inode
->i_sem
);
308 error
= d
->d_inode
->i_op
->removexattr(d
, kname
);
309 up(&d
->d_inode
->i_sem
);
316 sys_removexattr(char *path
, char *name
)
321 error
= user_path_walk(path
, &nd
);
324 error
= removexattr(nd
.dentry
, name
);
330 sys_lremovexattr(char *path
, char *name
)
335 error
= user_path_walk_link(path
, &nd
);
338 error
= removexattr(nd
.dentry
, name
);
344 sys_fremovexattr(int fd
, char *name
)
352 error
= removexattr(f
->f_dentry
, name
);