acl.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) International Business Machines Corp., 2002-2004
  4. * Copyright (C) Andreas Gruenbacher, 2001
  5. * Copyright (C) Linus Torvalds, 1991, 1992
  6. */
  7. #include <linux/sched.h>
  8. #include <linux/slab.h>
  9. #include <linux/fs.h>
  10. #include <linux/posix_acl_xattr.h>
  11. #include "jfs_incore.h"
  12. #include "jfs_txnmgr.h"
  13. #include "jfs_xattr.h"
  14. #include "jfs_acl.h"
  15. struct posix_acl *jfs_get_acl(struct inode *inode, int type)
  16. {
  17. struct posix_acl *acl;
  18. char *ea_name;
  19. int size;
  20. char *value = NULL;
  21. switch(type) {
  22. case ACL_TYPE_ACCESS:
  23. ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
  24. break;
  25. case ACL_TYPE_DEFAULT:
  26. ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
  27. break;
  28. default:
  29. return ERR_PTR(-EINVAL);
  30. }
  31. size = __jfs_getxattr(inode, ea_name, NULL, 0);
  32. if (size > 0) {
  33. value = kmalloc(size, GFP_KERNEL);
  34. if (!value)
  35. return ERR_PTR(-ENOMEM);
  36. size = __jfs_getxattr(inode, ea_name, value, size);
  37. }
  38. if (size < 0) {
  39. if (size == -ENODATA)
  40. acl = NULL;
  41. else
  42. acl = ERR_PTR(size);
  43. } else {
  44. acl = posix_acl_from_xattr(&init_user_ns, value, size);
  45. }
  46. kfree(value);
  47. return acl;
  48. }
  49. static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
  50. struct posix_acl *acl)
  51. {
  52. char *ea_name;
  53. int rc;
  54. int size = 0;
  55. char *value = NULL;
  56. switch (type) {
  57. case ACL_TYPE_ACCESS:
  58. ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
  59. break;
  60. case ACL_TYPE_DEFAULT:
  61. ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
  62. break;
  63. default:
  64. return -EINVAL;
  65. }
  66. if (acl) {
  67. size = posix_acl_xattr_size(acl->a_count);
  68. value = kmalloc(size, GFP_KERNEL);
  69. if (!value)
  70. return -ENOMEM;
  71. rc = posix_acl_to_xattr(&init_user_ns, acl, value, size);
  72. if (rc < 0)
  73. goto out;
  74. }
  75. rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0);
  76. out:
  77. kfree(value);
  78. if (!rc)
  79. set_cached_acl(inode, type, acl);
  80. return rc;
  81. }
  82. int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
  83. {
  84. int rc;
  85. tid_t tid;
  86. int update_mode = 0;
  87. umode_t mode = inode->i_mode;
  88. tid = txBegin(inode->i_sb, 0);
  89. mutex_lock(&JFS_IP(inode)->commit_mutex);
  90. if (type == ACL_TYPE_ACCESS && acl) {
  91. rc = posix_acl_update_mode(inode, &mode, &acl);
  92. if (rc)
  93. goto end_tx;
  94. if (mode != inode->i_mode)
  95. update_mode = 1;
  96. }
  97. rc = __jfs_set_acl(tid, inode, type, acl);
  98. if (!rc) {
  99. if (update_mode) {
  100. inode->i_mode = mode;
  101. inode->i_ctime = current_time(inode);
  102. mark_inode_dirty(inode);
  103. }
  104. rc = txCommit(tid, 1, &inode, 0);
  105. }
  106. end_tx:
  107. txEnd(tid);
  108. mutex_unlock(&JFS_IP(inode)->commit_mutex);
  109. return rc;
  110. }
  111. int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
  112. {
  113. struct posix_acl *default_acl, *acl;
  114. int rc = 0;
  115. rc = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
  116. if (rc)
  117. return rc;
  118. if (default_acl) {
  119. rc = __jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, default_acl);
  120. posix_acl_release(default_acl);
  121. } else {
  122. inode->i_default_acl = NULL;
  123. }
  124. if (acl) {
  125. if (!rc)
  126. rc = __jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
  127. posix_acl_release(acl);
  128. } else {
  129. inode->i_acl = NULL;
  130. }
  131. JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
  132. inode->i_mode;
  133. return rc;
  134. }