aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-12-20 08:16:44 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-01-25 23:58:19 -0500
commit64e178a7118b1cf7648391755e44dcc209091003 (patch)
treef06ee5408a04ee86c7a79dfd885aaab3c5f3f070
parent996a710d46418cacb5b4a519ab9341a74066551d (diff)
ext2/3/4: use generic posix ACL infrastructure
Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ext2/acl.c188
-rw-r--r--fs/ext2/acl.h8
-rw-r--r--fs/ext2/file.c1
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext2/namei.c2
-rw-r--r--fs/ext2/xattr.c8
-rw-r--r--fs/ext2/xattr.h2
-rw-r--r--fs/ext3/acl.c223
-rw-r--r--fs/ext3/acl.h9
-rw-r--r--fs/ext3/file.c1
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/ext3/namei.c2
-rw-r--r--fs/ext3/xattr.c8
-rw-r--r--fs/ext3/xattr.h2
-rw-r--r--fs/ext4/acl.c223
-rw-r--r--fs/ext4/acl.h9
-rw-r--r--fs/ext4/file.c1
-rw-r--r--fs/ext4/inode.c2
-rw-r--r--fs/ext4/namei.c2
-rw-r--r--fs/ext4/xattr.c8
-rw-r--r--fs/ext4/xattr.h2
21 files changed, 100 insertions, 605 deletions
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 6e842a764ee7..1b8001bbe947 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -148,13 +148,6 @@ ext2_get_acl(struct inode *inode, int type)
148 struct posix_acl *acl; 148 struct posix_acl *acl;
149 int retval; 149 int retval;
150 150
151 if (!test_opt(inode->i_sb, POSIX_ACL))
152 return NULL;
153
154 acl = get_cached_acl(inode, type);
155 if (acl != ACL_NOT_CACHED)
156 return acl;
157
158 switch (type) { 151 switch (type) {
159 case ACL_TYPE_ACCESS: 152 case ACL_TYPE_ACCESS:
160 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 153 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -189,19 +182,14 @@ ext2_get_acl(struct inode *inode, int type)
189/* 182/*
190 * inode->i_mutex: down 183 * inode->i_mutex: down
191 */ 184 */
192static int 185int
193ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) 186ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
194{ 187{
195 int name_index; 188 int name_index;
196 void *value = NULL; 189 void *value = NULL;
197 size_t size = 0; 190 size_t size = 0;
198 int error; 191 int error;
199 192
200 if (S_ISLNK(inode->i_mode))
201 return -EOPNOTSUPP;
202 if (!test_opt(inode->i_sb, POSIX_ACL))
203 return 0;
204
205 switch(type) { 193 switch(type) {
206 case ACL_TYPE_ACCESS: 194 case ACL_TYPE_ACCESS:
207 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 195 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -250,169 +238,21 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
250int 238int
251ext2_init_acl(struct inode *inode, struct inode *dir) 239ext2_init_acl(struct inode *inode, struct inode *dir)
252{ 240{
253 struct posix_acl *acl = NULL; 241 struct posix_acl *default_acl, *acl;
254 int error = 0; 242 int error;
255
256 if (!S_ISLNK(inode->i_mode)) {
257 if (test_opt(dir->i_sb, POSIX_ACL)) {
258 acl = ext2_get_acl(dir, ACL_TYPE_DEFAULT);
259 if (IS_ERR(acl))
260 return PTR_ERR(acl);
261 }
262 if (!acl)
263 inode->i_mode &= ~current_umask();
264 }
265 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
266 if (S_ISDIR(inode->i_mode)) {
267 error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
268 if (error)
269 goto cleanup;
270 }
271 error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
272 if (error < 0)
273 return error;
274 if (error > 0) {
275 /* This is an extended ACL */
276 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
277 }
278 }
279cleanup:
280 posix_acl_release(acl);
281 return error;
282}
283
284/*
285 * Does chmod for an inode that may have an Access Control List. The
286 * inode->i_mode field must be updated to the desired value by the caller
287 * before calling this function.
288 * Returns 0 on success, or a negative error number.
289 *
290 * We change the ACL rather than storing some ACL entries in the file
291 * mode permission bits (which would be more efficient), because that
292 * would break once additional permissions (like ACL_APPEND, ACL_DELETE
293 * for directories) are added. There are no more bits available in the
294 * file mode.
295 *
296 * inode->i_mutex: down
297 */
298int
299ext2_acl_chmod(struct inode *inode)
300{
301 struct posix_acl *acl;
302 int error;
303 243
304 if (!test_opt(inode->i_sb, POSIX_ACL)) 244 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
305 return 0;
306 if (S_ISLNK(inode->i_mode))
307 return -EOPNOTSUPP;
308 acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
309 if (IS_ERR(acl) || !acl)
310 return PTR_ERR(acl);
311 error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
312 if (error) 245 if (error)
313 return error; 246 return error;
314 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
315 posix_acl_release(acl);
316 return error;
317}
318 247
319/* 248 if (default_acl) {
320 * Extended attribut handlers 249 error = ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
321 */ 250 posix_acl_release(default_acl);
322static size_t 251 }
323ext2_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_size, 252 if (acl) {
324 const char *name, size_t name_len, int type) 253 if (!error)
325{ 254 error = ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
326 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); 255 posix_acl_release(acl);
327 256 }
328 if (!test_opt(dentry->d_sb, POSIX_ACL))
329 return 0;
330 if (list && size <= list_size)
331 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
332 return size;
333}
334
335static size_t
336ext2_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_size,
337 const char *name, size_t name_len, int type)
338{
339 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
340
341 if (!test_opt(dentry->d_sb, POSIX_ACL))
342 return 0;
343 if (list && size <= list_size)
344 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
345 return size;
346}
347
348static int
349ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
350 size_t size, int type)
351{
352 struct posix_acl *acl;
353 int error;
354
355 if (strcmp(name, "") != 0)
356 return -EINVAL;
357 if (!test_opt(dentry->d_sb, POSIX_ACL))
358 return -EOPNOTSUPP;
359
360 acl = ext2_get_acl(dentry->d_inode, type);
361 if (IS_ERR(acl))
362 return PTR_ERR(acl);
363 if (acl == NULL)
364 return -ENODATA;
365 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
366 posix_acl_release(acl);
367
368 return error;
369}
370
371static int
372ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
373 size_t size, int flags, int type)
374{
375 struct posix_acl *acl;
376 int error;
377
378 if (strcmp(name, "") != 0)
379 return -EINVAL;
380 if (!test_opt(dentry->d_sb, POSIX_ACL))
381 return -EOPNOTSUPP;
382 if (!inode_owner_or_capable(dentry->d_inode))
383 return -EPERM;
384
385 if (value) {
386 acl = posix_acl_from_xattr(&init_user_ns, value, size);
387 if (IS_ERR(acl))
388 return PTR_ERR(acl);
389 else if (acl) {
390 error = posix_acl_valid(acl);
391 if (error)
392 goto release_and_out;
393 }
394 } else
395 acl = NULL;
396
397 error = ext2_set_acl(dentry->d_inode, type, acl);
398
399release_and_out:
400 posix_acl_release(acl);
401 return error; 257 return error;
402} 258}
403
404const struct xattr_handler ext2_xattr_acl_access_handler = {
405 .prefix = POSIX_ACL_XATTR_ACCESS,
406 .flags = ACL_TYPE_ACCESS,
407 .list = ext2_xattr_list_acl_access,
408 .get = ext2_xattr_get_acl,
409 .set = ext2_xattr_set_acl,
410};
411
412const struct xattr_handler ext2_xattr_acl_default_handler = {
413 .prefix = POSIX_ACL_XATTR_DEFAULT,
414 .flags = ACL_TYPE_DEFAULT,
415 .list = ext2_xattr_list_acl_default,
416 .get = ext2_xattr_get_acl,
417 .set = ext2_xattr_set_acl,
418};
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
index 503bfb0ed79b..44937f9fcf32 100644
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -55,7 +55,7 @@ static inline int ext2_acl_count(size_t size)
55 55
56/* acl.c */ 56/* acl.c */
57extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); 57extern struct posix_acl *ext2_get_acl(struct inode *inode, int type);
58extern int ext2_acl_chmod (struct inode *); 58extern int ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
59extern int ext2_init_acl (struct inode *, struct inode *); 59extern int ext2_init_acl (struct inode *, struct inode *);
60 60
61#else 61#else
@@ -63,12 +63,6 @@ extern int ext2_init_acl (struct inode *, struct inode *);
63#define ext2_get_acl NULL 63#define ext2_get_acl NULL
64#define ext2_set_acl NULL 64#define ext2_set_acl NULL
65 65
66static inline int
67ext2_acl_chmod (struct inode *inode)
68{
69 return 0;
70}
71
72static inline int ext2_init_acl (struct inode *inode, struct inode *dir) 66static inline int ext2_init_acl (struct inode *inode, struct inode *dir)
73{ 67{
74 return 0; 68 return 0;
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index a5b3a5db3120..44c36e590765 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -103,5 +103,6 @@ const struct inode_operations ext2_file_inode_operations = {
103#endif 103#endif
104 .setattr = ext2_setattr, 104 .setattr = ext2_setattr,
105 .get_acl = ext2_get_acl, 105 .get_acl = ext2_get_acl,
106 .set_acl = ext2_set_acl,
106 .fiemap = ext2_fiemap, 107 .fiemap = ext2_fiemap,
107}; 108};
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 8a337640a46a..94ed36849b71 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1566,7 +1566,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1566 } 1566 }
1567 setattr_copy(inode, iattr); 1567 setattr_copy(inode, iattr);
1568 if (iattr->ia_valid & ATTR_MODE) 1568 if (iattr->ia_valid & ATTR_MODE)
1569 error = ext2_acl_chmod(inode); 1569 error = posix_acl_chmod(inode, inode->i_mode);
1570 mark_inode_dirty(inode); 1570 mark_inode_dirty(inode);
1571 1571
1572 return error; 1572 return error;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 256dd5f4c1c4..c268d0af1db9 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -421,6 +421,7 @@ const struct inode_operations ext2_dir_inode_operations = {
421#endif 421#endif
422 .setattr = ext2_setattr, 422 .setattr = ext2_setattr,
423 .get_acl = ext2_get_acl, 423 .get_acl = ext2_get_acl,
424 .set_acl = ext2_set_acl,
424 .tmpfile = ext2_tmpfile, 425 .tmpfile = ext2_tmpfile,
425}; 426};
426 427
@@ -433,4 +434,5 @@ const struct inode_operations ext2_special_inode_operations = {
433#endif 434#endif
434 .setattr = ext2_setattr, 435 .setattr = ext2_setattr,
435 .get_acl = ext2_get_acl, 436 .get_acl = ext2_get_acl,
437 .set_acl = ext2_set_acl,
436}; 438};
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 2d7557db3ae8..91426141c33a 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -103,8 +103,8 @@ static struct mb_cache *ext2_xattr_cache;
103static const struct xattr_handler *ext2_xattr_handler_map[] = { 103static const struct xattr_handler *ext2_xattr_handler_map[] = {
104 [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, 104 [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler,
105#ifdef CONFIG_EXT2_FS_POSIX_ACL 105#ifdef CONFIG_EXT2_FS_POSIX_ACL
106 [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, 106 [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
107 [EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext2_xattr_acl_default_handler, 107 [EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
108#endif 108#endif
109 [EXT2_XATTR_INDEX_TRUSTED] = &ext2_xattr_trusted_handler, 109 [EXT2_XATTR_INDEX_TRUSTED] = &ext2_xattr_trusted_handler,
110#ifdef CONFIG_EXT2_FS_SECURITY 110#ifdef CONFIG_EXT2_FS_SECURITY
@@ -116,8 +116,8 @@ const struct xattr_handler *ext2_xattr_handlers[] = {
116 &ext2_xattr_user_handler, 116 &ext2_xattr_user_handler,
117 &ext2_xattr_trusted_handler, 117 &ext2_xattr_trusted_handler,
118#ifdef CONFIG_EXT2_FS_POSIX_ACL 118#ifdef CONFIG_EXT2_FS_POSIX_ACL
119 &ext2_xattr_acl_access_handler, 119 &posix_acl_access_xattr_handler,
120 &ext2_xattr_acl_default_handler, 120 &posix_acl_default_xattr_handler,
121#endif 121#endif
122#ifdef CONFIG_EXT2_FS_SECURITY 122#ifdef CONFIG_EXT2_FS_SECURITY
123 &ext2_xattr_security_handler, 123 &ext2_xattr_security_handler,
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index 5e41cccff762..60edf298644e 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -57,8 +57,6 @@ struct ext2_xattr_entry {
57 57
58extern const struct xattr_handler ext2_xattr_user_handler; 58extern const struct xattr_handler ext2_xattr_user_handler;
59extern const struct xattr_handler ext2_xattr_trusted_handler; 59extern const struct xattr_handler ext2_xattr_trusted_handler;
60extern const struct xattr_handler ext2_xattr_acl_access_handler;
61extern const struct xattr_handler ext2_xattr_acl_default_handler;
62extern const struct xattr_handler ext2_xattr_security_handler; 60extern const struct xattr_handler ext2_xattr_security_handler;
63 61
64extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); 62extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 4f3d8fa0c0a3..8bbaf5bcf982 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -145,13 +145,6 @@ ext3_get_acl(struct inode *inode, int type)
145 struct posix_acl *acl; 145 struct posix_acl *acl;
146 int retval; 146 int retval;
147 147
148 if (!test_opt(inode->i_sb, POSIX_ACL))
149 return NULL;
150
151 acl = get_cached_acl(inode, type);
152 if (acl != ACL_NOT_CACHED)
153 return acl;
154
155 switch (type) { 148 switch (type) {
156 case ACL_TYPE_ACCESS: 149 case ACL_TYPE_ACCESS:
157 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; 150 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -190,7 +183,7 @@ ext3_get_acl(struct inode *inode, int type)
190 * inode->i_mutex: down unless called from ext3_new_inode 183 * inode->i_mutex: down unless called from ext3_new_inode
191 */ 184 */
192static int 185static int
193ext3_set_acl(handle_t *handle, struct inode *inode, int type, 186__ext3_set_acl(handle_t *handle, struct inode *inode, int type,
194 struct posix_acl *acl) 187 struct posix_acl *acl)
195{ 188{
196 int name_index; 189 int name_index;
@@ -198,9 +191,6 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
198 size_t size = 0; 191 size_t size = 0;
199 int error; 192 int error;
200 193
201 if (S_ISLNK(inode->i_mode))
202 return -EOPNOTSUPP;
203
204 switch(type) { 194 switch(type) {
205 case ACL_TYPE_ACCESS: 195 case ACL_TYPE_ACCESS:
206 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; 196 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -243,204 +233,49 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
243 return error; 233 return error;
244} 234}
245 235
246/*
247 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
248 *
249 * dir->i_mutex: down
250 * inode->i_mutex: up (access to inode is still exclusive)
251 */
252int 236int
253ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 237ext3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
254{ 238{
255 struct posix_acl *acl = NULL;
256 int error = 0;
257
258 if (!S_ISLNK(inode->i_mode)) {
259 if (test_opt(dir->i_sb, POSIX_ACL)) {
260 acl = ext3_get_acl(dir, ACL_TYPE_DEFAULT);
261 if (IS_ERR(acl))
262 return PTR_ERR(acl);
263 }
264 if (!acl)
265 inode->i_mode &= ~current_umask();
266 }
267 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
268 if (S_ISDIR(inode->i_mode)) {
269 error = ext3_set_acl(handle, inode,
270 ACL_TYPE_DEFAULT, acl);
271 if (error)
272 goto cleanup;
273 }
274 error = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
275 if (error < 0)
276 return error;
277
278 if (error > 0) {
279 /* This is an extended ACL */
280 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
281 }
282 }
283cleanup:
284 posix_acl_release(acl);
285 return error;
286}
287
288/*
289 * Does chmod for an inode that may have an Access Control List. The
290 * inode->i_mode field must be updated to the desired value by the caller
291 * before calling this function.
292 * Returns 0 on success, or a negative error number.
293 *
294 * We change the ACL rather than storing some ACL entries in the file
295 * mode permission bits (which would be more efficient), because that
296 * would break once additional permissions (like ACL_APPEND, ACL_DELETE
297 * for directories) are added. There are no more bits available in the
298 * file mode.
299 *
300 * inode->i_mutex: down
301 */
302int
303ext3_acl_chmod(struct inode *inode)
304{
305 struct posix_acl *acl;
306 handle_t *handle; 239 handle_t *handle;
307 int retries = 0; 240 int error, retries = 0;
308 int error;
309 241
310 if (S_ISLNK(inode->i_mode))
311 return -EOPNOTSUPP;
312 if (!test_opt(inode->i_sb, POSIX_ACL))
313 return 0;
314 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
315 if (IS_ERR(acl) || !acl)
316 return PTR_ERR(acl);
317 error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
318 if (error)
319 return error;
320retry: 242retry:
321 handle = ext3_journal_start(inode, 243 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
322 EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); 244 if (IS_ERR(handle))
323 if (IS_ERR(handle)) { 245 return PTR_ERR(handle);
324 error = PTR_ERR(handle); 246 error = __ext3_set_acl(handle, inode, type, acl);
325 ext3_std_error(inode->i_sb, error);
326 goto out;
327 }
328 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
329 ext3_journal_stop(handle); 247 ext3_journal_stop(handle);
330 if (error == -ENOSPC && 248 if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
331 ext3_should_retry_alloc(inode->i_sb, &retries))
332 goto retry; 249 goto retry;
333out:
334 posix_acl_release(acl);
335 return error; 250 return error;
336} 251}
337 252
338/* 253/*
339 * Extended attribute handlers 254 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
255 *
256 * dir->i_mutex: down
257 * inode->i_mutex: up (access to inode is still exclusive)
340 */ 258 */
341static size_t 259int
342ext3_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, 260ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
343 const char *name, size_t name_len, int type)
344{
345 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
346
347 if (!test_opt(dentry->d_sb, POSIX_ACL))
348 return 0;
349 if (list && size <= list_len)
350 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
351 return size;
352}
353
354static size_t
355ext3_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len,
356 const char *name, size_t name_len, int type)
357{
358 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
359
360 if (!test_opt(dentry->d_sb, POSIX_ACL))
361 return 0;
362 if (list && size <= list_len)
363 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
364 return size;
365}
366
367static int
368ext3_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
369 size_t size, int type)
370{ 261{
371 struct posix_acl *acl; 262 struct posix_acl *default_acl, *acl;
372 int error; 263 int error;
373 264
374 if (strcmp(name, "") != 0) 265 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
375 return -EINVAL; 266 if (error)
376 if (!test_opt(dentry->d_sb, POSIX_ACL)) 267 return error;
377 return -EOPNOTSUPP;
378
379 acl = ext3_get_acl(dentry->d_inode, type);
380 if (IS_ERR(acl))
381 return PTR_ERR(acl);
382 if (acl == NULL)
383 return -ENODATA;
384 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
385 posix_acl_release(acl);
386
387 return error;
388}
389
390static int
391ext3_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
392 size_t size, int flags, int type)
393{
394 struct inode *inode = dentry->d_inode;
395 handle_t *handle;
396 struct posix_acl *acl;
397 int error, retries = 0;
398
399 if (strcmp(name, "") != 0)
400 return -EINVAL;
401 if (!test_opt(inode->i_sb, POSIX_ACL))
402 return -EOPNOTSUPP;
403 if (!inode_owner_or_capable(inode))
404 return -EPERM;
405
406 if (value) {
407 acl = posix_acl_from_xattr(&init_user_ns, value, size);
408 if (IS_ERR(acl))
409 return PTR_ERR(acl);
410 else if (acl) {
411 error = posix_acl_valid(acl);
412 if (error)
413 goto release_and_out;
414 }
415 } else
416 acl = NULL;
417
418retry:
419 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
420 if (IS_ERR(handle))
421 return PTR_ERR(handle);
422 error = ext3_set_acl(handle, inode, type, acl);
423 ext3_journal_stop(handle);
424 if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
425 goto retry;
426 268
427release_and_out: 269 if (default_acl) {
428 posix_acl_release(acl); 270 error = __ext3_set_acl(handle, inode, ACL_TYPE_DEFAULT,
271 default_acl);
272 posix_acl_release(default_acl);
273 }
274 if (acl) {
275 if (!error)
276 error = __ext3_set_acl(handle, inode, ACL_TYPE_ACCESS,
277 acl);
278 posix_acl_release(acl);
279 }
429 return error; 280 return error;
430} 281}
431
432const struct xattr_handler ext3_xattr_acl_access_handler = {
433 .prefix = POSIX_ACL_XATTR_ACCESS,
434 .flags = ACL_TYPE_ACCESS,
435 .list = ext3_xattr_list_acl_access,
436 .get = ext3_xattr_get_acl,
437 .set = ext3_xattr_set_acl,
438};
439
440const struct xattr_handler ext3_xattr_acl_default_handler = {
441 .prefix = POSIX_ACL_XATTR_DEFAULT,
442 .flags = ACL_TYPE_DEFAULT,
443 .list = ext3_xattr_list_acl_default,
444 .get = ext3_xattr_get_acl,
445 .set = ext3_xattr_set_acl,
446};
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index dbc921e458c5..ea1c69edab9e 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -55,18 +55,13 @@ static inline int ext3_acl_count(size_t size)
55 55
56/* acl.c */ 56/* acl.c */
57extern struct posix_acl *ext3_get_acl(struct inode *inode, int type); 57extern struct posix_acl *ext3_get_acl(struct inode *inode, int type);
58extern int ext3_acl_chmod (struct inode *); 58extern int ext3_set_acl(struct inode *inode, struct posix_acl *acl, int type);
59extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); 59extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
60 60
61#else /* CONFIG_EXT3_FS_POSIX_ACL */ 61#else /* CONFIG_EXT3_FS_POSIX_ACL */
62#include <linux/sched.h> 62#include <linux/sched.h>
63#define ext3_get_acl NULL 63#define ext3_get_acl NULL
64 64#define ext3_set_acl NULL
65static inline int
66ext3_acl_chmod(struct inode *inode)
67{
68 return 0;
69}
70 65
71static inline int 66static inline int
72ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 67ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 25cb413277e9..aad05311392a 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -75,6 +75,7 @@ const struct inode_operations ext3_file_inode_operations = {
75 .removexattr = generic_removexattr, 75 .removexattr = generic_removexattr,
76#endif 76#endif
77 .get_acl = ext3_get_acl, 77 .get_acl = ext3_get_acl,
78 .set_acl = ext3_set_acl,
78 .fiemap = ext3_fiemap, 79 .fiemap = ext3_fiemap,
79}; 80};
80 81
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 2bd85486b879..384b6ebb655f 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -3365,7 +3365,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
3365 mark_inode_dirty(inode); 3365 mark_inode_dirty(inode);
3366 3366
3367 if (ia_valid & ATTR_MODE) 3367 if (ia_valid & ATTR_MODE)
3368 rc = ext3_acl_chmod(inode); 3368 rc = posix_acl_chmod(inode, inode->i_mode);
3369 3369
3370err_out: 3370err_out:
3371 ext3_std_error(inode->i_sb, error); 3371 ext3_std_error(inode->i_sb, error);
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index f8cde46de9cd..f197736dccfa 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2569,6 +2569,7 @@ const struct inode_operations ext3_dir_inode_operations = {
2569 .removexattr = generic_removexattr, 2569 .removexattr = generic_removexattr,
2570#endif 2570#endif
2571 .get_acl = ext3_get_acl, 2571 .get_acl = ext3_get_acl,
2572 .set_acl = ext3_set_acl,
2572}; 2573};
2573 2574
2574const struct inode_operations ext3_special_inode_operations = { 2575const struct inode_operations ext3_special_inode_operations = {
@@ -2580,4 +2581,5 @@ const struct inode_operations ext3_special_inode_operations = {
2580 .removexattr = generic_removexattr, 2581 .removexattr = generic_removexattr,
2581#endif 2582#endif
2582 .get_acl = ext3_get_acl, 2583 .get_acl = ext3_get_acl,
2584 .set_acl = ext3_set_acl,
2583}; 2585};
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index b1fc96383e08..c6874be6d58b 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -102,8 +102,8 @@ static struct mb_cache *ext3_xattr_cache;
102static const struct xattr_handler *ext3_xattr_handler_map[] = { 102static const struct xattr_handler *ext3_xattr_handler_map[] = {
103 [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler, 103 [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler,
104#ifdef CONFIG_EXT3_FS_POSIX_ACL 104#ifdef CONFIG_EXT3_FS_POSIX_ACL
105 [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext3_xattr_acl_access_handler, 105 [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
106 [EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext3_xattr_acl_default_handler, 106 [EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
107#endif 107#endif
108 [EXT3_XATTR_INDEX_TRUSTED] = &ext3_xattr_trusted_handler, 108 [EXT3_XATTR_INDEX_TRUSTED] = &ext3_xattr_trusted_handler,
109#ifdef CONFIG_EXT3_FS_SECURITY 109#ifdef CONFIG_EXT3_FS_SECURITY
@@ -115,8 +115,8 @@ const struct xattr_handler *ext3_xattr_handlers[] = {
115 &ext3_xattr_user_handler, 115 &ext3_xattr_user_handler,
116 &ext3_xattr_trusted_handler, 116 &ext3_xattr_trusted_handler,
117#ifdef CONFIG_EXT3_FS_POSIX_ACL 117#ifdef CONFIG_EXT3_FS_POSIX_ACL
118 &ext3_xattr_acl_access_handler, 118 &posix_acl_access_xattr_handler,
119 &ext3_xattr_acl_default_handler, 119 &posix_acl_default_xattr_handler,
120#endif 120#endif
121#ifdef CONFIG_EXT3_FS_SECURITY 121#ifdef CONFIG_EXT3_FS_SECURITY
122 &ext3_xattr_security_handler, 122 &ext3_xattr_security_handler,
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 2be4f69bfa64..32e93ebf8031 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -60,8 +60,6 @@ struct ext3_xattr_entry {
60 60
61extern const struct xattr_handler ext3_xattr_user_handler; 61extern const struct xattr_handler ext3_xattr_user_handler;
62extern const struct xattr_handler ext3_xattr_trusted_handler; 62extern const struct xattr_handler ext3_xattr_trusted_handler;
63extern const struct xattr_handler ext3_xattr_acl_access_handler;
64extern const struct xattr_handler ext3_xattr_acl_default_handler;
65extern const struct xattr_handler ext3_xattr_security_handler; 63extern const struct xattr_handler ext3_xattr_security_handler;
66 64
67extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); 65extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index f827f3bb6d41..d40c8dbbb0d6 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -152,13 +152,6 @@ ext4_get_acl(struct inode *inode, int type)
152 struct posix_acl *acl; 152 struct posix_acl *acl;
153 int retval; 153 int retval;
154 154
155 if (!test_opt(inode->i_sb, POSIX_ACL))
156 return NULL;
157
158 acl = get_cached_acl(inode, type);
159 if (acl != ACL_NOT_CACHED)
160 return acl;
161
162 switch (type) { 155 switch (type) {
163 case ACL_TYPE_ACCESS: 156 case ACL_TYPE_ACCESS:
164 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; 157 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -196,7 +189,7 @@ ext4_get_acl(struct inode *inode, int type)
196 * inode->i_mutex: down unless called from ext4_new_inode 189 * inode->i_mutex: down unless called from ext4_new_inode
197 */ 190 */
198static int 191static int
199ext4_set_acl(handle_t *handle, struct inode *inode, int type, 192__ext4_set_acl(handle_t *handle, struct inode *inode, int type,
200 struct posix_acl *acl) 193 struct posix_acl *acl)
201{ 194{
202 int name_index; 195 int name_index;
@@ -204,9 +197,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
204 size_t size = 0; 197 size_t size = 0;
205 int error; 198 int error;
206 199
207 if (S_ISLNK(inode->i_mode))
208 return -EOPNOTSUPP;
209
210 switch (type) { 200 switch (type) {
211 case ACL_TYPE_ACCESS: 201 case ACL_TYPE_ACCESS:
212 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; 202 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -248,208 +238,51 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
248 return error; 238 return error;
249} 239}
250 240
251/*
252 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
253 *
254 * dir->i_mutex: down
255 * inode->i_mutex: up (access to inode is still exclusive)
256 */
257int 241int
258ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 242ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
259{ 243{
260 struct posix_acl *acl = NULL;
261 int error = 0;
262
263 if (!S_ISLNK(inode->i_mode)) {
264 if (test_opt(dir->i_sb, POSIX_ACL)) {
265 acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT);
266 if (IS_ERR(acl))
267 return PTR_ERR(acl);
268 }
269 if (!acl)
270 inode->i_mode &= ~current_umask();
271 }
272 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
273 if (S_ISDIR(inode->i_mode)) {
274 error = ext4_set_acl(handle, inode,
275 ACL_TYPE_DEFAULT, acl);
276 if (error)
277 goto cleanup;
278 }
279 error = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
280 if (error < 0)
281 return error;
282
283 if (error > 0) {
284 /* This is an extended ACL */
285 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
286 }
287 }
288cleanup:
289 posix_acl_release(acl);
290 return error;
291}
292
293/*
294 * Does chmod for an inode that may have an Access Control List. The
295 * inode->i_mode field must be updated to the desired value by the caller
296 * before calling this function.
297 * Returns 0 on success, or a negative error number.
298 *
299 * We change the ACL rather than storing some ACL entries in the file
300 * mode permission bits (which would be more efficient), because that
301 * would break once additional permissions (like ACL_APPEND, ACL_DELETE
302 * for directories) are added. There are no more bits available in the
303 * file mode.
304 *
305 * inode->i_mutex: down
306 */
307int
308ext4_acl_chmod(struct inode *inode)
309{
310 struct posix_acl *acl;
311 handle_t *handle; 244 handle_t *handle;
312 int retries = 0; 245 int error, retries = 0;
313 int error;
314
315 246
316 if (S_ISLNK(inode->i_mode))
317 return -EOPNOTSUPP;
318 if (!test_opt(inode->i_sb, POSIX_ACL))
319 return 0;
320 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
321 if (IS_ERR(acl) || !acl)
322 return PTR_ERR(acl);
323 error = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
324 if (error)
325 return error;
326retry: 247retry:
327 handle = ext4_journal_start(inode, EXT4_HT_XATTR, 248 handle = ext4_journal_start(inode, EXT4_HT_XATTR,
328 ext4_jbd2_credits_xattr(inode)); 249 ext4_jbd2_credits_xattr(inode));
329 if (IS_ERR(handle)) { 250 if (IS_ERR(handle))
330 error = PTR_ERR(handle); 251 return PTR_ERR(handle);
331 ext4_std_error(inode->i_sb, error); 252
332 goto out; 253 error = __ext4_set_acl(handle, inode, type, acl);
333 }
334 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
335 ext4_journal_stop(handle); 254 ext4_journal_stop(handle);
336 if (error == -ENOSPC && 255 if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
337 ext4_should_retry_alloc(inode->i_sb, &retries))
338 goto retry; 256 goto retry;
339out:
340 posix_acl_release(acl);
341 return error; 257 return error;
342} 258}
343 259
344/* 260/*
345 * Extended attribute handlers 261 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
262 *
263 * dir->i_mutex: down
264 * inode->i_mutex: up (access to inode is still exclusive)
346 */ 265 */
347static size_t 266int
348ext4_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, 267ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
349 const char *name, size_t name_len, int type)
350{
351 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
352
353 if (!test_opt(dentry->d_sb, POSIX_ACL))
354 return 0;
355 if (list && size <= list_len)
356 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
357 return size;
358}
359
360static size_t
361ext4_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len,
362 const char *name, size_t name_len, int type)
363{
364 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
365
366 if (!test_opt(dentry->d_sb, POSIX_ACL))
367 return 0;
368 if (list && size <= list_len)
369 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
370 return size;
371}
372
373static int
374ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
375 size_t size, int type)
376{ 268{
377 struct posix_acl *acl; 269 struct posix_acl *default_acl, *acl;
378 int error; 270 int error;
379 271
380 if (strcmp(name, "") != 0) 272 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
381 return -EINVAL; 273 if (error)
382 if (!test_opt(dentry->d_sb, POSIX_ACL)) 274 return error;
383 return -EOPNOTSUPP;
384
385 acl = ext4_get_acl(dentry->d_inode, type);
386 if (IS_ERR(acl))
387 return PTR_ERR(acl);
388 if (acl == NULL)
389 return -ENODATA;
390 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
391 posix_acl_release(acl);
392
393 return error;
394}
395
396static int
397ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
398 size_t size, int flags, int type)
399{
400 struct inode *inode = dentry->d_inode;
401 handle_t *handle;
402 struct posix_acl *acl;
403 int error, retries = 0;
404
405 if (strcmp(name, "") != 0)
406 return -EINVAL;
407 if (!test_opt(inode->i_sb, POSIX_ACL))
408 return -EOPNOTSUPP;
409 if (!inode_owner_or_capable(inode))
410 return -EPERM;
411
412 if (value) {
413 acl = posix_acl_from_xattr(&init_user_ns, value, size);
414 if (IS_ERR(acl))
415 return PTR_ERR(acl);
416 else if (acl) {
417 error = posix_acl_valid(acl);
418 if (error)
419 goto release_and_out;
420 }
421 } else
422 acl = NULL;
423 275
424retry: 276 if (default_acl) {
425 handle = ext4_journal_start(inode, EXT4_HT_XATTR, 277 error = __ext4_set_acl(handle, inode, ACL_TYPE_DEFAULT,
426 ext4_jbd2_credits_xattr(inode)); 278 default_acl);
427 if (IS_ERR(handle)) { 279 posix_acl_release(default_acl);
428 error = PTR_ERR(handle); 280 }
429 goto release_and_out; 281 if (acl) {
282 if (!error)
283 error = __ext4_set_acl(handle, inode, ACL_TYPE_ACCESS,
284 acl);
285 posix_acl_release(acl);
430 } 286 }
431 error = ext4_set_acl(handle, inode, type, acl);
432 ext4_journal_stop(handle);
433 if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
434 goto retry;
435
436release_and_out:
437 posix_acl_release(acl);
438 return error; 287 return error;
439} 288}
440
441const struct xattr_handler ext4_xattr_acl_access_handler = {
442 .prefix = POSIX_ACL_XATTR_ACCESS,
443 .flags = ACL_TYPE_ACCESS,
444 .list = ext4_xattr_list_acl_access,
445 .get = ext4_xattr_get_acl,
446 .set = ext4_xattr_set_acl,
447};
448
449const struct xattr_handler ext4_xattr_acl_default_handler = {
450 .prefix = POSIX_ACL_XATTR_DEFAULT,
451 .flags = ACL_TYPE_DEFAULT,
452 .list = ext4_xattr_list_acl_default,
453 .get = ext4_xattr_get_acl,
454 .set = ext4_xattr_set_acl,
455};
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 18cb39ed7c7b..da2c79577d72 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -55,18 +55,13 @@ static inline int ext4_acl_count(size_t size)
55 55
56/* acl.c */ 56/* acl.c */
57struct posix_acl *ext4_get_acl(struct inode *inode, int type); 57struct posix_acl *ext4_get_acl(struct inode *inode, int type);
58extern int ext4_acl_chmod(struct inode *); 58int ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type);
59extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); 59extern int ext4_init_acl(handle_t *, struct inode *, struct inode *);
60 60
61#else /* CONFIG_EXT4_FS_POSIX_ACL */ 61#else /* CONFIG_EXT4_FS_POSIX_ACL */
62#include <linux/sched.h> 62#include <linux/sched.h>
63#define ext4_get_acl NULL 63#define ext4_get_acl NULL
64 64#define ext4_set_acl NULL
65static inline int
66ext4_acl_chmod(struct inode *inode)
67{
68 return 0;
69}
70 65
71static inline int 66static inline int
72ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 67ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3da21945ff1f..43e64f6022eb 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -617,6 +617,7 @@ const struct inode_operations ext4_file_inode_operations = {
617 .listxattr = ext4_listxattr, 617 .listxattr = ext4_listxattr,
618 .removexattr = generic_removexattr, 618 .removexattr = generic_removexattr,
619 .get_acl = ext4_get_acl, 619 .get_acl = ext4_get_acl,
620 .set_acl = ext4_set_acl,
620 .fiemap = ext4_fiemap, 621 .fiemap = ext4_fiemap,
621}; 622};
622 623
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 61d49ff22c81..23983c2cf959 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4663,7 +4663,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
4663 ext4_orphan_del(NULL, inode); 4663 ext4_orphan_del(NULL, inode);
4664 4664
4665 if (!rc && (ia_valid & ATTR_MODE)) 4665 if (!rc && (ia_valid & ATTR_MODE))
4666 rc = ext4_acl_chmod(inode); 4666 rc = posix_acl_chmod(inode, inode->i_mode);
4667 4667
4668err_out: 4668err_out:
4669 ext4_std_error(inode->i_sb, error); 4669 ext4_std_error(inode->i_sb, error);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5a0408d7b114..e77c1ba6c8af 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3225,6 +3225,7 @@ const struct inode_operations ext4_dir_inode_operations = {
3225 .listxattr = ext4_listxattr, 3225 .listxattr = ext4_listxattr,
3226 .removexattr = generic_removexattr, 3226 .removexattr = generic_removexattr,
3227 .get_acl = ext4_get_acl, 3227 .get_acl = ext4_get_acl,
3228 .set_acl = ext4_set_acl,
3228 .fiemap = ext4_fiemap, 3229 .fiemap = ext4_fiemap,
3229}; 3230};
3230 3231
@@ -3235,4 +3236,5 @@ const struct inode_operations ext4_special_inode_operations = {
3235 .listxattr = ext4_listxattr, 3236 .listxattr = ext4_listxattr,
3236 .removexattr = generic_removexattr, 3237 .removexattr = generic_removexattr,
3237 .get_acl = ext4_get_acl, 3238 .get_acl = ext4_get_acl,
3239 .set_acl = ext4_set_acl,
3238}; 3240};
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 1423c4816a47..e175e94116ac 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -95,8 +95,8 @@ static struct mb_cache *ext4_xattr_cache;
95static const struct xattr_handler *ext4_xattr_handler_map[] = { 95static const struct xattr_handler *ext4_xattr_handler_map[] = {
96 [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, 96 [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler,
97#ifdef CONFIG_EXT4_FS_POSIX_ACL 97#ifdef CONFIG_EXT4_FS_POSIX_ACL
98 [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, 98 [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
99 [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext4_xattr_acl_default_handler, 99 [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
100#endif 100#endif
101 [EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler, 101 [EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler,
102#ifdef CONFIG_EXT4_FS_SECURITY 102#ifdef CONFIG_EXT4_FS_SECURITY
@@ -108,8 +108,8 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
108 &ext4_xattr_user_handler, 108 &ext4_xattr_user_handler,
109 &ext4_xattr_trusted_handler, 109 &ext4_xattr_trusted_handler,
110#ifdef CONFIG_EXT4_FS_POSIX_ACL 110#ifdef CONFIG_EXT4_FS_POSIX_ACL
111 &ext4_xattr_acl_access_handler, 111 &posix_acl_access_xattr_handler,
112 &ext4_xattr_acl_default_handler, 112 &posix_acl_default_xattr_handler,
113#endif 113#endif
114#ifdef CONFIG_EXT4_FS_SECURITY 114#ifdef CONFIG_EXT4_FS_SECURITY
115 &ext4_xattr_security_handler, 115 &ext4_xattr_security_handler,
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index c767dbdd7fc4..819d6398833f 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -96,8 +96,6 @@ struct ext4_xattr_ibody_find {
96 96
97extern const struct xattr_handler ext4_xattr_user_handler; 97extern const struct xattr_handler ext4_xattr_user_handler;
98extern const struct xattr_handler ext4_xattr_trusted_handler; 98extern const struct xattr_handler ext4_xattr_trusted_handler;
99extern const struct xattr_handler ext4_xattr_acl_access_handler;
100extern const struct xattr_handler ext4_xattr_acl_default_handler;
101extern const struct xattr_handler ext4_xattr_security_handler; 99extern const struct xattr_handler ext4_xattr_security_handler;
102 100
103extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); 101extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);