4 * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
6 * This file is released under the GPL.
9 #include <linux/sched.h>
11 #include <linux/generic_acl.h>
14 * generic_acl_list - Generic xattr_handler->list() operation
15 * @ops: Filesystem specific getacl and setacl callbacks
18 generic_acl_list(struct inode
*inode
, struct generic_acl_operations
*ops
,
19 int type
, char *list
, size_t list_size
)
21 struct posix_acl
*acl
;
25 acl
= ops
->getacl(inode
, type
);
28 posix_acl_release(acl
);
32 name
= POSIX_ACL_XATTR_ACCESS
;
35 case ACL_TYPE_DEFAULT
:
36 name
= POSIX_ACL_XATTR_DEFAULT
;
42 size
= strlen(name
) + 1;
43 if (list
&& size
<= list_size
)
44 memcpy(list
, name
, size
);
49 * generic_acl_get - Generic xattr_handler->get() operation
50 * @ops: Filesystem specific getacl and setacl callbacks
53 generic_acl_get(struct inode
*inode
, struct generic_acl_operations
*ops
,
54 int type
, void *buffer
, size_t size
)
56 struct posix_acl
*acl
;
59 acl
= ops
->getacl(inode
, type
);
62 error
= posix_acl_to_xattr(acl
, buffer
, size
);
63 posix_acl_release(acl
);
69 * generic_acl_set - Generic xattr_handler->set() operation
70 * @ops: Filesystem specific getacl and setacl callbacks
73 generic_acl_set(struct inode
*inode
, struct generic_acl_operations
*ops
,
74 int type
, const void *value
, size_t size
)
76 struct posix_acl
*acl
= NULL
;
79 if (S_ISLNK(inode
->i_mode
))
81 if (!is_owner_or_cap(inode
))
84 acl
= posix_acl_from_xattr(value
, size
);
91 error
= posix_acl_valid(acl
);
97 error
= posix_acl_equiv_mode(acl
, &mode
);
100 inode
->i_mode
= mode
;
102 posix_acl_release(acl
);
107 case ACL_TYPE_DEFAULT
:
108 if (!S_ISDIR(inode
->i_mode
)) {
115 ops
->setacl(inode
, type
, acl
);
118 posix_acl_release(acl
);
123 * generic_acl_init - Take care of acl inheritance at @inode create time
124 * @ops: Filesystem specific getacl and setacl callbacks
126 * Files created inside a directory with a default ACL inherit the
127 * directory's default ACL.
130 generic_acl_init(struct inode
*inode
, struct inode
*dir
,
131 struct generic_acl_operations
*ops
)
133 struct posix_acl
*acl
= NULL
;
134 mode_t mode
= inode
->i_mode
;
137 inode
->i_mode
= mode
& ~current_umask();
138 if (!S_ISLNK(inode
->i_mode
))
139 acl
= ops
->getacl(dir
, ACL_TYPE_DEFAULT
);
141 struct posix_acl
*clone
;
143 if (S_ISDIR(inode
->i_mode
)) {
144 clone
= posix_acl_clone(acl
, GFP_KERNEL
);
148 ops
->setacl(inode
, ACL_TYPE_DEFAULT
, clone
);
149 posix_acl_release(clone
);
151 clone
= posix_acl_clone(acl
, GFP_KERNEL
);
155 error
= posix_acl_create_masq(clone
, &mode
);
157 inode
->i_mode
= mode
;
159 ops
->setacl(inode
, ACL_TYPE_ACCESS
, clone
);
161 posix_acl_release(clone
);
166 posix_acl_release(acl
);
171 * generic_acl_chmod - change the access acl of @inode upon chmod()
172 * @ops: FIlesystem specific getacl and setacl callbacks
174 * A chmod also changes the permissions of the owner, group/mask, and
178 generic_acl_chmod(struct inode
*inode
, struct generic_acl_operations
*ops
)
180 struct posix_acl
*acl
, *clone
;
183 if (S_ISLNK(inode
->i_mode
))
185 acl
= ops
->getacl(inode
, ACL_TYPE_ACCESS
);
187 clone
= posix_acl_clone(acl
, GFP_KERNEL
);
188 posix_acl_release(acl
);
191 error
= posix_acl_chmod_masq(clone
, inode
->i_mode
);
193 ops
->setacl(inode
, ACL_TYPE_ACCESS
, clone
);
194 posix_acl_release(clone
);