aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/acl.c')
-rw-r--r--fs/ocfs2/acl.c169
1 files changed, 98 insertions, 71 deletions
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index fbeaec762103..e13fc9e8fcdc 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h>
24#include <linux/string.h> 25#include <linux/string.h>
25 26
26#define MLOG_MASK_PREFIX ML_INODE 27#define MLOG_MASK_PREFIX ML_INODE
@@ -30,6 +31,8 @@
30#include "alloc.h" 31#include "alloc.h"
31#include "dlmglue.h" 32#include "dlmglue.h"
32#include "file.h" 33#include "file.h"
34#include "inode.h"
35#include "journal.h"
33#include "ocfs2_fs.h" 36#include "ocfs2_fs.h"
34 37
35#include "xattr.h" 38#include "xattr.h"
@@ -98,15 +101,11 @@ static struct posix_acl *ocfs2_get_acl_nolock(struct inode *inode,
98 int type, 101 int type,
99 struct buffer_head *di_bh) 102 struct buffer_head *di_bh)
100{ 103{
101 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
102 int name_index; 104 int name_index;
103 char *value = NULL; 105 char *value = NULL;
104 struct posix_acl *acl; 106 struct posix_acl *acl;
105 int retval; 107 int retval;
106 108
107 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
108 return NULL;
109
110 switch (type) { 109 switch (type) {
111 case ACL_TYPE_ACCESS: 110 case ACL_TYPE_ACCESS:
112 name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS; 111 name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -170,6 +169,60 @@ static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type)
170} 169}
171 170
172/* 171/*
172 * Helper function to set i_mode in memory and disk. Some call paths
173 * will not have di_bh or a journal handle to pass, in which case it
174 * will create it's own.
175 */
176static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh,
177 handle_t *handle, umode_t new_mode)
178{
179 int ret, commit_handle = 0;
180 struct ocfs2_dinode *di;
181
182 if (di_bh == NULL) {
183 ret = ocfs2_read_inode_block(inode, &di_bh);
184 if (ret) {
185 mlog_errno(ret);
186 goto out;
187 }
188 } else
189 get_bh(di_bh);
190
191 if (handle == NULL) {
192 handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb),
193 OCFS2_INODE_UPDATE_CREDITS);
194 if (IS_ERR(handle)) {
195 ret = PTR_ERR(handle);
196 mlog_errno(ret);
197 goto out_brelse;
198 }
199
200 commit_handle = 1;
201 }
202
203 di = (struct ocfs2_dinode *)di_bh->b_data;
204 ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
205 OCFS2_JOURNAL_ACCESS_WRITE);
206 if (ret) {
207 mlog_errno(ret);
208 goto out_commit;
209 }
210
211 inode->i_mode = new_mode;
212 di->i_mode = cpu_to_le16(inode->i_mode);
213
214 ocfs2_journal_dirty(handle, di_bh);
215
216out_commit:
217 if (commit_handle)
218 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
219out_brelse:
220 brelse(di_bh);
221out:
222 return ret;
223}
224
225/*
173 * Set the access or default ACL of an inode. 226 * Set the access or default ACL of an inode.
174 */ 227 */
175static int ocfs2_set_acl(handle_t *handle, 228static int ocfs2_set_acl(handle_t *handle,
@@ -197,9 +250,14 @@ static int ocfs2_set_acl(handle_t *handle,
197 if (ret < 0) 250 if (ret < 0)
198 return ret; 251 return ret;
199 else { 252 else {
200 inode->i_mode = mode;
201 if (ret == 0) 253 if (ret == 0)
202 acl = NULL; 254 acl = NULL;
255
256 ret = ocfs2_acl_set_mode(inode, di_bh,
257 handle, mode);
258 if (ret)
259 return ret;
260
203 } 261 }
204 } 262 }
205 break; 263 break;
@@ -287,6 +345,7 @@ int ocfs2_init_acl(handle_t *handle,
287 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 345 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
288 struct posix_acl *acl = NULL; 346 struct posix_acl *acl = NULL;
289 int ret = 0; 347 int ret = 0;
348 mode_t mode;
290 349
291 if (!S_ISLNK(inode->i_mode)) { 350 if (!S_ISLNK(inode->i_mode)) {
292 if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { 351 if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
@@ -295,12 +354,17 @@ int ocfs2_init_acl(handle_t *handle,
295 if (IS_ERR(acl)) 354 if (IS_ERR(acl))
296 return PTR_ERR(acl); 355 return PTR_ERR(acl);
297 } 356 }
298 if (!acl) 357 if (!acl) {
299 inode->i_mode &= ~current_umask(); 358 mode = inode->i_mode & ~current_umask();
359 ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
360 if (ret) {
361 mlog_errno(ret);
362 goto cleanup;
363 }
364 }
300 } 365 }
301 if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { 366 if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
302 struct posix_acl *clone; 367 struct posix_acl *clone;
303 mode_t mode;
304 368
305 if (S_ISDIR(inode->i_mode)) { 369 if (S_ISDIR(inode->i_mode)) {
306 ret = ocfs2_set_acl(handle, inode, di_bh, 370 ret = ocfs2_set_acl(handle, inode, di_bh,
@@ -317,7 +381,7 @@ int ocfs2_init_acl(handle_t *handle,
317 mode = inode->i_mode; 381 mode = inode->i_mode;
318 ret = posix_acl_create_masq(clone, &mode); 382 ret = posix_acl_create_masq(clone, &mode);
319 if (ret >= 0) { 383 if (ret >= 0) {
320 inode->i_mode = mode; 384 ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
321 if (ret > 0) { 385 if (ret > 0) {
322 ret = ocfs2_set_acl(handle, inode, 386 ret = ocfs2_set_acl(handle, inode,
323 di_bh, ACL_TYPE_ACCESS, 387 di_bh, ACL_TYPE_ACCESS,
@@ -331,13 +395,14 @@ cleanup:
331 return ret; 395 return ret;
332} 396}
333 397
334static size_t ocfs2_xattr_list_acl_access(struct inode *inode, 398static size_t ocfs2_xattr_list_acl_access(struct dentry *dentry,
335 char *list, 399 char *list,
336 size_t list_len, 400 size_t list_len,
337 const char *name, 401 const char *name,
338 size_t name_len) 402 size_t name_len,
403 int type)
339{ 404{
340 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 405 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
341 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); 406 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
342 407
343 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) 408 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
@@ -348,13 +413,14 @@ static size_t ocfs2_xattr_list_acl_access(struct inode *inode,
348 return size; 413 return size;
349} 414}
350 415
351static size_t ocfs2_xattr_list_acl_default(struct inode *inode, 416static size_t ocfs2_xattr_list_acl_default(struct dentry *dentry,
352 char *list, 417 char *list,
353 size_t list_len, 418 size_t list_len,
354 const char *name, 419 const char *name,
355 size_t name_len) 420 size_t name_len,
421 int type)
356{ 422{
357 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 423 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
358 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); 424 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
359 425
360 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) 426 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
@@ -365,19 +431,19 @@ static size_t ocfs2_xattr_list_acl_default(struct inode *inode,
365 return size; 431 return size;
366} 432}
367 433
368static int ocfs2_xattr_get_acl(struct inode *inode, 434static int ocfs2_xattr_get_acl(struct dentry *dentry, const char *name,
369 int type, 435 void *buffer, size_t size, int type)
370 void *buffer,
371 size_t size)
372{ 436{
373 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 437 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
374 struct posix_acl *acl; 438 struct posix_acl *acl;
375 int ret; 439 int ret;
376 440
441 if (strcmp(name, "") != 0)
442 return -EINVAL;
377 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) 443 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
378 return -EOPNOTSUPP; 444 return -EOPNOTSUPP;
379 445
380 acl = ocfs2_get_acl(inode, type); 446 acl = ocfs2_get_acl(dentry->d_inode, type);
381 if (IS_ERR(acl)) 447 if (IS_ERR(acl))
382 return PTR_ERR(acl); 448 return PTR_ERR(acl);
383 if (acl == NULL) 449 if (acl == NULL)
@@ -388,35 +454,16 @@ static int ocfs2_xattr_get_acl(struct inode *inode,
388 return ret; 454 return ret;
389} 455}
390 456
391static int ocfs2_xattr_get_acl_access(struct inode *inode, 457static int ocfs2_xattr_set_acl(struct dentry *dentry, const char *name,
392 const char *name, 458 const void *value, size_t size, int flags, int type)
393 void *buffer,
394 size_t size)
395{
396 if (strcmp(name, "") != 0)
397 return -EINVAL;
398 return ocfs2_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
399}
400
401static int ocfs2_xattr_get_acl_default(struct inode *inode,
402 const char *name,
403 void *buffer,
404 size_t size)
405{
406 if (strcmp(name, "") != 0)
407 return -EINVAL;
408 return ocfs2_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
409}
410
411static int ocfs2_xattr_set_acl(struct inode *inode,
412 int type,
413 const void *value,
414 size_t size)
415{ 459{
460 struct inode *inode = dentry->d_inode;
416 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 461 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
417 struct posix_acl *acl; 462 struct posix_acl *acl;
418 int ret = 0; 463 int ret = 0;
419 464
465 if (strcmp(name, "") != 0)
466 return -EINVAL;
420 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) 467 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
421 return -EOPNOTSUPP; 468 return -EOPNOTSUPP;
422 469
@@ -442,38 +489,18 @@ cleanup:
442 return ret; 489 return ret;
443} 490}
444 491
445static int ocfs2_xattr_set_acl_access(struct inode *inode,
446 const char *name,
447 const void *value,
448 size_t size,
449 int flags)
450{
451 if (strcmp(name, "") != 0)
452 return -EINVAL;
453 return ocfs2_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
454}
455
456static int ocfs2_xattr_set_acl_default(struct inode *inode,
457 const char *name,
458 const void *value,
459 size_t size,
460 int flags)
461{
462 if (strcmp(name, "") != 0)
463 return -EINVAL;
464 return ocfs2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
465}
466
467struct xattr_handler ocfs2_xattr_acl_access_handler = { 492struct xattr_handler ocfs2_xattr_acl_access_handler = {
468 .prefix = POSIX_ACL_XATTR_ACCESS, 493 .prefix = POSIX_ACL_XATTR_ACCESS,
494 .flags = ACL_TYPE_ACCESS,
469 .list = ocfs2_xattr_list_acl_access, 495 .list = ocfs2_xattr_list_acl_access,
470 .get = ocfs2_xattr_get_acl_access, 496 .get = ocfs2_xattr_get_acl,
471 .set = ocfs2_xattr_set_acl_access, 497 .set = ocfs2_xattr_set_acl,
472}; 498};
473 499
474struct xattr_handler ocfs2_xattr_acl_default_handler = { 500struct xattr_handler ocfs2_xattr_acl_default_handler = {
475 .prefix = POSIX_ACL_XATTR_DEFAULT, 501 .prefix = POSIX_ACL_XATTR_DEFAULT,
502 .flags = ACL_TYPE_DEFAULT,
476 .list = ocfs2_xattr_list_acl_default, 503 .list = ocfs2_xattr_list_acl_default,
477 .get = ocfs2_xattr_get_acl_default, 504 .get = ocfs2_xattr_get_acl,
478 .set = ocfs2_xattr_set_acl_default, 505 .set = ocfs2_xattr_set_acl,
479}; 506};