aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 15:53:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-25 15:53:15 -0400
commit0003230e8200699860f0b10af524dc47bf8aecad (patch)
tree8addb0c889b32111d6973c46cd3d0a5b5c17606c /fs
parent4b478cedcdc1b2d131170f22bd3f916e53472f52 (diff)
parent4e34e719e457f2e031297175410fc0bd4016a085 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: fs: take the ACL checks to common code bury posix_acl_..._masq() variants kill boilerplates around posix_acl_create_masq() generic_acl: no need to clone acl just to push it to set_cached_acl() kill boilerplate around posix_acl_chmod_masq() reiserfs: cache negative ACLs for v1 stat format xfs: cache negative ACLs if there is no attribute fork 9p: do no return 0 from ->check_acl without actually checking vfs: move ACL cache lookup into generic code CIFS: Fix oops while mounting with prefixpath xfs: Fix wrong return value of xfs_file_aio_write fix devtmpfs race caam: don't pass bogus S_IFCHR to debugfs_create_...() get rid of create_proc_entry() abuses - proc_mkdir() is there for purpose asus-wmi: ->is_visible() can't return negative fix jffs2 ACLs on big-endian with 16bit mode_t 9p: close ACL leaks ocfs2_init_acl(): fix a leak VFS : mount lock scalability for internal mounts
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/acl.c68
-rw-r--r--fs/9p/acl.h10
-rw-r--r--fs/9p/vfs_inode_dotl.c13
-rw-r--r--fs/anon_inodes.c2
-rw-r--r--fs/btrfs/acl.c63
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/inode.c10
-rw-r--r--fs/cifs/dir.c2
-rw-r--r--fs/ext2/acl.c63
-rw-r--r--fs/ext2/acl.h4
-rw-r--r--fs/ext2/file.c2
-rw-r--r--fs/ext2/namei.c4
-rw-r--r--fs/ext3/acl.c94
-rw-r--r--fs/ext3/acl.h4
-rw-r--r--fs/ext3/file.c2
-rw-r--r--fs/ext3/namei.c4
-rw-r--r--fs/ext4/acl.c95
-rw-r--r--fs/ext4/acl.h4
-rw-r--r--fs/ext4/file.c2
-rw-r--r--fs/ext4/namei.c4
-rw-r--r--fs/generic_acl.c62
-rw-r--r--fs/gfs2/acl.c75
-rw-r--r--fs/gfs2/acl.h2
-rw-r--r--fs/gfs2/inode.c6
-rw-r--r--fs/hugetlbfs/inode.c1
-rw-r--r--fs/jffs2/acl.c49
-rw-r--r--fs/jffs2/acl.h6
-rw-r--r--fs/jffs2/dir.c2
-rw-r--r--fs/jffs2/file.c2
-rw-r--r--fs/jffs2/fs.c2
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jffs2/symlink.c2
-rw-r--r--fs/jfs/acl.c75
-rw-r--r--fs/jfs/file.c2
-rw-r--r--fs/jfs/jfs_acl.h2
-rw-r--r--fs/jfs/namei.c2
-rw-r--r--fs/namei.c54
-rw-r--r--fs/namespace.c21
-rw-r--r--fs/nfs/nfs3acl.c10
-rw-r--r--fs/ocfs2/acl.c77
-rw-r--r--fs/ocfs2/acl.h2
-rw-r--r--fs/ocfs2/file.c4
-rw-r--r--fs/ocfs2/namei.c2
-rw-r--r--fs/pipe.c2
-rw-r--r--fs/posix_acl.c48
-rw-r--r--fs/reiserfs/file.c2
-rw-r--r--fs/reiserfs/inode.c5
-rw-r--r--fs/reiserfs/namei.c6
-rw-r--r--fs/reiserfs/xattr.c27
-rw-r--r--fs/reiserfs/xattr_acl.c71
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c80
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h2
-rw-r--r--fs/xfs/xfs_acl.h2
55 files changed, 438 insertions, 742 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index e98f56d3787d..814be079c185 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -96,14 +96,11 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
96 return acl; 96 return acl;
97} 97}
98 98
99int v9fs_check_acl(struct inode *inode, int mask) 99struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type)
100{ 100{
101 struct posix_acl *acl; 101 struct posix_acl *acl;
102 struct v9fs_session_info *v9ses; 102 struct v9fs_session_info *v9ses;
103 103
104 if (mask & MAY_NOT_BLOCK)
105 return -ECHILD;
106
107 v9ses = v9fs_inode2v9ses(inode); 104 v9ses = v9fs_inode2v9ses(inode);
108 if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) || 105 if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
109 ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) { 106 ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
@@ -111,18 +108,10 @@ int v9fs_check_acl(struct inode *inode, int mask)
111 * On access = client and acl = on mode get the acl 108 * On access = client and acl = on mode get the acl
112 * values from the server 109 * values from the server
113 */ 110 */
114 return 0; 111 return NULL;
115 } 112 }
116 acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); 113 return v9fs_get_cached_acl(inode, type);
117 114
118 if (IS_ERR(acl))
119 return PTR_ERR(acl);
120 if (acl) {
121 int error = posix_acl_permission(inode, acl, mask);
122 posix_acl_release(acl);
123 return error;
124 }
125 return -EAGAIN;
126} 115}
127 116
128static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl) 117static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl)
@@ -165,32 +154,32 @@ err_free_out:
165int v9fs_acl_chmod(struct dentry *dentry) 154int v9fs_acl_chmod(struct dentry *dentry)
166{ 155{
167 int retval = 0; 156 int retval = 0;
168 struct posix_acl *acl, *clone; 157 struct posix_acl *acl;
169 struct inode *inode = dentry->d_inode; 158 struct inode *inode = dentry->d_inode;
170 159
171 if (S_ISLNK(inode->i_mode)) 160 if (S_ISLNK(inode->i_mode))
172 return -EOPNOTSUPP; 161 return -EOPNOTSUPP;
173 acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); 162 acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
174 if (acl) { 163 if (acl) {
175 clone = posix_acl_clone(acl, GFP_KERNEL); 164 retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
165 if (retval)
166 return retval;
167 retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, acl);
176 posix_acl_release(acl); 168 posix_acl_release(acl);
177 if (!clone)
178 return -ENOMEM;
179 retval = posix_acl_chmod_masq(clone, inode->i_mode);
180 if (!retval)
181 retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, clone);
182 posix_acl_release(clone);
183 } 169 }
184 return retval; 170 return retval;
185} 171}
186 172
187int v9fs_set_create_acl(struct dentry *dentry, 173int v9fs_set_create_acl(struct dentry *dentry,
188 struct posix_acl *dpacl, struct posix_acl *pacl) 174 struct posix_acl **dpacl, struct posix_acl **pacl)
189{ 175{
190 v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, dpacl); 176 if (dentry) {
191 v9fs_set_acl(dentry, ACL_TYPE_ACCESS, pacl); 177 v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, *dpacl);
192 posix_acl_release(dpacl); 178 v9fs_set_acl(dentry, ACL_TYPE_ACCESS, *pacl);
193 posix_acl_release(pacl); 179 }
180 posix_acl_release(*dpacl);
181 posix_acl_release(*pacl);
182 *dpacl = *pacl = NULL;
194 return 0; 183 return 0;
195} 184}
196 185
@@ -209,29 +198,18 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep,
209 mode &= ~current_umask(); 198 mode &= ~current_umask();
210 } 199 }
211 if (acl) { 200 if (acl) {
212 struct posix_acl *clone;
213
214 if (S_ISDIR(mode)) 201 if (S_ISDIR(mode))
215 *dpacl = acl; 202 *dpacl = posix_acl_dup(acl);
216 clone = posix_acl_clone(acl, GFP_NOFS); 203 retval = posix_acl_create(&acl, GFP_NOFS, &mode);
217 retval = -ENOMEM; 204 if (retval < 0)
218 if (!clone) 205 return retval;
219 goto cleanup;
220
221 retval = posix_acl_create_masq(clone, &mode);
222 if (retval < 0) {
223 posix_acl_release(clone);
224 goto cleanup;
225 }
226 if (retval > 0) 206 if (retval > 0)
227 *pacl = clone; 207 *pacl = acl;
208 else
209 posix_acl_release(acl);
228 } 210 }
229 *modep = mode; 211 *modep = mode;
230 return 0; 212 return 0;
231cleanup:
232 posix_acl_release(acl);
233 return retval;
234
235} 213}
236 214
237static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, 215static int v9fs_remote_get_acl(struct dentry *dentry, const char *name,
diff --git a/fs/9p/acl.h b/fs/9p/acl.h
index 59e18c2e8c7e..ddb7ae19d971 100644
--- a/fs/9p/acl.h
+++ b/fs/9p/acl.h
@@ -16,14 +16,14 @@
16 16
17#ifdef CONFIG_9P_FS_POSIX_ACL 17#ifdef CONFIG_9P_FS_POSIX_ACL
18extern int v9fs_get_acl(struct inode *, struct p9_fid *); 18extern int v9fs_get_acl(struct inode *, struct p9_fid *);
19extern int v9fs_check_acl(struct inode *inode, int mask); 19extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type);
20extern int v9fs_acl_chmod(struct dentry *); 20extern int v9fs_acl_chmod(struct dentry *);
21extern int v9fs_set_create_acl(struct dentry *, 21extern int v9fs_set_create_acl(struct dentry *,
22 struct posix_acl *, struct posix_acl *); 22 struct posix_acl **, struct posix_acl **);
23extern int v9fs_acl_mode(struct inode *dir, mode_t *modep, 23extern int v9fs_acl_mode(struct inode *dir, mode_t *modep,
24 struct posix_acl **dpacl, struct posix_acl **pacl); 24 struct posix_acl **dpacl, struct posix_acl **pacl);
25#else 25#else
26#define v9fs_check_acl NULL 26#define v9fs_iop_get_acl NULL
27static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) 27static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
28{ 28{
29 return 0; 29 return 0;
@@ -33,8 +33,8 @@ static inline int v9fs_acl_chmod(struct dentry *dentry)
33 return 0; 33 return 0;
34} 34}
35static inline int v9fs_set_create_acl(struct dentry *dentry, 35static inline int v9fs_set_create_acl(struct dentry *dentry,
36 struct posix_acl *dpacl, 36 struct posix_acl **dpacl,
37 struct posix_acl *pacl) 37 struct posix_acl **pacl)
38{ 38{
39 return 0; 39 return 0;
40} 40}
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 276f4a69ecd4..9a26dce5a99f 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -287,7 +287,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
287 goto error; 287 goto error;
288 288
289 /* Now set the ACL based on the default value */ 289 /* Now set the ACL based on the default value */
290 v9fs_set_create_acl(dentry, dacl, pacl); 290 v9fs_set_create_acl(dentry, &dacl, &pacl);
291 291
292 v9inode = V9FS_I(inode); 292 v9inode = V9FS_I(inode);
293 mutex_lock(&v9inode->v_mutex); 293 mutex_lock(&v9inode->v_mutex);
@@ -328,6 +328,7 @@ error:
328err_clunk_old_fid: 328err_clunk_old_fid:
329 if (ofid) 329 if (ofid)
330 p9_client_clunk(ofid); 330 p9_client_clunk(ofid);
331 v9fs_set_create_acl(NULL, &dacl, &pacl);
331 return err; 332 return err;
332} 333}
333 334
@@ -421,12 +422,13 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
421 d_instantiate(dentry, inode); 422 d_instantiate(dentry, inode);
422 } 423 }
423 /* Now set the ACL based on the default value */ 424 /* Now set the ACL based on the default value */
424 v9fs_set_create_acl(dentry, dacl, pacl); 425 v9fs_set_create_acl(dentry, &dacl, &pacl);
425 inc_nlink(dir); 426 inc_nlink(dir);
426 v9fs_invalidate_inode_attr(dir); 427 v9fs_invalidate_inode_attr(dir);
427error: 428error:
428 if (fid) 429 if (fid)
429 p9_client_clunk(fid); 430 p9_client_clunk(fid);
431 v9fs_set_create_acl(NULL, &dacl, &pacl);
430 return err; 432 return err;
431} 433}
432 434
@@ -826,10 +828,11 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
826 d_instantiate(dentry, inode); 828 d_instantiate(dentry, inode);
827 } 829 }
828 /* Now set the ACL based on the default value */ 830 /* Now set the ACL based on the default value */
829 v9fs_set_create_acl(dentry, dacl, pacl); 831 v9fs_set_create_acl(dentry, &dacl, &pacl);
830error: 832error:
831 if (fid) 833 if (fid)
832 p9_client_clunk(fid); 834 p9_client_clunk(fid);
835 v9fs_set_create_acl(NULL, &dacl, &pacl);
833 return err; 836 return err;
834} 837}
835 838
@@ -914,7 +917,7 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = {
914 .getxattr = generic_getxattr, 917 .getxattr = generic_getxattr,
915 .removexattr = generic_removexattr, 918 .removexattr = generic_removexattr,
916 .listxattr = v9fs_listxattr, 919 .listxattr = v9fs_listxattr,
917 .check_acl = v9fs_check_acl, 920 .get_acl = v9fs_iop_get_acl,
918}; 921};
919 922
920const struct inode_operations v9fs_file_inode_operations_dotl = { 923const struct inode_operations v9fs_file_inode_operations_dotl = {
@@ -924,7 +927,7 @@ const struct inode_operations v9fs_file_inode_operations_dotl = {
924 .getxattr = generic_getxattr, 927 .getxattr = generic_getxattr,
925 .removexattr = generic_removexattr, 928 .removexattr = generic_removexattr,
926 .listxattr = v9fs_listxattr, 929 .listxattr = v9fs_listxattr,
927 .check_acl = v9fs_check_acl, 930 .get_acl = v9fs_iop_get_acl,
928}; 931};
929 932
930const struct inode_operations v9fs_symlink_inode_operations_dotl = { 933const struct inode_operations v9fs_symlink_inode_operations_dotl = {
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index c5567cb78432..4d433d34736f 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -233,7 +233,7 @@ static int __init anon_inode_init(void)
233 return 0; 233 return 0;
234 234
235err_mntput: 235err_mntput:
236 mntput(anon_inode_mnt); 236 kern_unmount(anon_inode_mnt);
237err_unregister_filesystem: 237err_unregister_filesystem:
238 unregister_filesystem(&anon_inode_fs_type); 238 unregister_filesystem(&anon_inode_fs_type);
239err_exit: 239err_exit:
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 9f62ab2a7282..65a735d8f6e4 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -30,7 +30,7 @@
30 30
31#ifdef CONFIG_BTRFS_FS_POSIX_ACL 31#ifdef CONFIG_BTRFS_FS_POSIX_ACL
32 32
33static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) 33struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
34{ 34{
35 int size; 35 int size;
36 const char *name; 36 const char *name;
@@ -195,27 +195,6 @@ out:
195 return ret; 195 return ret;
196} 196}
197 197
198int btrfs_check_acl(struct inode *inode, int mask)
199{
200 int error = -EAGAIN;
201
202 if (mask & MAY_NOT_BLOCK) {
203 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
204 error = -ECHILD;
205 } else {
206 struct posix_acl *acl;
207 acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
208 if (IS_ERR(acl))
209 return PTR_ERR(acl);
210 if (acl) {
211 error = posix_acl_permission(inode, acl, mask);
212 posix_acl_release(acl);
213 }
214 }
215
216 return error;
217}
218
219/* 198/*
220 * btrfs_init_acl is already generally called under fs_mutex, so the locking 199 * btrfs_init_acl is already generally called under fs_mutex, so the locking
221 * stuff has been fixed to work with that. If the locking stuff changes, we 200 * stuff has been fixed to work with that. If the locking stuff changes, we
@@ -243,8 +222,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans,
243 } 222 }
244 223
245 if (IS_POSIXACL(dir) && acl) { 224 if (IS_POSIXACL(dir) && acl) {
246 struct posix_acl *clone; 225 mode_t mode = inode->i_mode;
247 mode_t mode;
248 226
249 if (S_ISDIR(inode->i_mode)) { 227 if (S_ISDIR(inode->i_mode)) {
250 ret = btrfs_set_acl(trans, inode, acl, 228 ret = btrfs_set_acl(trans, inode, acl,
@@ -252,22 +230,15 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans,
252 if (ret) 230 if (ret)
253 goto failed; 231 goto failed;
254 } 232 }
255 clone = posix_acl_clone(acl, GFP_NOFS); 233 ret = posix_acl_create(&acl, GFP_NOFS, &mode);
256 ret = -ENOMEM; 234 if (ret < 0)
257 if (!clone) 235 return ret;
258 goto failed;
259 236
260 mode = inode->i_mode; 237 inode->i_mode = mode;
261 ret = posix_acl_create_masq(clone, &mode); 238 if (ret > 0) {
262 if (ret >= 0) { 239 /* we need an acl */
263 inode->i_mode = mode; 240 ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS);
264 if (ret > 0) {
265 /* we need an acl */
266 ret = btrfs_set_acl(trans, inode, clone,
267 ACL_TYPE_ACCESS);
268 }
269 } 241 }
270 posix_acl_release(clone);
271 } 242 }
272failed: 243failed:
273 posix_acl_release(acl); 244 posix_acl_release(acl);
@@ -277,7 +248,7 @@ failed:
277 248
278int btrfs_acl_chmod(struct inode *inode) 249int btrfs_acl_chmod(struct inode *inode)
279{ 250{
280 struct posix_acl *acl, *clone; 251 struct posix_acl *acl;
281 int ret = 0; 252 int ret = 0;
282 253
283 if (S_ISLNK(inode->i_mode)) 254 if (S_ISLNK(inode->i_mode))
@@ -290,17 +261,11 @@ int btrfs_acl_chmod(struct inode *inode)
290 if (IS_ERR_OR_NULL(acl)) 261 if (IS_ERR_OR_NULL(acl))
291 return PTR_ERR(acl); 262 return PTR_ERR(acl);
292 263
293 clone = posix_acl_clone(acl, GFP_KERNEL); 264 ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
265 if (ret)
266 return ret;
267 ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS);
294 posix_acl_release(acl); 268 posix_acl_release(acl);
295 if (!clone)
296 return -ENOMEM;
297
298 ret = posix_acl_chmod_masq(clone, inode->i_mode);
299 if (!ret)
300 ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS);
301
302 posix_acl_release(clone);
303
304 return ret; 269 return ret;
305} 270}
306 271
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 82be74efbb26..fe9287b06496 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2645,9 +2645,9 @@ do { \
2645 2645
2646/* acl.c */ 2646/* acl.c */
2647#ifdef CONFIG_BTRFS_FS_POSIX_ACL 2647#ifdef CONFIG_BTRFS_FS_POSIX_ACL
2648int btrfs_check_acl(struct inode *inode, int mask); 2648struct posix_acl *btrfs_get_acl(struct inode *inode, int type);
2649#else 2649#else
2650#define btrfs_check_acl NULL 2650#define btrfs_get_acl NULL
2651#endif 2651#endif
2652int btrfs_init_acl(struct btrfs_trans_handle *trans, 2652int btrfs_init_acl(struct btrfs_trans_handle *trans,
2653 struct inode *inode, struct inode *dir); 2653 struct inode *inode, struct inode *dir);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2548a04a0230..e91b097e7252 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7351,12 +7351,12 @@ static const struct inode_operations btrfs_dir_inode_operations = {
7351 .listxattr = btrfs_listxattr, 7351 .listxattr = btrfs_listxattr,
7352 .removexattr = btrfs_removexattr, 7352 .removexattr = btrfs_removexattr,
7353 .permission = btrfs_permission, 7353 .permission = btrfs_permission,
7354 .check_acl = btrfs_check_acl, 7354 .get_acl = btrfs_get_acl,
7355}; 7355};
7356static const struct inode_operations btrfs_dir_ro_inode_operations = { 7356static const struct inode_operations btrfs_dir_ro_inode_operations = {
7357 .lookup = btrfs_lookup, 7357 .lookup = btrfs_lookup,
7358 .permission = btrfs_permission, 7358 .permission = btrfs_permission,
7359 .check_acl = btrfs_check_acl, 7359 .get_acl = btrfs_get_acl,
7360}; 7360};
7361 7361
7362static const struct file_operations btrfs_dir_file_operations = { 7362static const struct file_operations btrfs_dir_file_operations = {
@@ -7425,7 +7425,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
7425 .removexattr = btrfs_removexattr, 7425 .removexattr = btrfs_removexattr,
7426 .permission = btrfs_permission, 7426 .permission = btrfs_permission,
7427 .fiemap = btrfs_fiemap, 7427 .fiemap = btrfs_fiemap,
7428 .check_acl = btrfs_check_acl, 7428 .get_acl = btrfs_get_acl,
7429}; 7429};
7430static const struct inode_operations btrfs_special_inode_operations = { 7430static const struct inode_operations btrfs_special_inode_operations = {
7431 .getattr = btrfs_getattr, 7431 .getattr = btrfs_getattr,
@@ -7435,7 +7435,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
7435 .getxattr = btrfs_getxattr, 7435 .getxattr = btrfs_getxattr,
7436 .listxattr = btrfs_listxattr, 7436 .listxattr = btrfs_listxattr,
7437 .removexattr = btrfs_removexattr, 7437 .removexattr = btrfs_removexattr,
7438 .check_acl = btrfs_check_acl, 7438 .get_acl = btrfs_get_acl,
7439}; 7439};
7440static const struct inode_operations btrfs_symlink_inode_operations = { 7440static const struct inode_operations btrfs_symlink_inode_operations = {
7441 .readlink = generic_readlink, 7441 .readlink = generic_readlink,
@@ -7447,7 +7447,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
7447 .getxattr = btrfs_getxattr, 7447 .getxattr = btrfs_getxattr,
7448 .listxattr = btrfs_listxattr, 7448 .listxattr = btrfs_listxattr,
7449 .removexattr = btrfs_removexattr, 7449 .removexattr = btrfs_removexattr,
7450 .check_acl = btrfs_check_acl, 7450 .get_acl = btrfs_get_acl,
7451}; 7451};
7452 7452
7453const struct dentry_operations btrfs_dentry_operations = { 7453const struct dentry_operations btrfs_dentry_operations = {
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 14d602f178c2..499f27fc8576 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -641,7 +641,7 @@ lookup_out:
641static int 641static int
642cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 642cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
643{ 643{
644 if (nd->flags & LOOKUP_RCU) 644 if (nd && (nd->flags & LOOKUP_RCU))
645 return -ECHILD; 645 return -ECHILD;
646 646
647 if (direntry->d_inode) { 647 if (direntry->d_inode) {
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index bfe651f9ae16..52c053763942 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -128,7 +128,7 @@ fail:
128/* 128/*
129 * inode->i_mutex: don't care 129 * inode->i_mutex: don't care
130 */ 130 */
131static struct posix_acl * 131struct posix_acl *
132ext2_get_acl(struct inode *inode, int type) 132ext2_get_acl(struct inode *inode, int type)
133{ 133{
134 int name_index; 134 int name_index;
@@ -231,29 +231,6 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
231 return error; 231 return error;
232} 232}
233 233
234int
235ext2_check_acl(struct inode *inode, int mask)
236{
237 struct posix_acl *acl;
238
239 if (mask & MAY_NOT_BLOCK) {
240 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
241 return -ECHILD;
242 return -EAGAIN;
243 }
244
245 acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
246 if (IS_ERR(acl))
247 return PTR_ERR(acl);
248 if (acl) {
249 int error = posix_acl_permission(inode, acl, mask);
250 posix_acl_release(acl);
251 return error;
252 }
253
254 return -EAGAIN;
255}
256
257/* 234/*
258 * Initialize the ACLs of a new inode. Called from ext2_new_inode. 235 * Initialize the ACLs of a new inode. Called from ext2_new_inode.
259 * 236 *
@@ -276,29 +253,20 @@ ext2_init_acl(struct inode *inode, struct inode *dir)
276 inode->i_mode &= ~current_umask(); 253 inode->i_mode &= ~current_umask();
277 } 254 }
278 if (test_opt(inode->i_sb, POSIX_ACL) && acl) { 255 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
279 struct posix_acl *clone; 256 mode_t mode = inode->i_mode;
280 mode_t mode;
281
282 if (S_ISDIR(inode->i_mode)) { 257 if (S_ISDIR(inode->i_mode)) {
283 error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); 258 error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
284 if (error) 259 if (error)
285 goto cleanup; 260 goto cleanup;
286 } 261 }
287 clone = posix_acl_clone(acl, GFP_KERNEL); 262 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
288 error = -ENOMEM; 263 if (error < 0)
289 if (!clone) 264 return error;
290 goto cleanup; 265 inode->i_mode = mode;
291 mode = inode->i_mode; 266 if (error > 0) {
292 error = posix_acl_create_masq(clone, &mode); 267 /* This is an extended ACL */
293 if (error >= 0) { 268 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
294 inode->i_mode = mode;
295 if (error > 0) {
296 /* This is an extended ACL */
297 error = ext2_set_acl(inode,
298 ACL_TYPE_ACCESS, clone);
299 }
300 } 269 }
301 posix_acl_release(clone);
302 } 270 }
303cleanup: 271cleanup:
304 posix_acl_release(acl); 272 posix_acl_release(acl);
@@ -322,7 +290,7 @@ cleanup:
322int 290int
323ext2_acl_chmod(struct inode *inode) 291ext2_acl_chmod(struct inode *inode)
324{ 292{
325 struct posix_acl *acl, *clone; 293 struct posix_acl *acl;
326 int error; 294 int error;
327 295
328 if (!test_opt(inode->i_sb, POSIX_ACL)) 296 if (!test_opt(inode->i_sb, POSIX_ACL))
@@ -332,14 +300,11 @@ ext2_acl_chmod(struct inode *inode)
332 acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); 300 acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
333 if (IS_ERR(acl) || !acl) 301 if (IS_ERR(acl) || !acl)
334 return PTR_ERR(acl); 302 return PTR_ERR(acl);
335 clone = posix_acl_clone(acl, GFP_KERNEL); 303 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
304 if (error)
305 return error;
306 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
336 posix_acl_release(acl); 307 posix_acl_release(acl);
337 if (!clone)
338 return -ENOMEM;
339 error = posix_acl_chmod_masq(clone, inode->i_mode);
340 if (!error)
341 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, clone);
342 posix_acl_release(clone);
343 return error; 308 return error;
344} 309}
345 310
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
index 3ff6cbb9ac44..5c0a6a4fb052 100644
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -54,13 +54,13 @@ static inline int ext2_acl_count(size_t size)
54#ifdef CONFIG_EXT2_FS_POSIX_ACL 54#ifdef CONFIG_EXT2_FS_POSIX_ACL
55 55
56/* acl.c */ 56/* acl.c */
57extern int ext2_check_acl (struct inode *, int); 57extern struct posix_acl *ext2_get_acl(struct inode *inode, int type);
58extern int ext2_acl_chmod (struct inode *); 58extern int ext2_acl_chmod (struct inode *);
59extern int ext2_init_acl (struct inode *, struct inode *); 59extern int ext2_init_acl (struct inode *, struct inode *);
60 60
61#else 61#else
62#include <linux/sched.h> 62#include <linux/sched.h>
63#define ext2_check_acl NULL 63#define ext2_get_acl NULL
64#define ext2_get_acl NULL 64#define ext2_get_acl NULL
65#define ext2_set_acl NULL 65#define ext2_set_acl NULL
66 66
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 82e06321de35..a5b3a5db3120 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -102,6 +102,6 @@ const struct inode_operations ext2_file_inode_operations = {
102 .removexattr = generic_removexattr, 102 .removexattr = generic_removexattr,
103#endif 103#endif
104 .setattr = ext2_setattr, 104 .setattr = ext2_setattr,
105 .check_acl = ext2_check_acl, 105 .get_acl = ext2_get_acl,
106 .fiemap = ext2_fiemap, 106 .fiemap = ext2_fiemap,
107}; 107};
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index d60b7099e2db..761fde807fc9 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -408,7 +408,7 @@ const struct inode_operations ext2_dir_inode_operations = {
408 .removexattr = generic_removexattr, 408 .removexattr = generic_removexattr,
409#endif 409#endif
410 .setattr = ext2_setattr, 410 .setattr = ext2_setattr,
411 .check_acl = ext2_check_acl, 411 .get_acl = ext2_get_acl,
412}; 412};
413 413
414const struct inode_operations ext2_special_inode_operations = { 414const struct inode_operations ext2_special_inode_operations = {
@@ -419,5 +419,5 @@ const struct inode_operations ext2_special_inode_operations = {
419 .removexattr = generic_removexattr, 419 .removexattr = generic_removexattr,
420#endif 420#endif
421 .setattr = ext2_setattr, 421 .setattr = ext2_setattr,
422 .check_acl = ext2_check_acl, 422 .get_acl = ext2_get_acl,
423}; 423};
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index edfeb293d4cb..6c29bf0df04a 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -131,7 +131,7 @@ fail:
131 * 131 *
132 * inode->i_mutex: don't care 132 * inode->i_mutex: don't care
133 */ 133 */
134static struct posix_acl * 134struct posix_acl *
135ext3_get_acl(struct inode *inode, int type) 135ext3_get_acl(struct inode *inode, int type)
136{ 136{
137 int name_index; 137 int name_index;
@@ -239,29 +239,6 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
239 return error; 239 return error;
240} 240}
241 241
242int
243ext3_check_acl(struct inode *inode, int mask)
244{
245 struct posix_acl *acl;
246
247 if (mask & MAY_NOT_BLOCK) {
248 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
249 return -ECHILD;
250 return -EAGAIN;
251 }
252
253 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
254 if (IS_ERR(acl))
255 return PTR_ERR(acl);
256 if (acl) {
257 int error = posix_acl_permission(inode, acl, mask);
258 posix_acl_release(acl);
259 return error;
260 }
261
262 return -EAGAIN;
263}
264
265/* 242/*
266 * Initialize the ACLs of a new inode. Called from ext3_new_inode. 243 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
267 * 244 *
@@ -284,8 +261,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
284 inode->i_mode &= ~current_umask(); 261 inode->i_mode &= ~current_umask();
285 } 262 }
286 if (test_opt(inode->i_sb, POSIX_ACL) && acl) { 263 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
287 struct posix_acl *clone; 264 mode_t mode = inode->i_mode;
288 mode_t mode;
289 265
290 if (S_ISDIR(inode->i_mode)) { 266 if (S_ISDIR(inode->i_mode)) {
291 error = ext3_set_acl(handle, inode, 267 error = ext3_set_acl(handle, inode,
@@ -293,22 +269,15 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
293 if (error) 269 if (error)
294 goto cleanup; 270 goto cleanup;
295 } 271 }
296 clone = posix_acl_clone(acl, GFP_NOFS); 272 error = posix_acl_create(&acl, GFP_NOFS, &mode);
297 error = -ENOMEM; 273 if (error < 0)
298 if (!clone) 274 return error;
299 goto cleanup; 275
300 276 inode->i_mode = mode;
301 mode = inode->i_mode; 277 if (error > 0) {
302 error = posix_acl_create_masq(clone, &mode); 278 /* This is an extended ACL */
303 if (error >= 0) { 279 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
304 inode->i_mode = mode;
305 if (error > 0) {
306 /* This is an extended ACL */
307 error = ext3_set_acl(handle, inode,
308 ACL_TYPE_ACCESS, clone);
309 }
310 } 280 }
311 posix_acl_release(clone);
312 } 281 }
313cleanup: 282cleanup:
314 posix_acl_release(acl); 283 posix_acl_release(acl);
@@ -332,7 +301,9 @@ cleanup:
332int 301int
333ext3_acl_chmod(struct inode *inode) 302ext3_acl_chmod(struct inode *inode)
334{ 303{
335 struct posix_acl *acl, *clone; 304 struct posix_acl *acl;
305 handle_t *handle;
306 int retries = 0;
336 int error; 307 int error;
337 308
338 if (S_ISLNK(inode->i_mode)) 309 if (S_ISLNK(inode->i_mode))
@@ -342,31 +313,24 @@ ext3_acl_chmod(struct inode *inode)
342 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); 313 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
343 if (IS_ERR(acl) || !acl) 314 if (IS_ERR(acl) || !acl)
344 return PTR_ERR(acl); 315 return PTR_ERR(acl);
345 clone = posix_acl_clone(acl, GFP_KERNEL); 316 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
346 posix_acl_release(acl); 317 if (error)
347 if (!clone) 318 return error;
348 return -ENOMEM; 319retry:
349 error = posix_acl_chmod_masq(clone, inode->i_mode); 320 handle = ext3_journal_start(inode,
350 if (!error) { 321 EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
351 handle_t *handle; 322 if (IS_ERR(handle)) {
352 int retries = 0; 323 error = PTR_ERR(handle);
353 324 ext3_std_error(inode->i_sb, error);
354 retry: 325 goto out;
355 handle = ext3_journal_start(inode,
356 EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
357 if (IS_ERR(handle)) {
358 error = PTR_ERR(handle);
359 ext3_std_error(inode->i_sb, error);
360 goto out;
361 }
362 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
363 ext3_journal_stop(handle);
364 if (error == -ENOSPC &&
365 ext3_should_retry_alloc(inode->i_sb, &retries))
366 goto retry;
367 } 326 }
327 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
328 ext3_journal_stop(handle);
329 if (error == -ENOSPC &&
330 ext3_should_retry_alloc(inode->i_sb, &retries))
331 goto retry;
368out: 332out:
369 posix_acl_release(clone); 333 posix_acl_release(acl);
370 return error; 334 return error;
371} 335}
372 336
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 597334626de9..dbc921e458c5 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -54,13 +54,13 @@ static inline int ext3_acl_count(size_t size)
54#ifdef CONFIG_EXT3_FS_POSIX_ACL 54#ifdef CONFIG_EXT3_FS_POSIX_ACL
55 55
56/* acl.c */ 56/* acl.c */
57extern int ext3_check_acl (struct inode *, int); 57extern struct posix_acl *ext3_get_acl(struct inode *inode, int type);
58extern int ext3_acl_chmod (struct inode *); 58extern int ext3_acl_chmod (struct inode *);
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_check_acl NULL 63#define ext3_get_acl NULL
64 64
65static inline int 65static inline int
66ext3_acl_chmod(struct inode *inode) 66ext3_acl_chmod(struct inode *inode)
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index f55df0e61cbd..2be5b99097f1 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -79,7 +79,7 @@ const struct inode_operations ext3_file_inode_operations = {
79 .listxattr = ext3_listxattr, 79 .listxattr = ext3_listxattr,
80 .removexattr = generic_removexattr, 80 .removexattr = generic_removexattr,
81#endif 81#endif
82 .check_acl = ext3_check_acl, 82 .get_acl = ext3_get_acl,
83 .fiemap = ext3_fiemap, 83 .fiemap = ext3_fiemap,
84}; 84};
85 85
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index c095cf5640c7..3b57230a17bb 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2529,7 +2529,7 @@ const struct inode_operations ext3_dir_inode_operations = {
2529 .listxattr = ext3_listxattr, 2529 .listxattr = ext3_listxattr,
2530 .removexattr = generic_removexattr, 2530 .removexattr = generic_removexattr,
2531#endif 2531#endif
2532 .check_acl = ext3_check_acl, 2532 .get_acl = ext3_get_acl,
2533}; 2533};
2534 2534
2535const struct inode_operations ext3_special_inode_operations = { 2535const struct inode_operations ext3_special_inode_operations = {
@@ -2540,5 +2540,5 @@ const struct inode_operations ext3_special_inode_operations = {
2540 .listxattr = ext3_listxattr, 2540 .listxattr = ext3_listxattr,
2541 .removexattr = generic_removexattr, 2541 .removexattr = generic_removexattr,
2542#endif 2542#endif
2543 .check_acl = ext3_check_acl, 2543 .get_acl = ext3_get_acl,
2544}; 2544};
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 60d900fcc3db..dca2d1ded931 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -131,7 +131,7 @@ fail:
131 * 131 *
132 * inode->i_mutex: don't care 132 * inode->i_mutex: don't care
133 */ 133 */
134static struct posix_acl * 134struct posix_acl *
135ext4_get_acl(struct inode *inode, int type) 135ext4_get_acl(struct inode *inode, int type)
136{ 136{
137 int name_index; 137 int name_index;
@@ -237,29 +237,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
237 return error; 237 return error;
238} 238}
239 239
240int
241ext4_check_acl(struct inode *inode, int mask)
242{
243 struct posix_acl *acl;
244
245 if (mask & MAY_NOT_BLOCK) {
246 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
247 return -ECHILD;
248 return -EAGAIN;
249 }
250
251 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
252 if (IS_ERR(acl))
253 return PTR_ERR(acl);
254 if (acl) {
255 int error = posix_acl_permission(inode, acl, mask);
256 posix_acl_release(acl);
257 return error;
258 }
259
260 return -EAGAIN;
261}
262
263/* 240/*
264 * Initialize the ACLs of a new inode. Called from ext4_new_inode. 241 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
265 * 242 *
@@ -282,8 +259,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
282 inode->i_mode &= ~current_umask(); 259 inode->i_mode &= ~current_umask();
283 } 260 }
284 if (test_opt(inode->i_sb, POSIX_ACL) && acl) { 261 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
285 struct posix_acl *clone; 262 mode_t mode = inode->i_mode;
286 mode_t mode;
287 263
288 if (S_ISDIR(inode->i_mode)) { 264 if (S_ISDIR(inode->i_mode)) {
289 error = ext4_set_acl(handle, inode, 265 error = ext4_set_acl(handle, inode,
@@ -291,22 +267,15 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
291 if (error) 267 if (error)
292 goto cleanup; 268 goto cleanup;
293 } 269 }
294 clone = posix_acl_clone(acl, GFP_NOFS); 270 error = posix_acl_create(&acl, GFP_NOFS, &mode);
295 error = -ENOMEM; 271 if (error < 0)
296 if (!clone) 272 return error;
297 goto cleanup; 273
298 274 inode->i_mode = mode;
299 mode = inode->i_mode; 275 if (error > 0) {
300 error = posix_acl_create_masq(clone, &mode); 276 /* This is an extended ACL */
301 if (error >= 0) { 277 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
302 inode->i_mode = mode;
303 if (error > 0) {
304 /* This is an extended ACL */
305 error = ext4_set_acl(handle, inode,
306 ACL_TYPE_ACCESS, clone);
307 }
308 } 278 }
309 posix_acl_release(clone);
310 } 279 }
311cleanup: 280cleanup:
312 posix_acl_release(acl); 281 posix_acl_release(acl);
@@ -330,9 +299,12 @@ cleanup:
330int 299int
331ext4_acl_chmod(struct inode *inode) 300ext4_acl_chmod(struct inode *inode)
332{ 301{
333 struct posix_acl *acl, *clone; 302 struct posix_acl *acl;
303 handle_t *handle;
304 int retries = 0;
334 int error; 305 int error;
335 306
307
336 if (S_ISLNK(inode->i_mode)) 308 if (S_ISLNK(inode->i_mode))
337 return -EOPNOTSUPP; 309 return -EOPNOTSUPP;
338 if (!test_opt(inode->i_sb, POSIX_ACL)) 310 if (!test_opt(inode->i_sb, POSIX_ACL))
@@ -340,31 +312,24 @@ ext4_acl_chmod(struct inode *inode)
340 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); 312 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
341 if (IS_ERR(acl) || !acl) 313 if (IS_ERR(acl) || !acl)
342 return PTR_ERR(acl); 314 return PTR_ERR(acl);
343 clone = posix_acl_clone(acl, GFP_KERNEL); 315 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
344 posix_acl_release(acl); 316 if (error)
345 if (!clone) 317 return error;
346 return -ENOMEM; 318retry:
347 error = posix_acl_chmod_masq(clone, inode->i_mode); 319 handle = ext4_journal_start(inode,
348 if (!error) { 320 EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
349 handle_t *handle; 321 if (IS_ERR(handle)) {
350 int retries = 0; 322 error = PTR_ERR(handle);
351 323 ext4_std_error(inode->i_sb, error);
352 retry: 324 goto out;
353 handle = ext4_journal_start(inode,
354 EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
355 if (IS_ERR(handle)) {
356 error = PTR_ERR(handle);
357 ext4_std_error(inode->i_sb, error);
358 goto out;
359 }
360 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
361 ext4_journal_stop(handle);
362 if (error == -ENOSPC &&
363 ext4_should_retry_alloc(inode->i_sb, &retries))
364 goto retry;
365 } 325 }
326 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
327 ext4_journal_stop(handle);
328 if (error == -ENOSPC &&
329 ext4_should_retry_alloc(inode->i_sb, &retries))
330 goto retry;
366out: 331out:
367 posix_acl_release(clone); 332 posix_acl_release(acl);
368 return error; 333 return error;
369} 334}
370 335
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 9d843d5deac4..18cb39ed7c7b 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -54,13 +54,13 @@ static inline int ext4_acl_count(size_t size)
54#ifdef CONFIG_EXT4_FS_POSIX_ACL 54#ifdef CONFIG_EXT4_FS_POSIX_ACL
55 55
56/* acl.c */ 56/* acl.c */
57extern int ext4_check_acl(struct inode *, int); 57struct posix_acl *ext4_get_acl(struct inode *inode, int type);
58extern int ext4_acl_chmod(struct inode *); 58extern int ext4_acl_chmod(struct inode *);
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_check_acl NULL 63#define ext4_get_acl NULL
64 64
65static inline int 65static inline int
66ext4_acl_chmod(struct inode *inode) 66ext4_acl_chmod(struct inode *inode)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index ce766f974b1d..e4095e988eba 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -301,7 +301,7 @@ const struct inode_operations ext4_file_inode_operations = {
301 .listxattr = ext4_listxattr, 301 .listxattr = ext4_listxattr,
302 .removexattr = generic_removexattr, 302 .removexattr = generic_removexattr,
303#endif 303#endif
304 .check_acl = ext4_check_acl, 304 .get_acl = ext4_get_acl,
305 .fiemap = ext4_fiemap, 305 .fiemap = ext4_fiemap,
306}; 306};
307 307
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 707d605bf769..8c9babac43dc 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2590,7 +2590,7 @@ const struct inode_operations ext4_dir_inode_operations = {
2590 .listxattr = ext4_listxattr, 2590 .listxattr = ext4_listxattr,
2591 .removexattr = generic_removexattr, 2591 .removexattr = generic_removexattr,
2592#endif 2592#endif
2593 .check_acl = ext4_check_acl, 2593 .get_acl = ext4_get_acl,
2594 .fiemap = ext4_fiemap, 2594 .fiemap = ext4_fiemap,
2595}; 2595};
2596 2596
@@ -2602,5 +2602,5 @@ const struct inode_operations ext4_special_inode_operations = {
2602 .listxattr = ext4_listxattr, 2602 .listxattr = ext4_listxattr,
2603 .removexattr = generic_removexattr, 2603 .removexattr = generic_removexattr,
2604#endif 2604#endif
2605 .check_acl = ext4_check_acl, 2605 .get_acl = ext4_get_acl,
2606}; 2606};
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
index 70e90b4974ce..d5e33a077a67 100644
--- a/fs/generic_acl.c
+++ b/fs/generic_acl.c
@@ -132,31 +132,17 @@ generic_acl_init(struct inode *inode, struct inode *dir)
132 if (!S_ISLNK(inode->i_mode)) 132 if (!S_ISLNK(inode->i_mode))
133 acl = get_cached_acl(dir, ACL_TYPE_DEFAULT); 133 acl = get_cached_acl(dir, ACL_TYPE_DEFAULT);
134 if (acl) { 134 if (acl) {
135 struct posix_acl *clone; 135 if (S_ISDIR(inode->i_mode))
136 136 set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
137 if (S_ISDIR(inode->i_mode)) { 137 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
138 clone = posix_acl_clone(acl, GFP_KERNEL); 138 if (error < 0)
139 error = -ENOMEM; 139 return error;
140 if (!clone) 140 inode->i_mode = mode;
141 goto cleanup; 141 if (error > 0)
142 set_cached_acl(inode, ACL_TYPE_DEFAULT, clone); 142 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
143 posix_acl_release(clone);
144 }
145 clone = posix_acl_clone(acl, GFP_KERNEL);
146 error = -ENOMEM;
147 if (!clone)
148 goto cleanup;
149 error = posix_acl_create_masq(clone, &mode);
150 if (error >= 0) {
151 inode->i_mode = mode;
152 if (error > 0)
153 set_cached_acl(inode, ACL_TYPE_ACCESS, clone);
154 }
155 posix_acl_release(clone);
156 } 143 }
157 error = 0; 144 error = 0;
158 145
159cleanup:
160 posix_acl_release(acl); 146 posix_acl_release(acl);
161 return error; 147 return error;
162} 148}
@@ -170,44 +156,22 @@ cleanup:
170int 156int
171generic_acl_chmod(struct inode *inode) 157generic_acl_chmod(struct inode *inode)
172{ 158{
173 struct posix_acl *acl, *clone; 159 struct posix_acl *acl;
174 int error = 0; 160 int error = 0;
175 161
176 if (S_ISLNK(inode->i_mode)) 162 if (S_ISLNK(inode->i_mode))
177 return -EOPNOTSUPP; 163 return -EOPNOTSUPP;
178 acl = get_cached_acl(inode, ACL_TYPE_ACCESS); 164 acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
179 if (acl) { 165 if (acl) {
180 clone = posix_acl_clone(acl, GFP_KERNEL); 166 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
167 if (error)
168 return error;
169 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
181 posix_acl_release(acl); 170 posix_acl_release(acl);
182 if (!clone)
183 return -ENOMEM;
184 error = posix_acl_chmod_masq(clone, inode->i_mode);
185 if (!error)
186 set_cached_acl(inode, ACL_TYPE_ACCESS, clone);
187 posix_acl_release(clone);
188 } 171 }
189 return error; 172 return error;
190} 173}
191 174
192int
193generic_check_acl(struct inode *inode, int mask)
194{
195 if (mask & MAY_NOT_BLOCK) {
196 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
197 return -ECHILD;
198 } else {
199 struct posix_acl *acl;
200
201 acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
202 if (acl) {
203 int error = posix_acl_permission(inode, acl, mask);
204 posix_acl_release(acl);
205 return error;
206 }
207 }
208 return -EAGAIN;
209}
210
211const struct xattr_handler generic_acl_access_handler = { 175const struct xattr_handler generic_acl_access_handler = {
212 .prefix = POSIX_ACL_XATTR_ACCESS, 176 .prefix = POSIX_ACL_XATTR_ACCESS,
213 .flags = ACL_TYPE_ACCESS, 177 .flags = ACL_TYPE_ACCESS,
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 8ef1079f1665..884c9af0542f 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -67,36 +67,9 @@ static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type)
67 return acl; 67 return acl;
68} 68}
69 69
70/** 70struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
71 * gfs2_check_acl - Check an ACL to see if we're allowed to do something
72 * @inode: the file we want to do something to
73 * @mask: what we want to do
74 *
75 * Returns: errno
76 */
77
78int gfs2_check_acl(struct inode *inode, int mask)
79{ 71{
80 struct posix_acl *acl; 72 return gfs2_acl_get(GFS2_I(inode), type);
81 int error;
82
83 if (mask & MAY_NOT_BLOCK) {
84 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
85 return -ECHILD;
86 return -EAGAIN;
87 }
88
89 acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS);
90 if (IS_ERR(acl))
91 return PTR_ERR(acl);
92
93 if (acl) {
94 error = posix_acl_permission(inode, acl, mask);
95 posix_acl_release(acl);
96 return error;
97 }
98
99 return -EAGAIN;
100} 73}
101 74
102static int gfs2_set_mode(struct inode *inode, mode_t mode) 75static int gfs2_set_mode(struct inode *inode, mode_t mode)
@@ -143,7 +116,7 @@ out:
143int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) 116int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
144{ 117{
145 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 118 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
146 struct posix_acl *acl, *clone; 119 struct posix_acl *acl;
147 mode_t mode = inode->i_mode; 120 mode_t mode = inode->i_mode;
148 int error = 0; 121 int error = 0;
149 122
@@ -168,16 +141,10 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
168 goto out; 141 goto out;
169 } 142 }
170 143
171 clone = posix_acl_clone(acl, GFP_NOFS); 144 error = posix_acl_create(&acl, GFP_NOFS, &mode);
172 error = -ENOMEM;
173 if (!clone)
174 goto out;
175 posix_acl_release(acl);
176 acl = clone;
177
178 error = posix_acl_create_masq(acl, &mode);
179 if (error < 0) 145 if (error < 0)
180 goto out; 146 return error;
147
181 if (error == 0) 148 if (error == 0)
182 goto munge; 149 goto munge;
183 150
@@ -193,7 +160,7 @@ out:
193 160
194int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) 161int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
195{ 162{
196 struct posix_acl *acl, *clone; 163 struct posix_acl *acl;
197 char *data; 164 char *data;
198 unsigned int len; 165 unsigned int len;
199 int error; 166 int error;
@@ -204,25 +171,19 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
204 if (!acl) 171 if (!acl)
205 return gfs2_setattr_simple(ip, attr); 172 return gfs2_setattr_simple(ip, attr);
206 173
207 clone = posix_acl_clone(acl, GFP_NOFS); 174 error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode);
175 if (error)
176 return error;
177
178 len = posix_acl_to_xattr(acl, NULL, 0);
179 data = kmalloc(len, GFP_NOFS);
208 error = -ENOMEM; 180 error = -ENOMEM;
209 if (!clone) 181 if (data == NULL)
210 goto out; 182 goto out;
211 posix_acl_release(acl); 183 posix_acl_to_xattr(acl, data, len);
212 acl = clone; 184 error = gfs2_xattr_acl_chmod(ip, attr, data);
213 185 kfree(data);
214 error = posix_acl_chmod_masq(acl, attr->ia_mode); 186 set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
215 if (!error) {
216 len = posix_acl_to_xattr(acl, NULL, 0);
217 data = kmalloc(len, GFP_NOFS);
218 error = -ENOMEM;
219 if (data == NULL)
220 goto out;
221 posix_acl_to_xattr(acl, data, len);
222 error = gfs2_xattr_acl_chmod(ip, attr, data);
223 kfree(data);
224 set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
225 }
226 187
227out: 188out:
228 posix_acl_release(acl); 189 posix_acl_release(acl);
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h
index b522b0cb39ea..0da38dc7efec 100644
--- a/fs/gfs2/acl.h
+++ b/fs/gfs2/acl.h
@@ -16,7 +16,7 @@
16#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" 16#define GFS2_POSIX_ACL_DEFAULT "posix_acl_default"
17#define GFS2_ACL_MAX_ENTRIES 25 17#define GFS2_ACL_MAX_ENTRIES 25
18 18
19extern int gfs2_check_acl(struct inode *inode, int mask); 19extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type);
20extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); 20extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode);
21extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); 21extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
22extern const struct xattr_handler gfs2_xattr_system_handler; 22extern const struct xattr_handler gfs2_xattr_system_handler;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 0fb51a96eff0..900cf986aadc 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1846,7 +1846,7 @@ const struct inode_operations gfs2_file_iops = {
1846 .listxattr = gfs2_listxattr, 1846 .listxattr = gfs2_listxattr,
1847 .removexattr = gfs2_removexattr, 1847 .removexattr = gfs2_removexattr,
1848 .fiemap = gfs2_fiemap, 1848 .fiemap = gfs2_fiemap,
1849 .check_acl = gfs2_check_acl, 1849 .get_acl = gfs2_get_acl,
1850}; 1850};
1851 1851
1852const struct inode_operations gfs2_dir_iops = { 1852const struct inode_operations gfs2_dir_iops = {
@@ -1867,7 +1867,7 @@ const struct inode_operations gfs2_dir_iops = {
1867 .listxattr = gfs2_listxattr, 1867 .listxattr = gfs2_listxattr,
1868 .removexattr = gfs2_removexattr, 1868 .removexattr = gfs2_removexattr,
1869 .fiemap = gfs2_fiemap, 1869 .fiemap = gfs2_fiemap,
1870 .check_acl = gfs2_check_acl, 1870 .get_acl = gfs2_get_acl,
1871}; 1871};
1872 1872
1873const struct inode_operations gfs2_symlink_iops = { 1873const struct inode_operations gfs2_symlink_iops = {
@@ -1882,6 +1882,6 @@ const struct inode_operations gfs2_symlink_iops = {
1882 .listxattr = gfs2_listxattr, 1882 .listxattr = gfs2_listxattr,
1883 .removexattr = gfs2_removexattr, 1883 .removexattr = gfs2_removexattr,
1884 .fiemap = gfs2_fiemap, 1884 .fiemap = gfs2_fiemap,
1885 .check_acl = gfs2_check_acl, 1885 .get_acl = gfs2_get_acl,
1886}; 1886};
1887 1887
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 7aafeb8fa300..0b686cec9976 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1030,6 +1030,7 @@ static int __init init_hugetlbfs_fs(void)
1030static void __exit exit_hugetlbfs_fs(void) 1030static void __exit exit_hugetlbfs_fs(void)
1031{ 1031{
1032 kmem_cache_destroy(hugetlbfs_inode_cachep); 1032 kmem_cache_destroy(hugetlbfs_inode_cachep);
1033 kern_unmount(hugetlbfs_vfsmount);
1033 unregister_filesystem(&hugetlbfs_fs_type); 1034 unregister_filesystem(&hugetlbfs_fs_type);
1034 bdi_destroy(&hugetlbfs_backing_dev_info); 1035 bdi_destroy(&hugetlbfs_backing_dev_info);
1035} 1036}
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 3675b3cdee89..27c511a1cf05 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -156,7 +156,7 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
156 return ERR_PTR(-EINVAL); 156 return ERR_PTR(-EINVAL);
157} 157}
158 158
159static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) 159struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
160{ 160{
161 struct posix_acl *acl; 161 struct posix_acl *acl;
162 char *value = NULL; 162 char *value = NULL;
@@ -259,30 +259,11 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
259 return rc; 259 return rc;
260} 260}
261 261
262int jffs2_check_acl(struct inode *inode, int mask) 262int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, mode_t *i_mode)
263{ 263{
264 struct posix_acl *acl; 264 struct posix_acl *acl;
265 int rc; 265 int rc;
266 266
267 if (mask & MAY_NOT_BLOCK)
268 return -ECHILD;
269
270 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
271 if (IS_ERR(acl))
272 return PTR_ERR(acl);
273 if (acl) {
274 rc = posix_acl_permission(inode, acl, mask);
275 posix_acl_release(acl);
276 return rc;
277 }
278 return -EAGAIN;
279}
280
281int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
282{
283 struct posix_acl *acl, *clone;
284 int rc;
285
286 cache_no_acl(inode); 267 cache_no_acl(inode);
287 268
288 if (S_ISLNK(*i_mode)) 269 if (S_ISLNK(*i_mode))
@@ -298,18 +279,13 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
298 if (S_ISDIR(*i_mode)) 279 if (S_ISDIR(*i_mode))
299 set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); 280 set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
300 281
301 clone = posix_acl_clone(acl, GFP_KERNEL); 282 rc = posix_acl_create(&acl, GFP_KERNEL, i_mode);
302 if (!clone) 283 if (rc < 0)
303 return -ENOMEM;
304 rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
305 if (rc < 0) {
306 posix_acl_release(clone);
307 return rc; 284 return rc;
308 }
309 if (rc > 0) 285 if (rc > 0)
310 set_cached_acl(inode, ACL_TYPE_ACCESS, clone); 286 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
311 287
312 posix_acl_release(clone); 288 posix_acl_release(acl);
313 } 289 }
314 return 0; 290 return 0;
315} 291}
@@ -335,7 +311,7 @@ int jffs2_init_acl_post(struct inode *inode)
335 311
336int jffs2_acl_chmod(struct inode *inode) 312int jffs2_acl_chmod(struct inode *inode)
337{ 313{
338 struct posix_acl *acl, *clone; 314 struct posix_acl *acl;
339 int rc; 315 int rc;
340 316
341 if (S_ISLNK(inode->i_mode)) 317 if (S_ISLNK(inode->i_mode))
@@ -343,14 +319,11 @@ int jffs2_acl_chmod(struct inode *inode)
343 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS); 319 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
344 if (IS_ERR(acl) || !acl) 320 if (IS_ERR(acl) || !acl)
345 return PTR_ERR(acl); 321 return PTR_ERR(acl);
346 clone = posix_acl_clone(acl, GFP_KERNEL); 322 rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
323 if (rc)
324 return rc;
325 rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl);
347 posix_acl_release(acl); 326 posix_acl_release(acl);
348 if (!clone)
349 return -ENOMEM;
350 rc = posix_acl_chmod_masq(clone, inode->i_mode);
351 if (!rc)
352 rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
353 posix_acl_release(clone);
354 return rc; 327 return rc;
355} 328}
356 329
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 5e42de8d9541..b3421c78d9f8 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -26,9 +26,9 @@ struct jffs2_acl_header {
26 26
27#ifdef CONFIG_JFFS2_FS_POSIX_ACL 27#ifdef CONFIG_JFFS2_FS_POSIX_ACL
28 28
29extern int jffs2_check_acl(struct inode *, int); 29struct posix_acl *jffs2_get_acl(struct inode *inode, int type);
30extern int jffs2_acl_chmod(struct inode *); 30extern int jffs2_acl_chmod(struct inode *);
31extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); 31extern int jffs2_init_acl_pre(struct inode *, struct inode *, mode_t *);
32extern int jffs2_init_acl_post(struct inode *); 32extern int jffs2_init_acl_post(struct inode *);
33 33
34extern const struct xattr_handler jffs2_acl_access_xattr_handler; 34extern const struct xattr_handler jffs2_acl_access_xattr_handler;
@@ -36,7 +36,7 @@ extern const struct xattr_handler jffs2_acl_default_xattr_handler;
36 36
37#else 37#else
38 38
39#define jffs2_check_acl (NULL) 39#define jffs2_get_acl (NULL)
40#define jffs2_acl_chmod(inode) (0) 40#define jffs2_acl_chmod(inode) (0)
41#define jffs2_init_acl_pre(dir_i,inode,mode) (0) 41#define jffs2_init_acl_pre(dir_i,inode,mode) (0)
42#define jffs2_init_acl_post(inode) (0) 42#define jffs2_init_acl_post(inode) (0)
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 5f243cd63afc..9659b7c00468 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -56,7 +56,7 @@ const struct inode_operations jffs2_dir_inode_operations =
56 .rmdir = jffs2_rmdir, 56 .rmdir = jffs2_rmdir,
57 .mknod = jffs2_mknod, 57 .mknod = jffs2_mknod,
58 .rename = jffs2_rename, 58 .rename = jffs2_rename,
59 .check_acl = jffs2_check_acl, 59 .get_acl = jffs2_get_acl,
60 .setattr = jffs2_setattr, 60 .setattr = jffs2_setattr,
61 .setxattr = jffs2_setxattr, 61 .setxattr = jffs2_setxattr,
62 .getxattr = jffs2_getxattr, 62 .getxattr = jffs2_getxattr,
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 3989f7e09f7f..61e6723535b9 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -63,7 +63,7 @@ const struct file_operations jffs2_file_operations =
63 63
64const struct inode_operations jffs2_file_inode_operations = 64const struct inode_operations jffs2_file_inode_operations =
65{ 65{
66 .check_acl = jffs2_check_acl, 66 .get_acl = jffs2_get_acl,
67 .setattr = jffs2_setattr, 67 .setattr = jffs2_setattr,
68 .setxattr = jffs2_setxattr, 68 .setxattr = jffs2_setxattr,
69 .getxattr = jffs2_getxattr, 69 .getxattr = jffs2_getxattr,
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 46ad619b6124..eeead33d8ef0 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -406,7 +406,7 @@ int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
406 406
407/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, 407/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
408 fill in the raw_inode while you're at it. */ 408 fill in the raw_inode while you're at it. */
409struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) 409struct inode *jffs2_new_inode (struct inode *dir_i, mode_t mode, struct jffs2_raw_inode *ri)
410{ 410{
411 struct inode *inode; 411 struct inode *inode;
412 struct super_block *sb = dir_i->i_sb; 412 struct super_block *sb = dir_i->i_sb;
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 9c252835e8e5..526979c607b6 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -173,7 +173,7 @@ int jffs2_do_setattr (struct inode *, struct iattr *);
173struct inode *jffs2_iget(struct super_block *, unsigned long); 173struct inode *jffs2_iget(struct super_block *, unsigned long);
174void jffs2_evict_inode (struct inode *); 174void jffs2_evict_inode (struct inode *);
175void jffs2_dirty_inode(struct inode *inode, int flags); 175void jffs2_dirty_inode(struct inode *inode, int flags);
176struct inode *jffs2_new_inode (struct inode *dir_i, int mode, 176struct inode *jffs2_new_inode (struct inode *dir_i, mode_t mode,
177 struct jffs2_raw_inode *ri); 177 struct jffs2_raw_inode *ri);
178int jffs2_statfs (struct dentry *, struct kstatfs *); 178int jffs2_statfs (struct dentry *, struct kstatfs *);
179int jffs2_remount_fs (struct super_block *, int *, char *); 179int jffs2_remount_fs (struct super_block *, int *, char *);
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index b955626071c2..e3035afb1814 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -20,7 +20,7 @@ const struct inode_operations jffs2_symlink_inode_operations =
20{ 20{
21 .readlink = generic_readlink, 21 .readlink = generic_readlink,
22 .follow_link = jffs2_follow_link, 22 .follow_link = jffs2_follow_link,
23 .check_acl = jffs2_check_acl, 23 .get_acl = jffs2_get_acl,
24 .setattr = jffs2_setattr, 24 .setattr = jffs2_setattr,
25 .setxattr = jffs2_setxattr, 25 .setxattr = jffs2_setxattr,
26 .getxattr = jffs2_getxattr, 26 .getxattr = jffs2_getxattr,
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 8a0a0666d5a6..b3a32caf2b45 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -27,7 +27,7 @@
27#include "jfs_xattr.h" 27#include "jfs_xattr.h"
28#include "jfs_acl.h" 28#include "jfs_acl.h"
29 29
30static struct posix_acl *jfs_get_acl(struct inode *inode, int type) 30struct posix_acl *jfs_get_acl(struct inode *inode, int type)
31{ 31{
32 struct posix_acl *acl; 32 struct posix_acl *acl;
33 char *ea_name; 33 char *ea_name;
@@ -114,30 +114,9 @@ out:
114 return rc; 114 return rc;
115} 115}
116 116
117int jfs_check_acl(struct inode *inode, int mask)
118{
119 struct posix_acl *acl;
120
121 if (mask & MAY_NOT_BLOCK)
122 return -ECHILD;
123
124 acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
125 if (IS_ERR(acl))
126 return PTR_ERR(acl);
127 if (acl) {
128 int error = posix_acl_permission(inode, acl, mask);
129 posix_acl_release(acl);
130 return error;
131 }
132
133 return -EAGAIN;
134}
135
136int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) 117int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
137{ 118{
138 struct posix_acl *acl = NULL; 119 struct posix_acl *acl = NULL;
139 struct posix_acl *clone;
140 mode_t mode;
141 int rc = 0; 120 int rc = 0;
142 121
143 if (S_ISLNK(inode->i_mode)) 122 if (S_ISLNK(inode->i_mode))
@@ -148,25 +127,18 @@ int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
148 return PTR_ERR(acl); 127 return PTR_ERR(acl);
149 128
150 if (acl) { 129 if (acl) {
130 mode_t mode = inode->i_mode;
151 if (S_ISDIR(inode->i_mode)) { 131 if (S_ISDIR(inode->i_mode)) {
152 rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); 132 rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl);
153 if (rc) 133 if (rc)
154 goto cleanup; 134 goto cleanup;
155 } 135 }
156 clone = posix_acl_clone(acl, GFP_KERNEL); 136 rc = posix_acl_create(&acl, GFP_KERNEL, &mode);
157 if (!clone) { 137 if (rc < 0)
158 rc = -ENOMEM; 138 goto cleanup; /* posix_acl_release(NULL) is no-op */
159 goto cleanup; 139 inode->i_mode = mode;
160 } 140 if (rc > 0)
161 mode = inode->i_mode; 141 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
162 rc = posix_acl_create_masq(clone, &mode);
163 if (rc >= 0) {
164 inode->i_mode = mode;
165 if (rc > 0)
166 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS,
167 clone);
168 }
169 posix_acl_release(clone);
170cleanup: 142cleanup:
171 posix_acl_release(acl); 143 posix_acl_release(acl);
172 } else 144 } else
@@ -180,8 +152,9 @@ cleanup:
180 152
181int jfs_acl_chmod(struct inode *inode) 153int jfs_acl_chmod(struct inode *inode)
182{ 154{
183 struct posix_acl *acl, *clone; 155 struct posix_acl *acl;
184 int rc; 156 int rc;
157 tid_t tid;
185 158
186 if (S_ISLNK(inode->i_mode)) 159 if (S_ISLNK(inode->i_mode))
187 return -EOPNOTSUPP; 160 return -EOPNOTSUPP;
@@ -190,22 +163,18 @@ int jfs_acl_chmod(struct inode *inode)
190 if (IS_ERR(acl) || !acl) 163 if (IS_ERR(acl) || !acl)
191 return PTR_ERR(acl); 164 return PTR_ERR(acl);
192 165
193 clone = posix_acl_clone(acl, GFP_KERNEL); 166 rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
194 posix_acl_release(acl); 167 if (rc)
195 if (!clone) 168 return rc;
196 return -ENOMEM;
197
198 rc = posix_acl_chmod_masq(clone, inode->i_mode);
199 if (!rc) {
200 tid_t tid = txBegin(inode->i_sb, 0);
201 mutex_lock(&JFS_IP(inode)->commit_mutex);
202 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone);
203 if (!rc)
204 rc = txCommit(tid, 1, &inode, 0);
205 txEnd(tid);
206 mutex_unlock(&JFS_IP(inode)->commit_mutex);
207 }
208 169
209 posix_acl_release(clone); 170 tid = txBegin(inode->i_sb, 0);
171 mutex_lock(&JFS_IP(inode)->commit_mutex);
172 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
173 if (!rc)
174 rc = txCommit(tid, 1, &inode, 0);
175 txEnd(tid);
176 mutex_unlock(&JFS_IP(inode)->commit_mutex);
177
178 posix_acl_release(acl);
210 return rc; 179 return rc;
211} 180}
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 7527855b5cc6..844f9460cb11 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -140,7 +140,7 @@ const struct inode_operations jfs_file_inode_operations = {
140 .removexattr = jfs_removexattr, 140 .removexattr = jfs_removexattr,
141 .setattr = jfs_setattr, 141 .setattr = jfs_setattr,
142#ifdef CONFIG_JFS_POSIX_ACL 142#ifdef CONFIG_JFS_POSIX_ACL
143 .check_acl = jfs_check_acl, 143 .get_acl = jfs_get_acl,
144#endif 144#endif
145}; 145};
146 146
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index 54e07559878d..ad84fe50ca9e 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -20,7 +20,7 @@
20 20
21#ifdef CONFIG_JFS_POSIX_ACL 21#ifdef CONFIG_JFS_POSIX_ACL
22 22
23int jfs_check_acl(struct inode *, int); 23struct posix_acl *jfs_get_acl(struct inode *inode, int type);
24int jfs_init_acl(tid_t, struct inode *, struct inode *); 24int jfs_init_acl(tid_t, struct inode *, struct inode *);
25int jfs_acl_chmod(struct inode *inode); 25int jfs_acl_chmod(struct inode *inode);
26 26
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 03787ef6a118..29b1f1a21142 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1537,7 +1537,7 @@ const struct inode_operations jfs_dir_inode_operations = {
1537 .removexattr = jfs_removexattr, 1537 .removexattr = jfs_removexattr,
1538 .setattr = jfs_setattr, 1538 .setattr = jfs_setattr,
1539#ifdef CONFIG_JFS_POSIX_ACL 1539#ifdef CONFIG_JFS_POSIX_ACL
1540 .check_acl = jfs_check_acl, 1540 .get_acl = jfs_get_acl,
1541#endif 1541#endif
1542}; 1542};
1543 1543
diff --git a/fs/namei.c b/fs/namei.c
index b7fad009bbf6..ec2e5656b444 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -32,6 +32,7 @@
32#include <linux/fcntl.h> 32#include <linux/fcntl.h>
33#include <linux/device_cgroup.h> 33#include <linux/device_cgroup.h>
34#include <linux/fs_struct.h> 34#include <linux/fs_struct.h>
35#include <linux/posix_acl.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36 37
37#include "internal.h" 38#include "internal.h"
@@ -173,12 +174,60 @@ void putname(const char *name)
173EXPORT_SYMBOL(putname); 174EXPORT_SYMBOL(putname);
174#endif 175#endif
175 176
177static int check_acl(struct inode *inode, int mask)
178{
179 struct posix_acl *acl;
180
181 /*
182 * Under RCU walk, we cannot even do a "get_cached_acl()",
183 * because that involves locking and getting a refcount on
184 * a cached ACL.
185 *
186 * So the only case we handle during RCU walking is the
187 * case of a cached "no ACL at all", which needs no locks
188 * or refcounts.
189 */
190 if (mask & MAY_NOT_BLOCK) {
191 if (negative_cached_acl(inode, ACL_TYPE_ACCESS))
192 return -EAGAIN;
193 return -ECHILD;
194 }
195
196 acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
197
198 /*
199 * A filesystem can force a ACL callback by just never filling the
200 * ACL cache. But normally you'd fill the cache either at inode
201 * instantiation time, or on the first ->get_acl call.
202 *
203 * If the filesystem doesn't have a get_acl() function at all, we'll
204 * just create the negative cache entry.
205 */
206 if (acl == ACL_NOT_CACHED) {
207 if (inode->i_op->get_acl) {
208 acl = inode->i_op->get_acl(inode, ACL_TYPE_ACCESS);
209 if (IS_ERR(acl))
210 return PTR_ERR(acl);
211 } else {
212 set_cached_acl(inode, ACL_TYPE_ACCESS, NULL);
213 return -EAGAIN;
214 }
215 }
216
217 if (acl) {
218 int error = posix_acl_permission(inode, acl, mask);
219 posix_acl_release(acl);
220 return error;
221 }
222
223 return -EAGAIN;
224}
225
176/* 226/*
177 * This does basic POSIX ACL permission checking 227 * This does basic POSIX ACL permission checking
178 */ 228 */
179static int acl_permission_check(struct inode *inode, int mask) 229static int acl_permission_check(struct inode *inode, int mask)
180{ 230{
181 int (*check_acl)(struct inode *inode, int mask);
182 unsigned int mode = inode->i_mode; 231 unsigned int mode = inode->i_mode;
183 232
184 mask &= MAY_READ | MAY_WRITE | MAY_EXEC | MAY_NOT_BLOCK; 233 mask &= MAY_READ | MAY_WRITE | MAY_EXEC | MAY_NOT_BLOCK;
@@ -189,8 +238,7 @@ static int acl_permission_check(struct inode *inode, int mask)
189 if (current_fsuid() == inode->i_uid) 238 if (current_fsuid() == inode->i_uid)
190 mode >>= 6; 239 mode >>= 6;
191 else { 240 else {
192 check_acl = inode->i_op->check_acl; 241 if (IS_POSIXACL(inode) && (mode & S_IRWXG)) {
193 if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
194 int error = check_acl(inode, mask); 242 int error = check_acl(inode, mask);
195 if (error != -EAGAIN) 243 if (error != -EAGAIN)
196 return error; 244 return error;
diff --git a/fs/namespace.c b/fs/namespace.c
index cda50fe9250a..22bfe8273c68 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2721,6 +2721,25 @@ EXPORT_SYMBOL(put_mnt_ns);
2721 2721
2722struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) 2722struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
2723{ 2723{
2724 return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); 2724 struct vfsmount *mnt;
2725 mnt = vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
2726 if (!IS_ERR(mnt)) {
2727 /*
2728 * it is a longterm mount, don't release mnt until
2729 * we unmount before file sys is unregistered
2730 */
2731 mnt_make_longterm(mnt);
2732 }
2733 return mnt;
2725} 2734}
2726EXPORT_SYMBOL_GPL(kern_mount_data); 2735EXPORT_SYMBOL_GPL(kern_mount_data);
2736
2737void kern_unmount(struct vfsmount *mnt)
2738{
2739 /* release long term mount so mount point can be released */
2740 if (!IS_ERR_OR_NULL(mnt)) {
2741 mnt_make_shortterm(mnt);
2742 mntput(mnt);
2743 }
2744}
2745EXPORT_SYMBOL(kern_unmount);
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 274342771655..e49e73107e62 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -427,16 +427,12 @@ int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
427 } 427 }
428 if (!dfacl) 428 if (!dfacl)
429 return 0; 429 return 0;
430 acl = posix_acl_clone(dfacl, GFP_KERNEL); 430 acl = posix_acl_dup(dfacl);
431 error = -ENOMEM; 431 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
432 if (!acl)
433 goto out_release_dfacl;
434 error = posix_acl_create_masq(acl, &mode);
435 if (error < 0) 432 if (error < 0)
436 goto out_release_acl; 433 goto out_release_dfacl;
437 error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ? 434 error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
438 dfacl : NULL); 435 dfacl : NULL);
439out_release_acl:
440 posix_acl_release(acl); 436 posix_acl_release(acl);
441out_release_dfacl: 437out_release_dfacl:
442 posix_acl_release(dfacl); 438 posix_acl_release(dfacl);
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 1cee970eb55a..783c58d9daf1 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -290,47 +290,32 @@ static int ocfs2_set_acl(handle_t *handle,
290 return ret; 290 return ret;
291} 291}
292 292
293int ocfs2_check_acl(struct inode *inode, int mask) 293struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type)
294{ 294{
295 struct ocfs2_super *osb; 295 struct ocfs2_super *osb;
296 struct buffer_head *di_bh = NULL; 296 struct buffer_head *di_bh = NULL;
297 struct posix_acl *acl; 297 struct posix_acl *acl;
298 int ret = -EAGAIN; 298 int ret = -EAGAIN;
299 299
300 if (mask & MAY_NOT_BLOCK)
301 return -ECHILD;
302
303 osb = OCFS2_SB(inode->i_sb); 300 osb = OCFS2_SB(inode->i_sb);
304 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) 301 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
305 return ret; 302 return NULL;
306 303
307 ret = ocfs2_read_inode_block(inode, &di_bh); 304 ret = ocfs2_read_inode_block(inode, &di_bh);
308 if (ret < 0) { 305 if (ret < 0)
309 mlog_errno(ret); 306 return ERR_PTR(ret);
310 return ret;
311 }
312 307
313 acl = ocfs2_get_acl_nolock(inode, ACL_TYPE_ACCESS, di_bh); 308 acl = ocfs2_get_acl_nolock(inode, type, di_bh);
314 309
315 brelse(di_bh); 310 brelse(di_bh);
316 311
317 if (IS_ERR(acl)) { 312 return acl;
318 mlog_errno(PTR_ERR(acl));
319 return PTR_ERR(acl);
320 }
321 if (acl) {
322 ret = posix_acl_permission(inode, acl, mask);
323 posix_acl_release(acl);
324 return ret;
325 }
326
327 return -EAGAIN;
328} 313}
329 314
330int ocfs2_acl_chmod(struct inode *inode) 315int ocfs2_acl_chmod(struct inode *inode)
331{ 316{
332 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 317 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
333 struct posix_acl *acl, *clone; 318 struct posix_acl *acl;
334 int ret; 319 int ret;
335 320
336 if (S_ISLNK(inode->i_mode)) 321 if (S_ISLNK(inode->i_mode))
@@ -342,15 +327,12 @@ int ocfs2_acl_chmod(struct inode *inode)
342 acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS); 327 acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS);
343 if (IS_ERR(acl) || !acl) 328 if (IS_ERR(acl) || !acl)
344 return PTR_ERR(acl); 329 return PTR_ERR(acl);
345 clone = posix_acl_clone(acl, GFP_KERNEL); 330 ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
331 if (ret)
332 return ret;
333 ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS,
334 acl, NULL, NULL);
346 posix_acl_release(acl); 335 posix_acl_release(acl);
347 if (!clone)
348 return -ENOMEM;
349 ret = posix_acl_chmod_masq(clone, inode->i_mode);
350 if (!ret)
351 ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS,
352 clone, NULL, NULL);
353 posix_acl_release(clone);
354 return ret; 336 return ret;
355} 337}
356 338
@@ -388,8 +370,6 @@ int ocfs2_init_acl(handle_t *handle,
388 } 370 }
389 } 371 }
390 if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { 372 if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
391 struct posix_acl *clone;
392
393 if (S_ISDIR(inode->i_mode)) { 373 if (S_ISDIR(inode->i_mode)) {
394 ret = ocfs2_set_acl(handle, inode, di_bh, 374 ret = ocfs2_set_acl(handle, inode, di_bh,
395 ACL_TYPE_DEFAULT, acl, 375 ACL_TYPE_DEFAULT, acl,
@@ -397,27 +377,22 @@ int ocfs2_init_acl(handle_t *handle,
397 if (ret) 377 if (ret)
398 goto cleanup; 378 goto cleanup;
399 } 379 }
400 clone = posix_acl_clone(acl, GFP_NOFS);
401 ret = -ENOMEM;
402 if (!clone)
403 goto cleanup;
404
405 mode = inode->i_mode; 380 mode = inode->i_mode;
406 ret = posix_acl_create_masq(clone, &mode); 381 ret = posix_acl_create(&acl, GFP_NOFS, &mode);
407 if (ret >= 0) { 382 if (ret < 0)
408 ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode); 383 return ret;
409 if (ret2) { 384
410 mlog_errno(ret2); 385 ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
411 ret = ret2; 386 if (ret2) {
412 goto cleanup; 387 mlog_errno(ret2);
413 } 388 ret = ret2;
414 if (ret > 0) { 389 goto cleanup;
415 ret = ocfs2_set_acl(handle, inode, 390 }
416 di_bh, ACL_TYPE_ACCESS, 391 if (ret > 0) {
417 clone, meta_ac, data_ac); 392 ret = ocfs2_set_acl(handle, inode,
418 } 393 di_bh, ACL_TYPE_ACCESS,
394 acl, meta_ac, data_ac);
419 } 395 }
420 posix_acl_release(clone);
421 } 396 }
422cleanup: 397cleanup:
423 posix_acl_release(acl); 398 posix_acl_release(acl);
diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h
index 5c5d31f05853..071fbd380f2f 100644
--- a/fs/ocfs2/acl.h
+++ b/fs/ocfs2/acl.h
@@ -26,7 +26,7 @@ struct ocfs2_acl_entry {
26 __le32 e_id; 26 __le32 e_id;
27}; 27};
28 28
29extern int ocfs2_check_acl(struct inode *, int); 29struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type);
30extern int ocfs2_acl_chmod(struct inode *); 30extern int ocfs2_acl_chmod(struct inode *);
31extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, 31extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
32 struct buffer_head *, struct buffer_head *, 32 struct buffer_head *, struct buffer_head *,
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 0fc2bd34039d..de4ea1af041b 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2600,14 +2600,14 @@ const struct inode_operations ocfs2_file_iops = {
2600 .listxattr = ocfs2_listxattr, 2600 .listxattr = ocfs2_listxattr,
2601 .removexattr = generic_removexattr, 2601 .removexattr = generic_removexattr,
2602 .fiemap = ocfs2_fiemap, 2602 .fiemap = ocfs2_fiemap,
2603 .check_acl = ocfs2_check_acl, 2603 .get_acl = ocfs2_iop_get_acl,
2604}; 2604};
2605 2605
2606const struct inode_operations ocfs2_special_file_iops = { 2606const struct inode_operations ocfs2_special_file_iops = {
2607 .setattr = ocfs2_setattr, 2607 .setattr = ocfs2_setattr,
2608 .getattr = ocfs2_getattr, 2608 .getattr = ocfs2_getattr,
2609 .permission = ocfs2_permission, 2609 .permission = ocfs2_permission,
2610 .check_acl = ocfs2_check_acl, 2610 .get_acl = ocfs2_iop_get_acl,
2611}; 2611};
2612 2612
2613/* 2613/*
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 33889dc52dd7..53aa41ed7bf3 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -2498,5 +2498,5 @@ const struct inode_operations ocfs2_dir_iops = {
2498 .listxattr = ocfs2_listxattr, 2498 .listxattr = ocfs2_listxattr,
2499 .removexattr = generic_removexattr, 2499 .removexattr = generic_removexattr,
2500 .fiemap = ocfs2_fiemap, 2500 .fiemap = ocfs2_fiemap,
2501 .check_acl = ocfs2_check_acl, 2501 .get_acl = ocfs2_iop_get_acl,
2502}; 2502};
diff --git a/fs/pipe.c b/fs/pipe.c
index da42f7db50de..1b7f9af67ccf 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1291,8 +1291,8 @@ static int __init init_pipe_fs(void)
1291 1291
1292static void __exit exit_pipe_fs(void) 1292static void __exit exit_pipe_fs(void)
1293{ 1293{
1294 kern_unmount(pipe_mnt);
1294 unregister_filesystem(&pipe_fs_type); 1295 unregister_filesystem(&pipe_fs_type);
1295 mntput(pipe_mnt);
1296} 1296}
1297 1297
1298fs_initcall(init_pipe_fs); 1298fs_initcall(init_pipe_fs);
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index b1cf6bf4b41d..a6227d219e93 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -24,13 +24,9 @@
24 24
25EXPORT_SYMBOL(posix_acl_init); 25EXPORT_SYMBOL(posix_acl_init);
26EXPORT_SYMBOL(posix_acl_alloc); 26EXPORT_SYMBOL(posix_acl_alloc);
27EXPORT_SYMBOL(posix_acl_clone);
28EXPORT_SYMBOL(posix_acl_valid); 27EXPORT_SYMBOL(posix_acl_valid);
29EXPORT_SYMBOL(posix_acl_equiv_mode); 28EXPORT_SYMBOL(posix_acl_equiv_mode);
30EXPORT_SYMBOL(posix_acl_from_mode); 29EXPORT_SYMBOL(posix_acl_from_mode);
31EXPORT_SYMBOL(posix_acl_create_masq);
32EXPORT_SYMBOL(posix_acl_chmod_masq);
33EXPORT_SYMBOL(posix_acl_permission);
34 30
35/* 31/*
36 * Init a fresh posix_acl 32 * Init a fresh posix_acl
@@ -59,7 +55,7 @@ posix_acl_alloc(int count, gfp_t flags)
59/* 55/*
60 * Clone an ACL. 56 * Clone an ACL.
61 */ 57 */
62struct posix_acl * 58static struct posix_acl *
63posix_acl_clone(const struct posix_acl *acl, gfp_t flags) 59posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
64{ 60{
65 struct posix_acl *clone = NULL; 61 struct posix_acl *clone = NULL;
@@ -283,8 +279,7 @@ check_perm:
283 * system calls. All permissions that are not granted by the acl are removed. 279 * system calls. All permissions that are not granted by the acl are removed.
284 * The permissions in the acl are changed to reflect the mode_p parameter. 280 * The permissions in the acl are changed to reflect the mode_p parameter.
285 */ 281 */
286int 282static int posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p)
287posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p)
288{ 283{
289 struct posix_acl_entry *pa, *pe; 284 struct posix_acl_entry *pa, *pe;
290 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; 285 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
@@ -341,8 +336,7 @@ posix_acl_create_masq(struct posix_acl *acl, mode_t *mode_p)
341/* 336/*
342 * Modify the ACL for the chmod syscall. 337 * Modify the ACL for the chmod syscall.
343 */ 338 */
344int 339static int posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
345posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
346{ 340{
347 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; 341 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
348 struct posix_acl_entry *pa, *pe; 342 struct posix_acl_entry *pa, *pe;
@@ -386,3 +380,39 @@ posix_acl_chmod_masq(struct posix_acl *acl, mode_t mode)
386 380
387 return 0; 381 return 0;
388} 382}
383
384int
385posix_acl_create(struct posix_acl **acl, gfp_t gfp, mode_t *mode_p)
386{
387 struct posix_acl *clone = posix_acl_clone(*acl, gfp);
388 int err = -ENOMEM;
389 if (clone) {
390 err = posix_acl_create_masq(clone, mode_p);
391 if (err < 0) {
392 posix_acl_release(clone);
393 clone = NULL;
394 }
395 }
396 posix_acl_release(*acl);
397 *acl = clone;
398 return err;
399}
400EXPORT_SYMBOL(posix_acl_create);
401
402int
403posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, mode_t mode)
404{
405 struct posix_acl *clone = posix_acl_clone(*acl, gfp);
406 int err = -ENOMEM;
407 if (clone) {
408 err = posix_acl_chmod_masq(clone, mode);
409 if (err) {
410 posix_acl_release(clone);
411 clone = NULL;
412 }
413 }
414 posix_acl_release(*acl);
415 *acl = clone;
416 return err;
417}
418EXPORT_SYMBOL(posix_acl_chmod);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c7156dc39ce7..ace635053a36 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -319,5 +319,5 @@ const struct inode_operations reiserfs_file_inode_operations = {
319 .listxattr = reiserfs_listxattr, 319 .listxattr = reiserfs_listxattr,
320 .removexattr = reiserfs_removexattr, 320 .removexattr = reiserfs_removexattr,
321 .permission = reiserfs_permission, 321 .permission = reiserfs_permission,
322 .check_acl = reiserfs_check_acl, 322 .get_acl = reiserfs_get_acl,
323}; 323};
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 2922b90ceac1..9b0d4b78b4fb 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1475,6 +1475,11 @@ void reiserfs_read_locked_inode(struct inode *inode,
1475 1475
1476 reiserfs_check_path(&path_to_sd); /* init inode should be relsing */ 1476 reiserfs_check_path(&path_to_sd); /* init inode should be relsing */
1477 1477
1478 /*
1479 * Stat data v1 doesn't support ACLs.
1480 */
1481 if (get_inode_sd_version(inode) == STAT_DATA_V1)
1482 cache_no_acl(inode);
1478} 1483}
1479 1484
1480/** 1485/**
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 551f1b79dbc4..ef392324bbf1 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1529,7 +1529,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
1529 .listxattr = reiserfs_listxattr, 1529 .listxattr = reiserfs_listxattr,
1530 .removexattr = reiserfs_removexattr, 1530 .removexattr = reiserfs_removexattr,
1531 .permission = reiserfs_permission, 1531 .permission = reiserfs_permission,
1532 .check_acl = reiserfs_check_acl, 1532 .get_acl = reiserfs_get_acl,
1533}; 1533};
1534 1534
1535/* 1535/*
@@ -1546,7 +1546,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
1546 .listxattr = reiserfs_listxattr, 1546 .listxattr = reiserfs_listxattr,
1547 .removexattr = reiserfs_removexattr, 1547 .removexattr = reiserfs_removexattr,
1548 .permission = reiserfs_permission, 1548 .permission = reiserfs_permission,
1549 .check_acl = reiserfs_check_acl, 1549 .get_acl = reiserfs_get_acl,
1550 1550
1551}; 1551};
1552 1552
@@ -1560,5 +1560,5 @@ const struct inode_operations reiserfs_special_inode_operations = {
1560 .listxattr = reiserfs_listxattr, 1560 .listxattr = reiserfs_listxattr,
1561 .removexattr = reiserfs_removexattr, 1561 .removexattr = reiserfs_removexattr,
1562 .permission = reiserfs_permission, 1562 .permission = reiserfs_permission,
1563 .check_acl = reiserfs_check_acl, 1563 .get_acl = reiserfs_get_acl,
1564}; 1564};
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 6938d8c68d6e..6bc346c160e7 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -867,33 +867,6 @@ out:
867 return err; 867 return err;
868} 868}
869 869
870int reiserfs_check_acl(struct inode *inode, int mask)
871{
872 struct posix_acl *acl;
873 int error = -EAGAIN; /* do regular unix permission checks by default */
874
875 /*
876 * Stat data v1 doesn't support ACLs.
877 */
878 if (get_inode_sd_version(inode) == STAT_DATA_V1)
879 return -EAGAIN;
880
881 if (mask & MAY_NOT_BLOCK)
882 return -ECHILD;
883
884 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
885
886 if (acl) {
887 if (!IS_ERR(acl)) {
888 error = posix_acl_permission(inode, acl, mask);
889 posix_acl_release(acl);
890 } else if (PTR_ERR(acl) != -ENODATA)
891 error = PTR_ERR(acl);
892 }
893
894 return error;
895}
896
897static int create_privroot(struct dentry *dentry) 870static int create_privroot(struct dentry *dentry)
898{ 871{
899 int err; 872 int err;
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 3dc38f1206fc..7362cf4c946a 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -354,9 +354,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
354 return PTR_ERR(acl); 354 return PTR_ERR(acl);
355 355
356 if (acl) { 356 if (acl) {
357 struct posix_acl *acl_copy;
358 mode_t mode = inode->i_mode; 357 mode_t mode = inode->i_mode;
359 int need_acl;
360 358
361 /* Copy the default ACL to the default ACL of a new directory */ 359 /* Copy the default ACL to the default ACL of a new directory */
362 if (S_ISDIR(inode->i_mode)) { 360 if (S_ISDIR(inode->i_mode)) {
@@ -368,29 +366,15 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
368 366
369 /* Now we reconcile the new ACL and the mode, 367 /* Now we reconcile the new ACL and the mode,
370 potentially modifying both */ 368 potentially modifying both */
371 acl_copy = posix_acl_clone(acl, GFP_NOFS); 369 err = posix_acl_create(&acl, GFP_NOFS, &mode);
372 if (!acl_copy) { 370 if (err < 0)
373 err = -ENOMEM; 371 return err;
374 goto cleanup;
375 }
376 372
377 need_acl = posix_acl_create_masq(acl_copy, &mode); 373 inode->i_mode = mode;
378 if (need_acl >= 0) {
379 if (mode != inode->i_mode) {
380 inode->i_mode = mode;
381 }
382 374
383 /* If we need an ACL.. */ 375 /* If we need an ACL.. */
384 if (need_acl > 0) { 376 if (err > 0)
385 err = reiserfs_set_acl(th, inode, 377 err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl);
386 ACL_TYPE_ACCESS,
387 acl_copy);
388 if (err)
389 goto cleanup_copy;
390 }
391 }
392 cleanup_copy:
393 posix_acl_release(acl_copy);
394 cleanup: 378 cleanup:
395 posix_acl_release(acl); 379 posix_acl_release(acl);
396 } else { 380 } else {
@@ -445,7 +429,10 @@ int reiserfs_cache_default_acl(struct inode *inode)
445 429
446int reiserfs_acl_chmod(struct inode *inode) 430int reiserfs_acl_chmod(struct inode *inode)
447{ 431{
448 struct posix_acl *acl, *clone; 432 struct reiserfs_transaction_handle th;
433 struct posix_acl *acl;
434 size_t size;
435 int depth;
449 int error; 436 int error;
450 437
451 if (S_ISLNK(inode->i_mode)) 438 if (S_ISLNK(inode->i_mode))
@@ -463,30 +450,22 @@ int reiserfs_acl_chmod(struct inode *inode)
463 return 0; 450 return 0;
464 if (IS_ERR(acl)) 451 if (IS_ERR(acl))
465 return PTR_ERR(acl); 452 return PTR_ERR(acl);
466 clone = posix_acl_clone(acl, GFP_NOFS); 453 error = posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
467 posix_acl_release(acl); 454 if (error)
468 if (!clone) 455 return error;
469 return -ENOMEM; 456
470 error = posix_acl_chmod_masq(clone, inode->i_mode); 457 size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(acl->a_count));
458 depth = reiserfs_write_lock_once(inode->i_sb);
459 error = journal_begin(&th, inode->i_sb, size * 2);
471 if (!error) { 460 if (!error) {
472 struct reiserfs_transaction_handle th; 461 int error2;
473 size_t size = reiserfs_xattr_nblocks(inode, 462 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, acl);
474 reiserfs_acl_size(clone->a_count)); 463 error2 = journal_end(&th, inode->i_sb, size * 2);
475 int depth; 464 if (error2)
476 465 error = error2;
477 depth = reiserfs_write_lock_once(inode->i_sb);
478 error = journal_begin(&th, inode->i_sb, size * 2);
479 if (!error) {
480 int error2;
481 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS,
482 clone);
483 error2 = journal_end(&th, inode->i_sb, size * 2);
484 if (error2)
485 error = error2;
486 }
487 reiserfs_write_unlock_once(inode->i_sb, depth);
488 } 466 }
489 posix_acl_release(clone); 467 reiserfs_write_unlock_once(inode->i_sb, depth);
468 posix_acl_release(acl);
490 return error; 469 return error;
491} 470}
492 471
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
index cac48fe22ad5..44ce51656804 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -114,6 +114,8 @@ xfs_get_acl(struct inode *inode, int type)
114 if (acl != ACL_NOT_CACHED) 114 if (acl != ACL_NOT_CACHED)
115 return acl; 115 return acl;
116 116
117 trace_xfs_get_acl(ip);
118
117 switch (type) { 119 switch (type) {
118 case ACL_TYPE_ACCESS: 120 case ACL_TYPE_ACCESS:
119 ea_name = SGI_ACL_FILE; 121 ea_name = SGI_ACL_FILE;
@@ -218,40 +220,6 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
218 return error; 220 return error;
219} 221}
220 222
221int
222xfs_check_acl(struct inode *inode, int mask)
223{
224 struct xfs_inode *ip;
225 struct posix_acl *acl;
226 int error = -EAGAIN;
227
228 ip = XFS_I(inode);
229 trace_xfs_check_acl(ip);
230
231 /*
232 * If there is no attribute fork no ACL exists on this inode and
233 * we can skip the whole exercise.
234 */
235 if (!XFS_IFORK_Q(ip))
236 return -EAGAIN;
237
238 if (mask & MAY_NOT_BLOCK) {
239 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
240 return -ECHILD;
241 return -EAGAIN;
242 }
243
244 acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
245 if (IS_ERR(acl))
246 return PTR_ERR(acl);
247 if (acl) {
248 error = posix_acl_permission(inode, acl, mask);
249 posix_acl_release(acl);
250 }
251
252 return error;
253}
254
255static int 223static int
256xfs_set_mode(struct inode *inode, mode_t mode) 224xfs_set_mode(struct inode *inode, mode_t mode)
257{ 225{
@@ -297,29 +265,23 @@ posix_acl_default_exists(struct inode *inode)
297 * No need for i_mutex because the inode is not yet exposed to the VFS. 265 * No need for i_mutex because the inode is not yet exposed to the VFS.
298 */ 266 */
299int 267int
300xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl) 268xfs_inherit_acl(struct inode *inode, struct posix_acl *acl)
301{ 269{
302 struct posix_acl *clone; 270 mode_t mode = inode->i_mode;
303 mode_t mode;
304 int error = 0, inherit = 0; 271 int error = 0, inherit = 0;
305 272
306 if (S_ISDIR(inode->i_mode)) { 273 if (S_ISDIR(inode->i_mode)) {
307 error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl); 274 error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
308 if (error) 275 if (error)
309 return error; 276 goto out;
310 } 277 }
311 278
312 clone = posix_acl_clone(default_acl, GFP_KERNEL); 279 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
313 if (!clone)
314 return -ENOMEM;
315
316 mode = inode->i_mode;
317 error = posix_acl_create_masq(clone, &mode);
318 if (error < 0) 280 if (error < 0)
319 goto out_release_clone; 281 return error;
320 282
321 /* 283 /*
322 * If posix_acl_create_masq returns a positive value we need to 284 * If posix_acl_create returns a positive value we need to
323 * inherit a permission that can't be represented using the Unix 285 * inherit a permission that can't be represented using the Unix
324 * mode bits and we actually need to set an ACL. 286 * mode bits and we actually need to set an ACL.
325 */ 287 */
@@ -328,20 +290,20 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl)
328 290
329 error = xfs_set_mode(inode, mode); 291 error = xfs_set_mode(inode, mode);
330 if (error) 292 if (error)
331 goto out_release_clone; 293 goto out;
332 294
333 if (inherit) 295 if (inherit)
334 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone); 296 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
335 297
336 out_release_clone: 298out:
337 posix_acl_release(clone); 299 posix_acl_release(acl);
338 return error; 300 return error;
339} 301}
340 302
341int 303int
342xfs_acl_chmod(struct inode *inode) 304xfs_acl_chmod(struct inode *inode)
343{ 305{
344 struct posix_acl *acl, *clone; 306 struct posix_acl *acl;
345 int error; 307 int error;
346 308
347 if (S_ISLNK(inode->i_mode)) 309 if (S_ISLNK(inode->i_mode))
@@ -351,16 +313,12 @@ xfs_acl_chmod(struct inode *inode)
351 if (IS_ERR(acl) || !acl) 313 if (IS_ERR(acl) || !acl)
352 return PTR_ERR(acl); 314 return PTR_ERR(acl);
353 315
354 clone = posix_acl_clone(acl, GFP_KERNEL); 316 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
355 posix_acl_release(acl); 317 if (error)
356 if (!clone) 318 return error;
357 return -ENOMEM;
358
359 error = posix_acl_chmod_masq(clone, inode->i_mode);
360 if (!error)
361 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
362 319
363 posix_acl_release(clone); 320 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
321 posix_acl_release(acl);
364 return error; 322 return error;
365} 323}
366 324
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index cca00f49e092..825390e1c138 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -881,11 +881,14 @@ xfs_file_aio_write(
881 /* Handle various SYNC-type writes */ 881 /* Handle various SYNC-type writes */
882 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 882 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
883 loff_t end = pos + ret - 1; 883 loff_t end = pos + ret - 1;
884 int error;
884 885
885 xfs_rw_iunlock(ip, iolock); 886 xfs_rw_iunlock(ip, iolock);
886 ret = -xfs_file_fsync(file, pos, end, 887 error = xfs_file_fsync(file, pos, end,
887 (file->f_flags & __O_SYNC) ? 0 : 1); 888 (file->f_flags & __O_SYNC) ? 0 : 1);
888 xfs_rw_ilock(ip, iolock); 889 xfs_rw_ilock(ip, iolock);
890 if (error)
891 ret = error;
889 } 892 }
890 893
891out_unlock: 894out_unlock:
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 501e4f630548..6544c3236bc8 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -202,9 +202,9 @@ xfs_vn_mknod(
202 202
203 if (default_acl) { 203 if (default_acl) {
204 error = -xfs_inherit_acl(inode, default_acl); 204 error = -xfs_inherit_acl(inode, default_acl);
205 default_acl = NULL;
205 if (unlikely(error)) 206 if (unlikely(error))
206 goto out_cleanup_inode; 207 goto out_cleanup_inode;
207 posix_acl_release(default_acl);
208 } 208 }
209 209
210 210
@@ -1022,7 +1022,7 @@ xfs_vn_fiemap(
1022} 1022}
1023 1023
1024static const struct inode_operations xfs_inode_operations = { 1024static const struct inode_operations xfs_inode_operations = {
1025 .check_acl = xfs_check_acl, 1025 .get_acl = xfs_get_acl,
1026 .getattr = xfs_vn_getattr, 1026 .getattr = xfs_vn_getattr,
1027 .setattr = xfs_vn_setattr, 1027 .setattr = xfs_vn_setattr,
1028 .setxattr = generic_setxattr, 1028 .setxattr = generic_setxattr,
@@ -1048,7 +1048,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
1048 .rmdir = xfs_vn_unlink, 1048 .rmdir = xfs_vn_unlink,
1049 .mknod = xfs_vn_mknod, 1049 .mknod = xfs_vn_mknod,
1050 .rename = xfs_vn_rename, 1050 .rename = xfs_vn_rename,
1051 .check_acl = xfs_check_acl, 1051 .get_acl = xfs_get_acl,
1052 .getattr = xfs_vn_getattr, 1052 .getattr = xfs_vn_getattr,
1053 .setattr = xfs_vn_setattr, 1053 .setattr = xfs_vn_setattr,
1054 .setxattr = generic_setxattr, 1054 .setxattr = generic_setxattr,
@@ -1073,7 +1073,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1073 .rmdir = xfs_vn_unlink, 1073 .rmdir = xfs_vn_unlink,
1074 .mknod = xfs_vn_mknod, 1074 .mknod = xfs_vn_mknod,
1075 .rename = xfs_vn_rename, 1075 .rename = xfs_vn_rename,
1076 .check_acl = xfs_check_acl, 1076 .get_acl = xfs_get_acl,
1077 .getattr = xfs_vn_getattr, 1077 .getattr = xfs_vn_getattr,
1078 .setattr = xfs_vn_setattr, 1078 .setattr = xfs_vn_setattr,
1079 .setxattr = generic_setxattr, 1079 .setxattr = generic_setxattr,
@@ -1086,7 +1086,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
1086 .readlink = generic_readlink, 1086 .readlink = generic_readlink,
1087 .follow_link = xfs_vn_follow_link, 1087 .follow_link = xfs_vn_follow_link,
1088 .put_link = xfs_vn_put_link, 1088 .put_link = xfs_vn_put_link,
1089 .check_acl = xfs_check_acl, 1089 .get_acl = xfs_get_acl,
1090 .getattr = xfs_vn_getattr, 1090 .getattr = xfs_vn_getattr,
1091 .setattr = xfs_vn_setattr, 1091 .setattr = xfs_vn_setattr,
1092 .setxattr = generic_setxattr, 1092 .setxattr = generic_setxattr,
@@ -1194,6 +1194,10 @@ xfs_setup_inode(
1194 break; 1194 break;
1195 } 1195 }
1196 1196
1197 /* if there is no attribute fork no ACL can exist on this inode */
1198 if (!XFS_IFORK_Q(ip))
1199 cache_no_acl(inode);
1200
1197 xfs_iflags_clear(ip, XFS_INEW); 1201 xfs_iflags_clear(ip, XFS_INEW);
1198 barrier(); 1202 barrier();
1199 1203
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index fda0708ef2ea..690fc7a7bd72 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -571,7 +571,7 @@ DEFINE_INODE_EVENT(xfs_alloc_file_space);
571DEFINE_INODE_EVENT(xfs_free_file_space); 571DEFINE_INODE_EVENT(xfs_free_file_space);
572DEFINE_INODE_EVENT(xfs_readdir); 572DEFINE_INODE_EVENT(xfs_readdir);
573#ifdef CONFIG_XFS_POSIX_ACL 573#ifdef CONFIG_XFS_POSIX_ACL
574DEFINE_INODE_EVENT(xfs_check_acl); 574DEFINE_INODE_EVENT(xfs_get_acl);
575#endif 575#endif
576DEFINE_INODE_EVENT(xfs_vm_bmap); 576DEFINE_INODE_EVENT(xfs_vm_bmap);
577DEFINE_INODE_EVENT(xfs_file_ioctl); 577DEFINE_INODE_EVENT(xfs_file_ioctl);
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 0135e2a669d7..2c656ef49473 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -42,7 +42,6 @@ struct xfs_acl {
42#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) 42#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
43 43
44#ifdef CONFIG_XFS_POSIX_ACL 44#ifdef CONFIG_XFS_POSIX_ACL
45extern int xfs_check_acl(struct inode *inode, int mask);
46extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); 45extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
47extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); 46extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
48extern int xfs_acl_chmod(struct inode *inode); 47extern int xfs_acl_chmod(struct inode *inode);
@@ -52,7 +51,6 @@ extern int posix_acl_default_exists(struct inode *inode);
52extern const struct xattr_handler xfs_xattr_acl_access_handler; 51extern const struct xattr_handler xfs_xattr_acl_access_handler;
53extern const struct xattr_handler xfs_xattr_acl_default_handler; 52extern const struct xattr_handler xfs_xattr_acl_default_handler;
54#else 53#else
55# define xfs_check_acl NULL
56# define xfs_get_acl(inode, type) NULL 54# define xfs_get_acl(inode, type) NULL
57# define xfs_inherit_acl(inode, default_acl) 0 55# define xfs_inherit_acl(inode, default_acl) 0
58# define xfs_acl_chmod(inode) 0 56# define xfs_acl_chmod(inode) 0