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 SET operations
22 setxattr(struct dentry
*d
, char __user
*name
, void __user
*value
,
23 size_t size
, int flags
)
27 char kname
[XATTR_NAME_MAX
+ 1];
29 if (flags
& ~(XATTR_CREATE
|XATTR_REPLACE
))
32 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
33 if (error
== 0 || error
== sizeof(kname
))
39 if (size
> XATTR_SIZE_MAX
)
41 kvalue
= kmalloc(size
, GFP_KERNEL
);
44 if (copy_from_user(kvalue
, value
, size
)) {
51 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->setxattr
) {
52 down(&d
->d_inode
->i_sem
);
53 error
= security_inode_setxattr(d
, kname
, kvalue
, size
, flags
);
56 error
= d
->d_inode
->i_op
->setxattr(d
, kname
, kvalue
, size
, flags
);
58 security_inode_post_setxattr(d
, kname
, kvalue
, size
, flags
);
60 up(&d
->d_inode
->i_sem
);
68 sys_setxattr(char __user
*path
, char __user
*name
, void __user
*value
,
69 size_t size
, int flags
)
74 error
= user_path_walk(path
, &nd
);
77 error
= setxattr(nd
.dentry
, name
, value
, size
, flags
);
83 sys_lsetxattr(char __user
*path
, char __user
*name
, void __user
*value
,
84 size_t size
, int flags
)
89 error
= user_path_walk_link(path
, &nd
);
92 error
= setxattr(nd
.dentry
, name
, value
, size
, flags
);
98 sys_fsetxattr(int fd
, char __user
*name
, void __user
*value
,
99 size_t size
, int flags
)
107 error
= setxattr(f
->f_dentry
, name
, value
, size
, flags
);
113 * Extended attribute GET operations
116 getxattr(struct dentry
*d
, char __user
*name
, void __user
*value
, size_t size
)
120 char kname
[XATTR_NAME_MAX
+ 1];
122 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
123 if (error
== 0 || error
== sizeof(kname
))
129 if (size
> XATTR_SIZE_MAX
)
130 size
= XATTR_SIZE_MAX
;
131 kvalue
= kmalloc(size
, GFP_KERNEL
);
137 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->getxattr
) {
138 error
= security_inode_getxattr(d
, kname
);
141 error
= d
->d_inode
->i_op
->getxattr(d
, kname
, kvalue
, size
);
143 if (size
&& copy_to_user(value
, kvalue
, error
))
145 } else if (error
== -ERANGE
&& size
>= XATTR_SIZE_MAX
) {
146 /* The file system tried to returned a value bigger
147 than XATTR_SIZE_MAX bytes. Not possible. */
158 sys_getxattr(char __user
*path
, char __user
*name
, void __user
*value
,
164 error
= user_path_walk(path
, &nd
);
167 error
= getxattr(nd
.dentry
, name
, value
, size
);
173 sys_lgetxattr(char __user
*path
, char __user
*name
, void __user
*value
,
179 error
= user_path_walk_link(path
, &nd
);
182 error
= getxattr(nd
.dentry
, name
, value
, size
);
188 sys_fgetxattr(int fd
, char __user
*name
, void __user
*value
, size_t size
)
191 ssize_t error
= -EBADF
;
196 error
= getxattr(f
->f_dentry
, name
, value
, size
);
202 * Extended attribute LIST operations
205 listxattr(struct dentry
*d
, char __user
*list
, size_t size
)
211 if (size
> XATTR_LIST_MAX
)
212 size
= XATTR_LIST_MAX
;
213 klist
= kmalloc(size
, GFP_KERNEL
);
219 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->listxattr
) {
220 error
= security_inode_listxattr(d
);
223 error
= d
->d_inode
->i_op
->listxattr(d
, klist
, size
);
225 if (size
&& copy_to_user(list
, klist
, error
))
227 } else if (error
== -ERANGE
&& size
>= XATTR_LIST_MAX
) {
228 /* The file system tried to returned a list bigger
229 than XATTR_LIST_MAX bytes. Not possible. */
240 sys_listxattr(char __user
*path
, char __user
*list
, size_t size
)
245 error
= user_path_walk(path
, &nd
);
248 error
= listxattr(nd
.dentry
, list
, size
);
254 sys_llistxattr(char __user
*path
, char __user
*list
, size_t size
)
259 error
= user_path_walk_link(path
, &nd
);
262 error
= listxattr(nd
.dentry
, list
, size
);
268 sys_flistxattr(int fd
, char __user
*list
, size_t size
)
271 ssize_t error
= -EBADF
;
276 error
= listxattr(f
->f_dentry
, list
, size
);
282 * Extended attribute REMOVE operations
285 removexattr(struct dentry
*d
, char __user
*name
)
288 char kname
[XATTR_NAME_MAX
+ 1];
290 error
= strncpy_from_user(kname
, name
, sizeof(kname
));
291 if (error
== 0 || error
== sizeof(kname
))
297 if (d
->d_inode
->i_op
&& d
->d_inode
->i_op
->removexattr
) {
298 error
= security_inode_removexattr(d
, kname
);
301 down(&d
->d_inode
->i_sem
);
302 error
= d
->d_inode
->i_op
->removexattr(d
, kname
);
303 up(&d
->d_inode
->i_sem
);
310 sys_removexattr(char __user
*path
, char __user
*name
)
315 error
= user_path_walk(path
, &nd
);
318 error
= removexattr(nd
.dentry
, name
);
324 sys_lremovexattr(char __user
*path
, char __user
*name
)
329 error
= user_path_walk_link(path
, &nd
);
332 error
= removexattr(nd
.dentry
, name
);
338 sys_fremovexattr(int fd
, char __user
*name
)
346 error
= removexattr(f
->f_dentry
, name
);