aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/posix_acl.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-12-20 08:16:46 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-01-25 23:58:20 -0500
commitb0a7ab5706647844e7a1b91b0c31cdb3bee1e1cc (patch)
tree44ca5a54d751a42f36acb53116da3240fc3a7bb3 /fs/hfsplus/posix_acl.c
parenta6dda0e63e97122ce9e0ba04367e37cca28315fa (diff)
hfsplus: use generic posix ACL infrastructure
Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Vyacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/hfsplus/posix_acl.c')
-rw-r--r--fs/hfsplus/posix_acl.c168
1 files changed, 17 insertions, 151 deletions
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
index 277942f36f80..df0c9af68d05 100644
--- a/fs/hfsplus/posix_acl.c
+++ b/fs/hfsplus/posix_acl.c
@@ -17,9 +17,7 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
17 char *value = NULL; 17 char *value = NULL;
18 ssize_t size; 18 ssize_t size;
19 19
20 acl = get_cached_acl(inode, type); 20 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
21 if (acl != ACL_NOT_CACHED)
22 return acl;
23 21
24 switch (type) { 22 switch (type) {
25 case ACL_TYPE_ACCESS: 23 case ACL_TYPE_ACCESS:
@@ -56,17 +54,15 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
56 return acl; 54 return acl;
57} 55}
58 56
59static int hfsplus_set_posix_acl(struct inode *inode, 57int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
60 int type, 58 int type)
61 struct posix_acl *acl)
62{ 59{
63 int err; 60 int err;
64 char *xattr_name; 61 char *xattr_name;
65 size_t size = 0; 62 size_t size = 0;
66 char *value = NULL; 63 char *value = NULL;
67 64
68 if (S_ISLNK(inode->i_mode)) 65 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
69 return -EOPNOTSUPP;
70 66
71 switch (type) { 67 switch (type) {
72 case ACL_TYPE_ACCESS: 68 case ACL_TYPE_ACCESS:
@@ -115,7 +111,7 @@ end_set_acl:
115int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) 111int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
116{ 112{
117 int err = 0; 113 int err = 0;
118 struct posix_acl *acl = NULL; 114 struct posix_acl *default_acl, *acl;
119 115
120 hfs_dbg(ACL_MOD, 116 hfs_dbg(ACL_MOD,
121 "[%s]: ino %lu, dir->ino %lu\n", 117 "[%s]: ino %lu, dir->ino %lu\n",
@@ -124,151 +120,21 @@ int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
124 if (S_ISLNK(inode->i_mode)) 120 if (S_ISLNK(inode->i_mode))
125 return 0; 121 return 0;
126 122
127 acl = hfsplus_get_posix_acl(dir, ACL_TYPE_DEFAULT); 123 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
128 if (IS_ERR(acl)) 124 if (err)
129 return PTR_ERR(acl);
130
131 if (acl) {
132 if (S_ISDIR(inode->i_mode)) {
133 err = hfsplus_set_posix_acl(inode,
134 ACL_TYPE_DEFAULT,
135 acl);
136 if (unlikely(err))
137 goto init_acl_cleanup;
138 }
139
140 err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
141 if (unlikely(err < 0))
142 return err;
143
144 if (err > 0)
145 err = hfsplus_set_posix_acl(inode,
146 ACL_TYPE_ACCESS,
147 acl);
148 } else
149 inode->i_mode &= ~current_umask();
150
151init_acl_cleanup:
152 posix_acl_release(acl);
153 return err;
154}
155
156int hfsplus_posix_acl_chmod(struct inode *inode)
157{
158 int err;
159 struct posix_acl *acl;
160
161 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
162
163 if (S_ISLNK(inode->i_mode))
164 return -EOPNOTSUPP;
165
166 acl = hfsplus_get_posix_acl(inode, ACL_TYPE_ACCESS);
167 if (IS_ERR(acl) || !acl)
168 return PTR_ERR(acl);
169
170 err = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
171 if (unlikely(err))
172 return err; 125 return err;
173 126
174 err = hfsplus_set_posix_acl(inode, ACL_TYPE_ACCESS, acl); 127 if (default_acl) {
175 posix_acl_release(acl); 128 err = hfsplus_set_posix_acl(inode, default_acl,
176 return err; 129 ACL_TYPE_DEFAULT);
177} 130 posix_acl_release(default_acl);
178
179static int hfsplus_xattr_get_posix_acl(struct dentry *dentry,
180 const char *name,
181 void *buffer,
182 size_t size,
183 int type)
184{
185 int err = 0;
186 struct posix_acl *acl;
187
188 hfs_dbg(ACL_MOD,
189 "[%s]: ino %lu, buffer %p, size %zu, type %#x\n",
190 __func__, dentry->d_inode->i_ino, buffer, size, type);
191
192 if (strcmp(name, "") != 0)
193 return -EINVAL;
194
195 acl = hfsplus_get_posix_acl(dentry->d_inode, type);
196 if (IS_ERR(acl))
197 return PTR_ERR(acl);
198 if (acl == NULL)
199 return -ENODATA;
200
201 err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
202 posix_acl_release(acl);
203
204 return err;
205}
206
207static int hfsplus_xattr_set_posix_acl(struct dentry *dentry,
208 const char *name,
209 const void *value,
210 size_t size,
211 int flags,
212 int type)
213{
214 int err = 0;
215 struct inode *inode = dentry->d_inode;
216 struct posix_acl *acl = NULL;
217
218 hfs_dbg(ACL_MOD,
219 "[%s]: ino %lu, value %p, size %zu, flags %#x, type %#x\n",
220 __func__, inode->i_ino, value, size, flags, type);
221
222 if (strcmp(name, "") != 0)
223 return -EINVAL;
224
225 if (!inode_owner_or_capable(inode))
226 return -EPERM;
227
228 if (value) {
229 acl = posix_acl_from_xattr(&init_user_ns, value, size);
230 if (IS_ERR(acl))
231 return PTR_ERR(acl);
232 else if (acl) {
233 err = posix_acl_valid(acl);
234 if (err)
235 goto end_xattr_set_acl;
236 }
237 } 131 }
238 132
239 err = hfsplus_set_posix_acl(inode, type, acl); 133 if (acl) {
240 134 if (!err)
241end_xattr_set_acl: 135 err = hfsplus_set_posix_acl(inode, acl,
242 posix_acl_release(acl); 136 ACL_TYPE_ACCESS);
137 posix_acl_release(acl);
138 }
243 return err; 139 return err;
244} 140}
245
246static size_t hfsplus_xattr_list_posix_acl(struct dentry *dentry,
247 char *list,
248 size_t list_size,
249 const char *name,
250 size_t name_len,
251 int type)
252{
253 /*
254 * This method is not used.
255 * It is used hfsplus_listxattr() instead of generic_listxattr().
256 */
257 return -EOPNOTSUPP;
258}
259
260const struct xattr_handler hfsplus_xattr_acl_access_handler = {
261 .prefix = POSIX_ACL_XATTR_ACCESS,
262 .flags = ACL_TYPE_ACCESS,
263 .list = hfsplus_xattr_list_posix_acl,
264 .get = hfsplus_xattr_get_posix_acl,
265 .set = hfsplus_xattr_set_posix_acl,
266};
267
268const struct xattr_handler hfsplus_xattr_acl_default_handler = {
269 .prefix = POSIX_ACL_XATTR_DEFAULT,
270 .flags = ACL_TYPE_DEFAULT,
271 .list = hfsplus_xattr_list_posix_acl,
272 .get = hfsplus_xattr_get_posix_acl,
273 .set = hfsplus_xattr_set_posix_acl,
274};