2 #include <linux/posix_acl.h>
3 #include <linux/reiserfs_fs.h>
4 #include <linux/errno.h>
5 #include <linux/pagemap.h>
6 #include <linux/xattr.h>
7 #include <linux/xattr_acl.h>
8 #include <linux/reiserfs_xattr.h>
9 #include <linux/reiserfs_acl.h>
10 #include <asm/uaccess.h>
12 static int reiserfs_set_acl(struct inode
*inode
, int type
, struct posix_acl
*acl
);
15 xattr_set_acl(struct inode
*inode
, int type
, const void *value
, size_t size
)
17 struct posix_acl
*acl
;
20 if (!reiserfs_posixacl(inode
->i_sb
))
22 if ((current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
26 acl
= posix_acl_from_xattr(value
, size
);
30 error
= posix_acl_valid(acl
);
37 error
= reiserfs_set_acl (inode
, type
, acl
);
40 posix_acl_release(acl
);
46 xattr_get_acl(struct inode
*inode
, int type
, void *buffer
, size_t size
)
48 struct posix_acl
*acl
;
51 if (!reiserfs_posixacl(inode
->i_sb
))
54 acl
= reiserfs_get_acl (inode
, type
);
59 error
= posix_acl_to_xattr(acl
, buffer
, size
);
60 posix_acl_release(acl
);
67 * Convert from filesystem to in-memory representation.
69 static struct posix_acl
*
70 posix_acl_from_disk(const void *value
, size_t size
)
72 const char *end
= (char *)value
+ size
;
74 struct posix_acl
*acl
;
78 if (size
< sizeof(reiserfs_acl_header
))
79 return ERR_PTR(-EINVAL
);
80 if (((reiserfs_acl_header
*)value
)->a_version
!=
81 cpu_to_le32(REISERFS_ACL_VERSION
))
82 return ERR_PTR(-EINVAL
);
83 value
= (char *)value
+ sizeof(reiserfs_acl_header
);
84 count
= reiserfs_acl_count(size
);
86 return ERR_PTR(-EINVAL
);
89 acl
= posix_acl_alloc(count
, GFP_NOFS
);
91 return ERR_PTR(-ENOMEM
);
92 for (n
=0; n
< count
; n
++) {
93 reiserfs_acl_entry
*entry
=
94 (reiserfs_acl_entry
*)value
;
95 if ((char *)value
+ sizeof(reiserfs_acl_entry_short
) > end
)
97 acl
->a_entries
[n
].e_tag
= le16_to_cpu(entry
->e_tag
);
98 acl
->a_entries
[n
].e_perm
= le16_to_cpu(entry
->e_perm
);
99 switch(acl
->a_entries
[n
].e_tag
) {
104 value
= (char *)value
+
105 sizeof(reiserfs_acl_entry_short
);
106 acl
->a_entries
[n
].e_id
= ACL_UNDEFINED_ID
;
111 value
= (char *)value
+ sizeof(reiserfs_acl_entry
);
112 if ((char *)value
> end
)
114 acl
->a_entries
[n
].e_id
=
115 le32_to_cpu(entry
->e_id
);
127 posix_acl_release(acl
);
128 return ERR_PTR(-EINVAL
);
132 * Convert from in-memory to filesystem representation.
135 posix_acl_to_disk(const struct posix_acl
*acl
, size_t *size
)
137 reiserfs_acl_header
*ext_acl
;
141 *size
= reiserfs_acl_size(acl
->a_count
);
142 ext_acl
= (reiserfs_acl_header
*)kmalloc(sizeof(reiserfs_acl_header
) +
143 acl
->a_count
* sizeof(reiserfs_acl_entry
), GFP_NOFS
);
145 return ERR_PTR(-ENOMEM
);
146 ext_acl
->a_version
= cpu_to_le32(REISERFS_ACL_VERSION
);
147 e
= (char *)ext_acl
+ sizeof(reiserfs_acl_header
);
148 for (n
=0; n
< acl
->a_count
; n
++) {
149 reiserfs_acl_entry
*entry
= (reiserfs_acl_entry
*)e
;
150 entry
->e_tag
= cpu_to_le16(acl
->a_entries
[n
].e_tag
);
151 entry
->e_perm
= cpu_to_le16(acl
->a_entries
[n
].e_perm
);
152 switch(acl
->a_entries
[n
].e_tag
) {
156 cpu_to_le32(acl
->a_entries
[n
].e_id
);
157 e
+= sizeof(reiserfs_acl_entry
);
164 e
+= sizeof(reiserfs_acl_entry_short
);
171 return (char *)ext_acl
;
175 return ERR_PTR(-EINVAL
);
179 * Inode operation get_posix_acl().
182 * BKL held [before 2.5.x]
185 reiserfs_get_acl(struct inode
*inode
, int type
)
188 struct posix_acl
*acl
, **p_acl
;
191 struct reiserfs_inode_info
*reiserfs_i
= REISERFS_I(inode
);
194 case ACL_TYPE_ACCESS
:
195 name
= XATTR_NAME_ACL_ACCESS
;
196 p_acl
= &reiserfs_i
->i_acl_access
;
198 case ACL_TYPE_DEFAULT
:
199 name
= XATTR_NAME_ACL_DEFAULT
;
200 p_acl
= &reiserfs_i
->i_acl_default
;
203 return ERR_PTR (-EINVAL
);
206 if (IS_ERR (*p_acl
)) {
207 if (PTR_ERR (*p_acl
) == -ENODATA
)
209 } else if (*p_acl
!= NULL
)
210 return posix_acl_dup (*p_acl
);
212 size
= reiserfs_xattr_get (inode
, name
, NULL
, 0);
214 if (size
== -ENODATA
|| size
== -ENOSYS
) {
215 *p_acl
= ERR_PTR (-ENODATA
);
218 return ERR_PTR (size
);
221 value
= kmalloc (size
, GFP_NOFS
);
223 return ERR_PTR (-ENOMEM
);
225 retval
= reiserfs_xattr_get(inode
, name
, value
, size
);
226 if (retval
== -ENODATA
|| retval
== -ENOSYS
) {
227 /* This shouldn't actually happen as it should have
228 been caught above.. but just in case */
230 *p_acl
= ERR_PTR (-ENODATA
);
231 } else if (retval
< 0) {
232 acl
= ERR_PTR(retval
);
234 acl
= posix_acl_from_disk(value
, retval
);
235 *p_acl
= posix_acl_dup (acl
);
243 * Inode operation set_posix_acl().
246 * BKL held [before 2.5.x]
249 reiserfs_set_acl(struct inode
*inode
, int type
, struct posix_acl
*acl
)
253 struct posix_acl
**p_acl
;
256 struct reiserfs_inode_info
*reiserfs_i
= REISERFS_I(inode
);
258 if (S_ISLNK(inode
->i_mode
))
262 case ACL_TYPE_ACCESS
:
263 name
= XATTR_NAME_ACL_ACCESS
;
264 p_acl
= &reiserfs_i
->i_acl_access
;
266 mode_t mode
= inode
->i_mode
;
267 error
= posix_acl_equiv_mode (acl
, &mode
);
271 inode
->i_mode
= mode
;
277 case ACL_TYPE_DEFAULT
:
278 name
= XATTR_NAME_ACL_DEFAULT
;
279 p_acl
= &reiserfs_i
->i_acl_default
;
280 if (!S_ISDIR (inode
->i_mode
))
281 return acl
? -EACCES
: 0;
288 value
= posix_acl_to_disk(acl
, &size
);
290 return (int)PTR_ERR(value
);
291 error
= reiserfs_xattr_set(inode
, name
, value
, size
, 0);
293 error
= reiserfs_xattr_del (inode
, name
);
294 if (error
== -ENODATA
) {
295 /* This may seem odd here, but it means that the ACL was set
296 * with a value representable with mode bits. If there was
297 * an ACL before, reiserfs_xattr_del already dirtied the inode.
299 mark_inode_dirty (inode
);
308 /* Release the old one */
309 if (!IS_ERR (*p_acl
) && *p_acl
)
310 posix_acl_release (*p_acl
);
313 *p_acl
= ERR_PTR (-ENODATA
);
315 *p_acl
= posix_acl_dup (acl
);
322 * inode is new and not released into the wild yet */
324 reiserfs_inherit_default_acl (struct inode
*dir
, struct dentry
*dentry
, struct inode
*inode
)
326 struct posix_acl
*acl
;
329 /* ACLs only get applied to files and directories */
330 if (S_ISLNK (inode
->i_mode
))
333 /* ACLs can only be used on "new" objects, so if it's an old object
334 * there is nothing to inherit from */
335 if (get_inode_sd_version (dir
) == STAT_DATA_V1
)
338 /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
339 * would be useless since permissions are ignored, and a pain because
340 * it introduces locking cycles */
341 if (is_reiserfs_priv_object (dir
)) {
342 reiserfs_mark_inode_private (inode
);
346 acl
= reiserfs_get_acl (dir
, ACL_TYPE_DEFAULT
);
348 if (PTR_ERR (acl
) == -ENODATA
)
350 return PTR_ERR (acl
);
354 struct posix_acl
*acl_copy
;
355 mode_t mode
= inode
->i_mode
;
358 /* Copy the default ACL to the default ACL of a new directory */
359 if (S_ISDIR (inode
->i_mode
)) {
360 err
= reiserfs_set_acl (inode
, ACL_TYPE_DEFAULT
, acl
);
365 /* Now we reconcile the new ACL and the mode,
366 potentially modifying both */
367 acl_copy
= posix_acl_clone (acl
, GFP_NOFS
);
374 need_acl
= posix_acl_create_masq (acl_copy
, &mode
);
376 if (mode
!= inode
->i_mode
) {
377 inode
->i_mode
= mode
;
380 /* If we need an ACL.. */
382 err
= reiserfs_set_acl (inode
, ACL_TYPE_ACCESS
, acl_copy
);
388 posix_acl_release (acl_copy
);
390 posix_acl_release (acl
);
393 /* no ACL, apply umask */
394 inode
->i_mode
&= ~current
->fs
->umask
;
400 /* Looks up and caches the result of the default ACL.
401 * We do this so that we don't need to carry the xattr_sem into
402 * reiserfs_new_inode if we don't need to */
404 reiserfs_cache_default_acl (struct inode
*inode
)
407 if (reiserfs_posixacl (inode
->i_sb
) &&
408 !is_reiserfs_priv_object (inode
)) {
409 struct posix_acl
*acl
;
410 reiserfs_read_lock_xattr_i (inode
);
411 reiserfs_read_lock_xattrs (inode
->i_sb
);
412 acl
= reiserfs_get_acl (inode
, ACL_TYPE_DEFAULT
);
413 reiserfs_read_unlock_xattrs (inode
->i_sb
);
414 reiserfs_read_unlock_xattr_i (inode
);
416 posix_acl_release (acl
);
423 reiserfs_acl_chmod (struct inode
*inode
)
425 struct posix_acl
*acl
, *clone
;
428 if (S_ISLNK(inode
->i_mode
))
431 if (get_inode_sd_version (inode
) == STAT_DATA_V1
||
432 !reiserfs_posixacl(inode
->i_sb
))
437 reiserfs_read_lock_xattrs (inode
->i_sb
);
438 acl
= reiserfs_get_acl(inode
, ACL_TYPE_ACCESS
);
439 reiserfs_read_unlock_xattrs (inode
->i_sb
);
444 clone
= posix_acl_clone(acl
, GFP_NOFS
);
445 posix_acl_release(acl
);
448 error
= posix_acl_chmod_masq(clone
, inode
->i_mode
);
450 int lock
= !has_xattr_dir (inode
);
451 reiserfs_write_lock_xattr_i (inode
);
453 reiserfs_write_lock_xattrs (inode
->i_sb
);
455 reiserfs_read_lock_xattrs (inode
->i_sb
);
456 error
= reiserfs_set_acl(inode
, ACL_TYPE_ACCESS
, clone
);
458 reiserfs_write_unlock_xattrs (inode
->i_sb
);
460 reiserfs_read_unlock_xattrs (inode
->i_sb
);
461 reiserfs_write_unlock_xattr_i (inode
);
463 posix_acl_release(clone
);
468 posix_acl_access_get(struct inode
*inode
, const char *name
,
469 void *buffer
, size_t size
)
471 if (strlen(name
) != sizeof(XATTR_NAME_ACL_ACCESS
)-1)
473 return xattr_get_acl(inode
, ACL_TYPE_ACCESS
, buffer
, size
);
477 posix_acl_access_set(struct inode
*inode
, const char *name
,
478 const void *value
, size_t size
, int flags
)
480 if (strlen(name
) != sizeof(XATTR_NAME_ACL_ACCESS
)-1)
482 return xattr_set_acl(inode
, ACL_TYPE_ACCESS
, value
, size
);
486 posix_acl_access_del (struct inode
*inode
, const char *name
)
488 struct reiserfs_inode_info
*reiserfs_i
= REISERFS_I(inode
);
489 struct posix_acl
**acl
= &reiserfs_i
->i_acl_access
;
490 if (strlen(name
) != sizeof(XATTR_NAME_ACL_ACCESS
)-1)
492 if (!IS_ERR (*acl
) && *acl
) {
493 posix_acl_release (*acl
);
494 *acl
= ERR_PTR (-ENODATA
);
501 posix_acl_access_list (struct inode
*inode
, const char *name
, int namelen
, char *out
)
504 if (!reiserfs_posixacl (inode
->i_sb
))
507 memcpy (out
, name
, len
);
512 struct reiserfs_xattr_handler posix_acl_access_handler
= {
513 .prefix
= XATTR_NAME_ACL_ACCESS
,
514 .get
= posix_acl_access_get
,
515 .set
= posix_acl_access_set
,
516 .del
= posix_acl_access_del
,
517 .list
= posix_acl_access_list
,
521 posix_acl_default_get (struct inode
*inode
, const char *name
,
522 void *buffer
, size_t size
)
524 if (strlen(name
) != sizeof(XATTR_NAME_ACL_DEFAULT
)-1)
526 return xattr_get_acl(inode
, ACL_TYPE_DEFAULT
, buffer
, size
);
530 posix_acl_default_set(struct inode
*inode
, const char *name
,
531 const void *value
, size_t size
, int flags
)
533 if (strlen(name
) != sizeof(XATTR_NAME_ACL_DEFAULT
)-1)
535 return xattr_set_acl(inode
, ACL_TYPE_DEFAULT
, value
, size
);
539 posix_acl_default_del (struct inode
*inode
, const char *name
)
541 struct reiserfs_inode_info
*reiserfs_i
= REISERFS_I(inode
);
542 struct posix_acl
**acl
= &reiserfs_i
->i_acl_default
;
543 if (strlen(name
) != sizeof(XATTR_NAME_ACL_DEFAULT
)-1)
545 if (!IS_ERR (*acl
) && *acl
) {
546 posix_acl_release (*acl
);
547 *acl
= ERR_PTR (-ENODATA
);
554 posix_acl_default_list (struct inode
*inode
, const char *name
, int namelen
, char *out
)
557 if (!reiserfs_posixacl (inode
->i_sb
))
560 memcpy (out
, name
, len
);
565 struct reiserfs_xattr_handler posix_acl_default_handler
= {
566 .prefix
= XATTR_NAME_ACL_DEFAULT
,
567 .get
= posix_acl_default_get
,
568 .set
= posix_acl_default_set
,
569 .del
= posix_acl_default_del
,
570 .list
= posix_acl_default_list
,