aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/acl.c')
-rw-r--r--fs/btrfs/acl.c82
1 files changed, 33 insertions, 49 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 361604244271..6ef7b26724ec 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -22,6 +22,7 @@
22#include <linux/posix_acl_xattr.h> 22#include <linux/posix_acl_xattr.h>
23#include <linux/posix_acl.h> 23#include <linux/posix_acl.h>
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/slab.h>
25 26
26#include "ctree.h" 27#include "ctree.h"
27#include "btrfs_inode.h" 28#include "btrfs_inode.h"
@@ -73,13 +74,13 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
73 return acl; 74 return acl;
74} 75}
75 76
76static int btrfs_xattr_get_acl(struct inode *inode, int type, 77static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name,
77 void *value, size_t size) 78 void *value, size_t size, int type)
78{ 79{
79 struct posix_acl *acl; 80 struct posix_acl *acl;
80 int ret = 0; 81 int ret = 0;
81 82
82 acl = btrfs_get_acl(inode, type); 83 acl = btrfs_get_acl(dentry->d_inode, type);
83 84
84 if (IS_ERR(acl)) 85 if (IS_ERR(acl))
85 return PTR_ERR(acl); 86 return PTR_ERR(acl);
@@ -94,7 +95,8 @@ static int btrfs_xattr_get_acl(struct inode *inode, int type,
94/* 95/*
95 * Needs to be called with fs_mutex held 96 * Needs to be called with fs_mutex held
96 */ 97 */
97static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) 98static int btrfs_set_acl(struct btrfs_trans_handle *trans,
99 struct inode *inode, struct posix_acl *acl, int type)
98{ 100{
99 int ret, size = 0; 101 int ret, size = 0;
100 const char *name; 102 const char *name;
@@ -111,12 +113,14 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
111 switch (type) { 113 switch (type) {
112 case ACL_TYPE_ACCESS: 114 case ACL_TYPE_ACCESS:
113 mode = inode->i_mode; 115 mode = inode->i_mode;
114 ret = posix_acl_equiv_mode(acl, &mode);
115 if (ret < 0)
116 return ret;
117 ret = 0;
118 inode->i_mode = mode;
119 name = POSIX_ACL_XATTR_ACCESS; 116 name = POSIX_ACL_XATTR_ACCESS;
117 if (acl) {
118 ret = posix_acl_equiv_mode(acl, &mode);
119 if (ret < 0)
120 return ret;
121 inode->i_mode = mode;
122 }
123 ret = 0;
120 break; 124 break;
121 case ACL_TYPE_DEFAULT: 125 case ACL_TYPE_DEFAULT:
122 if (!S_ISDIR(inode->i_mode)) 126 if (!S_ISDIR(inode->i_mode))
@@ -140,8 +144,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
140 goto out; 144 goto out;
141 } 145 }
142 146
143 ret = __btrfs_setxattr(inode, name, value, size, 0); 147 ret = __btrfs_setxattr(trans, inode, name, value, size, 0);
144
145out: 148out:
146 kfree(value); 149 kfree(value);
147 150
@@ -151,10 +154,10 @@ out:
151 return ret; 154 return ret;
152} 155}
153 156
154static int btrfs_xattr_set_acl(struct inode *inode, int type, 157static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
155 const void *value, size_t size) 158 const void *value, size_t size, int flags, int type)
156{ 159{
157 int ret = 0; 160 int ret;
158 struct posix_acl *acl = NULL; 161 struct posix_acl *acl = NULL;
159 162
160 if (value) { 163 if (value) {
@@ -167,38 +170,13 @@ static int btrfs_xattr_set_acl(struct inode *inode, int type,
167 } 170 }
168 } 171 }
169 172
170 ret = btrfs_set_acl(inode, acl, type); 173 ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type);
171 174
172 posix_acl_release(acl); 175 posix_acl_release(acl);
173 176
174 return ret; 177 return ret;
175} 178}
176 179
177
178static int btrfs_xattr_acl_access_get(struct inode *inode, const char *name,
179 void *value, size_t size)
180{
181 return btrfs_xattr_get_acl(inode, ACL_TYPE_ACCESS, value, size);
182}
183
184static int btrfs_xattr_acl_access_set(struct inode *inode, const char *name,
185 const void *value, size_t size, int flags)
186{
187 return btrfs_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
188}
189
190static int btrfs_xattr_acl_default_get(struct inode *inode, const char *name,
191 void *value, size_t size)
192{
193 return btrfs_xattr_get_acl(inode, ACL_TYPE_DEFAULT, value, size);
194}
195
196static int btrfs_xattr_acl_default_set(struct inode *inode, const char *name,
197 const void *value, size_t size, int flags)
198{
199 return btrfs_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
200}
201
202int btrfs_check_acl(struct inode *inode, int mask) 180int btrfs_check_acl(struct inode *inode, int mask)
203{ 181{
204 struct posix_acl *acl; 182 struct posix_acl *acl;
@@ -221,7 +199,8 @@ int btrfs_check_acl(struct inode *inode, int mask)
221 * stuff has been fixed to work with that. If the locking stuff changes, we 199 * stuff has been fixed to work with that. If the locking stuff changes, we
222 * need to re-evaluate the acl locking stuff. 200 * need to re-evaluate the acl locking stuff.
223 */ 201 */
224int btrfs_init_acl(struct inode *inode, struct inode *dir) 202int btrfs_init_acl(struct btrfs_trans_handle *trans,
203 struct inode *inode, struct inode *dir)
225{ 204{
226 struct posix_acl *acl = NULL; 205 struct posix_acl *acl = NULL;
227 int ret = 0; 206 int ret = 0;
@@ -246,7 +225,8 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
246 mode_t mode; 225 mode_t mode;
247 226
248 if (S_ISDIR(inode->i_mode)) { 227 if (S_ISDIR(inode->i_mode)) {
249 ret = btrfs_set_acl(inode, acl, ACL_TYPE_DEFAULT); 228 ret = btrfs_set_acl(trans, inode, acl,
229 ACL_TYPE_DEFAULT);
250 if (ret) 230 if (ret)
251 goto failed; 231 goto failed;
252 } 232 }
@@ -261,10 +241,11 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
261 inode->i_mode = mode; 241 inode->i_mode = mode;
262 if (ret > 0) { 242 if (ret > 0) {
263 /* we need an acl */ 243 /* we need an acl */
264 ret = btrfs_set_acl(inode, clone, 244 ret = btrfs_set_acl(trans, inode, clone,
265 ACL_TYPE_ACCESS); 245 ACL_TYPE_ACCESS);
266 } 246 }
267 } 247 }
248 posix_acl_release(clone);
268 } 249 }
269failed: 250failed:
270 posix_acl_release(acl); 251 posix_acl_release(acl);
@@ -294,7 +275,7 @@ int btrfs_acl_chmod(struct inode *inode)
294 275
295 ret = posix_acl_chmod_masq(clone, inode->i_mode); 276 ret = posix_acl_chmod_masq(clone, inode->i_mode);
296 if (!ret) 277 if (!ret)
297 ret = btrfs_set_acl(inode, clone, ACL_TYPE_ACCESS); 278 ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS);
298 279
299 posix_acl_release(clone); 280 posix_acl_release(clone);
300 281
@@ -303,14 +284,16 @@ int btrfs_acl_chmod(struct inode *inode)
303 284
304struct xattr_handler btrfs_xattr_acl_default_handler = { 285struct xattr_handler btrfs_xattr_acl_default_handler = {
305 .prefix = POSIX_ACL_XATTR_DEFAULT, 286 .prefix = POSIX_ACL_XATTR_DEFAULT,
306 .get = btrfs_xattr_acl_default_get, 287 .flags = ACL_TYPE_DEFAULT,
307 .set = btrfs_xattr_acl_default_set, 288 .get = btrfs_xattr_acl_get,
289 .set = btrfs_xattr_acl_set,
308}; 290};
309 291
310struct xattr_handler btrfs_xattr_acl_access_handler = { 292struct xattr_handler btrfs_xattr_acl_access_handler = {
311 .prefix = POSIX_ACL_XATTR_ACCESS, 293 .prefix = POSIX_ACL_XATTR_ACCESS,
312 .get = btrfs_xattr_acl_access_get, 294 .flags = ACL_TYPE_ACCESS,
313 .set = btrfs_xattr_acl_access_set, 295 .get = btrfs_xattr_acl_get,
296 .set = btrfs_xattr_acl_set,
314}; 297};
315 298
316#else /* CONFIG_BTRFS_FS_POSIX_ACL */ 299#else /* CONFIG_BTRFS_FS_POSIX_ACL */
@@ -320,7 +303,8 @@ int btrfs_acl_chmod(struct inode *inode)
320 return 0; 303 return 0;
321} 304}
322 305
323int btrfs_init_acl(struct inode *inode, struct inode *dir) 306int btrfs_init_acl(struct btrfs_trans_handle *trans,
307 struct inode *inode, struct inode *dir)
324{ 308{
325 return 0; 309 return 0;
326} 310}