diff options
Diffstat (limited to 'fs/generic_acl.c')
-rw-r--r-- | fs/generic_acl.c | 62 |
1 files changed, 13 insertions, 49 deletions
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 70e90b4974ce..d5e33a077a67 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
@@ -132,31 +132,17 @@ generic_acl_init(struct inode *inode, struct inode *dir) | |||
132 | if (!S_ISLNK(inode->i_mode)) | 132 | if (!S_ISLNK(inode->i_mode)) |
133 | acl = get_cached_acl(dir, ACL_TYPE_DEFAULT); | 133 | acl = get_cached_acl(dir, ACL_TYPE_DEFAULT); |
134 | if (acl) { | 134 | if (acl) { |
135 | struct posix_acl *clone; | 135 | if (S_ISDIR(inode->i_mode)) |
136 | 136 | set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); | |
137 | if (S_ISDIR(inode->i_mode)) { | 137 | error = posix_acl_create(&acl, GFP_KERNEL, &mode); |
138 | clone = posix_acl_clone(acl, GFP_KERNEL); | 138 | if (error < 0) |
139 | error = -ENOMEM; | 139 | return error; |
140 | if (!clone) | 140 | inode->i_mode = mode; |
141 | goto cleanup; | 141 | if (error > 0) |
142 | set_cached_acl(inode, ACL_TYPE_DEFAULT, clone); | 142 | set_cached_acl(inode, ACL_TYPE_ACCESS, acl); |
143 | posix_acl_release(clone); | ||
144 | } | ||
145 | clone = posix_acl_clone(acl, GFP_KERNEL); | ||
146 | error = -ENOMEM; | ||
147 | if (!clone) | ||
148 | goto cleanup; | ||
149 | error = posix_acl_create_masq(clone, &mode); | ||
150 | if (error >= 0) { | ||
151 | inode->i_mode = mode; | ||
152 | if (error > 0) | ||
153 | set_cached_acl(inode, ACL_TYPE_ACCESS, clone); | ||
154 | } | ||
155 | posix_acl_release(clone); | ||
156 | } | 143 | } |
157 | error = 0; | 144 | error = 0; |
158 | 145 | ||
159 | cleanup: | ||
160 | posix_acl_release(acl); | 146 | posix_acl_release(acl); |
161 | return error; | 147 | return error; |
162 | } | 148 | } |
@@ -170,44 +156,22 @@ cleanup: | |||
170 | int | 156 | int |
171 | generic_acl_chmod(struct inode *inode) | 157 | generic_acl_chmod(struct inode *inode) |
172 | { | 158 | { |
173 | struct posix_acl *acl, *clone; | 159 | struct posix_acl *acl; |
174 | int error = 0; | 160 | int error = 0; |
175 | 161 | ||
176 | if (S_ISLNK(inode->i_mode)) | 162 | if (S_ISLNK(inode->i_mode)) |
177 | return -EOPNOTSUPP; | 163 | return -EOPNOTSUPP; |
178 | acl = get_cached_acl(inode, ACL_TYPE_ACCESS); | 164 | acl = get_cached_acl(inode, ACL_TYPE_ACCESS); |
179 | if (acl) { | 165 | if (acl) { |
180 | clone = posix_acl_clone(acl, GFP_KERNEL); | 166 | error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); |
167 | if (error) | ||
168 | return error; | ||
169 | set_cached_acl(inode, ACL_TYPE_ACCESS, acl); | ||
181 | posix_acl_release(acl); | 170 | posix_acl_release(acl); |
182 | if (!clone) | ||
183 | return -ENOMEM; | ||
184 | error = posix_acl_chmod_masq(clone, inode->i_mode); | ||
185 | if (!error) | ||
186 | set_cached_acl(inode, ACL_TYPE_ACCESS, clone); | ||
187 | posix_acl_release(clone); | ||
188 | } | 171 | } |
189 | return error; | 172 | return error; |
190 | } | 173 | } |
191 | 174 | ||
192 | int | ||
193 | generic_check_acl(struct inode *inode, int mask) | ||
194 | { | ||
195 | if (mask & MAY_NOT_BLOCK) { | ||
196 | if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) | ||
197 | return -ECHILD; | ||
198 | } else { | ||
199 | struct posix_acl *acl; | ||
200 | |||
201 | acl = get_cached_acl(inode, ACL_TYPE_ACCESS); | ||
202 | if (acl) { | ||
203 | int error = posix_acl_permission(inode, acl, mask); | ||
204 | posix_acl_release(acl); | ||
205 | return error; | ||
206 | } | ||
207 | } | ||
208 | return -EAGAIN; | ||
209 | } | ||
210 | |||
211 | const struct xattr_handler generic_acl_access_handler = { | 175 | const struct xattr_handler generic_acl_access_handler = { |
212 | .prefix = POSIX_ACL_XATTR_ACCESS, | 176 | .prefix = POSIX_ACL_XATTR_ACCESS, |
213 | .flags = ACL_TYPE_ACCESS, | 177 | .flags = ACL_TYPE_ACCESS, |