aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 11:38:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-28 11:38:04 -0500
commitbf3d846b783327359ddc4bd4f52627b36abb4d1d (patch)
treec6b8fddbf04a2962dfcf9f487af25033f11b10b9
parent54c0a4b46150db1571d955d598cd342c9f1d9657 (diff)
parentf6500801522c61782d4990fa1ad96154cb397cd4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "Assorted stuff; the biggest pile here is Christoph's ACL series. Plus assorted cleanups and fixes all over the place... There will be another pile later this week" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (43 commits) __dentry_path() fixes vfs: Remove second variable named error in __dentry_path vfs: Is mounted should be testing mnt_ns for NULL or error. Fix race when checking i_size on direct i/o read hfsplus: remove can_set_xattr nfsd: use get_acl and ->set_acl fs: remove generic_acl nfs: use generic posix ACL infrastructure for v3 Posix ACLs gfs2: use generic posix ACL infrastructure jfs: use generic posix ACL infrastructure xfs: use generic posix ACL infrastructure reiserfs: use generic posix ACL infrastructure ocfs2: use generic posix ACL infrastructure jffs2: use generic posix ACL infrastructure hfsplus: use generic posix ACL infrastructure f2fs: use generic posix ACL infrastructure ext2/3/4: use generic posix ACL infrastructure btrfs: use generic posix ACL infrastructure fs: make posix_acl_create more useful fs: make posix_acl_chmod more useful ...
-rw-r--r--arch/blackfin/kernel/setup.c2
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c2
-rw-r--r--fs/9p/acl.c4
-rw-r--r--fs/Kconfig6
-rw-r--r--fs/Makefile3
-rw-r--r--fs/affs/super.c57
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/afs/proc.c122
-rw-r--r--fs/befs/linuxvfs.c4
-rw-r--r--fs/btrfs/acl.c142
-rw-r--r--fs/btrfs/ctree.h7
-rw-r--r--fs/btrfs/inode.c7
-rw-r--r--fs/btrfs/ioctl.c70
-rw-r--r--fs/btrfs/xattr.c5
-rw-r--r--fs/btrfs/xattr.h2
-rw-r--r--fs/cramfs/inode.c50
-rw-r--r--fs/cramfs/internal.h (renamed from include/linux/cramfs_fs.h)6
-rw-r--r--fs/cramfs/uncompress.c2
-rw-r--r--fs/dcache.c10
-rw-r--r--fs/ecryptfs/inode.c29
-rw-r--r--fs/efs/super.c39
-rw-r--r--fs/eventfd.c13
-rw-r--r--fs/ext2/acl.c188
-rw-r--r--fs/ext2/acl.h8
-rw-r--r--fs/ext2/file.c1
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext2/namei.c2
-rw-r--r--fs/ext2/xattr.c8
-rw-r--r--fs/ext2/xattr.h2
-rw-r--r--fs/ext3/acl.c223
-rw-r--r--fs/ext3/acl.h9
-rw-r--r--fs/ext3/file.c1
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/ext3/namei.c2
-rw-r--r--fs/ext3/xattr.c8
-rw-r--r--fs/ext3/xattr.h2
-rw-r--r--fs/ext4/acl.c223
-rw-r--r--fs/ext4/acl.h9
-rw-r--r--fs/ext4/file.c1
-rw-r--r--fs/ext4/inode.c2
-rw-r--r--fs/ext4/namei.c2
-rw-r--r--fs/ext4/xattr.c8
-rw-r--r--fs/ext4/xattr.h2
-rw-r--r--fs/f2fs/acl.c174
-rw-r--r--fs/f2fs/acl.h7
-rw-r--r--fs/f2fs/f2fs.h4
-rw-r--r--fs/f2fs/file.c3
-rw-r--r--fs/f2fs/namei.c2
-rw-r--r--fs/f2fs/xattr.c9
-rw-r--r--fs/f2fs/xattr.h2
-rw-r--r--fs/file.c98
-rw-r--r--fs/fuse/file.c3
-rw-r--r--fs/generic_acl.c184
-rw-r--r--fs/gfs2/acl.c234
-rw-r--r--fs/gfs2/acl.h4
-rw-r--r--fs/gfs2/inode.c34
-rw-r--r--fs/gfs2/xattr.c4
-rw-r--r--fs/hfsplus/acl.h9
-rw-r--r--fs/hfsplus/dir.c1
-rw-r--r--fs/hfsplus/inode.c3
-rw-r--r--fs/hfsplus/posix_acl.c168
-rw-r--r--fs/hfsplus/xattr.c92
-rw-r--r--fs/hfsplus/xattr.h2
-rw-r--r--fs/jffs2/acl.c141
-rw-r--r--fs/jffs2/acl.h7
-rw-r--r--fs/jffs2/dir.c1
-rw-r--r--fs/jffs2/file.c1
-rw-r--r--fs/jffs2/fs.c7
-rw-r--r--fs/jffs2/symlink.c1
-rw-r--r--fs/jffs2/xattr.c9
-rw-r--r--fs/jfs/acl.c105
-rw-r--r--fs/jfs/file.c4
-rw-r--r--fs/jfs/jfs_acl.h7
-rw-r--r--fs/jfs/jfs_xattr.h2
-rw-r--r--fs/jfs/namei.c1
-rw-r--r--fs/jfs/super.c2
-rw-r--r--fs/jfs/xattr.c108
-rw-r--r--fs/mount.h2
-rw-r--r--fs/namei.c24
-rw-r--r--fs/nfs/inode.c4
-rw-r--r--fs/nfs/nfs3acl.c291
-rw-r--r--fs/nfs/nfs3proc.c76
-rw-r--r--fs/nfs/nfs3super.c3
-rw-r--r--fs/nfsd/acl.h16
-rw-r--r--fs/nfsd/nfs2acl.c72
-rw-r--r--fs/nfsd/nfs3acl.c62
-rw-r--r--fs/nfsd/nfs4acl.c120
-rw-r--r--fs/nfsd/nfs4proc.c1
-rw-r--r--fs/nfsd/vfs.c241
-rw-r--r--fs/nfsd/vfs.h8
-rw-r--r--fs/nls/mac-celtic.c1
-rw-r--r--fs/nls/mac-centeuro.c1
-rw-r--r--fs/nls/mac-croatian.c1
-rw-r--r--fs/nls/mac-cyrillic.c1
-rw-r--r--fs/nls/mac-gaelic.c1
-rw-r--r--fs/nls/mac-greek.c1
-rw-r--r--fs/nls/mac-iceland.c1
-rw-r--r--fs/nls/mac-inuit.c1
-rw-r--r--fs/nls/mac-roman.c1
-rw-r--r--fs/nls/mac-romanian.c1
-rw-r--r--fs/nls/mac-turkish.c1
-rw-r--r--fs/nls/nls_ascii.c1
-rw-r--r--fs/nls/nls_base.c5
-rw-r--r--fs/nls/nls_cp1250.c1
-rw-r--r--fs/nls/nls_cp1251.c1
-rw-r--r--fs/nls/nls_cp1255.c1
-rw-r--r--fs/nls/nls_cp437.c1
-rw-r--r--fs/nls/nls_cp737.c1
-rw-r--r--fs/nls/nls_cp775.c1
-rw-r--r--fs/nls/nls_cp850.c1
-rw-r--r--fs/nls/nls_cp852.c1
-rw-r--r--fs/nls/nls_cp855.c1
-rw-r--r--fs/nls/nls_cp857.c1
-rw-r--r--fs/nls/nls_cp860.c1
-rw-r--r--fs/nls/nls_cp861.c1
-rw-r--r--fs/nls/nls_cp862.c1
-rw-r--r--fs/nls/nls_cp863.c1
-rw-r--r--fs/nls/nls_cp864.c1
-rw-r--r--fs/nls/nls_cp865.c1
-rw-r--r--fs/nls/nls_cp866.c1
-rw-r--r--fs/nls/nls_cp869.c1
-rw-r--r--fs/nls/nls_cp874.c1
-rw-r--r--fs/nls/nls_cp932.c1
-rw-r--r--fs/nls/nls_cp936.c1
-rw-r--r--fs/nls/nls_cp949.c1
-rw-r--r--fs/nls/nls_cp950.c1
-rw-r--r--fs/nls/nls_euc-jp.c1
-rw-r--r--fs/nls/nls_iso8859-1.c1
-rw-r--r--fs/nls/nls_iso8859-13.c1
-rw-r--r--fs/nls/nls_iso8859-14.c1
-rw-r--r--fs/nls/nls_iso8859-15.c1
-rw-r--r--fs/nls/nls_iso8859-2.c1
-rw-r--r--fs/nls/nls_iso8859-3.c1
-rw-r--r--fs/nls/nls_iso8859-4.c1
-rw-r--r--fs/nls/nls_iso8859-5.c1
-rw-r--r--fs/nls/nls_iso8859-6.c1
-rw-r--r--fs/nls/nls_iso8859-7.c1
-rw-r--r--fs/nls/nls_iso8859-9.c1
-rw-r--r--fs/nls/nls_koi8-r.c1
-rw-r--r--fs/nls/nls_koi8-ru.c1
-rw-r--r--fs/nls/nls_koi8-u.c1
-rw-r--r--fs/nls/nls_utf8.c1
-rw-r--r--fs/ocfs2/acl.c234
-rw-r--r--fs/ocfs2/acl.h13
-rw-r--r--fs/ocfs2/file.c4
-rw-r--r--fs/ocfs2/namei.c25
-rw-r--r--fs/ocfs2/refcounttree.c19
-rw-r--r--fs/ocfs2/xattr.c21
-rw-r--r--fs/ocfs2/xattr.h6
-rw-r--r--fs/posix_acl.c428
-rw-r--r--fs/qnx4/inode.c63
-rw-r--r--fs/qnx4/qnx4.h2
-rw-r--r--fs/reiserfs/acl.h4
-rw-r--r--fs/reiserfs/file.c1
-rw-r--r--fs/reiserfs/namei.c4
-rw-r--r--fs/reiserfs/procfs.c4
-rw-r--r--fs/reiserfs/reiserfs.h8
-rw-r--r--fs/reiserfs/super.c8
-rw-r--r--fs/reiserfs/xattr.c5
-rw-r--r--fs/reiserfs/xattr_acl.c190
-rw-r--r--fs/xattr_acl.c180
-rw-r--r--fs/xfs/xfs_acl.c151
-rw-r--r--fs/xfs/xfs_acl.h9
-rw-r--r--fs/xfs/xfs_iops.c55
-rw-r--r--fs/xfs/xfs_iops.h2
-rw-r--r--fs/xfs/xfs_xattr.c4
-rw-r--r--include/linux/cramfs_fs_sb.h20
-rw-r--r--include/linux/fdtable.h35
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/generic_acl.h14
-rw-r--r--include/linux/nfs_fs.h24
-rw-r--r--include/linux/nls.h3
-rw-r--r--include/linux/posix_acl.h43
-rw-r--r--include/linux/posix_acl_xattr.h3
-rw-r--r--include/linux/rcupdate.h2
-rw-r--r--init/do_mounts_rd.c2
-rw-r--r--kernel/rcu/update.c11
-rw-r--r--mm/filemap.c42
-rw-r--r--mm/shmem.c57
179 files changed, 1543 insertions, 3851 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 396193042127..4f424ae3b36d 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -17,7 +17,7 @@
17#ifdef CONFIG_MTD_UCLINUX 17#ifdef CONFIG_MTD_UCLINUX
18#include <linux/mtd/map.h> 18#include <linux/mtd/map.h>
19#include <linux/ext2_fs.h> 19#include <linux/ext2_fs.h>
20#include <linux/cramfs_fs.h> 20#include <uapi/linux/cramfs_fs.h>
21#include <linux/romfs_fs.h> 21#include <linux/romfs_fs.h>
22#endif 22#endif
23 23
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 1b6ad6247204..28dd77144e8f 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -24,8 +24,6 @@
24#include <linux/mtd/mtdram.h> 24#include <linux/mtd/mtdram.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26 26
27#include <linux/cramfs_fs.h>
28
29#include <asm/axisflashmap.h> 27#include <asm/axisflashmap.h>
30#include <asm/mmu.h> 28#include <asm/mmu.h>
31 29
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 7af425f53bee..8482f2d11606 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -156,7 +156,7 @@ int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
156 return -EOPNOTSUPP; 156 return -EOPNOTSUPP;
157 acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); 157 acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
158 if (acl) { 158 if (acl) {
159 retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); 159 retval = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
160 if (retval) 160 if (retval)
161 return retval; 161 return retval;
162 set_cached_acl(inode, ACL_TYPE_ACCESS, acl); 162 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
@@ -200,7 +200,7 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep,
200 if (acl) { 200 if (acl) {
201 if (S_ISDIR(mode)) 201 if (S_ISDIR(mode))
202 *dpacl = posix_acl_dup(acl); 202 *dpacl = posix_acl_dup(acl);
203 retval = posix_acl_create(&acl, GFP_NOFS, &mode); 203 retval = __posix_acl_create(&acl, GFP_NOFS, &mode);
204 if (retval < 0) 204 if (retval < 0)
205 return retval; 205 return retval;
206 if (retval > 0) 206 if (retval > 0)
diff --git a/fs/Kconfig b/fs/Kconfig
index c229f828eb01..7385e54be4b9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -68,10 +68,6 @@ source "fs/quota/Kconfig"
68source "fs/autofs4/Kconfig" 68source "fs/autofs4/Kconfig"
69source "fs/fuse/Kconfig" 69source "fs/fuse/Kconfig"
70 70
71config GENERIC_ACL
72 bool
73 select FS_POSIX_ACL
74
75menu "Caches" 71menu "Caches"
76 72
77source "fs/fscache/Kconfig" 73source "fs/fscache/Kconfig"
@@ -119,7 +115,7 @@ config TMPFS_POSIX_ACL
119 bool "Tmpfs POSIX Access Control Lists" 115 bool "Tmpfs POSIX Access Control Lists"
120 depends on TMPFS 116 depends on TMPFS
121 select TMPFS_XATTR 117 select TMPFS_XATTR
122 select GENERIC_ACL 118 select FS_POSIX_ACL
123 help 119 help
124 POSIX Access Control Lists (ACLs) support additional access rights 120 POSIX Access Control Lists (ACLs) support additional access rights
125 for users and groups beyond the standard owner/group/world scheme, 121 for users and groups beyond the standard owner/group/world scheme,
diff --git a/fs/Makefile b/fs/Makefile
index 39a824f44e7c..47ac07bb4acc 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -42,9 +42,8 @@ obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
42obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o 42obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
43 43
44obj-$(CONFIG_FS_MBCACHE) += mbcache.o 44obj-$(CONFIG_FS_MBCACHE) += mbcache.o
45obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o 45obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
46obj-$(CONFIG_NFS_COMMON) += nfs_common/ 46obj-$(CONFIG_NFS_COMMON) += nfs_common/
47obj-$(CONFIG_GENERIC_ACL) += generic_acl.o
48obj-$(CONFIG_COREDUMP) += coredump.o 47obj-$(CONFIG_COREDUMP) += coredump.o
49obj-$(CONFIG_SYSCTL) += drop_caches.o 48obj-$(CONFIG_SYSCTL) += drop_caches.o
50 49
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 45161a832bbc..d098731b82ff 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -49,11 +49,6 @@ affs_put_super(struct super_block *sb)
49 pr_debug("AFFS: put_super()\n"); 49 pr_debug("AFFS: put_super()\n");
50 50
51 cancel_delayed_work_sync(&sbi->sb_work); 51 cancel_delayed_work_sync(&sbi->sb_work);
52 kfree(sbi->s_prefix);
53 affs_free_bitmap(sb);
54 affs_brelse(sbi->s_root_bh);
55 kfree(sbi);
56 sb->s_fs_info = NULL;
57} 52}
58 53
59static int 54static int
@@ -316,7 +311,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
316 unsigned long mount_flags; 311 unsigned long mount_flags;
317 int tmp_flags; /* fix remount prototype... */ 312 int tmp_flags; /* fix remount prototype... */
318 u8 sig[4]; 313 u8 sig[4];
319 int ret = -EINVAL; 314 int ret;
320 315
321 save_mount_options(sb, data); 316 save_mount_options(sb, data);
322 317
@@ -412,17 +407,19 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
412 if (!silent) 407 if (!silent)
413 printk(KERN_ERR "AFFS: No valid root block on device %s\n", 408 printk(KERN_ERR "AFFS: No valid root block on device %s\n",
414 sb->s_id); 409 sb->s_id);
415 goto out_error; 410 return -EINVAL;
416 411
417 /* N.B. after this point bh must be released */ 412 /* N.B. after this point bh must be released */
418got_root: 413got_root:
414 /* Keep super block in cache */
415 sbi->s_root_bh = root_bh;
419 root_block = sbi->s_root_block; 416 root_block = sbi->s_root_block;
420 417
421 /* Find out which kind of FS we have */ 418 /* Find out which kind of FS we have */
422 boot_bh = sb_bread(sb, 0); 419 boot_bh = sb_bread(sb, 0);
423 if (!boot_bh) { 420 if (!boot_bh) {
424 printk(KERN_ERR "AFFS: Cannot read boot block\n"); 421 printk(KERN_ERR "AFFS: Cannot read boot block\n");
425 goto out_error; 422 return -EINVAL;
426 } 423 }
427 memcpy(sig, boot_bh->b_data, 4); 424 memcpy(sig, boot_bh->b_data, 4);
428 brelse(boot_bh); 425 brelse(boot_bh);
@@ -471,7 +468,7 @@ got_root:
471 default: 468 default:
472 printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n", 469 printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n",
473 sb->s_id, chksum); 470 sb->s_id, chksum);
474 goto out_error; 471 return -EINVAL;
475 } 472 }
476 473
477 if (mount_flags & SF_VERBOSE) { 474 if (mount_flags & SF_VERBOSE) {
@@ -488,22 +485,17 @@ got_root:
488 if (sbi->s_flags & SF_OFS) 485 if (sbi->s_flags & SF_OFS)
489 sbi->s_data_blksize -= 24; 486 sbi->s_data_blksize -= 24;
490 487
491 /* Keep super block in cache */
492 sbi->s_root_bh = root_bh;
493 /* N.B. after this point s_root_bh must be released */
494
495 tmp_flags = sb->s_flags; 488 tmp_flags = sb->s_flags;
496 if (affs_init_bitmap(sb, &tmp_flags)) 489 ret = affs_init_bitmap(sb, &tmp_flags);
497 goto out_error; 490 if (ret)
491 return ret;
498 sb->s_flags = tmp_flags; 492 sb->s_flags = tmp_flags;
499 493
500 /* set up enough so that it can read an inode */ 494 /* set up enough so that it can read an inode */
501 495
502 root_inode = affs_iget(sb, root_block); 496 root_inode = affs_iget(sb, root_block);
503 if (IS_ERR(root_inode)) { 497 if (IS_ERR(root_inode))
504 ret = PTR_ERR(root_inode); 498 return PTR_ERR(root_inode);
505 goto out_error;
506 }
507 499
508 if (AFFS_SB(sb)->s_flags & SF_INTL) 500 if (AFFS_SB(sb)->s_flags & SF_INTL)
509 sb->s_d_op = &affs_intl_dentry_operations; 501 sb->s_d_op = &affs_intl_dentry_operations;
@@ -513,22 +505,11 @@ got_root:
513 sb->s_root = d_make_root(root_inode); 505 sb->s_root = d_make_root(root_inode);
514 if (!sb->s_root) { 506 if (!sb->s_root) {
515 printk(KERN_ERR "AFFS: Get root inode failed\n"); 507 printk(KERN_ERR "AFFS: Get root inode failed\n");
516 goto out_error; 508 return -ENOMEM;
517 } 509 }
518 510
519 pr_debug("AFFS: s_flags=%lX\n",sb->s_flags); 511 pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
520 return 0; 512 return 0;
521
522 /*
523 * Begin the cascaded cleanup ...
524 */
525out_error:
526 kfree(sbi->s_bitmap);
527 affs_brelse(root_bh);
528 kfree(sbi->s_prefix);
529 kfree(sbi);
530 sb->s_fs_info = NULL;
531 return ret;
532} 513}
533 514
534static int 515static int
@@ -615,11 +596,23 @@ static struct dentry *affs_mount(struct file_system_type *fs_type,
615 return mount_bdev(fs_type, flags, dev_name, data, affs_fill_super); 596 return mount_bdev(fs_type, flags, dev_name, data, affs_fill_super);
616} 597}
617 598
599static void affs_kill_sb(struct super_block *sb)
600{
601 struct affs_sb_info *sbi = AFFS_SB(sb);
602 kill_block_super(sb);
603 if (sbi) {
604 affs_free_bitmap(sb);
605 affs_brelse(sbi->s_root_bh);
606 kfree(sbi->s_prefix);
607 kfree(sbi);
608 }
609}
610
618static struct file_system_type affs_fs_type = { 611static struct file_system_type affs_fs_type = {
619 .owner = THIS_MODULE, 612 .owner = THIS_MODULE,
620 .name = "affs", 613 .name = "affs",
621 .mount = affs_mount, 614 .mount = affs_mount,
622 .kill_sb = kill_block_super, 615 .kill_sb = affs_kill_sb,
623 .fs_flags = FS_REQUIRES_DEV, 616 .fs_flags = FS_REQUIRES_DEV,
624}; 617};
625MODULE_ALIAS_FS("affs"); 618MODULE_ALIAS_FS("affs");
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index a306bb6d88d9..6621f8008122 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -195,7 +195,6 @@ struct afs_cell {
195 struct list_head link; /* main cell list link */ 195 struct list_head link; /* main cell list link */
196 struct key *anonymous_key; /* anonymous user key for this cell */ 196 struct key *anonymous_key; /* anonymous user key for this cell */
197 struct list_head proc_link; /* /proc cell list link */ 197 struct list_head proc_link; /* /proc cell list link */
198 struct proc_dir_entry *proc_dir; /* /proc dir for this cell */
199#ifdef CONFIG_AFS_FSCACHE 198#ifdef CONFIG_AFS_FSCACHE
200 struct fscache_cookie *cache; /* caching cookie */ 199 struct fscache_cookie *cache; /* caching cookie */
201#endif 200#endif
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 526e4bbbde59..bddc5120ed40 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -41,11 +41,8 @@ static const struct file_operations afs_proc_cells_fops = {
41 .write = afs_proc_cells_write, 41 .write = afs_proc_cells_write,
42 .llseek = seq_lseek, 42 .llseek = seq_lseek,
43 .release = seq_release, 43 .release = seq_release,
44 .owner = THIS_MODULE,
45}; 44};
46 45
47static int afs_proc_rootcell_open(struct inode *inode, struct file *file);
48static int afs_proc_rootcell_release(struct inode *inode, struct file *file);
49static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 46static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
50 size_t size, loff_t *_pos); 47 size_t size, loff_t *_pos);
51static ssize_t afs_proc_rootcell_write(struct file *file, 48static ssize_t afs_proc_rootcell_write(struct file *file,
@@ -53,17 +50,12 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
53 size_t size, loff_t *_pos); 50 size_t size, loff_t *_pos);
54 51
55static const struct file_operations afs_proc_rootcell_fops = { 52static const struct file_operations afs_proc_rootcell_fops = {
56 .open = afs_proc_rootcell_open,
57 .read = afs_proc_rootcell_read, 53 .read = afs_proc_rootcell_read,
58 .write = afs_proc_rootcell_write, 54 .write = afs_proc_rootcell_write,
59 .llseek = no_llseek, 55 .llseek = no_llseek,
60 .release = afs_proc_rootcell_release,
61 .owner = THIS_MODULE,
62}; 56};
63 57
64static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file); 58static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file);
65static int afs_proc_cell_volumes_release(struct inode *inode,
66 struct file *file);
67static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos); 59static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos);
68static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, 60static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
69 loff_t *pos); 61 loff_t *pos);
@@ -81,14 +73,11 @@ static const struct file_operations afs_proc_cell_volumes_fops = {
81 .open = afs_proc_cell_volumes_open, 73 .open = afs_proc_cell_volumes_open,
82 .read = seq_read, 74 .read = seq_read,
83 .llseek = seq_lseek, 75 .llseek = seq_lseek,
84 .release = afs_proc_cell_volumes_release, 76 .release = seq_release,
85 .owner = THIS_MODULE,
86}; 77};
87 78
88static int afs_proc_cell_vlservers_open(struct inode *inode, 79static int afs_proc_cell_vlservers_open(struct inode *inode,
89 struct file *file); 80 struct file *file);
90static int afs_proc_cell_vlservers_release(struct inode *inode,
91 struct file *file);
92static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos); 81static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos);
93static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, 82static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
94 loff_t *pos); 83 loff_t *pos);
@@ -106,13 +95,10 @@ static const struct file_operations afs_proc_cell_vlservers_fops = {
106 .open = afs_proc_cell_vlservers_open, 95 .open = afs_proc_cell_vlservers_open,
107 .read = seq_read, 96 .read = seq_read,
108 .llseek = seq_lseek, 97 .llseek = seq_lseek,
109 .release = afs_proc_cell_vlservers_release, 98 .release = seq_release,
110 .owner = THIS_MODULE,
111}; 99};
112 100
113static int afs_proc_cell_servers_open(struct inode *inode, struct file *file); 101static int afs_proc_cell_servers_open(struct inode *inode, struct file *file);
114static int afs_proc_cell_servers_release(struct inode *inode,
115 struct file *file);
116static void *afs_proc_cell_servers_start(struct seq_file *p, loff_t *pos); 102static void *afs_proc_cell_servers_start(struct seq_file *p, loff_t *pos);
117static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, 103static void *afs_proc_cell_servers_next(struct seq_file *p, void *v,
118 loff_t *pos); 104 loff_t *pos);
@@ -130,8 +116,7 @@ static const struct file_operations afs_proc_cell_servers_fops = {
130 .open = afs_proc_cell_servers_open, 116 .open = afs_proc_cell_servers_open,
131 .read = seq_read, 117 .read = seq_read,
132 .llseek = seq_lseek, 118 .llseek = seq_lseek,
133 .release = afs_proc_cell_servers_release, 119 .release = seq_release,
134 .owner = THIS_MODULE,
135}; 120};
136 121
137/* 122/*
@@ -139,29 +124,21 @@ static const struct file_operations afs_proc_cell_servers_fops = {
139 */ 124 */
140int afs_proc_init(void) 125int afs_proc_init(void)
141{ 126{
142 struct proc_dir_entry *p;
143
144 _enter(""); 127 _enter("");
145 128
146 proc_afs = proc_mkdir("fs/afs", NULL); 129 proc_afs = proc_mkdir("fs/afs", NULL);
147 if (!proc_afs) 130 if (!proc_afs)
148 goto error_dir; 131 goto error_dir;
149 132
150 p = proc_create("cells", 0, proc_afs, &afs_proc_cells_fops); 133 if (!proc_create("cells", 0, proc_afs, &afs_proc_cells_fops) ||
151 if (!p) 134 !proc_create("rootcell", 0, proc_afs, &afs_proc_rootcell_fops))
152 goto error_cells; 135 goto error_tree;
153
154 p = proc_create("rootcell", 0, proc_afs, &afs_proc_rootcell_fops);
155 if (!p)
156 goto error_rootcell;
157 136
158 _leave(" = 0"); 137 _leave(" = 0");
159 return 0; 138 return 0;
160 139
161error_rootcell: 140error_tree:
162 remove_proc_entry("cells", proc_afs); 141 remove_proc_subtree("fs/afs", NULL);
163error_cells:
164 remove_proc_entry("fs/afs", NULL);
165error_dir: 142error_dir:
166 _leave(" = -ENOMEM"); 143 _leave(" = -ENOMEM");
167 return -ENOMEM; 144 return -ENOMEM;
@@ -172,9 +149,7 @@ error_dir:
172 */ 149 */
173void afs_proc_cleanup(void) 150void afs_proc_cleanup(void)
174{ 151{
175 remove_proc_entry("rootcell", proc_afs); 152 remove_proc_subtree("fs/afs", NULL);
176 remove_proc_entry("cells", proc_afs);
177 remove_proc_entry("fs/afs", NULL);
178} 153}
179 154
180/* 155/*
@@ -319,19 +294,6 @@ inval:
319 goto done; 294 goto done;
320} 295}
321 296
322/*
323 * Stubs for /proc/fs/afs/rootcell
324 */
325static int afs_proc_rootcell_open(struct inode *inode, struct file *file)
326{
327 return 0;
328}
329
330static int afs_proc_rootcell_release(struct inode *inode, struct file *file)
331{
332 return 0;
333}
334
335static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 297static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
336 size_t size, loff_t *_pos) 298 size_t size, loff_t *_pos)
337{ 299{
@@ -387,38 +349,27 @@ nomem:
387 */ 349 */
388int afs_proc_cell_setup(struct afs_cell *cell) 350int afs_proc_cell_setup(struct afs_cell *cell)
389{ 351{
390 struct proc_dir_entry *p; 352 struct proc_dir_entry *dir;
391 353
392 _enter("%p{%s}", cell, cell->name); 354 _enter("%p{%s}", cell, cell->name);
393 355
394 cell->proc_dir = proc_mkdir(cell->name, proc_afs); 356 dir = proc_mkdir(cell->name, proc_afs);
395 if (!cell->proc_dir) 357 if (!dir)
396 goto error_dir; 358 goto error_dir;
397 359
398 p = proc_create_data("servers", 0, cell->proc_dir, 360 if (!proc_create_data("servers", 0, dir,
399 &afs_proc_cell_servers_fops, cell); 361 &afs_proc_cell_servers_fops, cell) ||
400 if (!p) 362 !proc_create_data("vlservers", 0, dir,
401 goto error_servers; 363 &afs_proc_cell_vlservers_fops, cell) ||
402 364 !proc_create_data("volumes", 0, dir,
403 p = proc_create_data("vlservers", 0, cell->proc_dir, 365 &afs_proc_cell_volumes_fops, cell))
404 &afs_proc_cell_vlservers_fops, cell); 366 goto error_tree;
405 if (!p)
406 goto error_vlservers;
407
408 p = proc_create_data("volumes", 0, cell->proc_dir,
409 &afs_proc_cell_volumes_fops, cell);
410 if (!p)
411 goto error_volumes;
412 367
413 _leave(" = 0"); 368 _leave(" = 0");
414 return 0; 369 return 0;
415 370
416error_volumes: 371error_tree:
417 remove_proc_entry("vlservers", cell->proc_dir); 372 remove_proc_subtree(cell->name, proc_afs);
418error_vlservers:
419 remove_proc_entry("servers", cell->proc_dir);
420error_servers:
421 remove_proc_entry(cell->name, proc_afs);
422error_dir: 373error_dir:
423 _leave(" = -ENOMEM"); 374 _leave(" = -ENOMEM");
424 return -ENOMEM; 375 return -ENOMEM;
@@ -431,10 +382,7 @@ void afs_proc_cell_remove(struct afs_cell *cell)
431{ 382{
432 _enter(""); 383 _enter("");
433 384
434 remove_proc_entry("volumes", cell->proc_dir); 385 remove_proc_subtree(cell->name, proc_afs);
435 remove_proc_entry("vlservers", cell->proc_dir);
436 remove_proc_entry("servers", cell->proc_dir);
437 remove_proc_entry(cell->name, proc_afs);
438 386
439 _leave(""); 387 _leave("");
440} 388}
@@ -463,14 +411,6 @@ static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file)
463} 411}
464 412
465/* 413/*
466 * close the file and release the ref to the cell
467 */
468static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file)
469{
470 return seq_release(inode, file);
471}
472
473/*
474 * set up the iterator to start reading from the cells list and return the 414 * set up the iterator to start reading from the cells list and return the
475 * first item 415 * first item
476 */ 416 */
@@ -569,15 +509,6 @@ static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file)
569} 509}
570 510
571/* 511/*
572 * close the file and release the ref to the cell
573 */
574static int afs_proc_cell_vlservers_release(struct inode *inode,
575 struct file *file)
576{
577 return seq_release(inode, file);
578}
579
580/*
581 * set up the iterator to start reading from the cells list and return the 512 * set up the iterator to start reading from the cells list and return the
582 * first item 513 * first item
583 */ 514 */
@@ -673,15 +604,6 @@ static int afs_proc_cell_servers_open(struct inode *inode, struct file *file)
673} 604}
674 605
675/* 606/*
676 * close the file and release the ref to the cell
677 */
678static int afs_proc_cell_servers_release(struct inode *inode,
679 struct file *file)
680{
681 return seq_release(inode, file);
682}
683
684/*
685 * set up the iterator to start reading from the cells list and return the 607 * set up the iterator to start reading from the cells list and return the
686 * first item 608 * first item
687 */ 609 */
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index daa15d6ba450..845d2d690ce2 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -324,8 +324,8 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
324 befs_debug(sb, "---> befs_read_inode() " "inode = %lu", ino); 324 befs_debug(sb, "---> befs_read_inode() " "inode = %lu", ino);
325 325
326 inode = iget_locked(sb, ino); 326 inode = iget_locked(sb, ino);
327 if (IS_ERR(inode)) 327 if (!inode)
328 return inode; 328 return ERR_PTR(-ENOMEM);
329 if (!(inode->i_state & I_NEW)) 329 if (!(inode->i_state & I_NEW))
330 return inode; 330 return inode;
331 331
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 0890c83643e9..ff9b3995d453 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -35,13 +35,6 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
35 char *value = NULL; 35 char *value = NULL;
36 struct posix_acl *acl; 36 struct posix_acl *acl;
37 37
38 if (!IS_POSIXACL(inode))
39 return NULL;
40
41 acl = get_cached_acl(inode, type);
42 if (acl != ACL_NOT_CACHED)
43 return acl;
44
45 switch (type) { 38 switch (type) {
46 case ACL_TYPE_ACCESS: 39 case ACL_TYPE_ACCESS:
47 name = POSIX_ACL_XATTR_ACCESS; 40 name = POSIX_ACL_XATTR_ACCESS;
@@ -76,31 +69,10 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
76 return acl; 69 return acl;
77} 70}
78 71
79static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name,
80 void *value, size_t size, int type)
81{
82 struct posix_acl *acl;
83 int ret = 0;
84
85 if (!IS_POSIXACL(dentry->d_inode))
86 return -EOPNOTSUPP;
87
88 acl = btrfs_get_acl(dentry->d_inode, type);
89
90 if (IS_ERR(acl))
91 return PTR_ERR(acl);
92 if (acl == NULL)
93 return -ENODATA;
94 ret = posix_acl_to_xattr(&init_user_ns, acl, value, size);
95 posix_acl_release(acl);
96
97 return ret;
98}
99
100/* 72/*
101 * Needs to be called with fs_mutex held 73 * Needs to be called with fs_mutex held
102 */ 74 */
103static int btrfs_set_acl(struct btrfs_trans_handle *trans, 75static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
104 struct inode *inode, struct posix_acl *acl, int type) 76 struct inode *inode, struct posix_acl *acl, int type)
105{ 77{
106 int ret, size = 0; 78 int ret, size = 0;
@@ -158,35 +130,9 @@ out:
158 return ret; 130 return ret;
159} 131}
160 132
161static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, 133int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
162 const void *value, size_t size, int flags, int type)
163{ 134{
164 int ret; 135 return __btrfs_set_acl(NULL, inode, acl, type);
165 struct posix_acl *acl = NULL;
166
167 if (!inode_owner_or_capable(dentry->d_inode))
168 return -EPERM;
169
170 if (!IS_POSIXACL(dentry->d_inode))
171 return -EOPNOTSUPP;
172
173 if (value) {
174 acl = posix_acl_from_xattr(&init_user_ns, value, size);
175 if (IS_ERR(acl))
176 return PTR_ERR(acl);
177
178 if (acl) {
179 ret = posix_acl_valid(acl);
180 if (ret)
181 goto out;
182 }
183 }
184
185 ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type);
186out:
187 posix_acl_release(acl);
188
189 return ret;
190} 136}
191 137
192/* 138/*
@@ -197,83 +143,31 @@ out:
197int btrfs_init_acl(struct btrfs_trans_handle *trans, 143int btrfs_init_acl(struct btrfs_trans_handle *trans,
198 struct inode *inode, struct inode *dir) 144 struct inode *inode, struct inode *dir)
199{ 145{
200 struct posix_acl *acl = NULL; 146 struct posix_acl *default_acl, *acl;
201 int ret = 0; 147 int ret = 0;
202 148
203 /* this happens with subvols */ 149 /* this happens with subvols */
204 if (!dir) 150 if (!dir)
205 return 0; 151 return 0;
206 152
207 if (!S_ISLNK(inode->i_mode)) { 153 ret = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
208 if (IS_POSIXACL(dir)) { 154 if (ret)
209 acl = btrfs_get_acl(dir, ACL_TYPE_DEFAULT); 155 return ret;
210 if (IS_ERR(acl))
211 return PTR_ERR(acl);
212 }
213 156
214 if (!acl) 157 if (default_acl) {
215 inode->i_mode &= ~current_umask(); 158 ret = __btrfs_set_acl(trans, inode, default_acl,
159 ACL_TYPE_DEFAULT);
160 posix_acl_release(default_acl);
216 } 161 }
217 162
218 if (IS_POSIXACL(dir) && acl) { 163 if (acl) {
219 if (S_ISDIR(inode->i_mode)) { 164 if (!ret)
220 ret = btrfs_set_acl(trans, inode, acl, 165 ret = __btrfs_set_acl(trans, inode, acl,
221 ACL_TYPE_DEFAULT); 166 ACL_TYPE_ACCESS);
222 if (ret) 167 posix_acl_release(acl);
223 goto failed;
224 }
225 ret = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
226 if (ret < 0)
227 return ret;
228
229 if (ret > 0) {
230 /* we need an acl */
231 ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS);
232 } else if (ret < 0) {
233 cache_no_acl(inode);
234 }
235 } else {
236 cache_no_acl(inode);
237 } 168 }
238failed:
239 posix_acl_release(acl);
240
241 return ret;
242}
243 169
244int btrfs_acl_chmod(struct inode *inode) 170 if (!default_acl && !acl)
245{ 171 cache_no_acl(inode);
246 struct posix_acl *acl;
247 int ret = 0;
248
249 if (S_ISLNK(inode->i_mode))
250 return -EOPNOTSUPP;
251
252 if (!IS_POSIXACL(inode))
253 return 0;
254
255 acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
256 if (IS_ERR_OR_NULL(acl))
257 return PTR_ERR(acl);
258
259 ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
260 if (ret)
261 return ret;
262 ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS);
263 posix_acl_release(acl);
264 return ret; 172 return ret;
265} 173}
266
267const struct xattr_handler btrfs_xattr_acl_default_handler = {
268 .prefix = POSIX_ACL_XATTR_DEFAULT,
269 .flags = ACL_TYPE_DEFAULT,
270 .get = btrfs_xattr_acl_get,
271 .set = btrfs_xattr_acl_set,
272};
273
274const struct xattr_handler btrfs_xattr_acl_access_handler = {
275 .prefix = POSIX_ACL_XATTR_ACCESS,
276 .flags = ACL_TYPE_ACCESS,
277 .get = btrfs_xattr_acl_get,
278 .set = btrfs_xattr_acl_set,
279};
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 54ab86127f7a..7506825211a2 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3899,20 +3899,17 @@ do { \
3899/* acl.c */ 3899/* acl.c */
3900#ifdef CONFIG_BTRFS_FS_POSIX_ACL 3900#ifdef CONFIG_BTRFS_FS_POSIX_ACL
3901struct posix_acl *btrfs_get_acl(struct inode *inode, int type); 3901struct posix_acl *btrfs_get_acl(struct inode *inode, int type);
3902int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
3902int btrfs_init_acl(struct btrfs_trans_handle *trans, 3903int btrfs_init_acl(struct btrfs_trans_handle *trans,
3903 struct inode *inode, struct inode *dir); 3904 struct inode *inode, struct inode *dir);
3904int btrfs_acl_chmod(struct inode *inode);
3905#else 3905#else
3906#define btrfs_get_acl NULL 3906#define btrfs_get_acl NULL
3907#define btrfs_set_acl NULL
3907static inline int btrfs_init_acl(struct btrfs_trans_handle *trans, 3908static inline int btrfs_init_acl(struct btrfs_trans_handle *trans,
3908 struct inode *inode, struct inode *dir) 3909 struct inode *inode, struct inode *dir)
3909{ 3910{
3910 return 0; 3911 return 0;
3911} 3912}
3912static inline int btrfs_acl_chmod(struct inode *inode)
3913{
3914 return 0;
3915}
3916#endif 3913#endif
3917 3914
3918/* relocation.c */ 3915/* relocation.c */
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 471a4f7f4044..514b291b1354 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4468,7 +4468,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
4468 err = btrfs_dirty_inode(inode); 4468 err = btrfs_dirty_inode(inode);
4469 4469
4470 if (!err && attr->ia_valid & ATTR_MODE) 4470 if (!err && attr->ia_valid & ATTR_MODE)
4471 err = btrfs_acl_chmod(inode); 4471 err = posix_acl_chmod(inode, inode->i_mode);
4472 } 4472 }
4473 4473
4474 return err; 4474 return err;
@@ -8653,12 +8653,14 @@ static const struct inode_operations btrfs_dir_inode_operations = {
8653 .removexattr = btrfs_removexattr, 8653 .removexattr = btrfs_removexattr,
8654 .permission = btrfs_permission, 8654 .permission = btrfs_permission,
8655 .get_acl = btrfs_get_acl, 8655 .get_acl = btrfs_get_acl,
8656 .set_acl = btrfs_set_acl,
8656 .update_time = btrfs_update_time, 8657 .update_time = btrfs_update_time,
8657}; 8658};
8658static const struct inode_operations btrfs_dir_ro_inode_operations = { 8659static const struct inode_operations btrfs_dir_ro_inode_operations = {
8659 .lookup = btrfs_lookup, 8660 .lookup = btrfs_lookup,
8660 .permission = btrfs_permission, 8661 .permission = btrfs_permission,
8661 .get_acl = btrfs_get_acl, 8662 .get_acl = btrfs_get_acl,
8663 .set_acl = btrfs_set_acl,
8662 .update_time = btrfs_update_time, 8664 .update_time = btrfs_update_time,
8663}; 8665};
8664 8666
@@ -8728,6 +8730,7 @@ static const struct inode_operations btrfs_file_inode_operations = {
8728 .permission = btrfs_permission, 8730 .permission = btrfs_permission,
8729 .fiemap = btrfs_fiemap, 8731 .fiemap = btrfs_fiemap,
8730 .get_acl = btrfs_get_acl, 8732 .get_acl = btrfs_get_acl,
8733 .set_acl = btrfs_set_acl,
8731 .update_time = btrfs_update_time, 8734 .update_time = btrfs_update_time,
8732}; 8735};
8733static const struct inode_operations btrfs_special_inode_operations = { 8736static const struct inode_operations btrfs_special_inode_operations = {
@@ -8739,6 +8742,7 @@ static const struct inode_operations btrfs_special_inode_operations = {
8739 .listxattr = btrfs_listxattr, 8742 .listxattr = btrfs_listxattr,
8740 .removexattr = btrfs_removexattr, 8743 .removexattr = btrfs_removexattr,
8741 .get_acl = btrfs_get_acl, 8744 .get_acl = btrfs_get_acl,
8745 .set_acl = btrfs_set_acl,
8742 .update_time = btrfs_update_time, 8746 .update_time = btrfs_update_time,
8743}; 8747};
8744static const struct inode_operations btrfs_symlink_inode_operations = { 8748static const struct inode_operations btrfs_symlink_inode_operations = {
@@ -8752,7 +8756,6 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
8752 .getxattr = btrfs_getxattr, 8756 .getxattr = btrfs_getxattr,
8753 .listxattr = btrfs_listxattr, 8757 .listxattr = btrfs_listxattr,
8754 .removexattr = btrfs_removexattr, 8758 .removexattr = btrfs_removexattr,
8755 .get_acl = btrfs_get_acl,
8756 .update_time = btrfs_update_time, 8759 .update_time = btrfs_update_time,
8757}; 8760};
8758 8761
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 21da5762b0b1..ad27dcea319c 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2686,14 +2686,11 @@ out_unlock:
2686#define BTRFS_MAX_DEDUPE_LEN (16 * 1024 * 1024) 2686#define BTRFS_MAX_DEDUPE_LEN (16 * 1024 * 1024)
2687 2687
2688static long btrfs_ioctl_file_extent_same(struct file *file, 2688static long btrfs_ioctl_file_extent_same(struct file *file,
2689 void __user *argp) 2689 struct btrfs_ioctl_same_args __user *argp)
2690{ 2690{
2691 struct btrfs_ioctl_same_args tmp;
2692 struct btrfs_ioctl_same_args *same; 2691 struct btrfs_ioctl_same_args *same;
2693 struct btrfs_ioctl_same_extent_info *info; 2692 struct btrfs_ioctl_same_extent_info *info;
2694 struct inode *src = file->f_dentry->d_inode; 2693 struct inode *src = file_inode(file);
2695 struct file *dst_file = NULL;
2696 struct inode *dst;
2697 u64 off; 2694 u64 off;
2698 u64 len; 2695 u64 len;
2699 int i; 2696 int i;
@@ -2701,6 +2698,7 @@ static long btrfs_ioctl_file_extent_same(struct file *file,
2701 unsigned long size; 2698 unsigned long size;
2702 u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize; 2699 u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize;
2703 bool is_admin = capable(CAP_SYS_ADMIN); 2700 bool is_admin = capable(CAP_SYS_ADMIN);
2701 u16 count;
2704 2702
2705 if (!(file->f_mode & FMODE_READ)) 2703 if (!(file->f_mode & FMODE_READ))
2706 return -EINVAL; 2704 return -EINVAL;
@@ -2709,17 +2707,14 @@ static long btrfs_ioctl_file_extent_same(struct file *file,
2709 if (ret) 2707 if (ret)
2710 return ret; 2708 return ret;
2711 2709
2712 if (copy_from_user(&tmp, 2710 if (get_user(count, &argp->dest_count)) {
2713 (struct btrfs_ioctl_same_args __user *)argp,
2714 sizeof(tmp))) {
2715 ret = -EFAULT; 2711 ret = -EFAULT;
2716 goto out; 2712 goto out;
2717 } 2713 }
2718 2714
2719 size = sizeof(tmp) + 2715 size = offsetof(struct btrfs_ioctl_same_args __user, info[count]);
2720 tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info);
2721 2716
2722 same = memdup_user((struct btrfs_ioctl_same_args __user *)argp, size); 2717 same = memdup_user(argp, size);
2723 2718
2724 if (IS_ERR(same)) { 2719 if (IS_ERR(same)) {
2725 ret = PTR_ERR(same); 2720 ret = PTR_ERR(same);
@@ -2756,52 +2751,35 @@ static long btrfs_ioctl_file_extent_same(struct file *file,
2756 goto out; 2751 goto out;
2757 2752
2758 /* pre-format output fields to sane values */ 2753 /* pre-format output fields to sane values */
2759 for (i = 0; i < same->dest_count; i++) { 2754 for (i = 0; i < count; i++) {
2760 same->info[i].bytes_deduped = 0ULL; 2755 same->info[i].bytes_deduped = 0ULL;
2761 same->info[i].status = 0; 2756 same->info[i].status = 0;
2762 } 2757 }
2763 2758
2764 ret = 0; 2759 for (i = 0, info = same->info; i < count; i++, info++) {
2765 for (i = 0; i < same->dest_count; i++) { 2760 struct inode *dst;
2766 info = &same->info[i]; 2761 struct fd dst_file = fdget(info->fd);
2767 2762 if (!dst_file.file) {
2768 dst_file = fget(info->fd);
2769 if (!dst_file) {
2770 info->status = -EBADF; 2763 info->status = -EBADF;
2771 goto next; 2764 continue;
2772 } 2765 }
2766 dst = file_inode(dst_file.file);
2773 2767
2774 if (!(is_admin || (dst_file->f_mode & FMODE_WRITE))) { 2768 if (!(is_admin || (dst_file.file->f_mode & FMODE_WRITE))) {
2775 info->status = -EINVAL; 2769 info->status = -EINVAL;
2776 goto next; 2770 } else if (file->f_path.mnt != dst_file.file->f_path.mnt) {
2777 } 2771 info->status = -EXDEV;
2778 2772 } else if (S_ISDIR(dst->i_mode)) {
2779 info->status = -EXDEV;
2780 if (file->f_path.mnt != dst_file->f_path.mnt)
2781 goto next;
2782
2783 dst = dst_file->f_dentry->d_inode;
2784 if (src->i_sb != dst->i_sb)
2785 goto next;
2786
2787 if (S_ISDIR(dst->i_mode)) {
2788 info->status = -EISDIR; 2773 info->status = -EISDIR;
2789 goto next; 2774 } else if (!S_ISREG(dst->i_mode)) {
2790 }
2791
2792 if (!S_ISREG(dst->i_mode)) {
2793 info->status = -EACCES; 2775 info->status = -EACCES;
2794 goto next; 2776 } else {
2777 info->status = btrfs_extent_same(src, off, len, dst,
2778 info->logical_offset);
2779 if (info->status == 0)
2780 info->bytes_deduped += len;
2795 } 2781 }
2796 2782 fdput(dst_file);
2797 info->status = btrfs_extent_same(src, off, len, dst,
2798 info->logical_offset);
2799 if (info->status == 0)
2800 info->bytes_deduped += len;
2801
2802next:
2803 if (dst_file)
2804 fput(dst_file);
2805 } 2783 }
2806 2784
2807 ret = copy_to_user(argp, same, size); 2785 ret = copy_to_user(argp, same, size);
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 05740b9789e4..3d1c301c9260 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -22,6 +22,7 @@
22#include <linux/rwsem.h> 22#include <linux/rwsem.h>
23#include <linux/xattr.h> 23#include <linux/xattr.h>
24#include <linux/security.h> 24#include <linux/security.h>
25#include <linux/posix_acl_xattr.h>
25#include "ctree.h" 26#include "ctree.h"
26#include "btrfs_inode.h" 27#include "btrfs_inode.h"
27#include "transaction.h" 28#include "transaction.h"
@@ -313,8 +314,8 @@ err:
313 */ 314 */
314const struct xattr_handler *btrfs_xattr_handlers[] = { 315const struct xattr_handler *btrfs_xattr_handlers[] = {
315#ifdef CONFIG_BTRFS_FS_POSIX_ACL 316#ifdef CONFIG_BTRFS_FS_POSIX_ACL
316 &btrfs_xattr_acl_access_handler, 317 &posix_acl_access_xattr_handler,
317 &btrfs_xattr_acl_default_handler, 318 &posix_acl_default_xattr_handler,
318#endif 319#endif
319 NULL, 320 NULL,
320}; 321};
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h
index b3cc8039134b..5049608d1388 100644
--- a/fs/btrfs/xattr.h
+++ b/fs/btrfs/xattr.h
@@ -21,8 +21,6 @@
21 21
22#include <linux/xattr.h> 22#include <linux/xattr.h>
23 23
24extern const struct xattr_handler btrfs_xattr_acl_access_handler;
25extern const struct xattr_handler btrfs_xattr_acl_default_handler;
26extern const struct xattr_handler *btrfs_xattr_handlers[]; 24extern const struct xattr_handler *btrfs_xattr_handlers[];
27 25
28extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, 26extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name,
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index e501ac3a49ff..06610cf94d57 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -17,14 +17,30 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/blkdev.h> 19#include <linux/blkdev.h>
20#include <linux/cramfs_fs.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
22#include <linux/cramfs_fs_sb.h>
23#include <linux/vfs.h> 21#include <linux/vfs.h>
24#include <linux/mutex.h> 22#include <linux/mutex.h>
25 23#include <uapi/linux/cramfs_fs.h>
26#include <asm/uaccess.h> 24#include <asm/uaccess.h>
27 25
26#include "internal.h"
27
28/*
29 * cramfs super-block data in memory
30 */
31struct cramfs_sb_info {
32 unsigned long magic;
33 unsigned long size;
34 unsigned long blocks;
35 unsigned long files;
36 unsigned long flags;
37};
38
39static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb)
40{
41 return sb->s_fs_info;
42}
43
28static const struct super_operations cramfs_ops; 44static const struct super_operations cramfs_ops;
29static const struct inode_operations cramfs_dir_inode_operations; 45static const struct inode_operations cramfs_dir_inode_operations;
30static const struct file_operations cramfs_directory_operations; 46static const struct file_operations cramfs_directory_operations;
@@ -219,10 +235,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
219 return read_buffers[buffer] + offset; 235 return read_buffers[buffer] + offset;
220} 236}
221 237
222static void cramfs_put_super(struct super_block *sb) 238static void cramfs_kill_sb(struct super_block *sb)
223{ 239{
224 kfree(sb->s_fs_info); 240 struct cramfs_sb_info *sbi = CRAMFS_SB(sb);
225 sb->s_fs_info = NULL; 241 kill_block_super(sb);
242 kfree(sbi);
226} 243}
227 244
228static int cramfs_remount(struct super_block *sb, int *flags, char *data) 245static int cramfs_remount(struct super_block *sb, int *flags, char *data)
@@ -261,7 +278,7 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
261 if (super.magic == CRAMFS_MAGIC_WEND) { 278 if (super.magic == CRAMFS_MAGIC_WEND) {
262 if (!silent) 279 if (!silent)
263 printk(KERN_ERR "cramfs: wrong endianness\n"); 280 printk(KERN_ERR "cramfs: wrong endianness\n");
264 goto out; 281 return -EINVAL;
265 } 282 }
266 283
267 /* check at 512 byte offset */ 284 /* check at 512 byte offset */
@@ -273,20 +290,20 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
273 printk(KERN_ERR "cramfs: wrong endianness\n"); 290 printk(KERN_ERR "cramfs: wrong endianness\n");
274 else if (!silent) 291 else if (!silent)
275 printk(KERN_ERR "cramfs: wrong magic\n"); 292 printk(KERN_ERR "cramfs: wrong magic\n");
276 goto out; 293 return -EINVAL;
277 } 294 }
278 } 295 }
279 296
280 /* get feature flags first */ 297 /* get feature flags first */
281 if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { 298 if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
282 printk(KERN_ERR "cramfs: unsupported filesystem features\n"); 299 printk(KERN_ERR "cramfs: unsupported filesystem features\n");
283 goto out; 300 return -EINVAL;
284 } 301 }
285 302
286 /* Check that the root inode is in a sane state */ 303 /* Check that the root inode is in a sane state */
287 if (!S_ISDIR(super.root.mode)) { 304 if (!S_ISDIR(super.root.mode)) {
288 printk(KERN_ERR "cramfs: root is not a directory\n"); 305 printk(KERN_ERR "cramfs: root is not a directory\n");
289 goto out; 306 return -EINVAL;
290 } 307 }
291 /* correct strange, hard-coded permissions of mkcramfs */ 308 /* correct strange, hard-coded permissions of mkcramfs */
292 super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 309 super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
@@ -310,22 +327,18 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
310 (root_offset != 512 + sizeof(struct cramfs_super)))) 327 (root_offset != 512 + sizeof(struct cramfs_super))))
311 { 328 {
312 printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset); 329 printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset);
313 goto out; 330 return -EINVAL;
314 } 331 }
315 332
316 /* Set it all up.. */ 333 /* Set it all up.. */
317 sb->s_op = &cramfs_ops; 334 sb->s_op = &cramfs_ops;
318 root = get_cramfs_inode(sb, &super.root, 0); 335 root = get_cramfs_inode(sb, &super.root, 0);
319 if (IS_ERR(root)) 336 if (IS_ERR(root))
320 goto out; 337 return PTR_ERR(root);
321 sb->s_root = d_make_root(root); 338 sb->s_root = d_make_root(root);
322 if (!sb->s_root) 339 if (!sb->s_root)
323 goto out; 340 return -ENOMEM;
324 return 0; 341 return 0;
325out:
326 kfree(sbi);
327 sb->s_fs_info = NULL;
328 return -EINVAL;
329} 342}
330 343
331static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) 344static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -550,7 +563,6 @@ static const struct inode_operations cramfs_dir_inode_operations = {
550}; 563};
551 564
552static const struct super_operations cramfs_ops = { 565static const struct super_operations cramfs_ops = {
553 .put_super = cramfs_put_super,
554 .remount_fs = cramfs_remount, 566 .remount_fs = cramfs_remount,
555 .statfs = cramfs_statfs, 567 .statfs = cramfs_statfs,
556}; 568};
@@ -565,7 +577,7 @@ static struct file_system_type cramfs_fs_type = {
565 .owner = THIS_MODULE, 577 .owner = THIS_MODULE,
566 .name = "cramfs", 578 .name = "cramfs",
567 .mount = cramfs_mount, 579 .mount = cramfs_mount,
568 .kill_sb = kill_block_super, 580 .kill_sb = cramfs_kill_sb,
569 .fs_flags = FS_REQUIRES_DEV, 581 .fs_flags = FS_REQUIRES_DEV,
570}; 582};
571MODULE_ALIAS_FS("cramfs"); 583MODULE_ALIAS_FS("cramfs");
diff --git a/include/linux/cramfs_fs.h b/fs/cramfs/internal.h
index 133789609f23..349d71272157 100644
--- a/include/linux/cramfs_fs.h
+++ b/fs/cramfs/internal.h
@@ -1,10 +1,4 @@
1#ifndef __CRAMFS_H
2#define __CRAMFS_H
3
4#include <uapi/linux/cramfs_fs.h>
5
6/* Uncompression interfaces to the underlying zlib */ 1/* Uncompression interfaces to the underlying zlib */
7int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen); 2int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
8int cramfs_uncompress_init(void); 3int cramfs_uncompress_init(void);
9void cramfs_uncompress_exit(void); 4void cramfs_uncompress_exit(void);
10#endif
diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c
index 023329800d2e..1760c1b84d97 100644
--- a/fs/cramfs/uncompress.c
+++ b/fs/cramfs/uncompress.c
@@ -19,7 +19,7 @@
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/zlib.h> 21#include <linux/zlib.h>
22#include <linux/cramfs_fs.h> 22#include "internal.h"
23 23
24static z_stream stream; 24static z_stream stream;
25static int initialized; 25static int initialized;
diff --git a/fs/dcache.c b/fs/dcache.c
index cb4a10690868..265e0ce9769c 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -3116,26 +3116,28 @@ char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
3116/* 3116/*
3117 * Write full pathname from the root of the filesystem into the buffer. 3117 * Write full pathname from the root of the filesystem into the buffer.
3118 */ 3118 */
3119static char *__dentry_path(struct dentry *dentry, char *buf, int buflen) 3119static char *__dentry_path(struct dentry *d, char *buf, int buflen)
3120{ 3120{
3121 struct dentry *dentry;
3121 char *end, *retval; 3122 char *end, *retval;
3122 int len, seq = 0; 3123 int len, seq = 0;
3123 int error = 0; 3124 int error = 0;
3124 3125
3126 if (buflen < 2)
3127 goto Elong;
3128
3125 rcu_read_lock(); 3129 rcu_read_lock();
3126restart: 3130restart:
3131 dentry = d;
3127 end = buf + buflen; 3132 end = buf + buflen;
3128 len = buflen; 3133 len = buflen;
3129 prepend(&end, &len, "\0", 1); 3134 prepend(&end, &len, "\0", 1);
3130 if (buflen < 1)
3131 goto Elong;
3132 /* Get '/' right */ 3135 /* Get '/' right */
3133 retval = end-1; 3136 retval = end-1;
3134 *retval = '/'; 3137 *retval = '/';
3135 read_seqbegin_or_lock(&rename_lock, &seq); 3138 read_seqbegin_or_lock(&rename_lock, &seq);
3136 while (!IS_ROOT(dentry)) { 3139 while (!IS_ROOT(dentry)) {
3137 struct dentry *parent = dentry->d_parent; 3140 struct dentry *parent = dentry->d_parent;
3138 int error;
3139 3141
3140 prefetch(parent); 3142 prefetch(parent);
3141 error = prepend_name(&end, &len, &dentry->d_name); 3143 error = prepend_name(&end, &len, &dentry->d_name);
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index c36c44824471..b167ca48b8ee 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -659,19 +659,17 @@ out_lock:
659 return rc; 659 return rc;
660} 660}
661 661
662static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, 662static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
663 size_t *bufsiz)
664{ 663{
665 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 664 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
666 char *lower_buf; 665 char *lower_buf;
666 char *buf;
667 mm_segment_t old_fs; 667 mm_segment_t old_fs;
668 int rc; 668 int rc;
669 669
670 lower_buf = kmalloc(PATH_MAX, GFP_KERNEL); 670 lower_buf = kmalloc(PATH_MAX, GFP_KERNEL);
671 if (!lower_buf) { 671 if (!lower_buf)
672 rc = -ENOMEM; 672 return ERR_PTR(-ENOMEM);
673 goto out;
674 }
675 old_fs = get_fs(); 673 old_fs = get_fs();
676 set_fs(get_ds()); 674 set_fs(get_ds());
677 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, 675 rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
@@ -680,21 +678,18 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
680 set_fs(old_fs); 678 set_fs(old_fs);
681 if (rc < 0) 679 if (rc < 0)
682 goto out; 680 goto out;
683 rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry->d_sb, 681 rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
684 lower_buf, rc); 682 lower_buf, rc);
685out: 683out:
686 kfree(lower_buf); 684 kfree(lower_buf);
687 return rc; 685 return rc ? ERR_PTR(rc) : buf;
688} 686}
689 687
690static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) 688static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
691{ 689{
692 char *buf; 690 size_t len;
693 size_t len = PATH_MAX; 691 char *buf = ecryptfs_readlink_lower(dentry, &len);
694 int rc; 692 if (IS_ERR(buf))
695
696 rc = ecryptfs_readlink_lower(dentry, &buf, &len);
697 if (rc)
698 goto out; 693 goto out;
699 fsstack_copy_attr_atime(dentry->d_inode, 694 fsstack_copy_attr_atime(dentry->d_inode,
700 ecryptfs_dentry_to_lower(dentry)->d_inode); 695 ecryptfs_dentry_to_lower(dentry)->d_inode);
@@ -1003,10 +998,12 @@ static int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
1003 char *target; 998 char *target;
1004 size_t targetsiz; 999 size_t targetsiz;
1005 1000
1006 rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz); 1001 target = ecryptfs_readlink_lower(dentry, &targetsiz);
1007 if (!rc) { 1002 if (!IS_ERR(target)) {
1008 kfree(target); 1003 kfree(target);
1009 stat->size = targetsiz; 1004 stat->size = targetsiz;
1005 } else {
1006 rc = PTR_ERR(target);
1010 } 1007 }
1011 } 1008 }
1012 return rc; 1009 return rc;
diff --git a/fs/efs/super.c b/fs/efs/super.c
index c6f57a74a559..50215bbd6463 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -26,11 +26,18 @@ static struct dentry *efs_mount(struct file_system_type *fs_type,
26 return mount_bdev(fs_type, flags, dev_name, data, efs_fill_super); 26 return mount_bdev(fs_type, flags, dev_name, data, efs_fill_super);
27} 27}
28 28
29static void efs_kill_sb(struct super_block *s)
30{
31 struct efs_sb_info *sbi = SUPER_INFO(s);
32 kill_block_super(s);
33 kfree(sbi);
34}
35
29static struct file_system_type efs_fs_type = { 36static struct file_system_type efs_fs_type = {
30 .owner = THIS_MODULE, 37 .owner = THIS_MODULE,
31 .name = "efs", 38 .name = "efs",
32 .mount = efs_mount, 39 .mount = efs_mount,
33 .kill_sb = kill_block_super, 40 .kill_sb = efs_kill_sb,
34 .fs_flags = FS_REQUIRES_DEV, 41 .fs_flags = FS_REQUIRES_DEV,
35}; 42};
36MODULE_ALIAS_FS("efs"); 43MODULE_ALIAS_FS("efs");
@@ -105,12 +112,6 @@ static void destroy_inodecache(void)
105 kmem_cache_destroy(efs_inode_cachep); 112 kmem_cache_destroy(efs_inode_cachep);
106} 113}
107 114
108static void efs_put_super(struct super_block *s)
109{
110 kfree(s->s_fs_info);
111 s->s_fs_info = NULL;
112}
113
114static int efs_remount(struct super_block *sb, int *flags, char *data) 115static int efs_remount(struct super_block *sb, int *flags, char *data)
115{ 116{
116 *flags |= MS_RDONLY; 117 *flags |= MS_RDONLY;
@@ -120,7 +121,6 @@ static int efs_remount(struct super_block *sb, int *flags, char *data)
120static const struct super_operations efs_superblock_operations = { 121static const struct super_operations efs_superblock_operations = {
121 .alloc_inode = efs_alloc_inode, 122 .alloc_inode = efs_alloc_inode,
122 .destroy_inode = efs_destroy_inode, 123 .destroy_inode = efs_destroy_inode,
123 .put_super = efs_put_super,
124 .statfs = efs_statfs, 124 .statfs = efs_statfs,
125 .remount_fs = efs_remount, 125 .remount_fs = efs_remount,
126}; 126};
@@ -259,7 +259,6 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
259 struct efs_sb_info *sb; 259 struct efs_sb_info *sb;
260 struct buffer_head *bh; 260 struct buffer_head *bh;
261 struct inode *root; 261 struct inode *root;
262 int ret = -EINVAL;
263 262
264 sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL); 263 sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL);
265 if (!sb) 264 if (!sb)
@@ -270,7 +269,7 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
270 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) { 269 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) {
271 printk(KERN_ERR "EFS: device does not support %d byte blocks\n", 270 printk(KERN_ERR "EFS: device does not support %d byte blocks\n",
272 EFS_BLOCKSIZE); 271 EFS_BLOCKSIZE);
273 goto out_no_fs_ul; 272 return -EINVAL;
274 } 273 }
275 274
276 /* read the vh (volume header) block */ 275 /* read the vh (volume header) block */
@@ -278,7 +277,7 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
278 277
279 if (!bh) { 278 if (!bh) {
280 printk(KERN_ERR "EFS: cannot read volume header\n"); 279 printk(KERN_ERR "EFS: cannot read volume header\n");
281 goto out_no_fs_ul; 280 return -EINVAL;
282 } 281 }
283 282
284 /* 283 /*
@@ -290,13 +289,13 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
290 brelse(bh); 289 brelse(bh);
291 290
292 if (sb->fs_start == -1) { 291 if (sb->fs_start == -1) {
293 goto out_no_fs_ul; 292 return -EINVAL;
294 } 293 }
295 294
296 bh = sb_bread(s, sb->fs_start + EFS_SUPER); 295 bh = sb_bread(s, sb->fs_start + EFS_SUPER);
297 if (!bh) { 296 if (!bh) {
298 printk(KERN_ERR "EFS: cannot read superblock\n"); 297 printk(KERN_ERR "EFS: cannot read superblock\n");
299 goto out_no_fs_ul; 298 return -EINVAL;
300 } 299 }
301 300
302 if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) { 301 if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) {
@@ -304,7 +303,7 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
304 printk(KERN_WARNING "EFS: invalid superblock at block %u\n", sb->fs_start + EFS_SUPER); 303 printk(KERN_WARNING "EFS: invalid superblock at block %u\n", sb->fs_start + EFS_SUPER);
305#endif 304#endif
306 brelse(bh); 305 brelse(bh);
307 goto out_no_fs_ul; 306 return -EINVAL;
308 } 307 }
309 brelse(bh); 308 brelse(bh);
310 309
@@ -319,24 +318,16 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
319 root = efs_iget(s, EFS_ROOTINODE); 318 root = efs_iget(s, EFS_ROOTINODE);
320 if (IS_ERR(root)) { 319 if (IS_ERR(root)) {
321 printk(KERN_ERR "EFS: get root inode failed\n"); 320 printk(KERN_ERR "EFS: get root inode failed\n");
322 ret = PTR_ERR(root); 321 return PTR_ERR(root);
323 goto out_no_fs;
324 } 322 }
325 323
326 s->s_root = d_make_root(root); 324 s->s_root = d_make_root(root);
327 if (!(s->s_root)) { 325 if (!(s->s_root)) {
328 printk(KERN_ERR "EFS: get root dentry failed\n"); 326 printk(KERN_ERR "EFS: get root dentry failed\n");
329 ret = -ENOMEM; 327 return -ENOMEM;
330 goto out_no_fs;
331 } 328 }
332 329
333 return 0; 330 return 0;
334
335out_no_fs_ul:
336out_no_fs:
337 s->s_fs_info = NULL;
338 kfree(sb);
339 return ret;
340} 331}
341 332
342static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) { 333static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) {
diff --git a/fs/eventfd.c b/fs/eventfd.c
index 35470d9b96e6..d6a88e7812f3 100644
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -349,15 +349,12 @@ EXPORT_SYMBOL_GPL(eventfd_fget);
349 */ 349 */
350struct eventfd_ctx *eventfd_ctx_fdget(int fd) 350struct eventfd_ctx *eventfd_ctx_fdget(int fd)
351{ 351{
352 struct file *file;
353 struct eventfd_ctx *ctx; 352 struct eventfd_ctx *ctx;
354 353 struct fd f = fdget(fd);
355 file = eventfd_fget(fd); 354 if (!f.file)
356 if (IS_ERR(file)) 355 return ERR_PTR(-EBADF);
357 return (struct eventfd_ctx *) file; 356 ctx = eventfd_ctx_fileget(f.file);
358 ctx = eventfd_ctx_get(file->private_data); 357 fdput(f);
359 fput(file);
360
361 return ctx; 358 return ctx;
362} 359}
363EXPORT_SYMBOL_GPL(eventfd_ctx_fdget); 360EXPORT_SYMBOL_GPL(eventfd_ctx_fdget);
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 110b6b371a4e..1b8001bbe947 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -148,13 +148,6 @@ ext2_get_acl(struct inode *inode, int type)
148 struct posix_acl *acl; 148 struct posix_acl *acl;
149 int retval; 149 int retval;
150 150
151 if (!test_opt(inode->i_sb, POSIX_ACL))
152 return NULL;
153
154 acl = get_cached_acl(inode, type);
155 if (acl != ACL_NOT_CACHED)
156 return acl;
157
158 switch (type) { 151 switch (type) {
159 case ACL_TYPE_ACCESS: 152 case ACL_TYPE_ACCESS:
160 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 153 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -189,19 +182,14 @@ ext2_get_acl(struct inode *inode, int type)
189/* 182/*
190 * inode->i_mutex: down 183 * inode->i_mutex: down
191 */ 184 */
192static int 185int
193ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) 186ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
194{ 187{
195 int name_index; 188 int name_index;
196 void *value = NULL; 189 void *value = NULL;
197 size_t size = 0; 190 size_t size = 0;
198 int error; 191 int error;
199 192
200 if (S_ISLNK(inode->i_mode))
201 return -EOPNOTSUPP;
202 if (!test_opt(inode->i_sb, POSIX_ACL))
203 return 0;
204
205 switch(type) { 193 switch(type) {
206 case ACL_TYPE_ACCESS: 194 case ACL_TYPE_ACCESS:
207 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; 195 name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -250,169 +238,21 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
250int 238int
251ext2_init_acl(struct inode *inode, struct inode *dir) 239ext2_init_acl(struct inode *inode, struct inode *dir)
252{ 240{
253 struct posix_acl *acl = NULL; 241 struct posix_acl *default_acl, *acl;
254 int error = 0; 242 int error;
255
256 if (!S_ISLNK(inode->i_mode)) {
257 if (test_opt(dir->i_sb, POSIX_ACL)) {
258 acl = ext2_get_acl(dir, ACL_TYPE_DEFAULT);
259 if (IS_ERR(acl))
260 return PTR_ERR(acl);
261 }
262 if (!acl)
263 inode->i_mode &= ~current_umask();
264 }
265 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
266 if (S_ISDIR(inode->i_mode)) {
267 error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
268 if (error)
269 goto cleanup;
270 }
271 error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
272 if (error < 0)
273 return error;
274 if (error > 0) {
275 /* This is an extended ACL */
276 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
277 }
278 }
279cleanup:
280 posix_acl_release(acl);
281 return error;
282}
283
284/*
285 * Does chmod for an inode that may have an Access Control List. The
286 * inode->i_mode field must be updated to the desired value by the caller
287 * before calling this function.
288 * Returns 0 on success, or a negative error number.
289 *
290 * We change the ACL rather than storing some ACL entries in the file
291 * mode permission bits (which would be more efficient), because that
292 * would break once additional permissions (like ACL_APPEND, ACL_DELETE
293 * for directories) are added. There are no more bits available in the
294 * file mode.
295 *
296 * inode->i_mutex: down
297 */
298int
299ext2_acl_chmod(struct inode *inode)
300{
301 struct posix_acl *acl;
302 int error;
303 243
304 if (!test_opt(inode->i_sb, POSIX_ACL)) 244 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
305 return 0;
306 if (S_ISLNK(inode->i_mode))
307 return -EOPNOTSUPP;
308 acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
309 if (IS_ERR(acl) || !acl)
310 return PTR_ERR(acl);
311 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
312 if (error) 245 if (error)
313 return error; 246 return error;
314 error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
315 posix_acl_release(acl);
316 return error;
317}
318 247
319/* 248 if (default_acl) {
320 * Extended attribut handlers 249 error = ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
321 */ 250 posix_acl_release(default_acl);
322static size_t 251 }
323ext2_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_size, 252 if (acl) {
324 const char *name, size_t name_len, int type) 253 if (!error)
325{ 254 error = ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
326 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); 255 posix_acl_release(acl);
327 256 }
328 if (!test_opt(dentry->d_sb, POSIX_ACL))
329 return 0;
330 if (list && size <= list_size)
331 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
332 return size;
333}
334
335static size_t
336ext2_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_size,
337 const char *name, size_t name_len, int type)
338{
339 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
340
341 if (!test_opt(dentry->d_sb, POSIX_ACL))
342 return 0;
343 if (list && size <= list_size)
344 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
345 return size;
346}
347
348static int
349ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
350 size_t size, int type)
351{
352 struct posix_acl *acl;
353 int error;
354
355 if (strcmp(name, "") != 0)
356 return -EINVAL;
357 if (!test_opt(dentry->d_sb, POSIX_ACL))
358 return -EOPNOTSUPP;
359
360 acl = ext2_get_acl(dentry->d_inode, type);
361 if (IS_ERR(acl))
362 return PTR_ERR(acl);
363 if (acl == NULL)
364 return -ENODATA;
365 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
366 posix_acl_release(acl);
367
368 return error;
369}
370
371static int
372ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
373 size_t size, int flags, int type)
374{
375 struct posix_acl *acl;
376 int error;
377
378 if (strcmp(name, "") != 0)
379 return -EINVAL;
380 if (!test_opt(dentry->d_sb, POSIX_ACL))
381 return -EOPNOTSUPP;
382 if (!inode_owner_or_capable(dentry->d_inode))
383 return -EPERM;
384
385 if (value) {
386 acl = posix_acl_from_xattr(&init_user_ns, value, size);
387 if (IS_ERR(acl))
388 return PTR_ERR(acl);
389 else if (acl) {
390 error = posix_acl_valid(acl);
391 if (error)
392 goto release_and_out;
393 }
394 } else
395 acl = NULL;
396
397 error = ext2_set_acl(dentry->d_inode, type, acl);
398
399release_and_out:
400 posix_acl_release(acl);
401 return error; 257 return error;
402} 258}
403
404const struct xattr_handler ext2_xattr_acl_access_handler = {
405 .prefix = POSIX_ACL_XATTR_ACCESS,
406 .flags = ACL_TYPE_ACCESS,
407 .list = ext2_xattr_list_acl_access,
408 .get = ext2_xattr_get_acl,
409 .set = ext2_xattr_set_acl,
410};
411
412const struct xattr_handler ext2_xattr_acl_default_handler = {
413 .prefix = POSIX_ACL_XATTR_DEFAULT,
414 .flags = ACL_TYPE_DEFAULT,
415 .list = ext2_xattr_list_acl_default,
416 .get = ext2_xattr_get_acl,
417 .set = ext2_xattr_set_acl,
418};
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
index 503bfb0ed79b..44937f9fcf32 100644
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -55,7 +55,7 @@ static inline int ext2_acl_count(size_t size)
55 55
56/* acl.c */ 56/* acl.c */
57extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); 57extern struct posix_acl *ext2_get_acl(struct inode *inode, int type);
58extern int ext2_acl_chmod (struct inode *); 58extern int ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
59extern int ext2_init_acl (struct inode *, struct inode *); 59extern int ext2_init_acl (struct inode *, struct inode *);
60 60
61#else 61#else
@@ -63,12 +63,6 @@ extern int ext2_init_acl (struct inode *, struct inode *);
63#define ext2_get_acl NULL 63#define ext2_get_acl NULL
64#define ext2_set_acl NULL 64#define ext2_set_acl NULL
65 65
66static inline int
67ext2_acl_chmod (struct inode *inode)
68{
69 return 0;
70}
71
72static inline int ext2_init_acl (struct inode *inode, struct inode *dir) 66static inline int ext2_init_acl (struct inode *inode, struct inode *dir)
73{ 67{
74 return 0; 68 return 0;
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index a5b3a5db3120..44c36e590765 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -103,5 +103,6 @@ const struct inode_operations ext2_file_inode_operations = {
103#endif 103#endif
104 .setattr = ext2_setattr, 104 .setattr = ext2_setattr,
105 .get_acl = ext2_get_acl, 105 .get_acl = ext2_get_acl,
106 .set_acl = ext2_set_acl,
106 .fiemap = ext2_fiemap, 107 .fiemap = ext2_fiemap,
107}; 108};
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 8a337640a46a..94ed36849b71 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1566,7 +1566,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1566 } 1566 }
1567 setattr_copy(inode, iattr); 1567 setattr_copy(inode, iattr);
1568 if (iattr->ia_valid & ATTR_MODE) 1568 if (iattr->ia_valid & ATTR_MODE)
1569 error = ext2_acl_chmod(inode); 1569 error = posix_acl_chmod(inode, inode->i_mode);
1570 mark_inode_dirty(inode); 1570 mark_inode_dirty(inode);
1571 1571
1572 return error; 1572 return error;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 256dd5f4c1c4..c268d0af1db9 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -421,6 +421,7 @@ const struct inode_operations ext2_dir_inode_operations = {
421#endif 421#endif
422 .setattr = ext2_setattr, 422 .setattr = ext2_setattr,
423 .get_acl = ext2_get_acl, 423 .get_acl = ext2_get_acl,
424 .set_acl = ext2_set_acl,
424 .tmpfile = ext2_tmpfile, 425 .tmpfile = ext2_tmpfile,
425}; 426};
426 427
@@ -433,4 +434,5 @@ const struct inode_operations ext2_special_inode_operations = {
433#endif 434#endif
434 .setattr = ext2_setattr, 435 .setattr = ext2_setattr,
435 .get_acl = ext2_get_acl, 436 .get_acl = ext2_get_acl,
437 .set_acl = ext2_set_acl,
436}; 438};
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 2d7557db3ae8..91426141c33a 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -103,8 +103,8 @@ static struct mb_cache *ext2_xattr_cache;
103static const struct xattr_handler *ext2_xattr_handler_map[] = { 103static const struct xattr_handler *ext2_xattr_handler_map[] = {
104 [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, 104 [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler,
105#ifdef CONFIG_EXT2_FS_POSIX_ACL 105#ifdef CONFIG_EXT2_FS_POSIX_ACL
106 [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, 106 [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
107 [EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext2_xattr_acl_default_handler, 107 [EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
108#endif 108#endif
109 [EXT2_XATTR_INDEX_TRUSTED] = &ext2_xattr_trusted_handler, 109 [EXT2_XATTR_INDEX_TRUSTED] = &ext2_xattr_trusted_handler,
110#ifdef CONFIG_EXT2_FS_SECURITY 110#ifdef CONFIG_EXT2_FS_SECURITY
@@ -116,8 +116,8 @@ const struct xattr_handler *ext2_xattr_handlers[] = {
116 &ext2_xattr_user_handler, 116 &ext2_xattr_user_handler,
117 &ext2_xattr_trusted_handler, 117 &ext2_xattr_trusted_handler,
118#ifdef CONFIG_EXT2_FS_POSIX_ACL 118#ifdef CONFIG_EXT2_FS_POSIX_ACL
119 &ext2_xattr_acl_access_handler, 119 &posix_acl_access_xattr_handler,
120 &ext2_xattr_acl_default_handler, 120 &posix_acl_default_xattr_handler,
121#endif 121#endif
122#ifdef CONFIG_EXT2_FS_SECURITY 122#ifdef CONFIG_EXT2_FS_SECURITY
123 &ext2_xattr_security_handler, 123 &ext2_xattr_security_handler,
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index 5e41cccff762..60edf298644e 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -57,8 +57,6 @@ struct ext2_xattr_entry {
57 57
58extern const struct xattr_handler ext2_xattr_user_handler; 58extern const struct xattr_handler ext2_xattr_user_handler;
59extern const struct xattr_handler ext2_xattr_trusted_handler; 59extern const struct xattr_handler ext2_xattr_trusted_handler;
60extern const struct xattr_handler ext2_xattr_acl_access_handler;
61extern const struct xattr_handler ext2_xattr_acl_default_handler;
62extern const struct xattr_handler ext2_xattr_security_handler; 60extern const struct xattr_handler ext2_xattr_security_handler;
63 61
64extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); 62extern ssize_t ext2_listxattr(struct dentry *, char *, size_t);
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index dbb5ad59a7fc..8bbaf5bcf982 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -145,13 +145,6 @@ ext3_get_acl(struct inode *inode, int type)
145 struct posix_acl *acl; 145 struct posix_acl *acl;
146 int retval; 146 int retval;
147 147
148 if (!test_opt(inode->i_sb, POSIX_ACL))
149 return NULL;
150
151 acl = get_cached_acl(inode, type);
152 if (acl != ACL_NOT_CACHED)
153 return acl;
154
155 switch (type) { 148 switch (type) {
156 case ACL_TYPE_ACCESS: 149 case ACL_TYPE_ACCESS:
157 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; 150 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -190,7 +183,7 @@ ext3_get_acl(struct inode *inode, int type)
190 * inode->i_mutex: down unless called from ext3_new_inode 183 * inode->i_mutex: down unless called from ext3_new_inode
191 */ 184 */
192static int 185static int
193ext3_set_acl(handle_t *handle, struct inode *inode, int type, 186__ext3_set_acl(handle_t *handle, struct inode *inode, int type,
194 struct posix_acl *acl) 187 struct posix_acl *acl)
195{ 188{
196 int name_index; 189 int name_index;
@@ -198,9 +191,6 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
198 size_t size = 0; 191 size_t size = 0;
199 int error; 192 int error;
200 193
201 if (S_ISLNK(inode->i_mode))
202 return -EOPNOTSUPP;
203
204 switch(type) { 194 switch(type) {
205 case ACL_TYPE_ACCESS: 195 case ACL_TYPE_ACCESS:
206 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS; 196 name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -243,204 +233,49 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
243 return error; 233 return error;
244} 234}
245 235
246/*
247 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
248 *
249 * dir->i_mutex: down
250 * inode->i_mutex: up (access to inode is still exclusive)
251 */
252int 236int
253ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 237ext3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
254{ 238{
255 struct posix_acl *acl = NULL;
256 int error = 0;
257
258 if (!S_ISLNK(inode->i_mode)) {
259 if (test_opt(dir->i_sb, POSIX_ACL)) {
260 acl = ext3_get_acl(dir, ACL_TYPE_DEFAULT);
261 if (IS_ERR(acl))
262 return PTR_ERR(acl);
263 }
264 if (!acl)
265 inode->i_mode &= ~current_umask();
266 }
267 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
268 if (S_ISDIR(inode->i_mode)) {
269 error = ext3_set_acl(handle, inode,
270 ACL_TYPE_DEFAULT, acl);
271 if (error)
272 goto cleanup;
273 }
274 error = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
275 if (error < 0)
276 return error;
277
278 if (error > 0) {
279 /* This is an extended ACL */
280 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
281 }
282 }
283cleanup:
284 posix_acl_release(acl);
285 return error;
286}
287
288/*
289 * Does chmod for an inode that may have an Access Control List. The
290 * inode->i_mode field must be updated to the desired value by the caller
291 * before calling this function.
292 * Returns 0 on success, or a negative error number.
293 *
294 * We change the ACL rather than storing some ACL entries in the file
295 * mode permission bits (which would be more efficient), because that
296 * would break once additional permissions (like ACL_APPEND, ACL_DELETE
297 * for directories) are added. There are no more bits available in the
298 * file mode.
299 *
300 * inode->i_mutex: down
301 */
302int
303ext3_acl_chmod(struct inode *inode)
304{
305 struct posix_acl *acl;
306 handle_t *handle; 239 handle_t *handle;
307 int retries = 0; 240 int error, retries = 0;
308 int error;
309 241
310 if (S_ISLNK(inode->i_mode))
311 return -EOPNOTSUPP;
312 if (!test_opt(inode->i_sb, POSIX_ACL))
313 return 0;
314 acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
315 if (IS_ERR(acl) || !acl)
316 return PTR_ERR(acl);
317 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
318 if (error)
319 return error;
320retry: 242retry:
321 handle = ext3_journal_start(inode, 243 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
322 EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); 244 if (IS_ERR(handle))
323 if (IS_ERR(handle)) { 245 return PTR_ERR(handle);
324 error = PTR_ERR(handle); 246 error = __ext3_set_acl(handle, inode, type, acl);
325 ext3_std_error(inode->i_sb, error);
326 goto out;
327 }
328 error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
329 ext3_journal_stop(handle); 247 ext3_journal_stop(handle);
330 if (error == -ENOSPC && 248 if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
331 ext3_should_retry_alloc(inode->i_sb, &retries))
332 goto retry; 249 goto retry;
333out:
334 posix_acl_release(acl);
335 return error; 250 return error;
336} 251}
337 252
338/* 253/*
339 * Extended attribute handlers 254 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
255 *
256 * dir->i_mutex: down
257 * inode->i_mutex: up (access to inode is still exclusive)
340 */ 258 */
341static size_t 259int
342ext3_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, 260ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
343 const char *name, size_t name_len, int type)
344{
345 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
346
347 if (!test_opt(dentry->d_sb, POSIX_ACL))
348 return 0;
349 if (list && size <= list_len)
350 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
351 return size;
352}
353
354static size_t
355ext3_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len,
356 const char *name, size_t name_len, int type)
357{
358 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
359
360 if (!test_opt(dentry->d_sb, POSIX_ACL))
361 return 0;
362 if (list && size <= list_len)
363 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
364 return size;
365}
366
367static int
368ext3_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
369 size_t size, int type)
370{ 261{
371 struct posix_acl *acl; 262 struct posix_acl *default_acl, *acl;
372 int error; 263 int error;
373 264
374 if (strcmp(name, "") != 0) 265 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
375 return -EINVAL; 266 if (error)
376 if (!test_opt(dentry->d_sb, POSIX_ACL)) 267 return error;
377 return -EOPNOTSUPP;
378
379 acl = ext3_get_acl(dentry->d_inode, type);
380 if (IS_ERR(acl))
381 return PTR_ERR(acl);
382 if (acl == NULL)
383 return -ENODATA;
384 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
385 posix_acl_release(acl);
386
387 return error;
388}
389
390static int
391ext3_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
392 size_t size, int flags, int type)
393{
394 struct inode *inode = dentry->d_inode;
395 handle_t *handle;
396 struct posix_acl *acl;
397 int error, retries = 0;
398
399 if (strcmp(name, "") != 0)
400 return -EINVAL;
401 if (!test_opt(inode->i_sb, POSIX_ACL))
402 return -EOPNOTSUPP;
403 if (!inode_owner_or_capable(inode))
404 return -EPERM;
405
406 if (value) {
407 acl = posix_acl_from_xattr(&init_user_ns, value, size);
408 if (IS_ERR(acl))
409 return PTR_ERR(acl);
410 else if (acl) {
411 error = posix_acl_valid(acl);
412 if (error)
413 goto release_and_out;
414 }
415 } else
416 acl = NULL;
417
418retry:
419 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
420 if (IS_ERR(handle))
421 return PTR_ERR(handle);
422 error = ext3_set_acl(handle, inode, type, acl);
423 ext3_journal_stop(handle);
424 if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
425 goto retry;
426 268
427release_and_out: 269 if (default_acl) {
428 posix_acl_release(acl); 270 error = __ext3_set_acl(handle, inode, ACL_TYPE_DEFAULT,
271 default_acl);
272 posix_acl_release(default_acl);
273 }
274 if (acl) {
275 if (!error)
276 error = __ext3_set_acl(handle, inode, ACL_TYPE_ACCESS,
277 acl);
278 posix_acl_release(acl);
279 }
429 return error; 280 return error;
430} 281}
431
432const struct xattr_handler ext3_xattr_acl_access_handler = {
433 .prefix = POSIX_ACL_XATTR_ACCESS,
434 .flags = ACL_TYPE_ACCESS,
435 .list = ext3_xattr_list_acl_access,
436 .get = ext3_xattr_get_acl,
437 .set = ext3_xattr_set_acl,
438};
439
440const struct xattr_handler ext3_xattr_acl_default_handler = {
441 .prefix = POSIX_ACL_XATTR_DEFAULT,
442 .flags = ACL_TYPE_DEFAULT,
443 .list = ext3_xattr_list_acl_default,
444 .get = ext3_xattr_get_acl,
445 .set = ext3_xattr_set_acl,
446};
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index dbc921e458c5..ea1c69edab9e 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -55,18 +55,13 @@ static inline int ext3_acl_count(size_t size)
55 55
56/* acl.c */ 56/* acl.c */
57extern struct posix_acl *ext3_get_acl(struct inode *inode, int type); 57extern struct posix_acl *ext3_get_acl(struct inode *inode, int type);
58extern int ext3_acl_chmod (struct inode *); 58extern int ext3_set_acl(struct inode *inode, struct posix_acl *acl, int type);
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_get_acl NULL 63#define ext3_get_acl NULL
64 64#define ext3_set_acl NULL
65static inline int
66ext3_acl_chmod(struct inode *inode)
67{
68 return 0;
69}
70 65
71static inline int 66static inline int
72ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 67ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 25cb413277e9..aad05311392a 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -75,6 +75,7 @@ const struct inode_operations ext3_file_inode_operations = {
75 .removexattr = generic_removexattr, 75 .removexattr = generic_removexattr,
76#endif 76#endif
77 .get_acl = ext3_get_acl, 77 .get_acl = ext3_get_acl,
78 .set_acl = ext3_set_acl,
78 .fiemap = ext3_fiemap, 79 .fiemap = ext3_fiemap,
79}; 80};
80 81
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 2bd85486b879..384b6ebb655f 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -3365,7 +3365,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
3365 mark_inode_dirty(inode); 3365 mark_inode_dirty(inode);
3366 3366
3367 if (ia_valid & ATTR_MODE) 3367 if (ia_valid & ATTR_MODE)
3368 rc = ext3_acl_chmod(inode); 3368 rc = posix_acl_chmod(inode, inode->i_mode);
3369 3369
3370err_out: 3370err_out:
3371 ext3_std_error(inode->i_sb, error); 3371 ext3_std_error(inode->i_sb, error);
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index f8cde46de9cd..f197736dccfa 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2569,6 +2569,7 @@ const struct inode_operations ext3_dir_inode_operations = {
2569 .removexattr = generic_removexattr, 2569 .removexattr = generic_removexattr,
2570#endif 2570#endif
2571 .get_acl = ext3_get_acl, 2571 .get_acl = ext3_get_acl,
2572 .set_acl = ext3_set_acl,
2572}; 2573};
2573 2574
2574const struct inode_operations ext3_special_inode_operations = { 2575const struct inode_operations ext3_special_inode_operations = {
@@ -2580,4 +2581,5 @@ const struct inode_operations ext3_special_inode_operations = {
2580 .removexattr = generic_removexattr, 2581 .removexattr = generic_removexattr,
2581#endif 2582#endif
2582 .get_acl = ext3_get_acl, 2583 .get_acl = ext3_get_acl,
2584 .set_acl = ext3_set_acl,
2583}; 2585};
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index b1fc96383e08..c6874be6d58b 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -102,8 +102,8 @@ static struct mb_cache *ext3_xattr_cache;
102static const struct xattr_handler *ext3_xattr_handler_map[] = { 102static const struct xattr_handler *ext3_xattr_handler_map[] = {
103 [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler, 103 [EXT3_XATTR_INDEX_USER] = &ext3_xattr_user_handler,
104#ifdef CONFIG_EXT3_FS_POSIX_ACL 104#ifdef CONFIG_EXT3_FS_POSIX_ACL
105 [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext3_xattr_acl_access_handler, 105 [EXT3_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
106 [EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext3_xattr_acl_default_handler, 106 [EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
107#endif 107#endif
108 [EXT3_XATTR_INDEX_TRUSTED] = &ext3_xattr_trusted_handler, 108 [EXT3_XATTR_INDEX_TRUSTED] = &ext3_xattr_trusted_handler,
109#ifdef CONFIG_EXT3_FS_SECURITY 109#ifdef CONFIG_EXT3_FS_SECURITY
@@ -115,8 +115,8 @@ const struct xattr_handler *ext3_xattr_handlers[] = {
115 &ext3_xattr_user_handler, 115 &ext3_xattr_user_handler,
116 &ext3_xattr_trusted_handler, 116 &ext3_xattr_trusted_handler,
117#ifdef CONFIG_EXT3_FS_POSIX_ACL 117#ifdef CONFIG_EXT3_FS_POSIX_ACL
118 &ext3_xattr_acl_access_handler, 118 &posix_acl_access_xattr_handler,
119 &ext3_xattr_acl_default_handler, 119 &posix_acl_default_xattr_handler,
120#endif 120#endif
121#ifdef CONFIG_EXT3_FS_SECURITY 121#ifdef CONFIG_EXT3_FS_SECURITY
122 &ext3_xattr_security_handler, 122 &ext3_xattr_security_handler,
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 2be4f69bfa64..32e93ebf8031 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -60,8 +60,6 @@ struct ext3_xattr_entry {
60 60
61extern const struct xattr_handler ext3_xattr_user_handler; 61extern const struct xattr_handler ext3_xattr_user_handler;
62extern const struct xattr_handler ext3_xattr_trusted_handler; 62extern const struct xattr_handler ext3_xattr_trusted_handler;
63extern const struct xattr_handler ext3_xattr_acl_access_handler;
64extern const struct xattr_handler ext3_xattr_acl_default_handler;
65extern const struct xattr_handler ext3_xattr_security_handler; 63extern const struct xattr_handler ext3_xattr_security_handler;
66 64
67extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); 65extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 39a54a0e9fe4..d40c8dbbb0d6 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -152,13 +152,6 @@ ext4_get_acl(struct inode *inode, int type)
152 struct posix_acl *acl; 152 struct posix_acl *acl;
153 int retval; 153 int retval;
154 154
155 if (!test_opt(inode->i_sb, POSIX_ACL))
156 return NULL;
157
158 acl = get_cached_acl(inode, type);
159 if (acl != ACL_NOT_CACHED)
160 return acl;
161
162 switch (type) { 155 switch (type) {
163 case ACL_TYPE_ACCESS: 156 case ACL_TYPE_ACCESS:
164 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; 157 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -196,7 +189,7 @@ ext4_get_acl(struct inode *inode, int type)
196 * inode->i_mutex: down unless called from ext4_new_inode 189 * inode->i_mutex: down unless called from ext4_new_inode
197 */ 190 */
198static int 191static int
199ext4_set_acl(handle_t *handle, struct inode *inode, int type, 192__ext4_set_acl(handle_t *handle, struct inode *inode, int type,
200 struct posix_acl *acl) 193 struct posix_acl *acl)
201{ 194{
202 int name_index; 195 int name_index;
@@ -204,9 +197,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
204 size_t size = 0; 197 size_t size = 0;
205 int error; 198 int error;
206 199
207 if (S_ISLNK(inode->i_mode))
208 return -EOPNOTSUPP;
209
210 switch (type) { 200 switch (type) {
211 case ACL_TYPE_ACCESS: 201 case ACL_TYPE_ACCESS:
212 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; 202 name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -248,208 +238,51 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
248 return error; 238 return error;
249} 239}
250 240
251/*
252 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
253 *
254 * dir->i_mutex: down
255 * inode->i_mutex: up (access to inode is still exclusive)
256 */
257int 241int
258ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 242ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
259{ 243{
260 struct posix_acl *acl = NULL;
261 int error = 0;
262
263 if (!S_ISLNK(inode->i_mode)) {
264 if (test_opt(dir->i_sb, POSIX_ACL)) {
265 acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT);
266 if (IS_ERR(acl))
267 return PTR_ERR(acl);
268 }
269 if (!acl)
270 inode->i_mode &= ~current_umask();
271 }
272 if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
273 if (S_ISDIR(inode->i_mode)) {
274 error = ext4_set_acl(handle, inode,
275 ACL_TYPE_DEFAULT, acl);
276 if (error)
277 goto cleanup;
278 }
279 error = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
280 if (error < 0)
281 return error;
282
283 if (error > 0) {
284 /* This is an extended ACL */
285 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
286 }
287 }
288cleanup:
289 posix_acl_release(acl);
290 return error;
291}
292
293/*
294 * Does chmod for an inode that may have an Access Control List. The
295 * inode->i_mode field must be updated to the desired value by the caller
296 * before calling this function.
297 * Returns 0 on success, or a negative error number.
298 *
299 * We change the ACL rather than storing some ACL entries in the file
300 * mode permission bits (which would be more efficient), because that
301 * would break once additional permissions (like ACL_APPEND, ACL_DELETE
302 * for directories) are added. There are no more bits available in the
303 * file mode.
304 *
305 * inode->i_mutex: down
306 */
307int
308ext4_acl_chmod(struct inode *inode)
309{
310 struct posix_acl *acl;
311 handle_t *handle; 244 handle_t *handle;
312 int retries = 0; 245 int error, retries = 0;
313 int error;
314
315 246
316 if (S_ISLNK(inode->i_mode))
317 return -EOPNOTSUPP;
318 if (!test_opt(inode->i_sb, POSIX_ACL))
319 return 0;
320 acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
321 if (IS_ERR(acl) || !acl)
322 return PTR_ERR(acl);
323 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
324 if (error)
325 return error;
326retry: 247retry:
327 handle = ext4_journal_start(inode, EXT4_HT_XATTR, 248 handle = ext4_journal_start(inode, EXT4_HT_XATTR,
328 ext4_jbd2_credits_xattr(inode)); 249 ext4_jbd2_credits_xattr(inode));
329 if (IS_ERR(handle)) { 250 if (IS_ERR(handle))
330 error = PTR_ERR(handle); 251 return PTR_ERR(handle);
331 ext4_std_error(inode->i_sb, error); 252
332 goto out; 253 error = __ext4_set_acl(handle, inode, type, acl);
333 }
334 error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);
335 ext4_journal_stop(handle); 254 ext4_journal_stop(handle);
336 if (error == -ENOSPC && 255 if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
337 ext4_should_retry_alloc(inode->i_sb, &retries))
338 goto retry; 256 goto retry;
339out:
340 posix_acl_release(acl);
341 return error; 257 return error;
342} 258}
343 259
344/* 260/*
345 * Extended attribute handlers 261 * Initialize the ACLs of a new inode. Called from ext4_new_inode.
262 *
263 * dir->i_mutex: down
264 * inode->i_mutex: up (access to inode is still exclusive)
346 */ 265 */
347static size_t 266int
348ext4_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, 267ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
349 const char *name, size_t name_len, int type)
350{
351 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
352
353 if (!test_opt(dentry->d_sb, POSIX_ACL))
354 return 0;
355 if (list && size <= list_len)
356 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
357 return size;
358}
359
360static size_t
361ext4_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len,
362 const char *name, size_t name_len, int type)
363{
364 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
365
366 if (!test_opt(dentry->d_sb, POSIX_ACL))
367 return 0;
368 if (list && size <= list_len)
369 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
370 return size;
371}
372
373static int
374ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
375 size_t size, int type)
376{ 268{
377 struct posix_acl *acl; 269 struct posix_acl *default_acl, *acl;
378 int error; 270 int error;
379 271
380 if (strcmp(name, "") != 0) 272 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
381 return -EINVAL; 273 if (error)
382 if (!test_opt(dentry->d_sb, POSIX_ACL)) 274 return error;
383 return -EOPNOTSUPP;
384
385 acl = ext4_get_acl(dentry->d_inode, type);
386 if (IS_ERR(acl))
387 return PTR_ERR(acl);
388 if (acl == NULL)
389 return -ENODATA;
390 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
391 posix_acl_release(acl);
392
393 return error;
394}
395
396static int
397ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
398 size_t size, int flags, int type)
399{
400 struct inode *inode = dentry->d_inode;
401 handle_t *handle;
402 struct posix_acl *acl;
403 int error, retries = 0;
404
405 if (strcmp(name, "") != 0)
406 return -EINVAL;
407 if (!test_opt(inode->i_sb, POSIX_ACL))
408 return -EOPNOTSUPP;
409 if (!inode_owner_or_capable(inode))
410 return -EPERM;
411
412 if (value) {
413 acl = posix_acl_from_xattr(&init_user_ns, value, size);
414 if (IS_ERR(acl))
415 return PTR_ERR(acl);
416 else if (acl) {
417 error = posix_acl_valid(acl);
418 if (error)
419 goto release_and_out;
420 }
421 } else
422 acl = NULL;
423 275
424retry: 276 if (default_acl) {
425 handle = ext4_journal_start(inode, EXT4_HT_XATTR, 277 error = __ext4_set_acl(handle, inode, ACL_TYPE_DEFAULT,
426 ext4_jbd2_credits_xattr(inode)); 278 default_acl);
427 if (IS_ERR(handle)) { 279 posix_acl_release(default_acl);
428 error = PTR_ERR(handle); 280 }
429 goto release_and_out; 281 if (acl) {
282 if (!error)
283 error = __ext4_set_acl(handle, inode, ACL_TYPE_ACCESS,
284 acl);
285 posix_acl_release(acl);
430 } 286 }
431 error = ext4_set_acl(handle, inode, type, acl);
432 ext4_journal_stop(handle);
433 if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
434 goto retry;
435
436release_and_out:
437 posix_acl_release(acl);
438 return error; 287 return error;
439} 288}
440
441const struct xattr_handler ext4_xattr_acl_access_handler = {
442 .prefix = POSIX_ACL_XATTR_ACCESS,
443 .flags = ACL_TYPE_ACCESS,
444 .list = ext4_xattr_list_acl_access,
445 .get = ext4_xattr_get_acl,
446 .set = ext4_xattr_set_acl,
447};
448
449const struct xattr_handler ext4_xattr_acl_default_handler = {
450 .prefix = POSIX_ACL_XATTR_DEFAULT,
451 .flags = ACL_TYPE_DEFAULT,
452 .list = ext4_xattr_list_acl_default,
453 .get = ext4_xattr_get_acl,
454 .set = ext4_xattr_set_acl,
455};
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 18cb39ed7c7b..da2c79577d72 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -55,18 +55,13 @@ static inline int ext4_acl_count(size_t size)
55 55
56/* acl.c */ 56/* acl.c */
57struct posix_acl *ext4_get_acl(struct inode *inode, int type); 57struct posix_acl *ext4_get_acl(struct inode *inode, int type);
58extern int ext4_acl_chmod(struct inode *); 58int ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type);
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_get_acl NULL 63#define ext4_get_acl NULL
64 64#define ext4_set_acl NULL
65static inline int
66ext4_acl_chmod(struct inode *inode)
67{
68 return 0;
69}
70 65
71static inline int 66static inline int
72ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 67ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3da21945ff1f..43e64f6022eb 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -617,6 +617,7 @@ const struct inode_operations ext4_file_inode_operations = {
617 .listxattr = ext4_listxattr, 617 .listxattr = ext4_listxattr,
618 .removexattr = generic_removexattr, 618 .removexattr = generic_removexattr,
619 .get_acl = ext4_get_acl, 619 .get_acl = ext4_get_acl,
620 .set_acl = ext4_set_acl,
620 .fiemap = ext4_fiemap, 621 .fiemap = ext4_fiemap,
621}; 622};
622 623
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 31fa964742bc..fe4793e754d1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4667,7 +4667,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
4667 ext4_orphan_del(NULL, inode); 4667 ext4_orphan_del(NULL, inode);
4668 4668
4669 if (!rc && (ia_valid & ATTR_MODE)) 4669 if (!rc && (ia_valid & ATTR_MODE))
4670 rc = ext4_acl_chmod(inode); 4670 rc = posix_acl_chmod(inode, inode->i_mode);
4671 4671
4672err_out: 4672err_out:
4673 ext4_std_error(inode->i_sb, error); 4673 ext4_std_error(inode->i_sb, error);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5a0408d7b114..e77c1ba6c8af 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3225,6 +3225,7 @@ const struct inode_operations ext4_dir_inode_operations = {
3225 .listxattr = ext4_listxattr, 3225 .listxattr = ext4_listxattr,
3226 .removexattr = generic_removexattr, 3226 .removexattr = generic_removexattr,
3227 .get_acl = ext4_get_acl, 3227 .get_acl = ext4_get_acl,
3228 .set_acl = ext4_set_acl,
3228 .fiemap = ext4_fiemap, 3229 .fiemap = ext4_fiemap,
3229}; 3230};
3230 3231
@@ -3235,4 +3236,5 @@ const struct inode_operations ext4_special_inode_operations = {
3235 .listxattr = ext4_listxattr, 3236 .listxattr = ext4_listxattr,
3236 .removexattr = generic_removexattr, 3237 .removexattr = generic_removexattr,
3237 .get_acl = ext4_get_acl, 3238 .get_acl = ext4_get_acl,
3239 .set_acl = ext4_set_acl,
3238}; 3240};
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 1423c4816a47..e175e94116ac 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -95,8 +95,8 @@ static struct mb_cache *ext4_xattr_cache;
95static const struct xattr_handler *ext4_xattr_handler_map[] = { 95static const struct xattr_handler *ext4_xattr_handler_map[] = {
96 [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler, 96 [EXT4_XATTR_INDEX_USER] = &ext4_xattr_user_handler,
97#ifdef CONFIG_EXT4_FS_POSIX_ACL 97#ifdef CONFIG_EXT4_FS_POSIX_ACL
98 [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext4_xattr_acl_access_handler, 98 [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
99 [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext4_xattr_acl_default_handler, 99 [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
100#endif 100#endif
101 [EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler, 101 [EXT4_XATTR_INDEX_TRUSTED] = &ext4_xattr_trusted_handler,
102#ifdef CONFIG_EXT4_FS_SECURITY 102#ifdef CONFIG_EXT4_FS_SECURITY
@@ -108,8 +108,8 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
108 &ext4_xattr_user_handler, 108 &ext4_xattr_user_handler,
109 &ext4_xattr_trusted_handler, 109 &ext4_xattr_trusted_handler,
110#ifdef CONFIG_EXT4_FS_POSIX_ACL 110#ifdef CONFIG_EXT4_FS_POSIX_ACL
111 &ext4_xattr_acl_access_handler, 111 &posix_acl_access_xattr_handler,
112 &ext4_xattr_acl_default_handler, 112 &posix_acl_default_xattr_handler,
113#endif 113#endif
114#ifdef CONFIG_EXT4_FS_SECURITY 114#ifdef CONFIG_EXT4_FS_SECURITY
115 &ext4_xattr_security_handler, 115 &ext4_xattr_security_handler,
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index c767dbdd7fc4..819d6398833f 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -96,8 +96,6 @@ struct ext4_xattr_ibody_find {
96 96
97extern const struct xattr_handler ext4_xattr_user_handler; 97extern const struct xattr_handler ext4_xattr_user_handler;
98extern const struct xattr_handler ext4_xattr_trusted_handler; 98extern const struct xattr_handler ext4_xattr_trusted_handler;
99extern const struct xattr_handler ext4_xattr_acl_access_handler;
100extern const struct xattr_handler ext4_xattr_acl_default_handler;
101extern const struct xattr_handler ext4_xattr_security_handler; 99extern const struct xattr_handler ext4_xattr_security_handler;
102 100
103extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); 101extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index d0fc287efeff..fa8da4cb8c4b 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -17,9 +17,6 @@
17#include "xattr.h" 17#include "xattr.h"
18#include "acl.h" 18#include "acl.h"
19 19
20#define get_inode_mode(i) ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
21 (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
22
23static inline size_t f2fs_acl_size(int count) 20static inline size_t f2fs_acl_size(int count)
24{ 21{
25 if (count <= 4) { 22 if (count <= 4) {
@@ -167,19 +164,11 @@ fail:
167 164
168struct posix_acl *f2fs_get_acl(struct inode *inode, int type) 165struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
169{ 166{
170 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
171 int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT; 167 int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT;
172 void *value = NULL; 168 void *value = NULL;
173 struct posix_acl *acl; 169 struct posix_acl *acl;
174 int retval; 170 int retval;
175 171
176 if (!test_opt(sbi, POSIX_ACL))
177 return NULL;
178
179 acl = get_cached_acl(inode, type);
180 if (acl != ACL_NOT_CACHED)
181 return acl;
182
183 if (type == ACL_TYPE_ACCESS) 172 if (type == ACL_TYPE_ACCESS)
184 name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; 173 name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
185 174
@@ -205,21 +194,15 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
205 return acl; 194 return acl;
206} 195}
207 196
208static int f2fs_set_acl(struct inode *inode, int type, 197static int __f2fs_set_acl(struct inode *inode, int type,
209 struct posix_acl *acl, struct page *ipage) 198 struct posix_acl *acl, struct page *ipage)
210{ 199{
211 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
212 struct f2fs_inode_info *fi = F2FS_I(inode); 200 struct f2fs_inode_info *fi = F2FS_I(inode);
213 int name_index; 201 int name_index;
214 void *value = NULL; 202 void *value = NULL;
215 size_t size = 0; 203 size_t size = 0;
216 int error; 204 int error;
217 205
218 if (!test_opt(sbi, POSIX_ACL))
219 return 0;
220 if (S_ISLNK(inode->i_mode))
221 return -EOPNOTSUPP;
222
223 switch (type) { 206 switch (type) {
224 case ACL_TYPE_ACCESS: 207 case ACL_TYPE_ACCESS:
225 name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS; 208 name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
@@ -261,154 +244,31 @@ static int f2fs_set_acl(struct inode *inode, int type,
261 return error; 244 return error;
262} 245}
263 246
264int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage) 247int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
265{ 248{
266 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); 249 return __f2fs_set_acl(inode, type, acl, NULL);
267 struct posix_acl *acl = NULL;
268 int error = 0;
269
270 if (!S_ISLNK(inode->i_mode)) {
271 if (test_opt(sbi, POSIX_ACL)) {
272 acl = f2fs_get_acl(dir, ACL_TYPE_DEFAULT);
273 if (IS_ERR(acl))
274 return PTR_ERR(acl);
275 }
276 if (!acl)
277 inode->i_mode &= ~current_umask();
278 }
279
280 if (!test_opt(sbi, POSIX_ACL) || !acl)
281 goto cleanup;
282
283 if (S_ISDIR(inode->i_mode)) {
284 error = f2fs_set_acl(inode, ACL_TYPE_DEFAULT, acl, ipage);
285 if (error)
286 goto cleanup;
287 }
288 error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
289 if (error < 0)
290 return error;
291 if (error > 0)
292 error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, ipage);
293cleanup:
294 posix_acl_release(acl);
295 return error;
296} 250}
297 251
298int f2fs_acl_chmod(struct inode *inode) 252int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage)
299{ 253{
300 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 254 struct posix_acl *default_acl, *acl;
301 struct posix_acl *acl; 255 int error = 0;
302 int error;
303 umode_t mode = get_inode_mode(inode);
304
305 if (!test_opt(sbi, POSIX_ACL))
306 return 0;
307 if (S_ISLNK(mode))
308 return -EOPNOTSUPP;
309
310 acl = f2fs_get_acl(inode, ACL_TYPE_ACCESS);
311 if (IS_ERR(acl) || !acl)
312 return PTR_ERR(acl);
313 256
314 error = posix_acl_chmod(&acl, GFP_KERNEL, mode); 257 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
315 if (error) 258 if (error)
316 return error; 259 return error;
317 260
318 error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl, NULL); 261 if (default_acl) {
319 posix_acl_release(acl); 262 error = __f2fs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl,
320 return error; 263 ipage);
321} 264 posix_acl_release(default_acl);
322 265 }
323static size_t f2fs_xattr_list_acl(struct dentry *dentry, char *list, 266 if (acl) {
324 size_t list_size, const char *name, size_t name_len, int type) 267 if (error)
325{ 268 error = __f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl,
326 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); 269 ipage);
327 const char *xname = POSIX_ACL_XATTR_DEFAULT; 270 posix_acl_release(acl);
328 size_t size;
329
330 if (!test_opt(sbi, POSIX_ACL))
331 return 0;
332
333 if (type == ACL_TYPE_ACCESS)
334 xname = POSIX_ACL_XATTR_ACCESS;
335
336 size = strlen(xname) + 1;
337 if (list && size <= list_size)
338 memcpy(list, xname, size);
339 return size;
340}
341
342static int f2fs_xattr_get_acl(struct dentry *dentry, const char *name,
343 void *buffer, size_t size, int type)
344{
345 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
346 struct posix_acl *acl;
347 int error;
348
349 if (strcmp(name, "") != 0)
350 return -EINVAL;
351 if (!test_opt(sbi, POSIX_ACL))
352 return -EOPNOTSUPP;
353
354 acl = f2fs_get_acl(dentry->d_inode, type);
355 if (IS_ERR(acl))
356 return PTR_ERR(acl);
357 if (!acl)
358 return -ENODATA;
359 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
360 posix_acl_release(acl);
361
362 return error;
363}
364
365static int f2fs_xattr_set_acl(struct dentry *dentry, const char *name,
366 const void *value, size_t size, int flags, int type)
367{
368 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
369 struct inode *inode = dentry->d_inode;
370 struct posix_acl *acl = NULL;
371 int error;
372
373 if (strcmp(name, "") != 0)
374 return -EINVAL;
375 if (!test_opt(sbi, POSIX_ACL))
376 return -EOPNOTSUPP;
377 if (!inode_owner_or_capable(inode))
378 return -EPERM;
379
380 if (value) {
381 acl = posix_acl_from_xattr(&init_user_ns, value, size);
382 if (IS_ERR(acl))
383 return PTR_ERR(acl);
384 if (acl) {
385 error = posix_acl_valid(acl);
386 if (error)
387 goto release_and_out;
388 }
389 } else {
390 acl = NULL;
391 } 271 }
392 272
393 error = f2fs_set_acl(inode, type, acl, NULL);
394
395release_and_out:
396 posix_acl_release(acl);
397 return error; 273 return error;
398} 274}
399
400const struct xattr_handler f2fs_xattr_acl_default_handler = {
401 .prefix = POSIX_ACL_XATTR_DEFAULT,
402 .flags = ACL_TYPE_DEFAULT,
403 .list = f2fs_xattr_list_acl,
404 .get = f2fs_xattr_get_acl,
405 .set = f2fs_xattr_set_acl,
406};
407
408const struct xattr_handler f2fs_xattr_acl_access_handler = {
409 .prefix = POSIX_ACL_XATTR_ACCESS,
410 .flags = ACL_TYPE_ACCESS,
411 .list = f2fs_xattr_list_acl,
412 .get = f2fs_xattr_get_acl,
413 .set = f2fs_xattr_set_acl,
414};
diff --git a/fs/f2fs/acl.h b/fs/f2fs/acl.h
index 49633131e038..e0864651cdc1 100644
--- a/fs/f2fs/acl.h
+++ b/fs/f2fs/acl.h
@@ -37,18 +37,13 @@ struct f2fs_acl_header {
37#ifdef CONFIG_F2FS_FS_POSIX_ACL 37#ifdef CONFIG_F2FS_FS_POSIX_ACL
38 38
39extern struct posix_acl *f2fs_get_acl(struct inode *, int); 39extern struct posix_acl *f2fs_get_acl(struct inode *, int);
40extern int f2fs_acl_chmod(struct inode *); 40extern int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
41extern int f2fs_init_acl(struct inode *, struct inode *, struct page *); 41extern int f2fs_init_acl(struct inode *, struct inode *, struct page *);
42#else 42#else
43#define f2fs_check_acl NULL 43#define f2fs_check_acl NULL
44#define f2fs_get_acl NULL 44#define f2fs_get_acl NULL
45#define f2fs_set_acl NULL 45#define f2fs_set_acl NULL
46 46
47static inline int f2fs_acl_chmod(struct inode *inode)
48{
49 return 0;
50}
51
52static inline int f2fs_init_acl(struct inode *inode, struct inode *dir, 47static inline int f2fs_init_acl(struct inode *inode, struct inode *dir,
53 struct page *page) 48 struct page *page)
54{ 49{
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index af51a0bd2dee..fc3c558cb4f3 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1023,6 +1023,10 @@ static inline int f2fs_readonly(struct super_block *sb)
1023 return sb->s_flags & MS_RDONLY; 1023 return sb->s_flags & MS_RDONLY;
1024} 1024}
1025 1025
1026#define get_inode_mode(i) \
1027 ((is_inode_flag_set(F2FS_I(i), FI_ACL_MODE)) ? \
1028 (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
1029
1026/* 1030/*
1027 * file.c 1031 * file.c
1028 */ 1032 */
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 85e91ca88d57..0dfcef53a6ed 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -382,7 +382,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
382 __setattr_copy(inode, attr); 382 __setattr_copy(inode, attr);
383 383
384 if (attr->ia_valid & ATTR_MODE) { 384 if (attr->ia_valid & ATTR_MODE) {
385 err = f2fs_acl_chmod(inode); 385 err = posix_acl_chmod(inode, get_inode_mode(inode));
386 if (err || is_inode_flag_set(fi, FI_ACL_MODE)) { 386 if (err || is_inode_flag_set(fi, FI_ACL_MODE)) {
387 inode->i_mode = fi->i_acl_mode; 387 inode->i_mode = fi->i_acl_mode;
388 clear_inode_flag(fi, FI_ACL_MODE); 388 clear_inode_flag(fi, FI_ACL_MODE);
@@ -397,6 +397,7 @@ const struct inode_operations f2fs_file_inode_operations = {
397 .getattr = f2fs_getattr, 397 .getattr = f2fs_getattr,
398 .setattr = f2fs_setattr, 398 .setattr = f2fs_setattr,
399 .get_acl = f2fs_get_acl, 399 .get_acl = f2fs_get_acl,
400 .set_acl = f2fs_set_acl,
400#ifdef CONFIG_F2FS_FS_XATTR 401#ifdef CONFIG_F2FS_FS_XATTR
401 .setxattr = generic_setxattr, 402 .setxattr = generic_setxattr,
402 .getxattr = generic_getxattr, 403 .getxattr = generic_getxattr,
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 3d32f2969c5e..397d459e97bf 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -501,6 +501,7 @@ const struct inode_operations f2fs_dir_inode_operations = {
501 .getattr = f2fs_getattr, 501 .getattr = f2fs_getattr,
502 .setattr = f2fs_setattr, 502 .setattr = f2fs_setattr,
503 .get_acl = f2fs_get_acl, 503 .get_acl = f2fs_get_acl,
504 .set_acl = f2fs_set_acl,
504#ifdef CONFIG_F2FS_FS_XATTR 505#ifdef CONFIG_F2FS_FS_XATTR
505 .setxattr = generic_setxattr, 506 .setxattr = generic_setxattr,
506 .getxattr = generic_getxattr, 507 .getxattr = generic_getxattr,
@@ -527,6 +528,7 @@ const struct inode_operations f2fs_special_inode_operations = {
527 .getattr = f2fs_getattr, 528 .getattr = f2fs_getattr,
528 .setattr = f2fs_setattr, 529 .setattr = f2fs_setattr,
529 .get_acl = f2fs_get_acl, 530 .get_acl = f2fs_get_acl,
531 .set_acl = f2fs_set_acl,
530#ifdef CONFIG_F2FS_FS_XATTR 532#ifdef CONFIG_F2FS_FS_XATTR
531 .setxattr = generic_setxattr, 533 .setxattr = generic_setxattr,
532 .getxattr = generic_getxattr, 534 .getxattr = generic_getxattr,
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index b0fb8a27f3da..89d0422a91a8 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -21,6 +21,7 @@
21#include <linux/rwsem.h> 21#include <linux/rwsem.h>
22#include <linux/f2fs_fs.h> 22#include <linux/f2fs_fs.h>
23#include <linux/security.h> 23#include <linux/security.h>
24#include <linux/posix_acl_xattr.h>
24#include "f2fs.h" 25#include "f2fs.h"
25#include "xattr.h" 26#include "xattr.h"
26 27
@@ -216,8 +217,8 @@ const struct xattr_handler f2fs_xattr_security_handler = {
216static const struct xattr_handler *f2fs_xattr_handler_map[] = { 217static const struct xattr_handler *f2fs_xattr_handler_map[] = {
217 [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler, 218 [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
218#ifdef CONFIG_F2FS_FS_POSIX_ACL 219#ifdef CONFIG_F2FS_FS_POSIX_ACL
219 [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &f2fs_xattr_acl_access_handler, 220 [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
220 [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler, 221 [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
221#endif 222#endif
222 [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler, 223 [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
223#ifdef CONFIG_F2FS_FS_SECURITY 224#ifdef CONFIG_F2FS_FS_SECURITY
@@ -229,8 +230,8 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] = {
229const struct xattr_handler *f2fs_xattr_handlers[] = { 230const struct xattr_handler *f2fs_xattr_handlers[] = {
230 &f2fs_xattr_user_handler, 231 &f2fs_xattr_user_handler,
231#ifdef CONFIG_F2FS_FS_POSIX_ACL 232#ifdef CONFIG_F2FS_FS_POSIX_ACL
232 &f2fs_xattr_acl_access_handler, 233 &posix_acl_access_xattr_handler,
233 &f2fs_xattr_acl_default_handler, 234 &posix_acl_default_xattr_handler,
234#endif 235#endif
235 &f2fs_xattr_trusted_handler, 236 &f2fs_xattr_trusted_handler,
236#ifdef CONFIG_F2FS_FS_SECURITY 237#ifdef CONFIG_F2FS_FS_SECURITY
diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h
index 02a08fb88a15..b21d9ebdeff3 100644
--- a/fs/f2fs/xattr.h
+++ b/fs/f2fs/xattr.h
@@ -108,8 +108,6 @@ struct f2fs_xattr_entry {
108#ifdef CONFIG_F2FS_FS_XATTR 108#ifdef CONFIG_F2FS_FS_XATTR
109extern const struct xattr_handler f2fs_xattr_user_handler; 109extern const struct xattr_handler f2fs_xattr_user_handler;
110extern const struct xattr_handler f2fs_xattr_trusted_handler; 110extern const struct xattr_handler f2fs_xattr_trusted_handler;
111extern const struct xattr_handler f2fs_xattr_acl_access_handler;
112extern const struct xattr_handler f2fs_xattr_acl_default_handler;
113extern const struct xattr_handler f2fs_xattr_advise_handler; 111extern const struct xattr_handler f2fs_xattr_advise_handler;
114extern const struct xattr_handler f2fs_xattr_security_handler; 112extern const struct xattr_handler f2fs_xattr_security_handler;
115 113
diff --git a/fs/file.c b/fs/file.c
index 4a78f981557a..771578b33fb6 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -348,21 +348,16 @@ out:
348 return NULL; 348 return NULL;
349} 349}
350 350
351static void close_files(struct files_struct * files) 351static struct fdtable *close_files(struct files_struct * files)
352{ 352{
353 int i, j;
354 struct fdtable *fdt;
355
356 j = 0;
357
358 /* 353 /*
359 * It is safe to dereference the fd table without RCU or 354 * It is safe to dereference the fd table without RCU or
360 * ->file_lock because this is the last reference to the 355 * ->file_lock because this is the last reference to the
361 * files structure. But use RCU to shut RCU-lockdep up. 356 * files structure.
362 */ 357 */
363 rcu_read_lock(); 358 struct fdtable *fdt = rcu_dereference_raw(files->fdt);
364 fdt = files_fdtable(files); 359 int i, j = 0;
365 rcu_read_unlock(); 360
366 for (;;) { 361 for (;;) {
367 unsigned long set; 362 unsigned long set;
368 i = j * BITS_PER_LONG; 363 i = j * BITS_PER_LONG;
@@ -381,6 +376,8 @@ static void close_files(struct files_struct * files)
381 set >>= 1; 376 set >>= 1;
382 } 377 }
383 } 378 }
379
380 return fdt;
384} 381}
385 382
386struct files_struct *get_files_struct(struct task_struct *task) 383struct files_struct *get_files_struct(struct task_struct *task)
@@ -398,14 +395,9 @@ struct files_struct *get_files_struct(struct task_struct *task)
398 395
399void put_files_struct(struct files_struct *files) 396void put_files_struct(struct files_struct *files)
400{ 397{
401 struct fdtable *fdt;
402
403 if (atomic_dec_and_test(&files->count)) { 398 if (atomic_dec_and_test(&files->count)) {
404 close_files(files); 399 struct fdtable *fdt = close_files(files);
405 /* not really needed, since nobody can see us */ 400
406 rcu_read_lock();
407 fdt = files_fdtable(files);
408 rcu_read_unlock();
409 /* free the arrays if they are not embedded */ 401 /* free the arrays if they are not embedded */
410 if (fdt != &files->fdtab) 402 if (fdt != &files->fdtab)
411 __free_fdtable(fdt); 403 __free_fdtable(fdt);
@@ -645,16 +637,16 @@ void do_close_on_exec(struct files_struct *files)
645 spin_unlock(&files->file_lock); 637 spin_unlock(&files->file_lock);
646} 638}
647 639
648struct file *fget(unsigned int fd) 640static struct file *__fget(unsigned int fd, fmode_t mask)
649{ 641{
650 struct file *file;
651 struct files_struct *files = current->files; 642 struct files_struct *files = current->files;
643 struct file *file;
652 644
653 rcu_read_lock(); 645 rcu_read_lock();
654 file = fcheck_files(files, fd); 646 file = fcheck_files(files, fd);
655 if (file) { 647 if (file) {
656 /* File object ref couldn't be taken */ 648 /* File object ref couldn't be taken */
657 if (file->f_mode & FMODE_PATH || 649 if ((file->f_mode & mask) ||
658 !atomic_long_inc_not_zero(&file->f_count)) 650 !atomic_long_inc_not_zero(&file->f_count))
659 file = NULL; 651 file = NULL;
660 } 652 }
@@ -663,25 +655,16 @@ struct file *fget(unsigned int fd)
663 return file; 655 return file;
664} 656}
665 657
658struct file *fget(unsigned int fd)
659{
660 return __fget(fd, FMODE_PATH);
661}
666EXPORT_SYMBOL(fget); 662EXPORT_SYMBOL(fget);
667 663
668struct file *fget_raw(unsigned int fd) 664struct file *fget_raw(unsigned int fd)
669{ 665{
670 struct file *file; 666 return __fget(fd, 0);
671 struct files_struct *files = current->files;
672
673 rcu_read_lock();
674 file = fcheck_files(files, fd);
675 if (file) {
676 /* File object ref couldn't be taken */
677 if (!atomic_long_inc_not_zero(&file->f_count))
678 file = NULL;
679 }
680 rcu_read_unlock();
681
682 return file;
683} 667}
684
685EXPORT_SYMBOL(fget_raw); 668EXPORT_SYMBOL(fget_raw);
686 669
687/* 670/*
@@ -700,56 +683,33 @@ EXPORT_SYMBOL(fget_raw);
700 * The fput_needed flag returned by fget_light should be passed to the 683 * The fput_needed flag returned by fget_light should be passed to the
701 * corresponding fput_light. 684 * corresponding fput_light.
702 */ 685 */
703struct file *fget_light(unsigned int fd, int *fput_needed) 686struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed)
704{ 687{
705 struct file *file;
706 struct files_struct *files = current->files; 688 struct files_struct *files = current->files;
689 struct file *file;
707 690
708 *fput_needed = 0; 691 *fput_needed = 0;
709 if (atomic_read(&files->count) == 1) { 692 if (atomic_read(&files->count) == 1) {
710 file = fcheck_files(files, fd); 693 file = __fcheck_files(files, fd);
711 if (file && (file->f_mode & FMODE_PATH)) 694 if (file && (file->f_mode & mask))
712 file = NULL; 695 file = NULL;
713 } else { 696 } else {
714 rcu_read_lock(); 697 file = __fget(fd, mask);
715 file = fcheck_files(files, fd); 698 if (file)
716 if (file) { 699 *fput_needed = 1;
717 if (!(file->f_mode & FMODE_PATH) &&
718 atomic_long_inc_not_zero(&file->f_count))
719 *fput_needed = 1;
720 else
721 /* Didn't get the reference, someone's freed */
722 file = NULL;
723 }
724 rcu_read_unlock();
725 } 700 }
726 701
727 return file; 702 return file;
728} 703}
704struct file *fget_light(unsigned int fd, int *fput_needed)
705{
706 return __fget_light(fd, FMODE_PATH, fput_needed);
707}
729EXPORT_SYMBOL(fget_light); 708EXPORT_SYMBOL(fget_light);
730 709
731struct file *fget_raw_light(unsigned int fd, int *fput_needed) 710struct file *fget_raw_light(unsigned int fd, int *fput_needed)
732{ 711{
733 struct file *file; 712 return __fget_light(fd, 0, fput_needed);
734 struct files_struct *files = current->files;
735
736 *fput_needed = 0;
737 if (atomic_read(&files->count) == 1) {
738 file = fcheck_files(files, fd);
739 } else {
740 rcu_read_lock();
741 file = fcheck_files(files, fd);
742 if (file) {
743 if (atomic_long_inc_not_zero(&file->f_count))
744 *fput_needed = 1;
745 else
746 /* Didn't get the reference, someone's freed */
747 file = NULL;
748 }
749 rcu_read_unlock();
750 }
751
752 return file;
753} 713}
754 714
755void set_close_on_exec(unsigned int fd, int flag) 715void set_close_on_exec(unsigned int fd, int flag)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 74f6ca500504..77bcc303c3ae 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2727,6 +2727,9 @@ fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
2727 inode = file->f_mapping->host; 2727 inode = file->f_mapping->host;
2728 i_size = i_size_read(inode); 2728 i_size = i_size_read(inode);
2729 2729
2730 if ((rw == READ) && (offset > i_size))
2731 return 0;
2732
2730 /* optimization for short read */ 2733 /* optimization for short read */
2731 if (async_dio && rw != WRITE && offset + count > i_size) { 2734 if (async_dio && rw != WRITE && offset + count > i_size) {
2732 if (offset >= i_size) 2735 if (offset >= i_size)
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
deleted file mode 100644
index b3f3676796d3..000000000000
--- a/fs/generic_acl.c
+++ /dev/null
@@ -1,184 +0,0 @@
1/*
2 * (C) 2005 Andreas Gruenbacher <agruen@suse.de>
3 *
4 * This file is released under the GPL.
5 *
6 * Generic ACL support for in-memory filesystems.
7 */
8
9#include <linux/sched.h>
10#include <linux/gfp.h>
11#include <linux/fs.h>
12#include <linux/generic_acl.h>
13#include <linux/posix_acl.h>
14#include <linux/posix_acl_xattr.h>
15
16
17static size_t
18generic_acl_list(struct dentry *dentry, char *list, size_t list_size,
19 const char *name, size_t name_len, int type)
20{
21 struct posix_acl *acl;
22 const char *xname;
23 size_t size;
24
25 acl = get_cached_acl(dentry->d_inode, type);
26 if (!acl)
27 return 0;
28 posix_acl_release(acl);
29
30 switch (type) {
31 case ACL_TYPE_ACCESS:
32 xname = POSIX_ACL_XATTR_ACCESS;
33 break;
34 case ACL_TYPE_DEFAULT:
35 xname = POSIX_ACL_XATTR_DEFAULT;
36 break;
37 default:
38 return 0;
39 }
40 size = strlen(xname) + 1;
41 if (list && size <= list_size)
42 memcpy(list, xname, size);
43 return size;
44}
45
46static int
47generic_acl_get(struct dentry *dentry, const char *name, void *buffer,
48 size_t size, int type)
49{
50 struct posix_acl *acl;
51 int error;
52
53 if (strcmp(name, "") != 0)
54 return -EINVAL;
55
56 acl = get_cached_acl(dentry->d_inode, type);
57 if (!acl)
58 return -ENODATA;
59 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
60 posix_acl_release(acl);
61
62 return error;
63}
64
65static int
66generic_acl_set(struct dentry *dentry, const char *name, const void *value,
67 size_t size, int flags, int type)
68{
69 struct inode *inode = dentry->d_inode;
70 struct posix_acl *acl = NULL;
71 int error;
72
73 if (strcmp(name, "") != 0)
74 return -EINVAL;
75 if (S_ISLNK(inode->i_mode))
76 return -EOPNOTSUPP;
77 if (!inode_owner_or_capable(inode))
78 return -EPERM;
79 if (value) {
80 acl = posix_acl_from_xattr(&init_user_ns, value, size);
81 if (IS_ERR(acl))
82 return PTR_ERR(acl);
83 }
84 if (acl) {
85 error = posix_acl_valid(acl);
86 if (error)
87 goto failed;
88 switch (type) {
89 case ACL_TYPE_ACCESS:
90 error = posix_acl_equiv_mode(acl, &inode->i_mode);
91 if (error < 0)
92 goto failed;
93 inode->i_ctime = CURRENT_TIME;
94 if (error == 0) {
95 posix_acl_release(acl);
96 acl = NULL;
97 }
98 break;
99 case ACL_TYPE_DEFAULT:
100 if (!S_ISDIR(inode->i_mode)) {
101 error = -EINVAL;
102 goto failed;
103 }
104 break;
105 }
106 }
107 set_cached_acl(inode, type, acl);
108 error = 0;
109failed:
110 posix_acl_release(acl);
111 return error;
112}
113
114/**
115 * generic_acl_init - Take care of acl inheritance at @inode create time
116 *
117 * Files created inside a directory with a default ACL inherit the
118 * directory's default ACL.
119 */
120int
121generic_acl_init(struct inode *inode, struct inode *dir)
122{
123 struct posix_acl *acl = NULL;
124 int error;
125
126 if (!S_ISLNK(inode->i_mode))
127 acl = get_cached_acl(dir, ACL_TYPE_DEFAULT);
128 if (acl) {
129 if (S_ISDIR(inode->i_mode))
130 set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
131 error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
132 if (error < 0)
133 return error;
134 if (error > 0)
135 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
136 } else {
137 inode->i_mode &= ~current_umask();
138 }
139 error = 0;
140
141 posix_acl_release(acl);
142 return error;
143}
144
145/**
146 * generic_acl_chmod - change the access acl of @inode upon chmod()
147 *
148 * A chmod also changes the permissions of the owner, group/mask, and
149 * other ACL entries.
150 */
151int
152generic_acl_chmod(struct inode *inode)
153{
154 struct posix_acl *acl;
155 int error = 0;
156
157 if (S_ISLNK(inode->i_mode))
158 return -EOPNOTSUPP;
159 acl = get_cached_acl(inode, ACL_TYPE_ACCESS);
160 if (acl) {
161 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
162 if (error)
163 return error;
164 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
165 posix_acl_release(acl);
166 }
167 return error;
168}
169
170const struct xattr_handler generic_acl_access_handler = {
171 .prefix = POSIX_ACL_XATTR_ACCESS,
172 .flags = ACL_TYPE_ACCESS,
173 .list = generic_acl_list,
174 .get = generic_acl_get,
175 .set = generic_acl_set,
176};
177
178const struct xattr_handler generic_acl_default_handler = {
179 .prefix = POSIX_ACL_XATTR_DEFAULT,
180 .flags = ACL_TYPE_DEFAULT,
181 .list = generic_acl_list,
182 .get = generic_acl_get,
183 .set = generic_acl_set,
184};
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index f69ac0af5496..ba9456685f47 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -49,10 +49,6 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
49 if (!ip->i_eattr) 49 if (!ip->i_eattr)
50 return NULL; 50 return NULL;
51 51
52 acl = get_cached_acl(&ip->i_inode, type);
53 if (acl != ACL_NOT_CACHED)
54 return acl;
55
56 name = gfs2_acl_name(type); 52 name = gfs2_acl_name(type);
57 if (name == NULL) 53 if (name == NULL)
58 return ERR_PTR(-EINVAL); 54 return ERR_PTR(-EINVAL);
@@ -80,7 +76,7 @@ static int gfs2_set_mode(struct inode *inode, umode_t mode)
80 return error; 76 return error;
81} 77}
82 78
83static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl) 79int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
84{ 80{
85 int error; 81 int error;
86 int len; 82 int len;
@@ -88,219 +84,49 @@ static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl)
88 const char *name = gfs2_acl_name(type); 84 const char *name = gfs2_acl_name(type);
89 85
90 BUG_ON(name == NULL); 86 BUG_ON(name == NULL);
91 len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
92 if (len == 0)
93 return 0;
94 data = kmalloc(len, GFP_NOFS);
95 if (data == NULL)
96 return -ENOMEM;
97 error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
98 if (error < 0)
99 goto out;
100 error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
101 if (!error)
102 set_cached_acl(inode, type, acl);
103out:
104 kfree(data);
105 return error;
106}
107
108int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
109{
110 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
111 struct posix_acl *acl;
112 umode_t mode = inode->i_mode;
113 int error = 0;
114
115 if (!sdp->sd_args.ar_posix_acl)
116 return 0;
117 if (S_ISLNK(inode->i_mode))
118 return 0;
119
120 acl = gfs2_get_acl(&dip->i_inode, ACL_TYPE_DEFAULT);
121 if (IS_ERR(acl))
122 return PTR_ERR(acl);
123 if (!acl) {
124 mode &= ~current_umask();
125 return gfs2_set_mode(inode, mode);
126 }
127
128 if (S_ISDIR(inode->i_mode)) {
129 error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl);
130 if (error)
131 goto out;
132 }
133
134 error = posix_acl_create(&acl, GFP_NOFS, &mode);
135 if (error < 0)
136 return error;
137 87
138 if (error == 0)
139 goto munge;
140
141 error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl);
142 if (error)
143 goto out;
144munge:
145 error = gfs2_set_mode(inode, mode);
146out:
147 posix_acl_release(acl);
148 return error;
149}
150
151int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
152{
153 struct inode *inode = &ip->i_inode;
154 struct posix_acl *acl;
155 char *data;
156 unsigned int len;
157 int error;
158
159 acl = gfs2_get_acl(&ip->i_inode, ACL_TYPE_ACCESS);
160 if (IS_ERR(acl))
161 return PTR_ERR(acl);
162 if (!acl)
163 return gfs2_setattr_simple(inode, attr);
164
165 error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode);
166 if (error)
167 return error;
168
169 len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
170 data = kmalloc(len, GFP_NOFS);
171 error = -ENOMEM;
172 if (data == NULL)
173 goto out;
174 posix_acl_to_xattr(&init_user_ns, acl, data, len);
175 error = gfs2_xattr_acl_chmod(ip, attr, data);
176 kfree(data);
177 set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
178
179out:
180 posix_acl_release(acl);
181 return error;
182}
183
184static int gfs2_acl_type(const char *name)
185{
186 if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0)
187 return ACL_TYPE_ACCESS;
188 if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0)
189 return ACL_TYPE_DEFAULT;
190 return -EINVAL;
191}
192
193static int gfs2_xattr_system_get(struct dentry *dentry, const char *name,
194 void *buffer, size_t size, int xtype)
195{
196 struct inode *inode = dentry->d_inode;
197 struct gfs2_sbd *sdp = GFS2_SB(inode);
198 struct posix_acl *acl;
199 int type;
200 int error;
201
202 if (!sdp->sd_args.ar_posix_acl)
203 return -EOPNOTSUPP;
204
205 type = gfs2_acl_type(name);
206 if (type < 0)
207 return type;
208
209 acl = gfs2_get_acl(inode, type);
210 if (IS_ERR(acl))
211 return PTR_ERR(acl);
212 if (acl == NULL)
213 return -ENODATA;
214
215 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
216 posix_acl_release(acl);
217
218 return error;
219}
220
221static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
222 const void *value, size_t size, int flags,
223 int xtype)
224{
225 struct inode *inode = dentry->d_inode;
226 struct gfs2_sbd *sdp = GFS2_SB(inode);
227 struct posix_acl *acl = NULL;
228 int error = 0, type;
229
230 if (!sdp->sd_args.ar_posix_acl)
231 return -EOPNOTSUPP;
232
233 type = gfs2_acl_type(name);
234 if (type < 0)
235 return type;
236 if (flags & XATTR_CREATE)
237 return -EINVAL;
238 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
239 return value ? -EACCES : 0;
240 if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_FOWNER))
241 return -EPERM;
242 if (S_ISLNK(inode->i_mode))
243 return -EOPNOTSUPP;
244
245 if (!value)
246 goto set_acl;
247
248 acl = posix_acl_from_xattr(&init_user_ns, value, size);
249 if (!acl) {
250 /*
251 * acl_set_file(3) may request that we set default ACLs with
252 * zero length -- defend (gracefully) against that here.
253 */
254 goto out;
255 }
256 if (IS_ERR(acl)) {
257 error = PTR_ERR(acl);
258 goto out;
259 }
260
261 error = posix_acl_valid(acl);
262 if (error)
263 goto out_release;
264
265 error = -EINVAL;
266 if (acl->a_count > GFS2_ACL_MAX_ENTRIES) 88 if (acl->a_count > GFS2_ACL_MAX_ENTRIES)
267 goto out_release; 89 return -EINVAL;
268 90
269 if (type == ACL_TYPE_ACCESS) { 91 if (type == ACL_TYPE_ACCESS) {
270 umode_t mode = inode->i_mode; 92 umode_t mode = inode->i_mode;
93
271 error = posix_acl_equiv_mode(acl, &mode); 94 error = posix_acl_equiv_mode(acl, &mode);
95 if (error < 0)
96 return error;
272 97
273 if (error <= 0) { 98 if (error == 0)
274 posix_acl_release(acl);
275 acl = NULL; 99 acl = NULL;
276 100
277 if (error < 0)
278 return error;
279 }
280
281 error = gfs2_set_mode(inode, mode); 101 error = gfs2_set_mode(inode, mode);
282 if (error) 102 if (error)
283 goto out_release; 103 return error;
284 } 104 }
285 105
286set_acl: 106 if (acl) {
287 error = __gfs2_xattr_set(inode, name, value, size, 0, GFS2_EATYPE_SYS); 107 len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0);
288 if (!error) { 108 if (len == 0)
289 if (acl) 109 return 0;
290 set_cached_acl(inode, type, acl); 110 data = kmalloc(len, GFP_NOFS);
291 else 111 if (data == NULL)
292 forget_cached_acl(inode, type); 112 return -ENOMEM;
113 error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
114 if (error < 0)
115 goto out;
116 } else {
117 data = NULL;
118 len = 0;
293 } 119 }
294out_release: 120
295 posix_acl_release(acl); 121 error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
122 if (error)
123 goto out;
124
125 if (acl)
126 set_cached_acl(inode, type, acl);
127 else
128 forget_cached_acl(inode, type);
296out: 129out:
130 kfree(data);
297 return error; 131 return error;
298} 132}
299
300const struct xattr_handler gfs2_xattr_system_handler = {
301 .prefix = XATTR_SYSTEM_PREFIX,
302 .flags = GFS2_EATYPE_SYS,
303 .get = gfs2_xattr_system_get,
304 .set = gfs2_xattr_system_set,
305};
306
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h
index 0da38dc7efec..301260c999ba 100644
--- a/fs/gfs2/acl.h
+++ b/fs/gfs2/acl.h
@@ -17,8 +17,6 @@
17#define GFS2_ACL_MAX_ENTRIES 25 17#define GFS2_ACL_MAX_ENTRIES 25
18 18
19extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); 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_set_acl(struct inode *inode, struct posix_acl *acl, int type);
21extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
22extern const struct xattr_handler gfs2_xattr_system_handler;
23 21
24#endif /* __ACL_DOT_H__ */ 22#endif /* __ACL_DOT_H__ */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 890588c7fb33..5c524180c98e 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -571,6 +571,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
571 unsigned int size, int excl, int *opened) 571 unsigned int size, int excl, int *opened)
572{ 572{
573 const struct qstr *name = &dentry->d_name; 573 const struct qstr *name = &dentry->d_name;
574 struct posix_acl *default_acl, *acl;
574 struct gfs2_holder ghs[2]; 575 struct gfs2_holder ghs[2];
575 struct inode *inode = NULL; 576 struct inode *inode = NULL;
576 struct gfs2_inode *dip = GFS2_I(dir), *ip; 577 struct gfs2_inode *dip = GFS2_I(dir), *ip;
@@ -633,10 +634,14 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
633 if (!inode) 634 if (!inode)
634 goto fail_gunlock; 635 goto fail_gunlock;
635 636
637 error = posix_acl_create(dir, &mode, &default_acl, &acl);
638 if (error)
639 goto fail_free_vfs_inode;
640
636 ip = GFS2_I(inode); 641 ip = GFS2_I(inode);
637 error = gfs2_rs_alloc(ip); 642 error = gfs2_rs_alloc(ip);
638 if (error) 643 if (error)
639 goto fail_free_inode; 644 goto fail_free_acls;
640 645
641 inode->i_mode = mode; 646 inode->i_mode = mode;
642 set_nlink(inode, S_ISDIR(mode) ? 2 : 1); 647 set_nlink(inode, S_ISDIR(mode) ? 2 : 1);
@@ -704,7 +709,16 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
704 gfs2_set_iop(inode); 709 gfs2_set_iop(inode);
705 insert_inode_hash(inode); 710 insert_inode_hash(inode);
706 711
707 error = gfs2_acl_create(dip, inode); 712 if (default_acl) {
713 error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
714 posix_acl_release(default_acl);
715 }
716 if (acl) {
717 if (!error)
718 error = gfs2_set_acl(inode, acl, ACL_TYPE_ACCESS);
719 posix_acl_release(acl);
720 }
721
708 if (error) 722 if (error)
709 goto fail_gunlock3; 723 goto fail_gunlock3;
710 724
@@ -738,6 +752,12 @@ fail_free_inode:
738 if (ip->i_gl) 752 if (ip->i_gl)
739 gfs2_glock_put(ip->i_gl); 753 gfs2_glock_put(ip->i_gl);
740 gfs2_rs_delete(ip, NULL); 754 gfs2_rs_delete(ip, NULL);
755fail_free_acls:
756 if (default_acl)
757 posix_acl_release(default_acl);
758 if (acl)
759 posix_acl_release(acl);
760fail_free_vfs_inode:
741 free_inode_nonrcu(inode); 761 free_inode_nonrcu(inode);
742 inode = NULL; 762 inode = NULL;
743fail_gunlock: 763fail_gunlock:
@@ -1716,10 +1736,11 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
1716 error = gfs2_setattr_size(inode, attr->ia_size); 1736 error = gfs2_setattr_size(inode, attr->ia_size);
1717 else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) 1737 else if (attr->ia_valid & (ATTR_UID | ATTR_GID))
1718 error = setattr_chown(inode, attr); 1738 error = setattr_chown(inode, attr);
1719 else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) 1739 else {
1720 error = gfs2_acl_chmod(ip, attr);
1721 else
1722 error = gfs2_setattr_simple(inode, attr); 1740 error = gfs2_setattr_simple(inode, attr);
1741 if (!error && attr->ia_valid & ATTR_MODE)
1742 error = posix_acl_chmod(inode, inode->i_mode);
1743 }
1723 1744
1724out: 1745out:
1725 if (!error) 1746 if (!error)
@@ -1879,6 +1900,7 @@ const struct inode_operations gfs2_file_iops = {
1879 .removexattr = gfs2_removexattr, 1900 .removexattr = gfs2_removexattr,
1880 .fiemap = gfs2_fiemap, 1901 .fiemap = gfs2_fiemap,
1881 .get_acl = gfs2_get_acl, 1902 .get_acl = gfs2_get_acl,
1903 .set_acl = gfs2_set_acl,
1882}; 1904};
1883 1905
1884const struct inode_operations gfs2_dir_iops = { 1906const struct inode_operations gfs2_dir_iops = {
@@ -1900,6 +1922,7 @@ const struct inode_operations gfs2_dir_iops = {
1900 .removexattr = gfs2_removexattr, 1922 .removexattr = gfs2_removexattr,
1901 .fiemap = gfs2_fiemap, 1923 .fiemap = gfs2_fiemap,
1902 .get_acl = gfs2_get_acl, 1924 .get_acl = gfs2_get_acl,
1925 .set_acl = gfs2_set_acl,
1903 .atomic_open = gfs2_atomic_open, 1926 .atomic_open = gfs2_atomic_open,
1904}; 1927};
1905 1928
@@ -1915,6 +1938,5 @@ const struct inode_operations gfs2_symlink_iops = {
1915 .listxattr = gfs2_listxattr, 1938 .listxattr = gfs2_listxattr,
1916 .removexattr = gfs2_removexattr, 1939 .removexattr = gfs2_removexattr,
1917 .fiemap = gfs2_fiemap, 1940 .fiemap = gfs2_fiemap,
1918 .get_acl = gfs2_get_acl,
1919}; 1941};
1920 1942
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 8c6a6f6bdba9..0b81f783f787 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -13,6 +13,7 @@
13#include <linux/buffer_head.h> 13#include <linux/buffer_head.h>
14#include <linux/xattr.h> 14#include <linux/xattr.h>
15#include <linux/gfs2_ondisk.h> 15#include <linux/gfs2_ondisk.h>
16#include <linux/posix_acl_xattr.h>
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17 18
18#include "gfs2.h" 19#include "gfs2.h"
@@ -1500,7 +1501,8 @@ static const struct xattr_handler gfs2_xattr_security_handler = {
1500const struct xattr_handler *gfs2_xattr_handlers[] = { 1501const struct xattr_handler *gfs2_xattr_handlers[] = {
1501 &gfs2_xattr_user_handler, 1502 &gfs2_xattr_user_handler,
1502 &gfs2_xattr_security_handler, 1503 &gfs2_xattr_security_handler,
1503 &gfs2_xattr_system_handler, 1504 &posix_acl_access_xattr_handler,
1505 &posix_acl_default_xattr_handler,
1504 NULL, 1506 NULL,
1505}; 1507};
1506 1508
diff --git a/fs/hfsplus/acl.h b/fs/hfsplus/acl.h
index 07c0d4947527..95c8ed9ec17f 100644
--- a/fs/hfsplus/acl.h
+++ b/fs/hfsplus/acl.h
@@ -12,16 +12,13 @@
12 12
13/* posix_acl.c */ 13/* posix_acl.c */
14struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type); 14struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type);
15extern int hfsplus_posix_acl_chmod(struct inode *); 15int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
16 int type);
16extern int hfsplus_init_posix_acl(struct inode *, struct inode *); 17extern int hfsplus_init_posix_acl(struct inode *, struct inode *);
17 18
18#else /* CONFIG_HFSPLUS_FS_POSIX_ACL */ 19#else /* CONFIG_HFSPLUS_FS_POSIX_ACL */
19#define hfsplus_get_posix_acl NULL 20#define hfsplus_get_posix_acl NULL
20 21#define hfsplus_set_posix_acl NULL
21static inline int hfsplus_posix_acl_chmod(struct inode *inode)
22{
23 return 0;
24}
25 22
26static inline int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) 23static inline int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
27{ 24{
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 4a4fea002673..9ee62985e739 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -532,6 +532,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
532 .removexattr = hfsplus_removexattr, 532 .removexattr = hfsplus_removexattr,
533#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 533#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
534 .get_acl = hfsplus_get_posix_acl, 534 .get_acl = hfsplus_get_posix_acl,
535 .set_acl = hfsplus_set_posix_acl,
535#endif 536#endif
536}; 537};
537 538
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 3ebda928229c..4551cbd6bd43 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -261,7 +261,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
261 mark_inode_dirty(inode); 261 mark_inode_dirty(inode);
262 262
263 if (attr->ia_valid & ATTR_MODE) { 263 if (attr->ia_valid & ATTR_MODE) {
264 error = hfsplus_posix_acl_chmod(inode); 264 error = posix_acl_chmod(inode, inode->i_mode);
265 if (unlikely(error)) 265 if (unlikely(error))
266 return error; 266 return error;
267 } 267 }
@@ -334,6 +334,7 @@ static const struct inode_operations hfsplus_file_inode_operations = {
334 .removexattr = hfsplus_removexattr, 334 .removexattr = hfsplus_removexattr,
335#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 335#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
336 .get_acl = hfsplus_get_posix_acl, 336 .get_acl = hfsplus_get_posix_acl,
337 .set_acl = hfsplus_set_posix_acl,
337#endif 338#endif
338}; 339};
339 340
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
index b609cc14c72e..df0c9af68d05 100644
--- a/fs/hfsplus/posix_acl.c
+++ b/fs/hfsplus/posix_acl.c
@@ -17,9 +17,7 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
17 char *value = NULL; 17 char *value = NULL;
18 ssize_t size; 18 ssize_t size;
19 19
20 acl = get_cached_acl(inode, type); 20 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
21 if (acl != ACL_NOT_CACHED)
22 return acl;
23 21
24 switch (type) { 22 switch (type) {
25 case ACL_TYPE_ACCESS: 23 case ACL_TYPE_ACCESS:
@@ -56,17 +54,15 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
56 return acl; 54 return acl;
57} 55}
58 56
59static int hfsplus_set_posix_acl(struct inode *inode, 57int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
60 int type, 58 int type)
61 struct posix_acl *acl)
62{ 59{
63 int err; 60 int err;
64 char *xattr_name; 61 char *xattr_name;
65 size_t size = 0; 62 size_t size = 0;
66 char *value = NULL; 63 char *value = NULL;
67 64
68 if (S_ISLNK(inode->i_mode)) 65 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
69 return -EOPNOTSUPP;
70 66
71 switch (type) { 67 switch (type) {
72 case ACL_TYPE_ACCESS: 68 case ACL_TYPE_ACCESS:
@@ -115,7 +111,7 @@ end_set_acl:
115int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) 111int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
116{ 112{
117 int err = 0; 113 int err = 0;
118 struct posix_acl *acl = NULL; 114 struct posix_acl *default_acl, *acl;
119 115
120 hfs_dbg(ACL_MOD, 116 hfs_dbg(ACL_MOD,
121 "[%s]: ino %lu, dir->ino %lu\n", 117 "[%s]: ino %lu, dir->ino %lu\n",
@@ -124,151 +120,21 @@ int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
124 if (S_ISLNK(inode->i_mode)) 120 if (S_ISLNK(inode->i_mode))
125 return 0; 121 return 0;
126 122
127 acl = hfsplus_get_posix_acl(dir, ACL_TYPE_DEFAULT); 123 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
128 if (IS_ERR(acl)) 124 if (err)
129 return PTR_ERR(acl);
130
131 if (acl) {
132 if (S_ISDIR(inode->i_mode)) {
133 err = hfsplus_set_posix_acl(inode,
134 ACL_TYPE_DEFAULT,
135 acl);
136 if (unlikely(err))
137 goto init_acl_cleanup;
138 }
139
140 err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
141 if (unlikely(err < 0))
142 return err;
143
144 if (err > 0)
145 err = hfsplus_set_posix_acl(inode,
146 ACL_TYPE_ACCESS,
147 acl);
148 } else
149 inode->i_mode &= ~current_umask();
150
151init_acl_cleanup:
152 posix_acl_release(acl);
153 return err;
154}
155
156int hfsplus_posix_acl_chmod(struct inode *inode)
157{
158 int err;
159 struct posix_acl *acl;
160
161 hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
162
163 if (S_ISLNK(inode->i_mode))
164 return -EOPNOTSUPP;
165
166 acl = hfsplus_get_posix_acl(inode, ACL_TYPE_ACCESS);
167 if (IS_ERR(acl) || !acl)
168 return PTR_ERR(acl);
169
170 err = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
171 if (unlikely(err))
172 return err; 125 return err;
173 126
174 err = hfsplus_set_posix_acl(inode, ACL_TYPE_ACCESS, acl); 127 if (default_acl) {
175 posix_acl_release(acl); 128 err = hfsplus_set_posix_acl(inode, default_acl,
176 return err; 129 ACL_TYPE_DEFAULT);
177} 130 posix_acl_release(default_acl);
178
179static int hfsplus_xattr_get_posix_acl(struct dentry *dentry,
180 const char *name,
181 void *buffer,
182 size_t size,
183 int type)
184{
185 int err = 0;
186 struct posix_acl *acl;
187
188 hfs_dbg(ACL_MOD,
189 "[%s]: ino %lu, buffer %p, size %zu, type %#x\n",
190 __func__, dentry->d_inode->i_ino, buffer, size, type);
191
192 if (strcmp(name, "") != 0)
193 return -EINVAL;
194
195 acl = hfsplus_get_posix_acl(dentry->d_inode, type);
196 if (IS_ERR(acl))
197 return PTR_ERR(acl);
198 if (acl == NULL)
199 return -ENODATA;
200
201 err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
202 posix_acl_release(acl);
203
204 return err;
205}
206
207static int hfsplus_xattr_set_posix_acl(struct dentry *dentry,
208 const char *name,
209 const void *value,
210 size_t size,
211 int flags,
212 int type)
213{
214 int err = 0;
215 struct inode *inode = dentry->d_inode;
216 struct posix_acl *acl = NULL;
217
218 hfs_dbg(ACL_MOD,
219 "[%s]: ino %lu, value %p, size %zu, flags %#x, type %#x\n",
220 __func__, inode->i_ino, value, size, flags, type);
221
222 if (strcmp(name, "") != 0)
223 return -EINVAL;
224
225 if (!inode_owner_or_capable(inode))
226 return -EPERM;
227
228 if (value) {
229 acl = posix_acl_from_xattr(&init_user_ns, value, size);
230 if (IS_ERR(acl))
231 return PTR_ERR(acl);
232 else if (acl) {
233 err = posix_acl_valid(acl);
234 if (err)
235 goto end_xattr_set_acl;
236 }
237 } 131 }
238 132
239 err = hfsplus_set_posix_acl(inode, type, acl); 133 if (acl) {
240 134 if (!err)
241end_xattr_set_acl: 135 err = hfsplus_set_posix_acl(inode, acl,
242 posix_acl_release(acl); 136 ACL_TYPE_ACCESS);
137 posix_acl_release(acl);
138 }
243 return err; 139 return err;
244} 140}
245
246static size_t hfsplus_xattr_list_posix_acl(struct dentry *dentry,
247 char *list,
248 size_t list_size,
249 const char *name,
250 size_t name_len,
251 int type)
252{
253 /*
254 * This method is not used.
255 * It is used hfsplus_listxattr() instead of generic_listxattr().
256 */
257 return -EOPNOTSUPP;
258}
259
260const struct xattr_handler hfsplus_xattr_acl_access_handler = {
261 .prefix = POSIX_ACL_XATTR_ACCESS,
262 .flags = ACL_TYPE_ACCESS,
263 .list = hfsplus_xattr_list_posix_acl,
264 .get = hfsplus_xattr_get_posix_acl,
265 .set = hfsplus_xattr_set_posix_acl,
266};
267
268const struct xattr_handler hfsplus_xattr_acl_default_handler = {
269 .prefix = POSIX_ACL_XATTR_DEFAULT,
270 .flags = ACL_TYPE_DEFAULT,
271 .list = hfsplus_xattr_list_posix_acl,
272 .get = hfsplus_xattr_get_posix_acl,
273 .set = hfsplus_xattr_set_posix_acl,
274};
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 3c6136f98c73..0b4a5c9b93c4 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include "hfsplus_fs.h" 9#include "hfsplus_fs.h"
10#include <linux/posix_acl_xattr.h>
10#include "xattr.h" 11#include "xattr.h"
11#include "acl.h" 12#include "acl.h"
12 13
@@ -15,8 +16,8 @@ const struct xattr_handler *hfsplus_xattr_handlers[] = {
15 &hfsplus_xattr_user_handler, 16 &hfsplus_xattr_user_handler,
16 &hfsplus_xattr_trusted_handler, 17 &hfsplus_xattr_trusted_handler,
17#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL 18#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
18 &hfsplus_xattr_acl_access_handler, 19 &posix_acl_access_xattr_handler,
19 &hfsplus_xattr_acl_default_handler, 20 &posix_acl_default_xattr_handler,
20#endif 21#endif
21 &hfsplus_xattr_security_handler, 22 &hfsplus_xattr_security_handler,
22 NULL 23 NULL
@@ -51,82 +52,6 @@ static inline int is_known_namespace(const char *name)
51 return true; 52 return true;
52} 53}
53 54
54static int can_set_system_xattr(struct inode *inode, const char *name,
55 const void *value, size_t size)
56{
57#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
58 struct posix_acl *acl;
59 int err;
60
61 if (!inode_owner_or_capable(inode))
62 return -EPERM;
63
64 /*
65 * POSIX_ACL_XATTR_ACCESS is tied to i_mode
66 */
67 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) {
68 acl = posix_acl_from_xattr(&init_user_ns, value, size);
69 if (IS_ERR(acl))
70 return PTR_ERR(acl);
71 if (acl) {
72 err = posix_acl_equiv_mode(acl, &inode->i_mode);
73 posix_acl_release(acl);
74 if (err < 0)
75 return err;
76 mark_inode_dirty(inode);
77 }
78 /*
79 * We're changing the ACL. Get rid of the cached one
80 */
81 forget_cached_acl(inode, ACL_TYPE_ACCESS);
82
83 return 0;
84 } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
85 acl = posix_acl_from_xattr(&init_user_ns, value, size);
86 if (IS_ERR(acl))
87 return PTR_ERR(acl);
88 posix_acl_release(acl);
89
90 /*
91 * We're changing the default ACL. Get rid of the cached one
92 */
93 forget_cached_acl(inode, ACL_TYPE_DEFAULT);
94
95 return 0;
96 }
97#endif /* CONFIG_HFSPLUS_FS_POSIX_ACL */
98 return -EOPNOTSUPP;
99}
100
101static int can_set_xattr(struct inode *inode, const char *name,
102 const void *value, size_t value_len)
103{
104 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
105 return can_set_system_xattr(inode, name, value, value_len);
106
107 if (!strncmp(name, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN)) {
108 /*
109 * This makes sure that we aren't trying to set an
110 * attribute in a different namespace by prefixing it
111 * with "osx."
112 */
113 if (is_known_namespace(name + XATTR_MAC_OSX_PREFIX_LEN))
114 return -EOPNOTSUPP;
115
116 return 0;
117 }
118
119 /*
120 * Don't allow setting an attribute in an unknown namespace.
121 */
122 if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) &&
123 strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
124 strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
125 return -EOPNOTSUPP;
126
127 return 0;
128}
129
130static void hfsplus_init_header_node(struct inode *attr_file, 55static void hfsplus_init_header_node(struct inode *attr_file,
131 u32 clump_size, 56 u32 clump_size,
132 char *buf, u16 node_size) 57 char *buf, u16 node_size)
@@ -349,10 +274,6 @@ int __hfsplus_setxattr(struct inode *inode, const char *name,
349 HFSPLUS_IS_RSRC(inode)) 274 HFSPLUS_IS_RSRC(inode))
350 return -EOPNOTSUPP; 275 return -EOPNOTSUPP;
351 276
352 err = can_set_xattr(inode, name, value, size);
353 if (err)
354 return err;
355
356 if (strncmp(name, XATTR_MAC_OSX_PREFIX, 277 if (strncmp(name, XATTR_MAC_OSX_PREFIX,
357 XATTR_MAC_OSX_PREFIX_LEN) == 0) 278 XATTR_MAC_OSX_PREFIX_LEN) == 0)
358 name += XATTR_MAC_OSX_PREFIX_LEN; 279 name += XATTR_MAC_OSX_PREFIX_LEN;
@@ -840,10 +761,6 @@ int hfsplus_removexattr(struct dentry *dentry, const char *name)
840 if (!HFSPLUS_SB(inode->i_sb)->attr_tree) 761 if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
841 return -EOPNOTSUPP; 762 return -EOPNOTSUPP;
842 763
843 err = can_set_xattr(inode, name, NULL, 0);
844 if (err)
845 return err;
846
847 if (strncmp(name, XATTR_MAC_OSX_PREFIX, 764 if (strncmp(name, XATTR_MAC_OSX_PREFIX,
848 XATTR_MAC_OSX_PREFIX_LEN) == 0) 765 XATTR_MAC_OSX_PREFIX_LEN) == 0)
849 name += XATTR_MAC_OSX_PREFIX_LEN; 766 name += XATTR_MAC_OSX_PREFIX_LEN;
@@ -940,6 +857,9 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name,
940 if (len > HFSPLUS_ATTR_MAX_STRLEN) 857 if (len > HFSPLUS_ATTR_MAX_STRLEN)
941 return -EOPNOTSUPP; 858 return -EOPNOTSUPP;
942 859
860 if (is_known_namespace(name))
861 return -EOPNOTSUPP;
862
943 strcpy(xattr_name, XATTR_MAC_OSX_PREFIX); 863 strcpy(xattr_name, XATTR_MAC_OSX_PREFIX);
944 strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name); 864 strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name);
945 865
diff --git a/fs/hfsplus/xattr.h b/fs/hfsplus/xattr.h
index 841b5698c0fc..9e214490c313 100644
--- a/fs/hfsplus/xattr.h
+++ b/fs/hfsplus/xattr.h
@@ -14,8 +14,6 @@
14extern const struct xattr_handler hfsplus_xattr_osx_handler; 14extern const struct xattr_handler hfsplus_xattr_osx_handler;
15extern const struct xattr_handler hfsplus_xattr_user_handler; 15extern const struct xattr_handler hfsplus_xattr_user_handler;
16extern const struct xattr_handler hfsplus_xattr_trusted_handler; 16extern const struct xattr_handler hfsplus_xattr_trusted_handler;
17extern const struct xattr_handler hfsplus_xattr_acl_access_handler;
18extern const struct xattr_handler hfsplus_xattr_acl_default_handler;
19extern const struct xattr_handler hfsplus_xattr_security_handler; 17extern const struct xattr_handler hfsplus_xattr_security_handler;
20 18
21extern const struct xattr_handler *hfsplus_xattr_handlers[]; 19extern const struct xattr_handler *hfsplus_xattr_handlers[];
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 223283c30111..009ec0b5993d 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -178,10 +178,6 @@ struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
178 char *value = NULL; 178 char *value = NULL;
179 int rc, xprefix; 179 int rc, xprefix;
180 180
181 acl = get_cached_acl(inode, type);
182 if (acl != ACL_NOT_CACHED)
183 return acl;
184
185 switch (type) { 181 switch (type) {
186 case ACL_TYPE_ACCESS: 182 case ACL_TYPE_ACCESS:
187 xprefix = JFFS2_XPREFIX_ACL_ACCESS; 183 xprefix = JFFS2_XPREFIX_ACL_ACCESS;
@@ -232,13 +228,10 @@ static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *a
232 return rc; 228 return rc;
233} 229}
234 230
235static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) 231int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
236{ 232{
237 int rc, xprefix; 233 int rc, xprefix;
238 234
239 if (S_ISLNK(inode->i_mode))
240 return -EOPNOTSUPP;
241
242 switch (type) { 235 switch (type) {
243 case ACL_TYPE_ACCESS: 236 case ACL_TYPE_ACCESS:
244 xprefix = JFFS2_XPREFIX_ACL_ACCESS; 237 xprefix = JFFS2_XPREFIX_ACL_ACCESS;
@@ -277,30 +270,21 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
277 270
278int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode) 271int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode)
279{ 272{
280 struct posix_acl *acl; 273 struct posix_acl *default_acl, *acl;
281 int rc; 274 int rc;
282 275
283 cache_no_acl(inode); 276 cache_no_acl(inode);
284 277
285 if (S_ISLNK(*i_mode)) 278 rc = posix_acl_create(dir_i, i_mode, &default_acl, &acl);
286 return 0; /* Symlink always has no-ACL */ 279 if (rc)
287 280 return rc;
288 acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
289 if (IS_ERR(acl))
290 return PTR_ERR(acl);
291
292 if (!acl) {
293 *i_mode &= ~current_umask();
294 } else {
295 if (S_ISDIR(*i_mode))
296 set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
297
298 rc = posix_acl_create(&acl, GFP_KERNEL, i_mode);
299 if (rc < 0)
300 return rc;
301 if (rc > 0)
302 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
303 281
282 if (default_acl) {
283 set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
284 posix_acl_release(default_acl);
285 }
286 if (acl) {
287 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
304 posix_acl_release(acl); 288 posix_acl_release(acl);
305 } 289 }
306 return 0; 290 return 0;
@@ -324,106 +308,3 @@ int jffs2_init_acl_post(struct inode *inode)
324 308
325 return 0; 309 return 0;
326} 310}
327
328int jffs2_acl_chmod(struct inode *inode)
329{
330 struct posix_acl *acl;
331 int rc;
332
333 if (S_ISLNK(inode->i_mode))
334 return -EOPNOTSUPP;
335 acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
336 if (IS_ERR(acl) || !acl)
337 return PTR_ERR(acl);
338 rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
339 if (rc)
340 return rc;
341 rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl);
342 posix_acl_release(acl);
343 return rc;
344}
345
346static size_t jffs2_acl_access_listxattr(struct dentry *dentry, char *list,
347 size_t list_size, const char *name, size_t name_len, int type)
348{
349 const int retlen = sizeof(POSIX_ACL_XATTR_ACCESS);
350
351 if (list && retlen <= list_size)
352 strcpy(list, POSIX_ACL_XATTR_ACCESS);
353 return retlen;
354}
355
356static size_t jffs2_acl_default_listxattr(struct dentry *dentry, char *list,
357 size_t list_size, const char *name, size_t name_len, int type)
358{
359 const int retlen = sizeof(POSIX_ACL_XATTR_DEFAULT);
360
361 if (list && retlen <= list_size)
362 strcpy(list, POSIX_ACL_XATTR_DEFAULT);
363 return retlen;
364}
365
366static int jffs2_acl_getxattr(struct dentry *dentry, const char *name,
367 void *buffer, size_t size, int type)
368{
369 struct posix_acl *acl;
370 int rc;
371
372 if (name[0] != '\0')
373 return -EINVAL;
374
375 acl = jffs2_get_acl(dentry->d_inode, type);
376 if (IS_ERR(acl))
377 return PTR_ERR(acl);
378 if (!acl)
379 return -ENODATA;
380 rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
381 posix_acl_release(acl);
382
383 return rc;
384}
385
386static int jffs2_acl_setxattr(struct dentry *dentry, const char *name,
387 const void *value, size_t size, int flags, int type)
388{
389 struct posix_acl *acl;
390 int rc;
391
392 if (name[0] != '\0')
393 return -EINVAL;
394 if (!inode_owner_or_capable(dentry->d_inode))
395 return -EPERM;
396
397 if (value) {
398 acl = posix_acl_from_xattr(&init_user_ns, value, size);
399 if (IS_ERR(acl))
400 return PTR_ERR(acl);
401 if (acl) {
402 rc = posix_acl_valid(acl);
403 if (rc)
404 goto out;
405 }
406 } else {
407 acl = NULL;
408 }
409 rc = jffs2_set_acl(dentry->d_inode, type, acl);
410 out:
411 posix_acl_release(acl);
412 return rc;
413}
414
415const struct xattr_handler jffs2_acl_access_xattr_handler = {
416 .prefix = POSIX_ACL_XATTR_ACCESS,
417 .flags = ACL_TYPE_DEFAULT,
418 .list = jffs2_acl_access_listxattr,
419 .get = jffs2_acl_getxattr,
420 .set = jffs2_acl_setxattr,
421};
422
423const struct xattr_handler jffs2_acl_default_xattr_handler = {
424 .prefix = POSIX_ACL_XATTR_DEFAULT,
425 .flags = ACL_TYPE_DEFAULT,
426 .list = jffs2_acl_default_listxattr,
427 .get = jffs2_acl_getxattr,
428 .set = jffs2_acl_setxattr,
429};
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 9b477246f2a6..2e2b5745c3b7 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -27,17 +27,14 @@ struct jffs2_acl_header {
27#ifdef CONFIG_JFFS2_FS_POSIX_ACL 27#ifdef CONFIG_JFFS2_FS_POSIX_ACL
28 28
29struct posix_acl *jffs2_get_acl(struct inode *inode, int type); 29struct posix_acl *jffs2_get_acl(struct inode *inode, int type);
30extern int jffs2_acl_chmod(struct inode *); 30int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
31extern int jffs2_init_acl_pre(struct inode *, struct inode *, umode_t *); 31extern int jffs2_init_acl_pre(struct inode *, struct inode *, umode_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;
35extern const struct xattr_handler jffs2_acl_default_xattr_handler;
36
37#else 34#else
38 35
39#define jffs2_get_acl (NULL) 36#define jffs2_get_acl (NULL)
40#define jffs2_acl_chmod(inode) (0) 37#define jffs2_set_acl (NULL)
41#define jffs2_init_acl_pre(dir_i,inode,mode) (0) 38#define jffs2_init_acl_pre(dir_i,inode,mode) (0)
42#define jffs2_init_acl_post(inode) (0) 39#define jffs2_init_acl_post(inode) (0)
43 40
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index e3aac222472e..938556025d64 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -59,6 +59,7 @@ const struct inode_operations jffs2_dir_inode_operations =
59 .mknod = jffs2_mknod, 59 .mknod = jffs2_mknod,
60 .rename = jffs2_rename, 60 .rename = jffs2_rename,
61 .get_acl = jffs2_get_acl, 61 .get_acl = jffs2_get_acl,
62 .set_acl = jffs2_set_acl,
62 .setattr = jffs2_setattr, 63 .setattr = jffs2_setattr,
63 .setxattr = jffs2_setxattr, 64 .setxattr = jffs2_setxattr,
64 .getxattr = jffs2_getxattr, 65 .getxattr = jffs2_getxattr,
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 1506673c087e..256cd19a3b78 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -66,6 +66,7 @@ const struct file_operations jffs2_file_operations =
66const struct inode_operations jffs2_file_inode_operations = 66const struct inode_operations jffs2_file_inode_operations =
67{ 67{
68 .get_acl = jffs2_get_acl, 68 .get_acl = jffs2_get_acl,
69 .set_acl = jffs2_set_acl,
69 .setattr = jffs2_setattr, 70 .setattr = jffs2_setattr,
70 .setxattr = jffs2_setxattr, 71 .setxattr = jffs2_setxattr,
71 .getxattr = jffs2_getxattr, 72 .getxattr = jffs2_getxattr,
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 09b3ed455724..a69e426435dd 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -190,15 +190,16 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
190 190
191int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) 191int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
192{ 192{
193 struct inode *inode = dentry->d_inode;
193 int rc; 194 int rc;
194 195
195 rc = inode_change_ok(dentry->d_inode, iattr); 196 rc = inode_change_ok(inode, iattr);
196 if (rc) 197 if (rc)
197 return rc; 198 return rc;
198 199
199 rc = jffs2_do_setattr(dentry->d_inode, iattr); 200 rc = jffs2_do_setattr(inode, iattr);
200 if (!rc && (iattr->ia_valid & ATTR_MODE)) 201 if (!rc && (iattr->ia_valid & ATTR_MODE))
201 rc = jffs2_acl_chmod(dentry->d_inode); 202 rc = posix_acl_chmod(inode, inode->i_mode);
202 203
203 return rc; 204 return rc;
204} 205}
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 6e563332bb24..c7c77b0dfccd 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -22,7 +22,6 @@ const struct inode_operations jffs2_symlink_inode_operations =
22{ 22{
23 .readlink = generic_readlink, 23 .readlink = generic_readlink,
24 .follow_link = jffs2_follow_link, 24 .follow_link = jffs2_follow_link,
25 .get_acl = jffs2_get_acl,
26 .setattr = jffs2_setattr, 25 .setattr = jffs2_setattr,
27 .setxattr = jffs2_setxattr, 26 .setxattr = jffs2_setxattr,
28 .getxattr = jffs2_getxattr, 27 .getxattr = jffs2_getxattr,
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 3034e970eb9a..ad0f2e2a1700 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -22,6 +22,7 @@
22#include <linux/crc32.h> 22#include <linux/crc32.h>
23#include <linux/jffs2.h> 23#include <linux/jffs2.h>
24#include <linux/xattr.h> 24#include <linux/xattr.h>
25#include <linux/posix_acl_xattr.h>
25#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
26#include "nodelist.h" 27#include "nodelist.h"
27/* -------- xdatum related functions ---------------- 28/* -------- xdatum related functions ----------------
@@ -921,8 +922,8 @@ const struct xattr_handler *jffs2_xattr_handlers[] = {
921 &jffs2_security_xattr_handler, 922 &jffs2_security_xattr_handler,
922#endif 923#endif
923#ifdef CONFIG_JFFS2_FS_POSIX_ACL 924#ifdef CONFIG_JFFS2_FS_POSIX_ACL
924 &jffs2_acl_access_xattr_handler, 925 &posix_acl_access_xattr_handler,
925 &jffs2_acl_default_xattr_handler, 926 &posix_acl_default_xattr_handler,
926#endif 927#endif
927 &jffs2_trusted_xattr_handler, 928 &jffs2_trusted_xattr_handler,
928 NULL 929 NULL
@@ -942,10 +943,10 @@ static const struct xattr_handler *xprefix_to_handler(int xprefix) {
942#endif 943#endif
943#ifdef CONFIG_JFFS2_FS_POSIX_ACL 944#ifdef CONFIG_JFFS2_FS_POSIX_ACL
944 case JFFS2_XPREFIX_ACL_ACCESS: 945 case JFFS2_XPREFIX_ACL_ACCESS:
945 ret = &jffs2_acl_access_xattr_handler; 946 ret = &posix_acl_access_xattr_handler;
946 break; 947 break;
947 case JFFS2_XPREFIX_ACL_DEFAULT: 948 case JFFS2_XPREFIX_ACL_DEFAULT:
948 ret = &jffs2_acl_default_xattr_handler; 949 ret = &posix_acl_default_xattr_handler;
949 break; 950 break;
950#endif 951#endif
951 case JFFS2_XPREFIX_TRUSTED: 952 case JFFS2_XPREFIX_TRUSTED:
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index d254d6d35995..e973b85d6afd 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -72,7 +72,7 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type)
72 return acl; 72 return acl;
73} 73}
74 74
75static int jfs_set_acl(tid_t tid, struct inode *inode, int type, 75static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
76 struct posix_acl *acl) 76 struct posix_acl *acl)
77{ 77{
78 char *ea_name; 78 char *ea_name;
@@ -80,21 +80,22 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
80 int size = 0; 80 int size = 0;
81 char *value = NULL; 81 char *value = NULL;
82 82
83 if (S_ISLNK(inode->i_mode)) 83 switch (type) {
84 return -EOPNOTSUPP; 84 case ACL_TYPE_ACCESS:
85 85 ea_name = POSIX_ACL_XATTR_ACCESS;
86 switch(type) { 86 rc = posix_acl_equiv_mode(acl, &inode->i_mode);
87 case ACL_TYPE_ACCESS: 87 if (rc < 0)
88 ea_name = POSIX_ACL_XATTR_ACCESS; 88 return rc;
89 break; 89 if (rc == 0)
90 case ACL_TYPE_DEFAULT: 90 acl = NULL;
91 ea_name = POSIX_ACL_XATTR_DEFAULT; 91 break;
92 if (!S_ISDIR(inode->i_mode)) 92 case ACL_TYPE_DEFAULT:
93 return acl ? -EACCES : 0; 93 ea_name = POSIX_ACL_XATTR_DEFAULT;
94 break; 94 break;
95 default: 95 default:
96 return -EINVAL; 96 return -EINVAL;
97 } 97 }
98
98 if (acl) { 99 if (acl) {
99 size = posix_acl_xattr_size(acl->a_count); 100 size = posix_acl_xattr_size(acl->a_count);
100 value = kmalloc(size, GFP_KERNEL); 101 value = kmalloc(size, GFP_KERNEL);
@@ -114,65 +115,43 @@ out:
114 return rc; 115 return rc;
115} 116}
116 117
118int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
119{
120 int rc;
121 tid_t tid;
122
123 tid = txBegin(inode->i_sb, 0);
124 mutex_lock(&JFS_IP(inode)->commit_mutex);
125 rc = __jfs_set_acl(tid, inode, type, acl);
126 if (!rc)
127 rc = txCommit(tid, 1, &inode, 0);
128 txEnd(tid);
129 mutex_unlock(&JFS_IP(inode)->commit_mutex);
130 return rc;
131}
132
117int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) 133int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
118{ 134{
119 struct posix_acl *acl = NULL; 135 struct posix_acl *default_acl, *acl;
120 int rc = 0; 136 int rc = 0;
121 137
122 if (S_ISLNK(inode->i_mode)) 138 rc = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
123 return 0; 139 if (rc)
140 return rc;
124 141
125 acl = jfs_get_acl(dir, ACL_TYPE_DEFAULT); 142 if (default_acl) {
126 if (IS_ERR(acl)) 143 rc = __jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, default_acl);
127 return PTR_ERR(acl); 144 posix_acl_release(default_acl);
145 }
128 146
129 if (acl) { 147 if (acl) {
130 if (S_ISDIR(inode->i_mode)) { 148 if (!rc)
131 rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); 149 rc = __jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
132 if (rc)
133 goto cleanup;
134 }
135 rc = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode);
136 if (rc < 0)
137 goto cleanup; /* posix_acl_release(NULL) is no-op */
138 if (rc > 0)
139 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
140cleanup:
141 posix_acl_release(acl); 150 posix_acl_release(acl);
142 } else 151 }
143 inode->i_mode &= ~current_umask();
144 152
145 JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | 153 JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
146 inode->i_mode; 154 inode->i_mode;
147 155
148 return rc; 156 return rc;
149} 157}
150
151int jfs_acl_chmod(struct inode *inode)
152{
153 struct posix_acl *acl;
154 int rc;
155 tid_t tid;
156
157 if (S_ISLNK(inode->i_mode))
158 return -EOPNOTSUPP;
159
160 acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
161 if (IS_ERR(acl) || !acl)
162 return PTR_ERR(acl);
163
164 rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
165 if (rc)
166 return rc;
167
168 tid = txBegin(inode->i_sb, 0);
169 mutex_lock(&JFS_IP(inode)->commit_mutex);
170 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, acl);
171 if (!rc)
172 rc = txCommit(tid, 1, &inode, 0);
173 txEnd(tid);
174 mutex_unlock(&JFS_IP(inode)->commit_mutex);
175
176 posix_acl_release(acl);
177 return rc;
178}
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index dd7442c58358..794da944d5cd 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/posix_acl.h>
22#include <linux/quotaops.h> 23#include <linux/quotaops.h>
23#include "jfs_incore.h" 24#include "jfs_incore.h"
24#include "jfs_inode.h" 25#include "jfs_inode.h"
@@ -131,7 +132,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
131 mark_inode_dirty(inode); 132 mark_inode_dirty(inode);
132 133
133 if (iattr->ia_valid & ATTR_MODE) 134 if (iattr->ia_valid & ATTR_MODE)
134 rc = jfs_acl_chmod(inode); 135 rc = posix_acl_chmod(inode, inode->i_mode);
135 return rc; 136 return rc;
136} 137}
137 138
@@ -143,6 +144,7 @@ const struct inode_operations jfs_file_inode_operations = {
143 .setattr = jfs_setattr, 144 .setattr = jfs_setattr,
144#ifdef CONFIG_JFS_POSIX_ACL 145#ifdef CONFIG_JFS_POSIX_ACL
145 .get_acl = jfs_get_acl, 146 .get_acl = jfs_get_acl,
147 .set_acl = jfs_set_acl,
146#endif 148#endif
147}; 149};
148 150
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index ad84fe50ca9e..489f993b7b13 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -21,8 +21,8 @@
21#ifdef CONFIG_JFS_POSIX_ACL 21#ifdef CONFIG_JFS_POSIX_ACL
22 22
23struct posix_acl *jfs_get_acl(struct inode *inode, int type); 23struct posix_acl *jfs_get_acl(struct inode *inode, int type);
24int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
24int jfs_init_acl(tid_t, struct inode *, struct inode *); 25int jfs_init_acl(tid_t, struct inode *, struct inode *);
25int jfs_acl_chmod(struct inode *inode);
26 26
27#else 27#else
28 28
@@ -32,10 +32,5 @@ static inline int jfs_init_acl(tid_t tid, struct inode *inode,
32 return 0; 32 return 0;
33} 33}
34 34
35static inline int jfs_acl_chmod(struct inode *inode)
36{
37 return 0;
38}
39
40#endif 35#endif
41#endif /* _H_JFS_ACL */ 36#endif /* _H_JFS_ACL */
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h
index e9e100fd7c09..e8d717dabca3 100644
--- a/fs/jfs/jfs_xattr.h
+++ b/fs/jfs/jfs_xattr.h
@@ -61,6 +61,8 @@ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
61extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); 61extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
62extern int jfs_removexattr(struct dentry *, const char *); 62extern int jfs_removexattr(struct dentry *, const char *);
63 63
64extern const struct xattr_handler *jfs_xattr_handlers[];
65
64#ifdef CONFIG_JFS_SECURITY 66#ifdef CONFIG_JFS_SECURITY
65extern int jfs_init_security(tid_t, struct inode *, struct inode *, 67extern int jfs_init_security(tid_t, struct inode *, struct inode *,
66 const struct qstr *); 68 const struct qstr *);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index aa8a3370631b..d59c7defb1ef 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1524,6 +1524,7 @@ const struct inode_operations jfs_dir_inode_operations = {
1524 .setattr = jfs_setattr, 1524 .setattr = jfs_setattr,
1525#ifdef CONFIG_JFS_POSIX_ACL 1525#ifdef CONFIG_JFS_POSIX_ACL
1526 .get_acl = jfs_get_acl, 1526 .get_acl = jfs_get_acl,
1527 .set_acl = jfs_set_acl,
1527#endif 1528#endif
1528}; 1529};
1529 1530
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 6669aa2042c3..e2b7483444fd 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -44,6 +44,7 @@
44#include "jfs_imap.h" 44#include "jfs_imap.h"
45#include "jfs_acl.h" 45#include "jfs_acl.h"
46#include "jfs_debug.h" 46#include "jfs_debug.h"
47#include "jfs_xattr.h"
47 48
48MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); 49MODULE_DESCRIPTION("The Journaled Filesystem (JFS)");
49MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); 50MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM");
@@ -522,6 +523,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
522 */ 523 */
523 sb->s_op = &jfs_super_operations; 524 sb->s_op = &jfs_super_operations;
524 sb->s_export_op = &jfs_export_operations; 525 sb->s_export_op = &jfs_export_operations;
526 sb->s_xattr = jfs_xattr_handlers;
525#ifdef CONFIG_QUOTA 527#ifdef CONFIG_QUOTA
526 sb->dq_op = &dquot_operations; 528 sb->dq_op = &dquot_operations;
527 sb->s_qcop = &dquot_quotactl_ops; 529 sb->s_qcop = &dquot_quotactl_ops;
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index d3472f4cd530..5324e4e2b992 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -666,81 +666,12 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf,
666} 666}
667 667
668/* 668/*
669 * can_set_system_xattr
670 *
671 * This code is specific to the system.* namespace. It contains policy
672 * which doesn't belong in the main xattr codepath.
673 */
674static int can_set_system_xattr(struct inode *inode, const char *name,
675 const void *value, size_t value_len)
676{
677#ifdef CONFIG_JFS_POSIX_ACL
678 struct posix_acl *acl;
679 int rc;
680
681 if (!inode_owner_or_capable(inode))
682 return -EPERM;
683
684 /*
685 * POSIX_ACL_XATTR_ACCESS is tied to i_mode
686 */
687 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) {
688 acl = posix_acl_from_xattr(&init_user_ns, value, value_len);
689 if (IS_ERR(acl)) {
690 rc = PTR_ERR(acl);
691 printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
692 rc);
693 return rc;
694 }
695 if (acl) {
696 rc = posix_acl_equiv_mode(acl, &inode->i_mode);
697 posix_acl_release(acl);
698 if (rc < 0) {
699 printk(KERN_ERR
700 "posix_acl_equiv_mode returned %d\n",
701 rc);
702 return rc;
703 }
704 mark_inode_dirty(inode);
705 }
706 /*
707 * We're changing the ACL. Get rid of the cached one
708 */
709 forget_cached_acl(inode, ACL_TYPE_ACCESS);
710
711 return 0;
712 } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
713 acl = posix_acl_from_xattr(&init_user_ns, value, value_len);
714 if (IS_ERR(acl)) {
715 rc = PTR_ERR(acl);
716 printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
717 rc);
718 return rc;
719 }
720 posix_acl_release(acl);
721
722 /*
723 * We're changing the default ACL. Get rid of the cached one
724 */
725 forget_cached_acl(inode, ACL_TYPE_DEFAULT);
726
727 return 0;
728 }
729#endif /* CONFIG_JFS_POSIX_ACL */
730 return -EOPNOTSUPP;
731}
732
733/*
734 * Most of the permission checking is done by xattr_permission in the vfs. 669 * Most of the permission checking is done by xattr_permission in the vfs.
735 * The local file system is responsible for handling the system.* namespace.
736 * We also need to verify that this is a namespace that we recognize. 670 * We also need to verify that this is a namespace that we recognize.
737 */ 671 */
738static int can_set_xattr(struct inode *inode, const char *name, 672static int can_set_xattr(struct inode *inode, const char *name,
739 const void *value, size_t value_len) 673 const void *value, size_t value_len)
740{ 674{
741 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
742 return can_set_system_xattr(inode, name, value, value_len);
743
744 if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { 675 if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) {
745 /* 676 /*
746 * This makes sure that we aren't trying to set an 677 * This makes sure that we aren't trying to set an
@@ -748,7 +679,7 @@ static int can_set_xattr(struct inode *inode, const char *name,
748 * with "os2." 679 * with "os2."
749 */ 680 */
750 if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) 681 if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN))
751 return -EOPNOTSUPP; 682 return -EOPNOTSUPP;
752 return 0; 683 return 0;
753 } 684 }
754 685
@@ -913,6 +844,14 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
913 if ((rc = can_set_xattr(inode, name, value, value_len))) 844 if ((rc = can_set_xattr(inode, name, value, value_len)))
914 return rc; 845 return rc;
915 846
847 /*
848 * If this is a request for a synthetic attribute in the system.*
849 * namespace use the generic infrastructure to resolve a handler
850 * for it via sb->s_xattr.
851 */
852 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
853 return generic_setxattr(dentry, name, value, value_len, flags);
854
916 if (value == NULL) { /* empty EA, do not remove */ 855 if (value == NULL) { /* empty EA, do not remove */
917 value = ""; 856 value = "";
918 value_len = 0; 857 value_len = 0;
@@ -986,6 +925,14 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data,
986{ 925{
987 int err; 926 int err;
988 927
928 /*
929 * If this is a request for a synthetic attribute in the system.*
930 * namespace use the generic infrastructure to resolve a handler
931 * for it via sb->s_xattr.
932 */
933 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
934 return generic_getxattr(dentry, name, data, buf_size);
935
989 if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { 936 if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
990 /* 937 /*
991 * skip past "os2." prefix 938 * skip past "os2." prefix
@@ -1077,6 +1024,14 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
1077 if ((rc = can_set_xattr(inode, name, NULL, 0))) 1024 if ((rc = can_set_xattr(inode, name, NULL, 0)))
1078 return rc; 1025 return rc;
1079 1026
1027 /*
1028 * If this is a request for a synthetic attribute in the system.*
1029 * namespace use the generic infrastructure to resolve a handler
1030 * for it via sb->s_xattr.
1031 */
1032 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
1033 return generic_removexattr(dentry, name);
1034
1080 tid = txBegin(inode->i_sb, 0); 1035 tid = txBegin(inode->i_sb, 0);
1081 mutex_lock(&ji->commit_mutex); 1036 mutex_lock(&ji->commit_mutex);
1082 rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); 1037 rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
@@ -1088,6 +1043,19 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
1088 return rc; 1043 return rc;
1089} 1044}
1090 1045
1046/*
1047 * List of handlers for synthetic system.* attributes. All real ondisk
1048 * attributes are handled directly.
1049 */
1050const struct xattr_handler *jfs_xattr_handlers[] = {
1051#ifdef JFS_POSIX_ACL
1052 &posix_acl_access_xattr_handler,
1053 &posix_acl_default_xattr_handler,
1054#endif
1055 NULL,
1056};
1057
1058
1091#ifdef CONFIG_JFS_SECURITY 1059#ifdef CONFIG_JFS_SECURITY
1092static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, 1060static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
1093 void *fs_info) 1061 void *fs_info)
diff --git a/fs/mount.h b/fs/mount.h
index d64c594be6c4..a17458ca6f29 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -74,7 +74,7 @@ static inline int mnt_has_parent(struct mount *mnt)
74static inline int is_mounted(struct vfsmount *mnt) 74static inline int is_mounted(struct vfsmount *mnt)
75{ 75{
76 /* neither detached nor internal? */ 76 /* neither detached nor internal? */
77 return !IS_ERR_OR_NULL(real_mount(mnt)); 77 return !IS_ERR_OR_NULL(real_mount(mnt)->mnt_ns);
78} 78}
79 79
80extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *); 80extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
diff --git a/fs/namei.c b/fs/namei.c
index 3531deebad30..bcb838e2e52f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -235,27 +235,9 @@ static int check_acl(struct inode *inode, int mask)
235 return posix_acl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); 235 return posix_acl_permission(inode, acl, mask & ~MAY_NOT_BLOCK);
236 } 236 }
237 237
238 acl = get_cached_acl(inode, ACL_TYPE_ACCESS); 238 acl = get_acl(inode, ACL_TYPE_ACCESS);
239 239 if (IS_ERR(acl))
240 /* 240 return PTR_ERR(acl);
241 * A filesystem can force a ACL callback by just never filling the
242 * ACL cache. But normally you'd fill the cache either at inode
243 * instantiation time, or on the first ->get_acl call.
244 *
245 * If the filesystem doesn't have a get_acl() function at all, we'll
246 * just create the negative cache entry.
247 */
248 if (acl == ACL_NOT_CACHED) {
249 if (inode->i_op->get_acl) {
250 acl = inode->i_op->get_acl(inode, ACL_TYPE_ACCESS);
251 if (IS_ERR(acl))
252 return PTR_ERR(acl);
253 } else {
254 set_cached_acl(inode, ACL_TYPE_ACCESS, NULL);
255 return -EAGAIN;
256 }
257 }
258
259 if (acl) { 241 if (acl) {
260 int error = posix_acl_permission(inode, acl, mask); 242 int error = posix_acl_permission(inode, acl, mask);
261 posix_acl_release(acl); 243 posix_acl_release(acl);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 00ad1c2b217d..ecd11ba7f960 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1641,10 +1641,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
1641 return NULL; 1641 return NULL;
1642 nfsi->flags = 0UL; 1642 nfsi->flags = 0UL;
1643 nfsi->cache_validity = 0UL; 1643 nfsi->cache_validity = 0UL;
1644#ifdef CONFIG_NFS_V3_ACL
1645 nfsi->acl_access = ERR_PTR(-EAGAIN);
1646 nfsi->acl_default = ERR_PTR(-EAGAIN);
1647#endif
1648#if IS_ENABLED(CONFIG_NFS_V4) 1644#if IS_ENABLED(CONFIG_NFS_V4)
1649 nfsi->nfs4_acl = NULL; 1645 nfsi->nfs4_acl = NULL;
1650#endif /* CONFIG_NFS_V4 */ 1646#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 4a1aafba6a20..9a5ca03fa539 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -10,179 +10,7 @@
10 10
11#define NFSDBG_FACILITY NFSDBG_PROC 11#define NFSDBG_FACILITY NFSDBG_PROC
12 12
13ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size) 13struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
14{
15 struct inode *inode = dentry->d_inode;
16 struct posix_acl *acl;
17 int pos=0, len=0;
18
19# define output(s) do { \
20 if (pos + sizeof(s) <= size) { \
21 memcpy(buffer + pos, s, sizeof(s)); \
22 pos += sizeof(s); \
23 } \
24 len += sizeof(s); \
25 } while(0)
26
27 acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS);
28 if (IS_ERR(acl))
29 return PTR_ERR(acl);
30 if (acl) {
31 output("system.posix_acl_access");
32 posix_acl_release(acl);
33 }
34
35 if (S_ISDIR(inode->i_mode)) {
36 acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT);
37 if (IS_ERR(acl))
38 return PTR_ERR(acl);
39 if (acl) {
40 output("system.posix_acl_default");
41 posix_acl_release(acl);
42 }
43 }
44
45# undef output
46
47 if (!buffer || len <= size)
48 return len;
49 return -ERANGE;
50}
51
52ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
53 void *buffer, size_t size)
54{
55 struct inode *inode = dentry->d_inode;
56 struct posix_acl *acl;
57 int type, error = 0;
58
59 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
60 type = ACL_TYPE_ACCESS;
61 else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
62 type = ACL_TYPE_DEFAULT;
63 else
64 return -EOPNOTSUPP;
65
66 acl = nfs3_proc_getacl(inode, type);
67 if (IS_ERR(acl))
68 return PTR_ERR(acl);
69 else if (acl) {
70 if (type == ACL_TYPE_ACCESS && acl->a_count == 0)
71 error = -ENODATA;
72 else
73 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
74 posix_acl_release(acl);
75 } else
76 error = -ENODATA;
77
78 return error;
79}
80
81int nfs3_setxattr(struct dentry *dentry, const char *name,
82 const void *value, size_t size, int flags)
83{
84 struct inode *inode = dentry->d_inode;
85 struct posix_acl *acl;
86 int type, error;
87
88 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
89 type = ACL_TYPE_ACCESS;
90 else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
91 type = ACL_TYPE_DEFAULT;
92 else
93 return -EOPNOTSUPP;
94
95 acl = posix_acl_from_xattr(&init_user_ns, value, size);
96 if (IS_ERR(acl))
97 return PTR_ERR(acl);
98 error = nfs3_proc_setacl(inode, type, acl);
99 posix_acl_release(acl);
100
101 return error;
102}
103
104int nfs3_removexattr(struct dentry *dentry, const char *name)
105{
106 struct inode *inode = dentry->d_inode;
107 int type;
108
109 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
110 type = ACL_TYPE_ACCESS;
111 else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
112 type = ACL_TYPE_DEFAULT;
113 else
114 return -EOPNOTSUPP;
115
116 return nfs3_proc_setacl(inode, type, NULL);
117}
118
119static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
120{
121 if (!IS_ERR(nfsi->acl_access)) {
122 posix_acl_release(nfsi->acl_access);
123 nfsi->acl_access = ERR_PTR(-EAGAIN);
124 }
125 if (!IS_ERR(nfsi->acl_default)) {
126 posix_acl_release(nfsi->acl_default);
127 nfsi->acl_default = ERR_PTR(-EAGAIN);
128 }
129}
130
131void nfs3_forget_cached_acls(struct inode *inode)
132{
133 dprintk("NFS: nfs3_forget_cached_acls(%s/%ld)\n", inode->i_sb->s_id,
134 inode->i_ino);
135 spin_lock(&inode->i_lock);
136 __nfs3_forget_cached_acls(NFS_I(inode));
137 spin_unlock(&inode->i_lock);
138}
139
140static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
141{
142 struct nfs_inode *nfsi = NFS_I(inode);
143 struct posix_acl *acl = ERR_PTR(-EINVAL);
144
145 spin_lock(&inode->i_lock);
146 switch(type) {
147 case ACL_TYPE_ACCESS:
148 acl = nfsi->acl_access;
149 break;
150
151 case ACL_TYPE_DEFAULT:
152 acl = nfsi->acl_default;
153 break;
154
155 default:
156 goto out;
157 }
158 if (IS_ERR(acl))
159 acl = ERR_PTR(-EAGAIN);
160 else
161 acl = posix_acl_dup(acl);
162out:
163 spin_unlock(&inode->i_lock);
164 dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id,
165 inode->i_ino, type, acl);
166 return acl;
167}
168
169static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
170 struct posix_acl *dfacl)
171{
172 struct nfs_inode *nfsi = NFS_I(inode);
173
174 dprintk("nfs3_cache_acls(%s/%ld, %p, %p)\n", inode->i_sb->s_id,
175 inode->i_ino, acl, dfacl);
176 spin_lock(&inode->i_lock);
177 __nfs3_forget_cached_acls(NFS_I(inode));
178 if (!IS_ERR(acl))
179 nfsi->acl_access = posix_acl_dup(acl);
180 if (!IS_ERR(dfacl))
181 nfsi->acl_default = posix_acl_dup(dfacl);
182 spin_unlock(&inode->i_lock);
183}
184
185struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
186{ 14{
187 struct nfs_server *server = NFS_SERVER(inode); 15 struct nfs_server *server = NFS_SERVER(inode);
188 struct page *pages[NFSACL_MAXPAGES] = { }; 16 struct page *pages[NFSACL_MAXPAGES] = { };
@@ -198,7 +26,6 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
198 .rpc_argp = &args, 26 .rpc_argp = &args,
199 .rpc_resp = &res, 27 .rpc_resp = &res,
200 }; 28 };
201 struct posix_acl *acl;
202 int status, count; 29 int status, count;
203 30
204 if (!nfs_server_capable(inode, NFS_CAP_ACLS)) 31 if (!nfs_server_capable(inode, NFS_CAP_ACLS))
@@ -207,10 +34,6 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
207 status = nfs_revalidate_inode(server, inode); 34 status = nfs_revalidate_inode(server, inode);
208 if (status < 0) 35 if (status < 0)
209 return ERR_PTR(status); 36 return ERR_PTR(status);
210 acl = nfs3_get_cached_acl(inode, type);
211 if (acl != ERR_PTR(-EAGAIN))
212 return acl;
213 acl = NULL;
214 37
215 /* 38 /*
216 * Only get the access acl when explicitly requested: We don't 39 * Only get the access acl when explicitly requested: We don't
@@ -257,40 +80,41 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
257 } 80 }
258 81
259 if (res.acl_access != NULL) { 82 if (res.acl_access != NULL) {
260 if (posix_acl_equiv_mode(res.acl_access, NULL) == 0) { 83 if (posix_acl_equiv_mode(res.acl_access, NULL) ||
84 res.acl_access->a_count == 0) {
261 posix_acl_release(res.acl_access); 85 posix_acl_release(res.acl_access);
262 res.acl_access = NULL; 86 res.acl_access = NULL;
263 } 87 }
264 } 88 }
265 nfs3_cache_acls(inode,
266 (res.mask & NFS_ACL) ? res.acl_access : ERR_PTR(-EINVAL),
267 (res.mask & NFS_DFACL) ? res.acl_default : ERR_PTR(-EINVAL));
268 89
269 switch(type) { 90 if (res.mask & NFS_ACL)
270 case ACL_TYPE_ACCESS: 91 set_cached_acl(inode, ACL_TYPE_ACCESS, res.acl_access);
271 acl = res.acl_access; 92 else
272 res.acl_access = NULL; 93 forget_cached_acl(inode, ACL_TYPE_ACCESS);
273 break;
274 94
275 case ACL_TYPE_DEFAULT: 95 if (res.mask & NFS_DFACL)
276 acl = res.acl_default; 96 set_cached_acl(inode, ACL_TYPE_DEFAULT, res.acl_default);
277 res.acl_default = NULL; 97 else
98 forget_cached_acl(inode, ACL_TYPE_DEFAULT);
99
100 nfs_free_fattr(res.fattr);
101 if (type == ACL_TYPE_ACCESS) {
102 posix_acl_release(res.acl_default);
103 return res.acl_access;
104 } else {
105 posix_acl_release(res.acl_access);
106 return res.acl_default;
278 } 107 }
279 108
280getout: 109getout:
281 posix_acl_release(res.acl_access); 110 posix_acl_release(res.acl_access);
282 posix_acl_release(res.acl_default); 111 posix_acl_release(res.acl_default);
283 nfs_free_fattr(res.fattr); 112 nfs_free_fattr(res.fattr);
284 113 return ERR_PTR(status);
285 if (status != 0) {
286 posix_acl_release(acl);
287 acl = ERR_PTR(status);
288 }
289 return acl;
290} 114}
291 115
292static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, 116int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
293 struct posix_acl *dfacl) 117 struct posix_acl *dfacl)
294{ 118{
295 struct nfs_server *server = NFS_SERVER(inode); 119 struct nfs_server *server = NFS_SERVER(inode);
296 struct nfs_fattr *fattr; 120 struct nfs_fattr *fattr;
@@ -353,7 +177,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
353 switch (status) { 177 switch (status) {
354 case 0: 178 case 0:
355 status = nfs_refresh_inode(inode, fattr); 179 status = nfs_refresh_inode(inode, fattr);
356 nfs3_cache_acls(inode, acl, dfacl); 180 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
181 set_cached_acl(inode, ACL_TYPE_DEFAULT, dfacl);
357 break; 182 break;
358 case -EPFNOSUPPORT: 183 case -EPFNOSUPPORT:
359 case -EPROTONOSUPPORT: 184 case -EPROTONOSUPPORT:
@@ -373,33 +198,27 @@ out:
373 return status; 198 return status;
374} 199}
375 200
376int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl) 201int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type)
377{ 202{
378 struct posix_acl *alloc = NULL, *dfacl = NULL; 203 struct posix_acl *alloc = NULL, *dfacl = NULL;
379 int status; 204 int status;
380 205
381 if (S_ISDIR(inode->i_mode)) { 206 if (S_ISDIR(inode->i_mode)) {
382 switch(type) { 207 switch(type) {
383 case ACL_TYPE_ACCESS: 208 case ACL_TYPE_ACCESS:
384 alloc = dfacl = nfs3_proc_getacl(inode, 209 alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT);
385 ACL_TYPE_DEFAULT); 210 if (IS_ERR(alloc))
386 if (IS_ERR(alloc)) 211 goto fail;
387 goto fail; 212 break;
388 break; 213
389 214 case ACL_TYPE_DEFAULT:
390 case ACL_TYPE_DEFAULT: 215 dfacl = acl;
391 dfacl = acl; 216 alloc = acl = get_acl(inode, ACL_TYPE_ACCESS);
392 alloc = acl = nfs3_proc_getacl(inode, 217 if (IS_ERR(alloc))
393 ACL_TYPE_ACCESS); 218 goto fail;
394 if (IS_ERR(alloc)) 219 break;
395 goto fail;
396 break;
397
398 default:
399 return -EINVAL;
400 } 220 }
401 } else if (type != ACL_TYPE_ACCESS) 221 }
402 return -EINVAL;
403 222
404 if (acl == NULL) { 223 if (acl == NULL) {
405 alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 224 alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
@@ -417,24 +236,24 @@ fail:
417int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, 236int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
418 umode_t mode) 237 umode_t mode)
419{ 238{
420 struct posix_acl *dfacl, *acl; 239 struct posix_acl *default_acl, *acl;
421 int error = 0; 240 int error;
422 241
423 dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT); 242 error = posix_acl_create(dir, &mode, &default_acl, &acl);
424 if (IS_ERR(dfacl)) { 243 if (error)
425 error = PTR_ERR(dfacl);
426 return (error == -EOPNOTSUPP) ? 0 : error; 244 return (error == -EOPNOTSUPP) ? 0 : error;
427 } 245
428 if (!dfacl) 246 error = nfs3_proc_setacls(inode, acl, default_acl);
429 return 0; 247
430 acl = posix_acl_dup(dfacl); 248 if (acl)
431 error = posix_acl_create(&acl, GFP_KERNEL, &mode); 249 posix_acl_release(acl);
432 if (error < 0) 250 if (default_acl)
433 goto out_release_dfacl; 251 posix_acl_release(default_acl);
434 error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
435 dfacl : NULL);
436 posix_acl_release(acl);
437out_release_dfacl:
438 posix_acl_release(dfacl);
439 return error; 252 return error;
440} 253}
254
255const struct xattr_handler *nfs3_xattr_handlers[] = {
256 &posix_acl_access_xattr_handler,
257 &posix_acl_default_xattr_handler,
258 NULL,
259};
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 01b6f6a49d16..d2255d705421 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -317,8 +317,8 @@ static int
317nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 317nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
318 int flags) 318 int flags)
319{ 319{
320 struct posix_acl *default_acl, *acl;
320 struct nfs3_createdata *data; 321 struct nfs3_createdata *data;
321 umode_t mode = sattr->ia_mode;
322 int status = -ENOMEM; 322 int status = -ENOMEM;
323 323
324 dprintk("NFS call create %pd\n", dentry); 324 dprintk("NFS call create %pd\n", dentry);
@@ -340,7 +340,9 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
340 data->arg.create.verifier[1] = cpu_to_be32(current->pid); 340 data->arg.create.verifier[1] = cpu_to_be32(current->pid);
341 } 341 }
342 342
343 sattr->ia_mode &= ~current_umask(); 343 status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
344 if (status)
345 goto out;
344 346
345 for (;;) { 347 for (;;) {
346 status = nfs3_do_create(dir, dentry, data); 348 status = nfs3_do_create(dir, dentry, data);
@@ -366,7 +368,7 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
366 } 368 }
367 369
368 if (status != 0) 370 if (status != 0)
369 goto out; 371 goto out_release_acls;
370 372
371 /* When we created the file with exclusive semantics, make 373 /* When we created the file with exclusive semantics, make
372 * sure we set the attributes afterwards. */ 374 * sure we set the attributes afterwards. */
@@ -385,9 +387,14 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
385 nfs_post_op_update_inode(dentry->d_inode, data->res.fattr); 387 nfs_post_op_update_inode(dentry->d_inode, data->res.fattr);
386 dprintk("NFS reply setattr (post-create): %d\n", status); 388 dprintk("NFS reply setattr (post-create): %d\n", status);
387 if (status != 0) 389 if (status != 0)
388 goto out; 390 goto out_release_acls;
389 } 391 }
390 status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); 392
393 status = nfs3_proc_setacls(dentry->d_inode, acl, default_acl);
394
395out_release_acls:
396 posix_acl_release(acl);
397 posix_acl_release(default_acl);
391out: 398out:
392 nfs3_free_createdata(data); 399 nfs3_free_createdata(data);
393 dprintk("NFS reply create: %d\n", status); 400 dprintk("NFS reply create: %d\n", status);
@@ -572,18 +579,20 @@ out:
572static int 579static int
573nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) 580nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
574{ 581{
582 struct posix_acl *default_acl, *acl;
575 struct nfs3_createdata *data; 583 struct nfs3_createdata *data;
576 umode_t mode = sattr->ia_mode;
577 int status = -ENOMEM; 584 int status = -ENOMEM;
578 585
579 dprintk("NFS call mkdir %pd\n", dentry); 586 dprintk("NFS call mkdir %pd\n", dentry);
580 587
581 sattr->ia_mode &= ~current_umask();
582
583 data = nfs3_alloc_createdata(); 588 data = nfs3_alloc_createdata();
584 if (data == NULL) 589 if (data == NULL)
585 goto out; 590 goto out;
586 591
592 status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
593 if (status)
594 goto out;
595
587 data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR]; 596 data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
588 data->arg.mkdir.fh = NFS_FH(dir); 597 data->arg.mkdir.fh = NFS_FH(dir);
589 data->arg.mkdir.name = dentry->d_name.name; 598 data->arg.mkdir.name = dentry->d_name.name;
@@ -592,9 +601,13 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
592 601
593 status = nfs3_do_create(dir, dentry, data); 602 status = nfs3_do_create(dir, dentry, data);
594 if (status != 0) 603 if (status != 0)
595 goto out; 604 goto out_release_acls;
596 605
597 status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); 606 status = nfs3_proc_setacls(dentry->d_inode, acl, default_acl);
607
608out_release_acls:
609 posix_acl_release(acl);
610 posix_acl_release(default_acl);
598out: 611out:
599 nfs3_free_createdata(data); 612 nfs3_free_createdata(data);
600 dprintk("NFS reply mkdir: %d\n", status); 613 dprintk("NFS reply mkdir: %d\n", status);
@@ -691,19 +704,21 @@ static int
691nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 704nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
692 dev_t rdev) 705 dev_t rdev)
693{ 706{
707 struct posix_acl *default_acl, *acl;
694 struct nfs3_createdata *data; 708 struct nfs3_createdata *data;
695 umode_t mode = sattr->ia_mode;
696 int status = -ENOMEM; 709 int status = -ENOMEM;
697 710
698 dprintk("NFS call mknod %pd %u:%u\n", dentry, 711 dprintk("NFS call mknod %pd %u:%u\n", dentry,
699 MAJOR(rdev), MINOR(rdev)); 712 MAJOR(rdev), MINOR(rdev));
700 713
701 sattr->ia_mode &= ~current_umask();
702
703 data = nfs3_alloc_createdata(); 714 data = nfs3_alloc_createdata();
704 if (data == NULL) 715 if (data == NULL)
705 goto out; 716 goto out;
706 717
718 status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
719 if (status)
720 goto out;
721
707 data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD]; 722 data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD];
708 data->arg.mknod.fh = NFS_FH(dir); 723 data->arg.mknod.fh = NFS_FH(dir);
709 data->arg.mknod.name = dentry->d_name.name; 724 data->arg.mknod.name = dentry->d_name.name;
@@ -731,8 +746,13 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
731 746
732 status = nfs3_do_create(dir, dentry, data); 747 status = nfs3_do_create(dir, dentry, data);
733 if (status != 0) 748 if (status != 0)
734 goto out; 749 goto out_release_acls;
735 status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode); 750
751 status = nfs3_proc_setacls(dentry->d_inode, acl, default_acl);
752
753out_release_acls:
754 posix_acl_release(acl);
755 posix_acl_release(default_acl);
736out: 756out:
737 nfs3_free_createdata(data); 757 nfs3_free_createdata(data);
738 dprintk("NFS reply mknod: %d\n", status); 758 dprintk("NFS reply mknod: %d\n", status);
@@ -904,20 +924,28 @@ static const struct inode_operations nfs3_dir_inode_operations = {
904 .permission = nfs_permission, 924 .permission = nfs_permission,
905 .getattr = nfs_getattr, 925 .getattr = nfs_getattr,
906 .setattr = nfs_setattr, 926 .setattr = nfs_setattr,
907 .listxattr = nfs3_listxattr, 927 .listxattr = generic_listxattr,
908 .getxattr = nfs3_getxattr, 928 .getxattr = generic_getxattr,
909 .setxattr = nfs3_setxattr, 929 .setxattr = generic_setxattr,
910 .removexattr = nfs3_removexattr, 930 .removexattr = generic_removexattr,
931#ifdef CONFIG_NFS_V3_ACL
932 .get_acl = nfs3_get_acl,
933 .set_acl = nfs3_set_acl,
934#endif
911}; 935};
912 936
913static const struct inode_operations nfs3_file_inode_operations = { 937static const struct inode_operations nfs3_file_inode_operations = {
914 .permission = nfs_permission, 938 .permission = nfs_permission,
915 .getattr = nfs_getattr, 939 .getattr = nfs_getattr,
916 .setattr = nfs_setattr, 940 .setattr = nfs_setattr,
917 .listxattr = nfs3_listxattr, 941 .listxattr = generic_listxattr,
918 .getxattr = nfs3_getxattr, 942 .getxattr = generic_getxattr,
919 .setxattr = nfs3_setxattr, 943 .setxattr = generic_setxattr,
920 .removexattr = nfs3_removexattr, 944 .removexattr = generic_removexattr,
945#ifdef CONFIG_NFS_V3_ACL
946 .get_acl = nfs3_get_acl,
947 .set_acl = nfs3_set_acl,
948#endif
921}; 949};
922 950
923const struct nfs_rpc_ops nfs_v3_clientops = { 951const struct nfs_rpc_ops nfs_v3_clientops = {
@@ -965,7 +993,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
965 .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare, 993 .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare,
966 .commit_done = nfs3_commit_done, 994 .commit_done = nfs3_commit_done,
967 .lock = nfs3_proc_lock, 995 .lock = nfs3_proc_lock,
968 .clear_acl_cache = nfs3_forget_cached_acls, 996 .clear_acl_cache = forget_all_cached_acls,
969 .close_context = nfs_close_context, 997 .close_context = nfs_close_context,
970 .have_delegation = nfs3_have_delegation, 998 .have_delegation = nfs3_have_delegation,
971 .return_delegation = nfs3_return_delegation, 999 .return_delegation = nfs3_return_delegation,
diff --git a/fs/nfs/nfs3super.c b/fs/nfs/nfs3super.c
index cc471c725230..d6a98949af19 100644
--- a/fs/nfs/nfs3super.c
+++ b/fs/nfs/nfs3super.c
@@ -12,6 +12,9 @@ static struct nfs_subversion nfs_v3 = {
12 .rpc_vers = &nfs_version3, 12 .rpc_vers = &nfs_version3,
13 .rpc_ops = &nfs_v3_clientops, 13 .rpc_ops = &nfs_v3_clientops,
14 .sops = &nfs_sops, 14 .sops = &nfs_sops,
15#ifdef CONFIG_NFS_V3_ACL
16 .xattr = nfs3_xattr_handlers,
17#endif
15}; 18};
16 19
17static int __init init_nfs_v3(void) 20static int __init init_nfs_v3(void)
diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
index 8b186a4955cc..8b68218e2c1c 100644
--- a/fs/nfsd/acl.h
+++ b/fs/nfsd/acl.h
@@ -35,7 +35,9 @@
35#ifndef LINUX_NFS4_ACL_H 35#ifndef LINUX_NFS4_ACL_H
36#define LINUX_NFS4_ACL_H 36#define LINUX_NFS4_ACL_H
37 37
38#include <linux/posix_acl.h> 38struct nfs4_acl;
39struct svc_fh;
40struct svc_rqst;
39 41
40/* Maximum ACL we'll accept from client; chosen (somewhat arbitrarily) to 42/* Maximum ACL we'll accept from client; chosen (somewhat arbitrarily) to
41 * fit in a page: */ 43 * fit in a page: */
@@ -45,13 +47,9 @@ struct nfs4_acl *nfs4_acl_new(int);
45int nfs4_acl_get_whotype(char *, u32); 47int nfs4_acl_get_whotype(char *, u32);
46int nfs4_acl_write_who(int who, char *p); 48int nfs4_acl_write_who(int who, char *p);
47 49
48#define NFS4_ACL_TYPE_DEFAULT 0x01 50int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
49#define NFS4_ACL_DIR 0x02 51 struct nfs4_acl **acl);
50#define NFS4_ACL_OWNER 0x04 52__be32 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
51 53 struct nfs4_acl *acl);
52struct nfs4_acl *nfs4_acl_posix_to_nfsv4(struct posix_acl *,
53 struct posix_acl *, unsigned int flags);
54int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *, struct posix_acl **,
55 struct posix_acl **, unsigned int flags);
56 54
57#endif /* LINUX_NFS4_ACL_H */ 55#endif /* LINUX_NFS4_ACL_H */
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 95d76dc6c5da..11c1fba29312 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -30,8 +30,9 @@ nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
30static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, 30static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
31 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) 31 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
32{ 32{
33 svc_fh *fh;
34 struct posix_acl *acl; 33 struct posix_acl *acl;
34 struct inode *inode;
35 svc_fh *fh;
35 __be32 nfserr = 0; 36 __be32 nfserr = 0;
36 37
37 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 38 dprintk("nfsd: GETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
@@ -41,6 +42,8 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
41 if (nfserr) 42 if (nfserr)
42 RETURN_STATUS(nfserr); 43 RETURN_STATUS(nfserr);
43 44
45 inode = fh->fh_dentry->d_inode;
46
44 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) 47 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
45 RETURN_STATUS(nfserr_inval); 48 RETURN_STATUS(nfserr_inval);
46 resp->mask = argp->mask; 49 resp->mask = argp->mask;
@@ -50,21 +53,13 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
50 goto fail; 53 goto fail;
51 54
52 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { 55 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
53 acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS); 56 acl = get_acl(inode, ACL_TYPE_ACCESS);
54 if (IS_ERR(acl)) { 57 if (IS_ERR(acl)) {
55 int err = PTR_ERR(acl); 58 nfserr = nfserrno(PTR_ERR(acl));
56 59 goto fail;
57 if (err == -ENODATA || err == -EOPNOTSUPP)
58 acl = NULL;
59 else {
60 nfserr = nfserrno(err);
61 goto fail;
62 }
63 } 60 }
64 if (acl == NULL) { 61 if (acl == NULL) {
65 /* Solaris returns the inode's minimum ACL. */ 62 /* Solaris returns the inode's minimum ACL. */
66
67 struct inode *inode = fh->fh_dentry->d_inode;
68 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 63 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
69 } 64 }
70 resp->acl_access = acl; 65 resp->acl_access = acl;
@@ -72,17 +67,10 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
72 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) { 67 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
73 /* Check how Solaris handles requests for the Default ACL 68 /* Check how Solaris handles requests for the Default ACL
74 of a non-directory! */ 69 of a non-directory! */
75 70 acl = get_acl(inode, ACL_TYPE_DEFAULT);
76 acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
77 if (IS_ERR(acl)) { 71 if (IS_ERR(acl)) {
78 int err = PTR_ERR(acl); 72 nfserr = nfserrno(PTR_ERR(acl));
79 73 goto fail;
80 if (err == -ENODATA || err == -EOPNOTSUPP)
81 acl = NULL;
82 else {
83 nfserr = nfserrno(err);
84 goto fail;
85 }
86 } 74 }
87 resp->acl_default = acl; 75 resp->acl_default = acl;
88 } 76 }
@@ -103,31 +91,51 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
103 struct nfsd3_setaclargs *argp, 91 struct nfsd3_setaclargs *argp,
104 struct nfsd_attrstat *resp) 92 struct nfsd_attrstat *resp)
105{ 93{
94 struct inode *inode;
106 svc_fh *fh; 95 svc_fh *fh;
107 __be32 nfserr = 0; 96 __be32 nfserr = 0;
97 int error;
108 98
109 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); 99 dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh));
110 100
111 fh = fh_copy(&resp->fh, &argp->fh); 101 fh = fh_copy(&resp->fh, &argp->fh);
112 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR); 102 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR);
103 if (nfserr)
104 goto out;
113 105
114 if (!nfserr) { 106 inode = fh->fh_dentry->d_inode;
115 nfserr = nfserrno( nfsd_set_posix_acl( 107 if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
116 fh, ACL_TYPE_ACCESS, argp->acl_access) ); 108 error = -EOPNOTSUPP;
117 } 109 goto out_errno;
118 if (!nfserr) {
119 nfserr = nfserrno( nfsd_set_posix_acl(
120 fh, ACL_TYPE_DEFAULT, argp->acl_default) );
121 }
122 if (!nfserr) {
123 nfserr = fh_getattr(fh, &resp->stat);
124 } 110 }
125 111
112 error = fh_want_write(fh);
113 if (error)
114 goto out_errno;
115
116 error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
117 if (error)
118 goto out_drop_write;
119 error = inode->i_op->set_acl(inode, argp->acl_default,
120 ACL_TYPE_DEFAULT);
121 if (error)
122 goto out_drop_write;
123
124 fh_drop_write(fh);
125
126 nfserr = fh_getattr(fh, &resp->stat);
127
128out:
126 /* argp->acl_{access,default} may have been allocated in 129 /* argp->acl_{access,default} may have been allocated in
127 nfssvc_decode_setaclargs. */ 130 nfssvc_decode_setaclargs. */
128 posix_acl_release(argp->acl_access); 131 posix_acl_release(argp->acl_access);
129 posix_acl_release(argp->acl_default); 132 posix_acl_release(argp->acl_default);
130 return nfserr; 133 return nfserr;
134out_drop_write:
135 fh_drop_write(fh);
136out_errno:
137 nfserr = nfserrno(error);
138 goto out;
131} 139}
132 140
133/* 141/*
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 9cbc1a841f87..adc5f1b1dc26 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -29,8 +29,9 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
29static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, 29static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp,
30 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) 30 struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
31{ 31{
32 svc_fh *fh;
33 struct posix_acl *acl; 32 struct posix_acl *acl;
33 struct inode *inode;
34 svc_fh *fh;
34 __be32 nfserr = 0; 35 __be32 nfserr = 0;
35 36
36 fh = fh_copy(&resp->fh, &argp->fh); 37 fh = fh_copy(&resp->fh, &argp->fh);
@@ -38,26 +39,20 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp,
38 if (nfserr) 39 if (nfserr)
39 RETURN_STATUS(nfserr); 40 RETURN_STATUS(nfserr);
40 41
42 inode = fh->fh_dentry->d_inode;
43
41 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) 44 if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
42 RETURN_STATUS(nfserr_inval); 45 RETURN_STATUS(nfserr_inval);
43 resp->mask = argp->mask; 46 resp->mask = argp->mask;
44 47
45 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { 48 if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
46 acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS); 49 acl = get_acl(inode, ACL_TYPE_ACCESS);
47 if (IS_ERR(acl)) { 50 if (IS_ERR(acl)) {
48 int err = PTR_ERR(acl); 51 nfserr = nfserrno(PTR_ERR(acl));
49 52 goto fail;
50 if (err == -ENODATA || err == -EOPNOTSUPP)
51 acl = NULL;
52 else {
53 nfserr = nfserrno(err);
54 goto fail;
55 }
56 } 53 }
57 if (acl == NULL) { 54 if (acl == NULL) {
58 /* Solaris returns the inode's minimum ACL. */ 55 /* Solaris returns the inode's minimum ACL. */
59
60 struct inode *inode = fh->fh_dentry->d_inode;
61 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 56 acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
62 } 57 }
63 resp->acl_access = acl; 58 resp->acl_access = acl;
@@ -65,17 +60,10 @@ static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp,
65 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) { 60 if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
66 /* Check how Solaris handles requests for the Default ACL 61 /* Check how Solaris handles requests for the Default ACL
67 of a non-directory! */ 62 of a non-directory! */
68 63 acl = get_acl(inode, ACL_TYPE_DEFAULT);
69 acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
70 if (IS_ERR(acl)) { 64 if (IS_ERR(acl)) {
71 int err = PTR_ERR(acl); 65 nfserr = nfserrno(PTR_ERR(acl));
72 66 goto fail;
73 if (err == -ENODATA || err == -EOPNOTSUPP)
74 acl = NULL;
75 else {
76 nfserr = nfserrno(err);
77 goto fail;
78 }
79 } 67 }
80 resp->acl_default = acl; 68 resp->acl_default = acl;
81 } 69 }
@@ -96,21 +84,37 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp,
96 struct nfsd3_setaclargs *argp, 84 struct nfsd3_setaclargs *argp,
97 struct nfsd3_attrstat *resp) 85 struct nfsd3_attrstat *resp)
98{ 86{
87 struct inode *inode;
99 svc_fh *fh; 88 svc_fh *fh;
100 __be32 nfserr = 0; 89 __be32 nfserr = 0;
90 int error;
101 91
102 fh = fh_copy(&resp->fh, &argp->fh); 92 fh = fh_copy(&resp->fh, &argp->fh);
103 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR); 93 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR);
94 if (nfserr)
95 goto out;
104 96
105 if (!nfserr) { 97 inode = fh->fh_dentry->d_inode;
106 nfserr = nfserrno( nfsd_set_posix_acl( 98 if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
107 fh, ACL_TYPE_ACCESS, argp->acl_access) ); 99 error = -EOPNOTSUPP;
108 } 100 goto out_errno;
109 if (!nfserr) {
110 nfserr = nfserrno( nfsd_set_posix_acl(
111 fh, ACL_TYPE_DEFAULT, argp->acl_default) );
112 } 101 }
113 102
103 error = fh_want_write(fh);
104 if (error)
105 goto out_errno;
106
107 error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
108 if (error)
109 goto out_drop_write;
110 error = inode->i_op->set_acl(inode, argp->acl_default,
111 ACL_TYPE_DEFAULT);
112
113out_drop_write:
114 fh_drop_write(fh);
115out_errno:
116 nfserr = nfserrno(error);
117out:
114 /* argp->acl_{access,default} may have been allocated in 118 /* argp->acl_{access,default} may have been allocated in
115 nfs3svc_decode_setaclargs. */ 119 nfs3svc_decode_setaclargs. */
116 posix_acl_release(argp->acl_access); 120 posix_acl_release(argp->acl_access);
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 8a50b3c18093..649ad7cf2204 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -37,8 +37,13 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/nfs_fs.h> 38#include <linux/nfs_fs.h>
39#include <linux/export.h> 39#include <linux/export.h>
40#include "nfsfh.h"
40#include "acl.h" 41#include "acl.h"
42#include "vfs.h"
41 43
44#define NFS4_ACL_TYPE_DEFAULT 0x01
45#define NFS4_ACL_DIR 0x02
46#define NFS4_ACL_OWNER 0x04
42 47
43/* mode bit translations: */ 48/* mode bit translations: */
44#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) 49#define NFS4_READ_MODE (NFS4_ACE_READ_DATA)
@@ -130,36 +135,50 @@ static short ace2type(struct nfs4_ace *);
130static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, 135static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *,
131 unsigned int); 136 unsigned int);
132 137
133struct nfs4_acl * 138int
134nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl, 139nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
135 unsigned int flags) 140 struct nfs4_acl **acl)
136{ 141{
137 struct nfs4_acl *acl; 142 struct inode *inode = dentry->d_inode;
143 int error = 0;
144 struct posix_acl *pacl = NULL, *dpacl = NULL;
145 unsigned int flags = 0;
138 int size = 0; 146 int size = 0;
139 147
140 if (pacl) { 148 pacl = get_acl(inode, ACL_TYPE_ACCESS);
141 if (posix_acl_valid(pacl) < 0) 149 if (!pacl) {
142 return ERR_PTR(-EINVAL); 150 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
143 size += 2*pacl->a_count; 151 if (IS_ERR(pacl))
152 return PTR_ERR(pacl);
153 /* allocate for worst case: one (deny, allow) pair each: */
154 size += 2 * pacl->a_count;
144 } 155 }
145 if (dpacl) { 156
146 if (posix_acl_valid(dpacl) < 0) 157 if (S_ISDIR(inode->i_mode)) {
147 return ERR_PTR(-EINVAL); 158 flags = NFS4_ACL_DIR;
148 size += 2*dpacl->a_count; 159 dpacl = get_acl(inode, ACL_TYPE_DEFAULT);
160 if (dpacl)
161 size += 2 * dpacl->a_count;
162 } else {
163 dpacl = NULL;
149 } 164 }
150 165
151 /* Allocate for worst case: one (deny, allow) pair each: */ 166 *acl = nfs4_acl_new(size);
152 acl = nfs4_acl_new(size); 167 if (*acl == NULL) {
153 if (acl == NULL) 168 error = -ENOMEM;
154 return ERR_PTR(-ENOMEM); 169 goto out;
170 }
155 171
156 if (pacl) 172 if (pacl)
157 _posix_to_nfsv4_one(pacl, acl, flags & ~NFS4_ACL_TYPE_DEFAULT); 173 _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT);
158 174
159 if (dpacl) 175 if (dpacl)
160 _posix_to_nfsv4_one(dpacl, acl, flags | NFS4_ACL_TYPE_DEFAULT); 176 _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT);
161 177
162 return acl; 178 out:
179 posix_acl_release(pacl);
180 posix_acl_release(dpacl);
181 return error;
163} 182}
164 183
165struct posix_acl_summary { 184struct posix_acl_summary {
@@ -719,8 +738,9 @@ static void process_one_v4_ace(struct posix_acl_state *state,
719 } 738 }
720} 739}
721 740
722int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, 741static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl,
723 struct posix_acl **dpacl, unsigned int flags) 742 struct posix_acl **pacl, struct posix_acl **dpacl,
743 unsigned int flags)
724{ 744{
725 struct posix_acl_state effective_acl_state, default_acl_state; 745 struct posix_acl_state effective_acl_state, default_acl_state;
726 struct nfs4_ace *ace; 746 struct nfs4_ace *ace;
@@ -780,6 +800,57 @@ out_estate:
780 return ret; 800 return ret;
781} 801}
782 802
803__be32
804nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
805 struct nfs4_acl *acl)
806{
807 __be32 error;
808 int host_error;
809 struct dentry *dentry;
810 struct inode *inode;
811 struct posix_acl *pacl = NULL, *dpacl = NULL;
812 unsigned int flags = 0;
813
814 /* Get inode */
815 error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR);
816 if (error)
817 return error;
818
819 dentry = fhp->fh_dentry;
820 inode = dentry->d_inode;
821
822 if (!inode->i_op->set_acl || !IS_POSIXACL(inode))
823 return nfserr_attrnotsupp;
824
825 if (S_ISDIR(inode->i_mode))
826 flags = NFS4_ACL_DIR;
827
828 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
829 if (host_error == -EINVAL)
830 return nfserr_attrnotsupp;
831 if (host_error < 0)
832 goto out_nfserr;
833
834 host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS);
835 if (host_error < 0)
836 goto out_release;
837
838 if (S_ISDIR(inode->i_mode)) {
839 host_error = inode->i_op->set_acl(inode, dpacl,
840 ACL_TYPE_DEFAULT);
841 }
842
843out_release:
844 posix_acl_release(pacl);
845 posix_acl_release(dpacl);
846out_nfserr:
847 if (host_error == -EOPNOTSUPP)
848 return nfserr_attrnotsupp;
849 else
850 return nfserrno(host_error);
851}
852
853
783static short 854static short
784ace2type(struct nfs4_ace *ace) 855ace2type(struct nfs4_ace *ace)
785{ 856{
@@ -798,9 +869,6 @@ ace2type(struct nfs4_ace *ace)
798 return -1; 869 return -1;
799} 870}
800 871
801EXPORT_SYMBOL(nfs4_acl_posix_to_nfsv4);
802EXPORT_SYMBOL(nfs4_acl_nfsv4_to_posix);
803
804struct nfs4_acl * 872struct nfs4_acl *
805nfs4_acl_new(int n) 873nfs4_acl_new(int n)
806{ 874{
@@ -862,7 +930,3 @@ nfs4_acl_write_who(int who, char *p)
862 BUG(); 930 BUG();
863 return -1; 931 return -1;
864} 932}
865
866EXPORT_SYMBOL(nfs4_acl_new);
867EXPORT_SYMBOL(nfs4_acl_get_whotype);
868EXPORT_SYMBOL(nfs4_acl_write_who);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 419572f33b72..825b8a99b99b 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -41,6 +41,7 @@
41#include "vfs.h" 41#include "vfs.h"
42#include "current_stateid.h" 42#include "current_stateid.h"
43#include "netns.h" 43#include "netns.h"
44#include "acl.h"
44 45
45#ifdef CONFIG_NFSD_V4_SECURITY_LABEL 46#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
46#include <linux/security.h> 47#include <linux/security.h>
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7eea63cada1d..1426eb66c8c6 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -468,158 +468,7 @@ out:
468 return err; 468 return err;
469} 469}
470 470
471#if defined(CONFIG_NFSD_V2_ACL) || \
472 defined(CONFIG_NFSD_V3_ACL) || \
473 defined(CONFIG_NFSD_V4)
474static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
475{
476 ssize_t buflen;
477 ssize_t ret;
478
479 buflen = vfs_getxattr(dentry, key, NULL, 0);
480 if (buflen <= 0)
481 return buflen;
482
483 *buf = kmalloc(buflen, GFP_KERNEL);
484 if (!*buf)
485 return -ENOMEM;
486
487 ret = vfs_getxattr(dentry, key, *buf, buflen);
488 if (ret < 0)
489 kfree(*buf);
490 return ret;
491}
492#endif
493
494#if defined(CONFIG_NFSD_V4) 471#if defined(CONFIG_NFSD_V4)
495static int
496set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
497{
498 int len;
499 size_t buflen;
500 char *buf = NULL;
501 int error = 0;
502
503 buflen = posix_acl_xattr_size(pacl->a_count);
504 buf = kmalloc(buflen, GFP_KERNEL);
505 error = -ENOMEM;
506 if (buf == NULL)
507 goto out;
508
509 len = posix_acl_to_xattr(&init_user_ns, pacl, buf, buflen);
510 if (len < 0) {
511 error = len;
512 goto out;
513 }
514
515 error = vfs_setxattr(dentry, key, buf, len, 0);
516out:
517 kfree(buf);
518 return error;
519}
520
521__be32
522nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
523 struct nfs4_acl *acl)
524{
525 __be32 error;
526 int host_error;
527 struct dentry *dentry;
528 struct inode *inode;
529 struct posix_acl *pacl = NULL, *dpacl = NULL;
530 unsigned int flags = 0;
531
532 /* Get inode */
533 error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR);
534 if (error)
535 return error;
536
537 dentry = fhp->fh_dentry;
538 inode = dentry->d_inode;
539 if (S_ISDIR(inode->i_mode))
540 flags = NFS4_ACL_DIR;
541
542 host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
543 if (host_error == -EINVAL) {
544 return nfserr_attrnotsupp;
545 } else if (host_error < 0)
546 goto out_nfserr;
547
548 host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
549 if (host_error < 0)
550 goto out_release;
551
552 if (S_ISDIR(inode->i_mode))
553 host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
554
555out_release:
556 posix_acl_release(pacl);
557 posix_acl_release(dpacl);
558out_nfserr:
559 if (host_error == -EOPNOTSUPP)
560 return nfserr_attrnotsupp;
561 else
562 return nfserrno(host_error);
563}
564
565static struct posix_acl *
566_get_posix_acl(struct dentry *dentry, char *key)
567{
568 void *buf = NULL;
569 struct posix_acl *pacl = NULL;
570 int buflen;
571
572 buflen = nfsd_getxattr(dentry, key, &buf);
573 if (!buflen)
574 buflen = -ENODATA;
575 if (buflen <= 0)
576 return ERR_PTR(buflen);
577
578 pacl = posix_acl_from_xattr(&init_user_ns, buf, buflen);
579 kfree(buf);
580 return pacl;
581}
582
583int
584nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl)
585{
586 struct inode *inode = dentry->d_inode;
587 int error = 0;
588 struct posix_acl *pacl = NULL, *dpacl = NULL;
589 unsigned int flags = 0;
590
591 pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
592 if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA)
593 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
594 if (IS_ERR(pacl)) {
595 error = PTR_ERR(pacl);
596 pacl = NULL;
597 goto out;
598 }
599
600 if (S_ISDIR(inode->i_mode)) {
601 dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
602 if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA)
603 dpacl = NULL;
604 else if (IS_ERR(dpacl)) {
605 error = PTR_ERR(dpacl);
606 dpacl = NULL;
607 goto out;
608 }
609 flags = NFS4_ACL_DIR;
610 }
611
612 *acl = nfs4_acl_posix_to_nfsv4(pacl, dpacl, flags);
613 if (IS_ERR(*acl)) {
614 error = PTR_ERR(*acl);
615 *acl = NULL;
616 }
617 out:
618 posix_acl_release(pacl);
619 posix_acl_release(dpacl);
620 return error;
621}
622
623/* 472/*
624 * NFS junction information is stored in an extended attribute. 473 * NFS junction information is stored in an extended attribute.
625 */ 474 */
@@ -2284,93 +2133,3 @@ out_nomem:
2284 nfsd_racache_shutdown(); 2133 nfsd_racache_shutdown();
2285 return -ENOMEM; 2134 return -ENOMEM;
2286} 2135}
2287
2288#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
2289struct posix_acl *
2290nfsd_get_posix_acl(struct svc_fh *fhp, int type)
2291{
2292 struct inode *inode = fhp->fh_dentry->d_inode;
2293 char *name;
2294 void *value = NULL;
2295 ssize_t size;
2296 struct posix_acl *acl;
2297
2298 if (!IS_POSIXACL(inode))
2299 return ERR_PTR(-EOPNOTSUPP);
2300
2301 switch (type) {
2302 case ACL_TYPE_ACCESS:
2303 name = POSIX_ACL_XATTR_ACCESS;
2304 break;
2305 case ACL_TYPE_DEFAULT:
2306 name = POSIX_ACL_XATTR_DEFAULT;
2307 break;
2308 default:
2309 return ERR_PTR(-EOPNOTSUPP);
2310 }
2311
2312 size = nfsd_getxattr(fhp->fh_dentry, name, &value);
2313 if (size < 0)
2314 return ERR_PTR(size);
2315
2316 acl = posix_acl_from_xattr(&init_user_ns, value, size);
2317 kfree(value);
2318 return acl;
2319}
2320
2321int
2322nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
2323{
2324 struct inode *inode = fhp->fh_dentry->d_inode;
2325 char *name;
2326 void *value = NULL;
2327 size_t size;
2328 int error;
2329
2330 if (!IS_POSIXACL(inode) ||
2331 !inode->i_op->setxattr || !inode->i_op->removexattr)
2332 return -EOPNOTSUPP;
2333 switch(type) {
2334 case ACL_TYPE_ACCESS:
2335 name = POSIX_ACL_XATTR_ACCESS;
2336 break;
2337 case ACL_TYPE_DEFAULT:
2338 name = POSIX_ACL_XATTR_DEFAULT;
2339 break;
2340 default:
2341 return -EOPNOTSUPP;
2342 }
2343
2344 if (acl && acl->a_count) {
2345 size = posix_acl_xattr_size(acl->a_count);
2346 value = kmalloc(size, GFP_KERNEL);
2347 if (!value)
2348 return -ENOMEM;
2349 error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
2350 if (error < 0)
2351 goto getout;
2352 size = error;
2353 } else
2354 size = 0;
2355
2356 error = fh_want_write(fhp);
2357 if (error)
2358 goto getout;
2359 if (size)
2360 error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
2361 else {
2362 if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
2363 error = 0;
2364 else {
2365 error = vfs_removexattr(fhp->fh_dentry, name);
2366 if (error == -ENODATA)
2367 error = 0;
2368 }
2369 }
2370 fh_drop_write(fhp);
2371
2372getout:
2373 kfree(value);
2374 return error;
2375}
2376#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index a4be2e389670..1bc1d440a1a5 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -52,9 +52,6 @@ __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *,
52 struct iattr *, int, time_t); 52 struct iattr *, int, time_t);
53int nfsd_mountpoint(struct dentry *, struct svc_export *); 53int nfsd_mountpoint(struct dentry *, struct svc_export *);
54#ifdef CONFIG_NFSD_V4 54#ifdef CONFIG_NFSD_V4
55__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
56 struct nfs4_acl *);
57int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
58__be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, 55__be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
59 struct xdr_netobj *); 56 struct xdr_netobj *);
60#endif /* CONFIG_NFSD_V4 */ 57#endif /* CONFIG_NFSD_V4 */
@@ -101,11 +98,6 @@ __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
101__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, 98__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
102 struct dentry *, int); 99 struct dentry *, int);
103 100
104#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
105struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
106int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
107#endif
108
109static inline int fh_want_write(struct svc_fh *fh) 101static inline int fh_want_write(struct svc_fh *fh)
110{ 102{
111 int ret = mnt_want_write(fh->fh_export->ex_path.mnt); 103 int ret = mnt_want_write(fh->fh_export->ex_path.mnt);
diff --git a/fs/nls/mac-celtic.c b/fs/nls/mac-celtic.c
index 634a8b717b02..266c2d7d50bd 100644
--- a/fs/nls/mac-celtic.c
+++ b/fs/nls/mac-celtic.c
@@ -583,7 +583,6 @@ static struct nls_table table = {
583 .char2uni = char2uni, 583 .char2uni = char2uni,
584 .charset2lower = charset2lower, 584 .charset2lower = charset2lower,
585 .charset2upper = charset2upper, 585 .charset2upper = charset2upper,
586 .owner = THIS_MODULE,
587}; 586};
588 587
589static int __init init_nls_macceltic(void) 588static int __init init_nls_macceltic(void)
diff --git a/fs/nls/mac-centeuro.c b/fs/nls/mac-centeuro.c
index 979e6265ac5e..9789c6057551 100644
--- a/fs/nls/mac-centeuro.c
+++ b/fs/nls/mac-centeuro.c
@@ -513,7 +513,6 @@ static struct nls_table table = {
513 .char2uni = char2uni, 513 .char2uni = char2uni,
514 .charset2lower = charset2lower, 514 .charset2lower = charset2lower,
515 .charset2upper = charset2upper, 515 .charset2upper = charset2upper,
516 .owner = THIS_MODULE,
517}; 516};
518 517
519static int __init init_nls_maccenteuro(void) 518static int __init init_nls_maccenteuro(void)
diff --git a/fs/nls/mac-croatian.c b/fs/nls/mac-croatian.c
index dd3f675911ee..bb19e7a07d43 100644
--- a/fs/nls/mac-croatian.c
+++ b/fs/nls/mac-croatian.c
@@ -583,7 +583,6 @@ static struct nls_table table = {
583 .char2uni = char2uni, 583 .char2uni = char2uni,
584 .charset2lower = charset2lower, 584 .charset2lower = charset2lower,
585 .charset2upper = charset2upper, 585 .charset2upper = charset2upper,
586 .owner = THIS_MODULE,
587}; 586};
588 587
589static int __init init_nls_maccroatian(void) 588static int __init init_nls_maccroatian(void)
diff --git a/fs/nls/mac-cyrillic.c b/fs/nls/mac-cyrillic.c
index 1112c84dd8bb..2a7dea36acba 100644
--- a/fs/nls/mac-cyrillic.c
+++ b/fs/nls/mac-cyrillic.c
@@ -478,7 +478,6 @@ static struct nls_table table = {
478 .char2uni = char2uni, 478 .char2uni = char2uni,
479 .charset2lower = charset2lower, 479 .charset2lower = charset2lower,
480 .charset2upper = charset2upper, 480 .charset2upper = charset2upper,
481 .owner = THIS_MODULE,
482}; 481};
483 482
484static int __init init_nls_maccyrillic(void) 483static int __init init_nls_maccyrillic(void)
diff --git a/fs/nls/mac-gaelic.c b/fs/nls/mac-gaelic.c
index 2de9158409c8..77b001653588 100644
--- a/fs/nls/mac-gaelic.c
+++ b/fs/nls/mac-gaelic.c
@@ -548,7 +548,6 @@ static struct nls_table table = {
548 .char2uni = char2uni, 548 .char2uni = char2uni,
549 .charset2lower = charset2lower, 549 .charset2lower = charset2lower,
550 .charset2upper = charset2upper, 550 .charset2upper = charset2upper,
551 .owner = THIS_MODULE,
552}; 551};
553 552
554static int __init init_nls_macgaelic(void) 553static int __init init_nls_macgaelic(void)
diff --git a/fs/nls/mac-greek.c b/fs/nls/mac-greek.c
index a86310082802..1eccf499e2eb 100644
--- a/fs/nls/mac-greek.c
+++ b/fs/nls/mac-greek.c
@@ -478,7 +478,6 @@ static struct nls_table table = {
478 .char2uni = char2uni, 478 .char2uni = char2uni,
479 .charset2lower = charset2lower, 479 .charset2lower = charset2lower,
480 .charset2upper = charset2upper, 480 .charset2upper = charset2upper,
481 .owner = THIS_MODULE,
482}; 481};
483 482
484static int __init init_nls_macgreek(void) 483static int __init init_nls_macgreek(void)
diff --git a/fs/nls/mac-iceland.c b/fs/nls/mac-iceland.c
index babe2998d5ce..cbd0875c6d69 100644
--- a/fs/nls/mac-iceland.c
+++ b/fs/nls/mac-iceland.c
@@ -583,7 +583,6 @@ static struct nls_table table = {
583 .char2uni = char2uni, 583 .char2uni = char2uni,
584 .charset2lower = charset2lower, 584 .charset2lower = charset2lower,
585 .charset2upper = charset2upper, 585 .charset2upper = charset2upper,
586 .owner = THIS_MODULE,
587}; 586};
588 587
589static int __init init_nls_maciceland(void) 588static int __init init_nls_maciceland(void)
diff --git a/fs/nls/mac-inuit.c b/fs/nls/mac-inuit.c
index 312364f010dc..fba8357aaf03 100644
--- a/fs/nls/mac-inuit.c
+++ b/fs/nls/mac-inuit.c
@@ -513,7 +513,6 @@ static struct nls_table table = {
513 .char2uni = char2uni, 513 .char2uni = char2uni,
514 .charset2lower = charset2lower, 514 .charset2lower = charset2lower,
515 .charset2upper = charset2upper, 515 .charset2upper = charset2upper,
516 .owner = THIS_MODULE,
517}; 516};
518 517
519static int __init init_nls_macinuit(void) 518static int __init init_nls_macinuit(void)
diff --git a/fs/nls/mac-roman.c b/fs/nls/mac-roman.c
index 53ce0809cbd2..b6a98a5208cd 100644
--- a/fs/nls/mac-roman.c
+++ b/fs/nls/mac-roman.c
@@ -618,7 +618,6 @@ static struct nls_table table = {
618 .char2uni = char2uni, 618 .char2uni = char2uni,
619 .charset2lower = charset2lower, 619 .charset2lower = charset2lower,
620 .charset2upper = charset2upper, 620 .charset2upper = charset2upper,
621 .owner = THIS_MODULE,
622}; 621};
623 622
624static int __init init_nls_macroman(void) 623static int __init init_nls_macroman(void)
diff --git a/fs/nls/mac-romanian.c b/fs/nls/mac-romanian.c
index add6f7a0c666..25547f023638 100644
--- a/fs/nls/mac-romanian.c
+++ b/fs/nls/mac-romanian.c
@@ -583,7 +583,6 @@ static struct nls_table table = {
583 .char2uni = char2uni, 583 .char2uni = char2uni,
584 .charset2lower = charset2lower, 584 .charset2lower = charset2lower,
585 .charset2upper = charset2upper, 585 .charset2upper = charset2upper,
586 .owner = THIS_MODULE,
587}; 586};
588 587
589static int __init init_nls_macromanian(void) 588static int __init init_nls_macromanian(void)
diff --git a/fs/nls/mac-turkish.c b/fs/nls/mac-turkish.c
index dffa96d5de00..b5454bc7b7fa 100644
--- a/fs/nls/mac-turkish.c
+++ b/fs/nls/mac-turkish.c
@@ -583,7 +583,6 @@ static struct nls_table table = {
583 .char2uni = char2uni, 583 .char2uni = char2uni,
584 .charset2lower = charset2lower, 584 .charset2lower = charset2lower,
585 .charset2upper = charset2upper, 585 .charset2upper = charset2upper,
586 .owner = THIS_MODULE,
587}; 586};
588 587
589static int __init init_nls_macturkish(void) 588static int __init init_nls_macturkish(void)
diff --git a/fs/nls/nls_ascii.c b/fs/nls/nls_ascii.c
index 7020e940f74e..a2620650d5e4 100644
--- a/fs/nls/nls_ascii.c
+++ b/fs/nls/nls_ascii.c
@@ -148,7 +148,6 @@ static struct nls_table table = {
148 .char2uni = char2uni, 148 .char2uni = char2uni,
149 .charset2lower = charset2lower, 149 .charset2lower = charset2lower,
150 .charset2upper = charset2upper, 150 .charset2upper = charset2upper,
151 .owner = THIS_MODULE,
152}; 151};
153 152
154static int __init init_nls_ascii(void) 153static int __init init_nls_ascii(void)
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index fea6bd5831dc..52ccd34b1e79 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -232,13 +232,14 @@ int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
232} 232}
233EXPORT_SYMBOL(utf16s_to_utf8s); 233EXPORT_SYMBOL(utf16s_to_utf8s);
234 234
235int register_nls(struct nls_table * nls) 235int __register_nls(struct nls_table *nls, struct module *owner)
236{ 236{
237 struct nls_table ** tmp = &tables; 237 struct nls_table ** tmp = &tables;
238 238
239 if (nls->next) 239 if (nls->next)
240 return -EBUSY; 240 return -EBUSY;
241 241
242 nls->owner = owner;
242 spin_lock(&nls_lock); 243 spin_lock(&nls_lock);
243 while (*tmp) { 244 while (*tmp) {
244 if (nls == *tmp) { 245 if (nls == *tmp) {
@@ -252,6 +253,7 @@ int register_nls(struct nls_table * nls)
252 spin_unlock(&nls_lock); 253 spin_unlock(&nls_lock);
253 return 0; 254 return 0;
254} 255}
256EXPORT_SYMBOL(__register_nls);
255 257
256int unregister_nls(struct nls_table * nls) 258int unregister_nls(struct nls_table * nls)
257{ 259{
@@ -538,7 +540,6 @@ struct nls_table *load_nls_default(void)
538 return &default_table; 540 return &default_table;
539} 541}
540 542
541EXPORT_SYMBOL(register_nls);
542EXPORT_SYMBOL(unregister_nls); 543EXPORT_SYMBOL(unregister_nls);
543EXPORT_SYMBOL(unload_nls); 544EXPORT_SYMBOL(unload_nls);
544EXPORT_SYMBOL(load_nls); 545EXPORT_SYMBOL(load_nls);
diff --git a/fs/nls/nls_cp1250.c b/fs/nls/nls_cp1250.c
index c8471fe78e4e..ace3e19d3407 100644
--- a/fs/nls/nls_cp1250.c
+++ b/fs/nls/nls_cp1250.c
@@ -329,7 +329,6 @@ static struct nls_table table = {
329 .char2uni = char2uni, 329 .char2uni = char2uni,
330 .charset2lower = charset2lower, 330 .charset2lower = charset2lower,
331 .charset2upper = charset2upper, 331 .charset2upper = charset2upper,
332 .owner = THIS_MODULE,
333}; 332};
334 333
335static int __init init_nls_cp1250(void) 334static int __init init_nls_cp1250(void)
diff --git a/fs/nls/nls_cp1251.c b/fs/nls/nls_cp1251.c
index 1939b46e772f..9273ddfd08a1 100644
--- a/fs/nls/nls_cp1251.c
+++ b/fs/nls/nls_cp1251.c
@@ -283,7 +283,6 @@ static struct nls_table table = {
283 .char2uni = char2uni, 283 .char2uni = char2uni,
284 .charset2lower = charset2lower, 284 .charset2lower = charset2lower,
285 .charset2upper = charset2upper, 285 .charset2upper = charset2upper,
286 .owner = THIS_MODULE,
287}; 286};
288 287
289static int __init init_nls_cp1251(void) 288static int __init init_nls_cp1251(void)
diff --git a/fs/nls/nls_cp1255.c b/fs/nls/nls_cp1255.c
index 8120ae2e091a..1caf5dfed85b 100644
--- a/fs/nls/nls_cp1255.c
+++ b/fs/nls/nls_cp1255.c
@@ -365,7 +365,6 @@ static struct nls_table table = {
365 .char2uni = char2uni, 365 .char2uni = char2uni,
366 .charset2lower = charset2lower, 366 .charset2lower = charset2lower,
367 .charset2upper = charset2upper, 367 .charset2upper = charset2upper,
368 .owner = THIS_MODULE,
369}; 368};
370 369
371static int __init init_nls_cp1255(void) 370static int __init init_nls_cp1255(void)
diff --git a/fs/nls/nls_cp437.c b/fs/nls/nls_cp437.c
index ff37a4628ce4..7ddb830da3fd 100644
--- a/fs/nls/nls_cp437.c
+++ b/fs/nls/nls_cp437.c
@@ -369,7 +369,6 @@ static struct nls_table table = {
369 .char2uni = char2uni, 369 .char2uni = char2uni,
370 .charset2lower = charset2lower, 370 .charset2lower = charset2lower,
371 .charset2upper = charset2upper, 371 .charset2upper = charset2upper,
372 .owner = THIS_MODULE,
373}; 372};
374 373
375static int __init init_nls_cp437(void) 374static int __init init_nls_cp437(void)
diff --git a/fs/nls/nls_cp737.c b/fs/nls/nls_cp737.c
index f5576b8be1b9..c593f683a0cd 100644
--- a/fs/nls/nls_cp737.c
+++ b/fs/nls/nls_cp737.c
@@ -332,7 +332,6 @@ static struct nls_table table = {
332 .char2uni = char2uni, 332 .char2uni = char2uni,
333 .charset2lower = charset2lower, 333 .charset2lower = charset2lower,
334 .charset2upper = charset2upper, 334 .charset2upper = charset2upper,
335 .owner = THIS_MODULE,
336}; 335};
337 336
338static int __init init_nls_cp737(void) 337static int __init init_nls_cp737(void)
diff --git a/fs/nls/nls_cp775.c b/fs/nls/nls_cp775.c
index 4905635d1c00..554c863745f2 100644
--- a/fs/nls/nls_cp775.c
+++ b/fs/nls/nls_cp775.c
@@ -301,7 +301,6 @@ static struct nls_table table = {
301 .char2uni = char2uni, 301 .char2uni = char2uni,
302 .charset2lower = charset2lower, 302 .charset2lower = charset2lower,
303 .charset2upper = charset2upper, 303 .charset2upper = charset2upper,
304 .owner = THIS_MODULE,
305}; 304};
306 305
307static int __init init_nls_cp775(void) 306static int __init init_nls_cp775(void)
diff --git a/fs/nls/nls_cp850.c b/fs/nls/nls_cp850.c
index fe5bdad50e2b..56cccd14b40b 100644
--- a/fs/nls/nls_cp850.c
+++ b/fs/nls/nls_cp850.c
@@ -297,7 +297,6 @@ static struct nls_table table = {
297 .char2uni = char2uni, 297 .char2uni = char2uni,
298 .charset2lower = charset2lower, 298 .charset2lower = charset2lower,
299 .charset2upper = charset2upper, 299 .charset2upper = charset2upper,
300 .owner = THIS_MODULE,
301}; 300};
302 301
303static int __init init_nls_cp850(void) 302static int __init init_nls_cp850(void)
diff --git a/fs/nls/nls_cp852.c b/fs/nls/nls_cp852.c
index ceb1c0166dd8..7cdc05ac1d40 100644
--- a/fs/nls/nls_cp852.c
+++ b/fs/nls/nls_cp852.c
@@ -319,7 +319,6 @@ static struct nls_table table = {
319 .char2uni = char2uni, 319 .char2uni = char2uni,
320 .charset2lower = charset2lower, 320 .charset2lower = charset2lower,
321 .charset2upper = charset2upper, 321 .charset2upper = charset2upper,
322 .owner = THIS_MODULE,
323}; 322};
324 323
325static int __init init_nls_cp852(void) 324static int __init init_nls_cp852(void)
diff --git a/fs/nls/nls_cp855.c b/fs/nls/nls_cp855.c
index cc7f5fb2e0c2..7426eea05663 100644
--- a/fs/nls/nls_cp855.c
+++ b/fs/nls/nls_cp855.c
@@ -281,7 +281,6 @@ static struct nls_table table = {
281 .char2uni = char2uni, 281 .char2uni = char2uni,
282 .charset2lower = charset2lower, 282 .charset2lower = charset2lower,
283 .charset2upper = charset2upper, 283 .charset2upper = charset2upper,
284 .owner = THIS_MODULE,
285}; 284};
286 285
287static int __init init_nls_cp855(void) 286static int __init init_nls_cp855(void)
diff --git a/fs/nls/nls_cp857.c b/fs/nls/nls_cp857.c
index e418e198e8d8..098309733ebd 100644
--- a/fs/nls/nls_cp857.c
+++ b/fs/nls/nls_cp857.c
@@ -283,7 +283,6 @@ static struct nls_table table = {
283 .char2uni = char2uni, 283 .char2uni = char2uni,
284 .charset2lower = charset2lower, 284 .charset2lower = charset2lower,
285 .charset2upper = charset2upper, 285 .charset2upper = charset2upper,
286 .owner = THIS_MODULE,
287}; 286};
288 287
289static int __init init_nls_cp857(void) 288static int __init init_nls_cp857(void)
diff --git a/fs/nls/nls_cp860.c b/fs/nls/nls_cp860.c
index a86c97d1aa34..84224478e731 100644
--- a/fs/nls/nls_cp860.c
+++ b/fs/nls/nls_cp860.c
@@ -346,7 +346,6 @@ static struct nls_table table = {
346 .char2uni = char2uni, 346 .char2uni = char2uni,
347 .charset2lower = charset2lower, 347 .charset2lower = charset2lower,
348 .charset2upper = charset2upper, 348 .charset2upper = charset2upper,
349 .owner = THIS_MODULE,
350}; 349};
351 350
352static int __init init_nls_cp860(void) 351static int __init init_nls_cp860(void)
diff --git a/fs/nls/nls_cp861.c b/fs/nls/nls_cp861.c
index bd920227acdf..dc873e4be092 100644
--- a/fs/nls/nls_cp861.c
+++ b/fs/nls/nls_cp861.c
@@ -369,7 +369,6 @@ static struct nls_table table = {
369 .char2uni = char2uni, 369 .char2uni = char2uni,
370 .charset2lower = charset2lower, 370 .charset2lower = charset2lower,
371 .charset2upper = charset2upper, 371 .charset2upper = charset2upper,
372 .owner = THIS_MODULE,
373}; 372};
374 373
375static int __init init_nls_cp861(void) 374static int __init init_nls_cp861(void)
diff --git a/fs/nls/nls_cp862.c b/fs/nls/nls_cp862.c
index e9b68eb3daf0..d5263e3c5566 100644
--- a/fs/nls/nls_cp862.c
+++ b/fs/nls/nls_cp862.c
@@ -403,7 +403,6 @@ static struct nls_table table = {
403 .char2uni = char2uni, 403 .char2uni = char2uni,
404 .charset2lower = charset2lower, 404 .charset2lower = charset2lower,
405 .charset2upper = charset2upper, 405 .charset2upper = charset2upper,
406 .owner = THIS_MODULE,
407}; 406};
408 407
409static int __init init_nls_cp862(void) 408static int __init init_nls_cp862(void)
diff --git a/fs/nls/nls_cp863.c b/fs/nls/nls_cp863.c
index f8a9b07ab4e2..051c9832e36a 100644
--- a/fs/nls/nls_cp863.c
+++ b/fs/nls/nls_cp863.c
@@ -363,7 +363,6 @@ static struct nls_table table = {
363 .char2uni = char2uni, 363 .char2uni = char2uni,
364 .charset2lower = charset2lower, 364 .charset2lower = charset2lower,
365 .charset2upper = charset2upper, 365 .charset2upper = charset2upper,
366 .owner = THIS_MODULE,
367}; 366};
368 367
369static int __init init_nls_cp863(void) 368static int __init init_nls_cp863(void)
diff --git a/fs/nls/nls_cp864.c b/fs/nls/nls_cp864.c
index 8d31f435fc6f..97eb1273b2f7 100644
--- a/fs/nls/nls_cp864.c
+++ b/fs/nls/nls_cp864.c
@@ -389,7 +389,6 @@ static struct nls_table table = {
389 .char2uni = char2uni, 389 .char2uni = char2uni,
390 .charset2lower = charset2lower, 390 .charset2lower = charset2lower,
391 .charset2upper = charset2upper, 391 .charset2upper = charset2upper,
392 .owner = THIS_MODULE,
393}; 392};
394 393
395static int __init init_nls_cp864(void) 394static int __init init_nls_cp864(void)
diff --git a/fs/nls/nls_cp865.c b/fs/nls/nls_cp865.c
index 4bd902fe3ec9..111214228525 100644
--- a/fs/nls/nls_cp865.c
+++ b/fs/nls/nls_cp865.c
@@ -369,7 +369,6 @@ static struct nls_table table = {
369 .char2uni = char2uni, 369 .char2uni = char2uni,
370 .charset2lower = charset2lower, 370 .charset2lower = charset2lower,
371 .charset2upper = charset2upper, 371 .charset2upper = charset2upper,
372 .owner = THIS_MODULE,
373}; 372};
374 373
375static int __init init_nls_cp865(void) 374static int __init init_nls_cp865(void)
diff --git a/fs/nls/nls_cp866.c b/fs/nls/nls_cp866.c
index bdc7cb391398..ffdcbc3fc38d 100644
--- a/fs/nls/nls_cp866.c
+++ b/fs/nls/nls_cp866.c
@@ -287,7 +287,6 @@ static struct nls_table table = {
287 .char2uni = char2uni, 287 .char2uni = char2uni,
288 .charset2lower = charset2lower, 288 .charset2lower = charset2lower,
289 .charset2upper = charset2upper, 289 .charset2upper = charset2upper,
290 .owner = THIS_MODULE,
291}; 290};
292 291
293static int __init init_nls_cp866(void) 292static int __init init_nls_cp866(void)
diff --git a/fs/nls/nls_cp869.c b/fs/nls/nls_cp869.c
index 9f283a2b151a..3b5a34589354 100644
--- a/fs/nls/nls_cp869.c
+++ b/fs/nls/nls_cp869.c
@@ -297,7 +297,6 @@ static struct nls_table table = {
297 .char2uni = char2uni, 297 .char2uni = char2uni,
298 .charset2lower = charset2lower, 298 .charset2lower = charset2lower,
299 .charset2upper = charset2upper, 299 .charset2upper = charset2upper,
300 .owner = THIS_MODULE,
301}; 300};
302 301
303static int __init init_nls_cp869(void) 302static int __init init_nls_cp869(void)
diff --git a/fs/nls/nls_cp874.c b/fs/nls/nls_cp874.c
index 0b3c4886f8c0..8dfaa10710fa 100644
--- a/fs/nls/nls_cp874.c
+++ b/fs/nls/nls_cp874.c
@@ -256,7 +256,6 @@ static struct nls_table table = {
256 .char2uni = char2uni, 256 .char2uni = char2uni,
257 .charset2lower = charset2lower, 257 .charset2lower = charset2lower,
258 .charset2upper = charset2upper, 258 .charset2upper = charset2upper,
259 .owner = THIS_MODULE,
260}; 259};
261 260
262static int __init init_nls_cp874(void) 261static int __init init_nls_cp874(void)
diff --git a/fs/nls/nls_cp932.c b/fs/nls/nls_cp932.c
index 0ffed6f1cebb..67b7398e8483 100644
--- a/fs/nls/nls_cp932.c
+++ b/fs/nls/nls_cp932.c
@@ -7914,7 +7914,6 @@ static struct nls_table table = {
7914 .char2uni = char2uni, 7914 .char2uni = char2uni,
7915 .charset2lower = charset2lower, 7915 .charset2lower = charset2lower,
7916 .charset2upper = charset2upper, 7916 .charset2upper = charset2upper,
7917 .owner = THIS_MODULE,
7918}; 7917};
7919 7918
7920static int __init init_nls_cp932(void) 7919static int __init init_nls_cp932(void)
diff --git a/fs/nls/nls_cp936.c b/fs/nls/nls_cp936.c
index 82770301bc3d..c96546cfec9f 100644
--- a/fs/nls/nls_cp936.c
+++ b/fs/nls/nls_cp936.c
@@ -11092,7 +11092,6 @@ static struct nls_table table = {
11092 .char2uni = char2uni, 11092 .char2uni = char2uni,
11093 .charset2lower = charset2lower, 11093 .charset2lower = charset2lower,
11094 .charset2upper = charset2upper, 11094 .charset2upper = charset2upper,
11095 .owner = THIS_MODULE,
11096}; 11095};
11097 11096
11098static int __init init_nls_cp936(void) 11097static int __init init_nls_cp936(void)
diff --git a/fs/nls/nls_cp949.c b/fs/nls/nls_cp949.c
index 8a7a2fe85c65..199171e97aa4 100644
--- a/fs/nls/nls_cp949.c
+++ b/fs/nls/nls_cp949.c
@@ -13927,7 +13927,6 @@ static struct nls_table table = {
13927 .char2uni = char2uni, 13927 .char2uni = char2uni,
13928 .charset2lower = charset2lower, 13928 .charset2lower = charset2lower,
13929 .charset2upper = charset2upper, 13929 .charset2upper = charset2upper,
13930 .owner = THIS_MODULE,
13931}; 13930};
13932 13931
13933static int __init init_nls_cp949(void) 13932static int __init init_nls_cp949(void)
diff --git a/fs/nls/nls_cp950.c b/fs/nls/nls_cp950.c
index ef2536829aa5..8e1418708209 100644
--- a/fs/nls/nls_cp950.c
+++ b/fs/nls/nls_cp950.c
@@ -9463,7 +9463,6 @@ static struct nls_table table = {
9463 .char2uni = char2uni, 9463 .char2uni = char2uni,
9464 .charset2lower = charset2lower, 9464 .charset2lower = charset2lower,
9465 .charset2upper = charset2upper, 9465 .charset2upper = charset2upper,
9466 .owner = THIS_MODULE,
9467}; 9466};
9468 9467
9469static int __init init_nls_cp950(void) 9468static int __init init_nls_cp950(void)
diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c
index 7424929a278b..162b3f160353 100644
--- a/fs/nls/nls_euc-jp.c
+++ b/fs/nls/nls_euc-jp.c
@@ -553,7 +553,6 @@ static struct nls_table table = {
553 .charset = "euc-jp", 553 .charset = "euc-jp",
554 .uni2char = uni2char, 554 .uni2char = uni2char,
555 .char2uni = char2uni, 555 .char2uni = char2uni,
556 .owner = THIS_MODULE,
557}; 556};
558 557
559static int __init init_nls_euc_jp(void) 558static int __init init_nls_euc_jp(void)
diff --git a/fs/nls/nls_iso8859-1.c b/fs/nls/nls_iso8859-1.c
index 7b951bb5849c..69ac020d43b1 100644
--- a/fs/nls/nls_iso8859-1.c
+++ b/fs/nls/nls_iso8859-1.c
@@ -239,7 +239,6 @@ static struct nls_table table = {
239 .char2uni = char2uni, 239 .char2uni = char2uni,
240 .charset2lower = charset2lower, 240 .charset2lower = charset2lower,
241 .charset2upper = charset2upper, 241 .charset2upper = charset2upper,
242 .owner = THIS_MODULE,
243}; 242};
244 243
245static int __init init_nls_iso8859_1(void) 244static int __init init_nls_iso8859_1(void)
diff --git a/fs/nls/nls_iso8859-13.c b/fs/nls/nls_iso8859-13.c
index c4d52ea9f092..afb3f8f275f0 100644
--- a/fs/nls/nls_iso8859-13.c
+++ b/fs/nls/nls_iso8859-13.c
@@ -267,7 +267,6 @@ static struct nls_table table = {
267 .char2uni = char2uni, 267 .char2uni = char2uni,
268 .charset2lower = charset2lower, 268 .charset2lower = charset2lower,
269 .charset2upper = charset2upper, 269 .charset2upper = charset2upper,
270 .owner = THIS_MODULE,
271}; 270};
272 271
273static int __init init_nls_iso8859_13(void) 272static int __init init_nls_iso8859_13(void)
diff --git a/fs/nls/nls_iso8859-14.c b/fs/nls/nls_iso8859-14.c
index dc02600c7fe1..046370f0b6f0 100644
--- a/fs/nls/nls_iso8859-14.c
+++ b/fs/nls/nls_iso8859-14.c
@@ -323,7 +323,6 @@ static struct nls_table table = {
323 .char2uni = char2uni, 323 .char2uni = char2uni,
324 .charset2lower = charset2lower, 324 .charset2lower = charset2lower,
325 .charset2upper = charset2upper, 325 .charset2upper = charset2upper,
326 .owner = THIS_MODULE,
327}; 326};
328 327
329static int __init init_nls_iso8859_14(void) 328static int __init init_nls_iso8859_14(void)
diff --git a/fs/nls/nls_iso8859-15.c b/fs/nls/nls_iso8859-15.c
index 3c7dfc832ef1..7e34a841a056 100644
--- a/fs/nls/nls_iso8859-15.c
+++ b/fs/nls/nls_iso8859-15.c
@@ -289,7 +289,6 @@ static struct nls_table table = {
289 .char2uni = char2uni, 289 .char2uni = char2uni,
290 .charset2lower = charset2lower, 290 .charset2lower = charset2lower,
291 .charset2upper = charset2upper, 291 .charset2upper = charset2upper,
292 .owner = THIS_MODULE,
293}; 292};
294 293
295static int __init init_nls_iso8859_15(void) 294static int __init init_nls_iso8859_15(void)
diff --git a/fs/nls/nls_iso8859-2.c b/fs/nls/nls_iso8859-2.c
index a2d2197e4c77..7dd571181741 100644
--- a/fs/nls/nls_iso8859-2.c
+++ b/fs/nls/nls_iso8859-2.c
@@ -290,7 +290,6 @@ static struct nls_table table = {
290 .char2uni = char2uni, 290 .char2uni = char2uni,
291 .charset2lower = charset2lower, 291 .charset2lower = charset2lower,
292 .charset2upper = charset2upper, 292 .charset2upper = charset2upper,
293 .owner = THIS_MODULE,
294}; 293};
295 294
296static int __init init_nls_iso8859_2(void) 295static int __init init_nls_iso8859_2(void)
diff --git a/fs/nls/nls_iso8859-3.c b/fs/nls/nls_iso8859-3.c
index a61e0daa3a86..740b75ec4493 100644
--- a/fs/nls/nls_iso8859-3.c
+++ b/fs/nls/nls_iso8859-3.c
@@ -290,7 +290,6 @@ static struct nls_table table = {
290 .char2uni = char2uni, 290 .char2uni = char2uni,
291 .charset2lower = charset2lower, 291 .charset2lower = charset2lower,
292 .charset2upper = charset2upper, 292 .charset2upper = charset2upper,
293 .owner = THIS_MODULE,
294}; 293};
295 294
296static int __init init_nls_iso8859_3(void) 295static int __init init_nls_iso8859_3(void)
diff --git a/fs/nls/nls_iso8859-4.c b/fs/nls/nls_iso8859-4.c
index e8ff555483b6..8826021e32f5 100644
--- a/fs/nls/nls_iso8859-4.c
+++ b/fs/nls/nls_iso8859-4.c
@@ -290,7 +290,6 @@ static struct nls_table table = {
290 .char2uni = char2uni, 290 .char2uni = char2uni,
291 .charset2lower = charset2lower, 291 .charset2lower = charset2lower,
292 .charset2upper = charset2upper, 292 .charset2upper = charset2upper,
293 .owner = THIS_MODULE,
294}; 293};
295 294
296static int __init init_nls_iso8859_4(void) 295static int __init init_nls_iso8859_4(void)
diff --git a/fs/nls/nls_iso8859-5.c b/fs/nls/nls_iso8859-5.c
index 4721e8930124..7c04057a1ad8 100644
--- a/fs/nls/nls_iso8859-5.c
+++ b/fs/nls/nls_iso8859-5.c
@@ -254,7 +254,6 @@ static struct nls_table table = {
254 .char2uni = char2uni, 254 .char2uni = char2uni,
255 .charset2lower = charset2lower, 255 .charset2lower = charset2lower,
256 .charset2upper = charset2upper, 256 .charset2upper = charset2upper,
257 .owner = THIS_MODULE,
258}; 257};
259 258
260static int __init init_nls_iso8859_5(void) 259static int __init init_nls_iso8859_5(void)
diff --git a/fs/nls/nls_iso8859-6.c b/fs/nls/nls_iso8859-6.c
index 01a517d6d306..d4a881400d74 100644
--- a/fs/nls/nls_iso8859-6.c
+++ b/fs/nls/nls_iso8859-6.c
@@ -245,7 +245,6 @@ static struct nls_table table = {
245 .char2uni = char2uni, 245 .char2uni = char2uni,
246 .charset2lower = charset2lower, 246 .charset2lower = charset2lower,
247 .charset2upper = charset2upper, 247 .charset2upper = charset2upper,
248 .owner = THIS_MODULE,
249}; 248};
250 249
251static int __init init_nls_iso8859_6(void) 250static int __init init_nls_iso8859_6(void)
diff --git a/fs/nls/nls_iso8859-7.c b/fs/nls/nls_iso8859-7.c
index 2d27b93ef19e..37b75d825a75 100644
--- a/fs/nls/nls_iso8859-7.c
+++ b/fs/nls/nls_iso8859-7.c
@@ -299,7 +299,6 @@ static struct nls_table table = {
299 .char2uni = char2uni, 299 .char2uni = char2uni,
300 .charset2lower = charset2lower, 300 .charset2lower = charset2lower,
301 .charset2upper = charset2upper, 301 .charset2upper = charset2upper,
302 .owner = THIS_MODULE,
303}; 302};
304 303
305static int __init init_nls_iso8859_7(void) 304static int __init init_nls_iso8859_7(void)
diff --git a/fs/nls/nls_iso8859-9.c b/fs/nls/nls_iso8859-9.c
index 694bf070c721..557b98250d37 100644
--- a/fs/nls/nls_iso8859-9.c
+++ b/fs/nls/nls_iso8859-9.c
@@ -254,7 +254,6 @@ static struct nls_table table = {
254 .char2uni = char2uni, 254 .char2uni = char2uni,
255 .charset2lower = charset2lower, 255 .charset2lower = charset2lower,
256 .charset2upper = charset2upper, 256 .charset2upper = charset2upper,
257 .owner = THIS_MODULE,
258}; 257};
259 258
260static int __init init_nls_iso8859_9(void) 259static int __init init_nls_iso8859_9(void)
diff --git a/fs/nls/nls_koi8-r.c b/fs/nls/nls_koi8-r.c
index 43875310540d..811f232fccfb 100644
--- a/fs/nls/nls_koi8-r.c
+++ b/fs/nls/nls_koi8-r.c
@@ -305,7 +305,6 @@ static struct nls_table table = {
305 .char2uni = char2uni, 305 .char2uni = char2uni,
306 .charset2lower = charset2lower, 306 .charset2lower = charset2lower,
307 .charset2upper = charset2upper, 307 .charset2upper = charset2upper,
308 .owner = THIS_MODULE,
309}; 308};
310 309
311static int __init init_nls_koi8_r(void) 310static int __init init_nls_koi8_r(void)
diff --git a/fs/nls/nls_koi8-ru.c b/fs/nls/nls_koi8-ru.c
index e7bc1d75c78c..a80a741a8676 100644
--- a/fs/nls/nls_koi8-ru.c
+++ b/fs/nls/nls_koi8-ru.c
@@ -55,7 +55,6 @@ static struct nls_table table = {
55 .charset = "koi8-ru", 55 .charset = "koi8-ru",
56 .uni2char = uni2char, 56 .uni2char = uni2char,
57 .char2uni = char2uni, 57 .char2uni = char2uni,
58 .owner = THIS_MODULE,
59}; 58};
60 59
61static int __init init_nls_koi8_ru(void) 60static int __init init_nls_koi8_ru(void)
diff --git a/fs/nls/nls_koi8-u.c b/fs/nls/nls_koi8-u.c
index 8c9f0292b5ae..7e029e4c188a 100644
--- a/fs/nls/nls_koi8-u.c
+++ b/fs/nls/nls_koi8-u.c
@@ -312,7 +312,6 @@ static struct nls_table table = {
312 .char2uni = char2uni, 312 .char2uni = char2uni,
313 .charset2lower = charset2lower, 313 .charset2lower = charset2lower,
314 .charset2upper = charset2upper, 314 .charset2upper = charset2upper,
315 .owner = THIS_MODULE,
316}; 315};
317 316
318static int __init init_nls_koi8_u(void) 317static int __init init_nls_koi8_u(void)
diff --git a/fs/nls/nls_utf8.c b/fs/nls/nls_utf8.c
index 0d60a44acacd..afcfbc4a14db 100644
--- a/fs/nls/nls_utf8.c
+++ b/fs/nls/nls_utf8.c
@@ -46,7 +46,6 @@ static struct nls_table table = {
46 .char2uni = char2uni, 46 .char2uni = char2uni,
47 .charset2lower = identity, /* no conversion */ 47 .charset2lower = identity, /* no conversion */
48 .charset2upper = identity, 48 .charset2upper = identity,
49 .owner = THIS_MODULE,
50}; 49};
51 50
52static int __init init_nls_utf8(void) 51static int __init init_nls_utf8(void)
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index b4f788e0ca31..555f4cddefe3 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -160,36 +160,6 @@ static struct posix_acl *ocfs2_get_acl_nolock(struct inode *inode,
160 return acl; 160 return acl;
161} 161}
162 162
163
164/*
165 * Get posix acl.
166 */
167static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type)
168{
169 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
170 struct buffer_head *di_bh = NULL;
171 struct posix_acl *acl;
172 int ret;
173
174 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
175 return NULL;
176
177 ret = ocfs2_inode_lock(inode, &di_bh, 0);
178 if (ret < 0) {
179 mlog_errno(ret);
180 acl = ERR_PTR(ret);
181 return acl;
182 }
183
184 acl = ocfs2_get_acl_nolock(inode, type, di_bh);
185
186 ocfs2_inode_unlock(inode, 0);
187
188 brelse(di_bh);
189
190 return acl;
191}
192
193/* 163/*
194 * Helper function to set i_mode in memory and disk. Some call paths 164 * Helper function to set i_mode in memory and disk. Some call paths
195 * will not have di_bh or a journal handle to pass, in which case it 165 * will not have di_bh or a journal handle to pass, in which case it
@@ -250,7 +220,7 @@ out:
250/* 220/*
251 * Set the access or default ACL of an inode. 221 * Set the access or default ACL of an inode.
252 */ 222 */
253static int ocfs2_set_acl(handle_t *handle, 223int ocfs2_set_acl(handle_t *handle,
254 struct inode *inode, 224 struct inode *inode,
255 struct buffer_head *di_bh, 225 struct buffer_head *di_bh,
256 int type, 226 int type,
@@ -313,6 +283,11 @@ static int ocfs2_set_acl(handle_t *handle,
313 return ret; 283 return ret;
314} 284}
315 285
286int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type)
287{
288 return ocfs2_set_acl(NULL, inode, NULL, type, acl, NULL, NULL);
289}
290
316struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type) 291struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type)
317{ 292{
318 struct ocfs2_super *osb; 293 struct ocfs2_super *osb;
@@ -334,200 +309,3 @@ struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type)
334 309
335 return acl; 310 return acl;
336} 311}
337
338int ocfs2_acl_chmod(struct inode *inode)
339{
340 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
341 struct posix_acl *acl;
342 int ret;
343
344 if (S_ISLNK(inode->i_mode))
345 return -EOPNOTSUPP;
346
347 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
348 return 0;
349
350 acl = ocfs2_get_acl(inode, ACL_TYPE_ACCESS);
351 if (IS_ERR(acl) || !acl)
352 return PTR_ERR(acl);
353 ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
354 if (ret)
355 return ret;
356 ret = ocfs2_set_acl(NULL, inode, NULL, ACL_TYPE_ACCESS,
357 acl, NULL, NULL);
358 posix_acl_release(acl);
359 return ret;
360}
361
362/*
363 * Initialize the ACLs of a new inode. If parent directory has default ACL,
364 * then clone to new inode. Called from ocfs2_mknod.
365 */
366int ocfs2_init_acl(handle_t *handle,
367 struct inode *inode,
368 struct inode *dir,
369 struct buffer_head *di_bh,
370 struct buffer_head *dir_bh,
371 struct ocfs2_alloc_context *meta_ac,
372 struct ocfs2_alloc_context *data_ac)
373{
374 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
375 struct posix_acl *acl = NULL;
376 int ret = 0, ret2;
377 umode_t mode;
378
379 if (!S_ISLNK(inode->i_mode)) {
380 if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
381 acl = ocfs2_get_acl_nolock(dir, ACL_TYPE_DEFAULT,
382 dir_bh);
383 if (IS_ERR(acl))
384 return PTR_ERR(acl);
385 }
386 if (!acl) {
387 mode = inode->i_mode & ~current_umask();
388 ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
389 if (ret) {
390 mlog_errno(ret);
391 goto cleanup;
392 }
393 }
394 }
395 if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
396 if (S_ISDIR(inode->i_mode)) {
397 ret = ocfs2_set_acl(handle, inode, di_bh,
398 ACL_TYPE_DEFAULT, acl,
399 meta_ac, data_ac);
400 if (ret)
401 goto cleanup;
402 }
403 mode = inode->i_mode;
404 ret = posix_acl_create(&acl, GFP_NOFS, &mode);
405 if (ret < 0)
406 return ret;
407
408 ret2 = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
409 if (ret2) {
410 mlog_errno(ret2);
411 ret = ret2;
412 goto cleanup;
413 }
414 if (ret > 0) {
415 ret = ocfs2_set_acl(handle, inode,
416 di_bh, ACL_TYPE_ACCESS,
417 acl, meta_ac, data_ac);
418 }
419 }
420cleanup:
421 posix_acl_release(acl);
422 return ret;
423}
424
425static size_t ocfs2_xattr_list_acl_access(struct dentry *dentry,
426 char *list,
427 size_t list_len,
428 const char *name,
429 size_t name_len,
430 int type)
431{
432 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
433 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
434
435 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
436 return 0;
437
438 if (list && size <= list_len)
439 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
440 return size;
441}
442
443static size_t ocfs2_xattr_list_acl_default(struct dentry *dentry,
444 char *list,
445 size_t list_len,
446 const char *name,
447 size_t name_len,
448 int type)
449{
450 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
451 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
452
453 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
454 return 0;
455
456 if (list && size <= list_len)
457 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
458 return size;
459}
460
461static int ocfs2_xattr_get_acl(struct dentry *dentry, const char *name,
462 void *buffer, size_t size, int type)
463{
464 struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
465 struct posix_acl *acl;
466 int ret;
467
468 if (strcmp(name, "") != 0)
469 return -EINVAL;
470 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
471 return -EOPNOTSUPP;
472
473 acl = ocfs2_get_acl(dentry->d_inode, type);
474 if (IS_ERR(acl))
475 return PTR_ERR(acl);
476 if (acl == NULL)
477 return -ENODATA;
478 ret = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
479 posix_acl_release(acl);
480
481 return ret;
482}
483
484static int ocfs2_xattr_set_acl(struct dentry *dentry, const char *name,
485 const void *value, size_t size, int flags, int type)
486{
487 struct inode *inode = dentry->d_inode;
488 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
489 struct posix_acl *acl;
490 int ret = 0;
491
492 if (strcmp(name, "") != 0)
493 return -EINVAL;
494 if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
495 return -EOPNOTSUPP;
496
497 if (!inode_owner_or_capable(inode))
498 return -EPERM;
499
500 if (value) {
501 acl = posix_acl_from_xattr(&init_user_ns, value, size);
502 if (IS_ERR(acl))
503 return PTR_ERR(acl);
504 else if (acl) {
505 ret = posix_acl_valid(acl);
506 if (ret)
507 goto cleanup;
508 }
509 } else
510 acl = NULL;
511
512 ret = ocfs2_set_acl(NULL, inode, NULL, type, acl, NULL, NULL);
513
514cleanup:
515 posix_acl_release(acl);
516 return ret;
517}
518
519const struct xattr_handler ocfs2_xattr_acl_access_handler = {
520 .prefix = POSIX_ACL_XATTR_ACCESS,
521 .flags = ACL_TYPE_ACCESS,
522 .list = ocfs2_xattr_list_acl_access,
523 .get = ocfs2_xattr_get_acl,
524 .set = ocfs2_xattr_set_acl,
525};
526
527const struct xattr_handler ocfs2_xattr_acl_default_handler = {
528 .prefix = POSIX_ACL_XATTR_DEFAULT,
529 .flags = ACL_TYPE_DEFAULT,
530 .list = ocfs2_xattr_list_acl_default,
531 .get = ocfs2_xattr_get_acl,
532 .set = ocfs2_xattr_set_acl,
533};
diff --git a/fs/ocfs2/acl.h b/fs/ocfs2/acl.h
index 071fbd380f2f..3fce68d08625 100644
--- a/fs/ocfs2/acl.h
+++ b/fs/ocfs2/acl.h
@@ -27,10 +27,13 @@ struct ocfs2_acl_entry {
27}; 27};
28 28
29struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type); 29struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type);
30extern int ocfs2_acl_chmod(struct inode *); 30int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type);
31extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, 31int ocfs2_set_acl(handle_t *handle,
32 struct buffer_head *, struct buffer_head *, 32 struct inode *inode,
33 struct ocfs2_alloc_context *, 33 struct buffer_head *di_bh,
34 struct ocfs2_alloc_context *); 34 int type,
35 struct posix_acl *acl,
36 struct ocfs2_alloc_context *meta_ac,
37 struct ocfs2_alloc_context *data_ac);
35 38
36#endif /* OCFS2_ACL_H */ 39#endif /* OCFS2_ACL_H */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index f42eecef6478..d77d71ead8d1 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1236,7 +1236,7 @@ bail:
1236 dqput(transfer_to[qtype]); 1236 dqput(transfer_to[qtype]);
1237 1237
1238 if (!status && attr->ia_valid & ATTR_MODE) { 1238 if (!status && attr->ia_valid & ATTR_MODE) {
1239 status = ocfs2_acl_chmod(inode); 1239 status = posix_acl_chmod(inode, inode->i_mode);
1240 if (status < 0) 1240 if (status < 0)
1241 mlog_errno(status); 1241 mlog_errno(status);
1242 } 1242 }
@@ -2662,6 +2662,7 @@ const struct inode_operations ocfs2_file_iops = {
2662 .removexattr = generic_removexattr, 2662 .removexattr = generic_removexattr,
2663 .fiemap = ocfs2_fiemap, 2663 .fiemap = ocfs2_fiemap,
2664 .get_acl = ocfs2_iop_get_acl, 2664 .get_acl = ocfs2_iop_get_acl,
2665 .set_acl = ocfs2_iop_set_acl,
2665}; 2666};
2666 2667
2667const struct inode_operations ocfs2_special_file_iops = { 2668const struct inode_operations ocfs2_special_file_iops = {
@@ -2669,6 +2670,7 @@ const struct inode_operations ocfs2_special_file_iops = {
2669 .getattr = ocfs2_getattr, 2670 .getattr = ocfs2_getattr,
2670 .permission = ocfs2_permission, 2671 .permission = ocfs2_permission,
2671 .get_acl = ocfs2_iop_get_acl, 2672 .get_acl = ocfs2_iop_get_acl,
2673 .set_acl = ocfs2_iop_set_acl,
2672}; 2674};
2673 2675
2674/* 2676/*
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 41513a4e98e4..f4d609be9400 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -230,6 +230,7 @@ static int ocfs2_mknod(struct inode *dir,
230 struct ocfs2_dir_lookup_result lookup = { NULL, }; 230 struct ocfs2_dir_lookup_result lookup = { NULL, };
231 sigset_t oldset; 231 sigset_t oldset;
232 int did_block_signals = 0; 232 int did_block_signals = 0;
233 struct posix_acl *default_acl = NULL, *acl = NULL;
233 234
234 trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name, 235 trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name,
235 (unsigned long long)OCFS2_I(dir)->ip_blkno, 236 (unsigned long long)OCFS2_I(dir)->ip_blkno,
@@ -331,6 +332,12 @@ static int ocfs2_mknod(struct inode *dir,
331 goto leave; 332 goto leave;
332 } 333 }
333 334
335 status = posix_acl_create(dir, &mode, &default_acl, &acl);
336 if (status) {
337 mlog_errno(status);
338 goto leave;
339 }
340
334 handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb, 341 handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
335 S_ISDIR(mode), 342 S_ISDIR(mode),
336 xattr_credits)); 343 xattr_credits));
@@ -379,8 +386,17 @@ static int ocfs2_mknod(struct inode *dir,
379 inc_nlink(dir); 386 inc_nlink(dir);
380 } 387 }
381 388
382 status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh, 389 if (default_acl) {
383 meta_ac, data_ac); 390 status = ocfs2_set_acl(handle, inode, new_fe_bh,
391 ACL_TYPE_DEFAULT, default_acl,
392 meta_ac, data_ac);
393 }
394 if (!status && acl) {
395 status = ocfs2_set_acl(handle, inode, new_fe_bh,
396 ACL_TYPE_ACCESS, acl,
397 meta_ac, data_ac);
398 }
399
384 if (status < 0) { 400 if (status < 0) {
385 mlog_errno(status); 401 mlog_errno(status);
386 goto leave; 402 goto leave;
@@ -419,6 +435,10 @@ static int ocfs2_mknod(struct inode *dir,
419 d_instantiate(dentry, inode); 435 d_instantiate(dentry, inode);
420 status = 0; 436 status = 0;
421leave: 437leave:
438 if (default_acl)
439 posix_acl_release(default_acl);
440 if (acl)
441 posix_acl_release(acl);
422 if (status < 0 && did_quota_inode) 442 if (status < 0 && did_quota_inode)
423 dquot_free_inode(inode); 443 dquot_free_inode(inode);
424 if (handle) 444 if (handle)
@@ -2504,4 +2524,5 @@ const struct inode_operations ocfs2_dir_iops = {
2504 .removexattr = generic_removexattr, 2524 .removexattr = generic_removexattr,
2505 .fiemap = ocfs2_fiemap, 2525 .fiemap = ocfs2_fiemap,
2506 .get_acl = ocfs2_iop_get_acl, 2526 .get_acl = ocfs2_iop_get_acl,
2527 .set_acl = ocfs2_iop_set_acl,
2507}; 2528};
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 55767e1ba724..6ba4bcbc4796 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -46,6 +46,7 @@
46#include <linux/quotaops.h> 46#include <linux/quotaops.h>
47#include <linux/namei.h> 47#include <linux/namei.h>
48#include <linux/mount.h> 48#include <linux/mount.h>
49#include <linux/posix_acl.h>
49 50
50struct ocfs2_cow_context { 51struct ocfs2_cow_context {
51 struct inode *inode; 52 struct inode *inode;
@@ -4268,11 +4269,20 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
4268 struct inode *inode = old_dentry->d_inode; 4269 struct inode *inode = old_dentry->d_inode;
4269 struct buffer_head *old_bh = NULL; 4270 struct buffer_head *old_bh = NULL;
4270 struct inode *new_orphan_inode = NULL; 4271 struct inode *new_orphan_inode = NULL;
4272 struct posix_acl *default_acl, *acl;
4273 umode_t mode;
4271 4274
4272 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) 4275 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
4273 return -EOPNOTSUPP; 4276 return -EOPNOTSUPP;
4274 4277
4275 error = ocfs2_create_inode_in_orphan(dir, inode->i_mode, 4278 mode = inode->i_mode;
4279 error = posix_acl_create(dir, &mode, &default_acl, &acl);
4280 if (error) {
4281 mlog_errno(error);
4282 goto out;
4283 }
4284
4285 error = ocfs2_create_inode_in_orphan(dir, mode,
4276 &new_orphan_inode); 4286 &new_orphan_inode);
4277 if (error) { 4287 if (error) {
4278 mlog_errno(error); 4288 mlog_errno(error);
@@ -4303,11 +4313,16 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir,
4303 /* If the security isn't preserved, we need to re-initialize them. */ 4313 /* If the security isn't preserved, we need to re-initialize them. */
4304 if (!preserve) { 4314 if (!preserve) {
4305 error = ocfs2_init_security_and_acl(dir, new_orphan_inode, 4315 error = ocfs2_init_security_and_acl(dir, new_orphan_inode,
4306 &new_dentry->d_name); 4316 &new_dentry->d_name,
4317 default_acl, acl);
4307 if (error) 4318 if (error)
4308 mlog_errno(error); 4319 mlog_errno(error);
4309 } 4320 }
4310out: 4321out:
4322 if (default_acl)
4323 posix_acl_release(default_acl);
4324 if (acl)
4325 posix_acl_release(acl);
4311 if (!error) { 4326 if (!error) {
4312 error = ocfs2_mv_orphaned_inode_to_new(dir, new_orphan_inode, 4327 error = ocfs2_mv_orphaned_inode_to_new(dir, new_orphan_inode,
4313 new_dentry); 4328 new_dentry);
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index f0a1326d9bba..185fa3b7f962 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -99,8 +99,8 @@ static struct ocfs2_xattr_def_value_root def_xv = {
99 99
100const struct xattr_handler *ocfs2_xattr_handlers[] = { 100const struct xattr_handler *ocfs2_xattr_handlers[] = {
101 &ocfs2_xattr_user_handler, 101 &ocfs2_xattr_user_handler,
102 &ocfs2_xattr_acl_access_handler, 102 &posix_acl_access_xattr_handler,
103 &ocfs2_xattr_acl_default_handler, 103 &posix_acl_default_xattr_handler,
104 &ocfs2_xattr_trusted_handler, 104 &ocfs2_xattr_trusted_handler,
105 &ocfs2_xattr_security_handler, 105 &ocfs2_xattr_security_handler,
106 NULL 106 NULL
@@ -109,9 +109,9 @@ const struct xattr_handler *ocfs2_xattr_handlers[] = {
109static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { 109static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
110 [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler, 110 [OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
111 [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS] 111 [OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]
112 = &ocfs2_xattr_acl_access_handler, 112 = &posix_acl_access_xattr_handler,
113 [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT] 113 [OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]
114 = &ocfs2_xattr_acl_default_handler, 114 = &posix_acl_default_xattr_handler,
115 [OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler, 115 [OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
116 [OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler, 116 [OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
117}; 117};
@@ -7190,10 +7190,12 @@ out:
7190 */ 7190 */
7191int ocfs2_init_security_and_acl(struct inode *dir, 7191int ocfs2_init_security_and_acl(struct inode *dir,
7192 struct inode *inode, 7192 struct inode *inode,
7193 const struct qstr *qstr) 7193 const struct qstr *qstr,
7194 struct posix_acl *default_acl,
7195 struct posix_acl *acl)
7194{ 7196{
7195 int ret = 0;
7196 struct buffer_head *dir_bh = NULL; 7197 struct buffer_head *dir_bh = NULL;
7198 int ret = 0;
7197 7199
7198 ret = ocfs2_init_security_get(inode, dir, qstr, NULL); 7200 ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
7199 if (ret) { 7201 if (ret) {
@@ -7207,9 +7209,10 @@ int ocfs2_init_security_and_acl(struct inode *dir,
7207 goto leave; 7209 goto leave;
7208 } 7210 }
7209 7211
7210 ret = ocfs2_init_acl(NULL, inode, dir, NULL, dir_bh, NULL, NULL); 7212 if (!ret && default_acl)
7211 if (ret) 7213 ret = ocfs2_iop_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
7212 mlog_errno(ret); 7214 if (!ret && acl)
7215 ret = ocfs2_iop_set_acl(inode, acl, ACL_TYPE_ACCESS);
7213 7216
7214 ocfs2_inode_unlock(dir, 0); 7217 ocfs2_inode_unlock(dir, 0);
7215 brelse(dir_bh); 7218 brelse(dir_bh);
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
index 19f134e896a9..f10d5b93c366 100644
--- a/fs/ocfs2/xattr.h
+++ b/fs/ocfs2/xattr.h
@@ -40,8 +40,6 @@ struct ocfs2_security_xattr_info {
40extern const struct xattr_handler ocfs2_xattr_user_handler; 40extern const struct xattr_handler ocfs2_xattr_user_handler;
41extern const struct xattr_handler ocfs2_xattr_trusted_handler; 41extern const struct xattr_handler ocfs2_xattr_trusted_handler;
42extern const struct xattr_handler ocfs2_xattr_security_handler; 42extern const struct xattr_handler ocfs2_xattr_security_handler;
43extern const struct xattr_handler ocfs2_xattr_acl_access_handler;
44extern const struct xattr_handler ocfs2_xattr_acl_default_handler;
45extern const struct xattr_handler *ocfs2_xattr_handlers[]; 43extern const struct xattr_handler *ocfs2_xattr_handlers[];
46 44
47ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); 45ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
@@ -96,5 +94,7 @@ int ocfs2_reflink_xattrs(struct inode *old_inode,
96 bool preserve_security); 94 bool preserve_security);
97int ocfs2_init_security_and_acl(struct inode *dir, 95int ocfs2_init_security_and_acl(struct inode *dir,
98 struct inode *inode, 96 struct inode *inode,
99 const struct qstr *qstr); 97 const struct qstr *qstr,
98 struct posix_acl *default_acl,
99 struct posix_acl *acl);
100#endif /* OCFS2_XATTR_H */ 100#endif /* OCFS2_XATTR_H */
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 551e61ba15b6..38bae5a0ea25 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1,10 +1,8 @@
1/* 1/*
2 * linux/fs/posix_acl.c 2 * Copyright (C) 2002,2003 by Andreas Gruenbacher <a.gruenbacher@computer.org>
3 * 3 *
4 * Copyright (C) 2002 by Andreas Gruenbacher <a.gruenbacher@computer.org> 4 * Fixes from William Schumacher incorporated on 15 March 2001.
5 * 5 * (Reported by Charles Bertsch, <CBertsch@microtest.com>).
6 * Fixes from William Schumacher incorporated on 15 March 2001.
7 * (Reported by Charles Bertsch, <CBertsch@microtest.com>).
8 */ 6 */
9 7
10/* 8/*
@@ -18,9 +16,10 @@
18#include <linux/fs.h> 16#include <linux/fs.h>
19#include <linux/sched.h> 17#include <linux/sched.h>
20#include <linux/posix_acl.h> 18#include <linux/posix_acl.h>
19#include <linux/posix_acl_xattr.h>
20#include <linux/xattr.h>
21#include <linux/export.h> 21#include <linux/export.h>
22 22#include <linux/user_namespace.h>
23#include <linux/errno.h>
24 23
25struct posix_acl **acl_by_type(struct inode *inode, int type) 24struct posix_acl **acl_by_type(struct inode *inode, int type)
26{ 25{
@@ -97,6 +96,33 @@ void forget_all_cached_acls(struct inode *inode)
97} 96}
98EXPORT_SYMBOL(forget_all_cached_acls); 97EXPORT_SYMBOL(forget_all_cached_acls);
99 98
99struct posix_acl *get_acl(struct inode *inode, int type)
100{
101 struct posix_acl *acl;
102
103 acl = get_cached_acl(inode, type);
104 if (acl != ACL_NOT_CACHED)
105 return acl;
106
107 if (!IS_POSIXACL(inode))
108 return NULL;
109
110 /*
111 * A filesystem can force a ACL callback by just never filling the
112 * ACL cache. But normally you'd fill the cache either at inode
113 * instantiation time, or on the first ->get_acl call.
114 *
115 * If the filesystem doesn't have a get_acl() function at all, we'll
116 * just create the negative cache entry.
117 */
118 if (!inode->i_op->get_acl) {
119 set_cached_acl(inode, type, NULL);
120 return NULL;
121 }
122 return inode->i_op->get_acl(inode, type);
123}
124EXPORT_SYMBOL(get_acl);
125
100/* 126/*
101 * Init a fresh posix_acl 127 * Init a fresh posix_acl
102 */ 128 */
@@ -402,7 +428,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
402/* 428/*
403 * Modify the ACL for the chmod syscall. 429 * Modify the ACL for the chmod syscall.
404 */ 430 */
405static int posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) 431static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
406{ 432{
407 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; 433 struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
408 struct posix_acl_entry *pa, *pe; 434 struct posix_acl_entry *pa, *pe;
@@ -448,7 +474,7 @@ static int posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
448} 474}
449 475
450int 476int
451posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p) 477__posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)
452{ 478{
453 struct posix_acl *clone = posix_acl_clone(*acl, gfp); 479 struct posix_acl *clone = posix_acl_clone(*acl, gfp);
454 int err = -ENOMEM; 480 int err = -ENOMEM;
@@ -463,15 +489,15 @@ posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p)
463 *acl = clone; 489 *acl = clone;
464 return err; 490 return err;
465} 491}
466EXPORT_SYMBOL(posix_acl_create); 492EXPORT_SYMBOL(__posix_acl_create);
467 493
468int 494int
469posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode) 495__posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
470{ 496{
471 struct posix_acl *clone = posix_acl_clone(*acl, gfp); 497 struct posix_acl *clone = posix_acl_clone(*acl, gfp);
472 int err = -ENOMEM; 498 int err = -ENOMEM;
473 if (clone) { 499 if (clone) {
474 err = posix_acl_chmod_masq(clone, mode); 500 err = __posix_acl_chmod_masq(clone, mode);
475 if (err) { 501 if (err) {
476 posix_acl_release(clone); 502 posix_acl_release(clone);
477 clone = NULL; 503 clone = NULL;
@@ -481,4 +507,382 @@ posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode)
481 *acl = clone; 507 *acl = clone;
482 return err; 508 return err;
483} 509}
510EXPORT_SYMBOL(__posix_acl_chmod);
511
512int
513posix_acl_chmod(struct inode *inode, umode_t mode)
514{
515 struct posix_acl *acl;
516 int ret = 0;
517
518 if (!IS_POSIXACL(inode))
519 return 0;
520 if (!inode->i_op->set_acl)
521 return -EOPNOTSUPP;
522
523 acl = get_acl(inode, ACL_TYPE_ACCESS);
524 if (IS_ERR_OR_NULL(acl))
525 return PTR_ERR(acl);
526
527 ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode);
528 if (ret)
529 return ret;
530 ret = inode->i_op->set_acl(inode, acl, ACL_TYPE_ACCESS);
531 posix_acl_release(acl);
532 return ret;
533}
484EXPORT_SYMBOL(posix_acl_chmod); 534EXPORT_SYMBOL(posix_acl_chmod);
535
536int
537posix_acl_create(struct inode *dir, umode_t *mode,
538 struct posix_acl **default_acl, struct posix_acl **acl)
539{
540 struct posix_acl *p;
541 int ret;
542
543 if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
544 goto no_acl;
545
546 p = get_acl(dir, ACL_TYPE_DEFAULT);
547 if (IS_ERR(p))
548 return PTR_ERR(p);
549
550 if (!p) {
551 *mode &= ~current_umask();
552 goto no_acl;
553 }
554
555 *acl = posix_acl_clone(p, GFP_NOFS);
556 if (!*acl)
557 return -ENOMEM;
558
559 ret = posix_acl_create_masq(*acl, mode);
560 if (ret < 0) {
561 posix_acl_release(*acl);
562 return -ENOMEM;
563 }
564
565 if (ret == 0) {
566 posix_acl_release(*acl);
567 *acl = NULL;
568 }
569
570 if (!S_ISDIR(*mode)) {
571 posix_acl_release(p);
572 *default_acl = NULL;
573 } else {
574 *default_acl = p;
575 }
576 return 0;
577
578no_acl:
579 *default_acl = NULL;
580 *acl = NULL;
581 return 0;
582}
583EXPORT_SYMBOL_GPL(posix_acl_create);
584
585/*
586 * Fix up the uids and gids in posix acl extended attributes in place.
587 */
588static void posix_acl_fix_xattr_userns(
589 struct user_namespace *to, struct user_namespace *from,
590 void *value, size_t size)
591{
592 posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
593 posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
594 int count;
595 kuid_t uid;
596 kgid_t gid;
597
598 if (!value)
599 return;
600 if (size < sizeof(posix_acl_xattr_header))
601 return;
602 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
603 return;
604
605 count = posix_acl_xattr_count(size);
606 if (count < 0)
607 return;
608 if (count == 0)
609 return;
610
611 for (end = entry + count; entry != end; entry++) {
612 switch(le16_to_cpu(entry->e_tag)) {
613 case ACL_USER:
614 uid = make_kuid(from, le32_to_cpu(entry->e_id));
615 entry->e_id = cpu_to_le32(from_kuid(to, uid));
616 break;
617 case ACL_GROUP:
618 gid = make_kgid(from, le32_to_cpu(entry->e_id));
619 entry->e_id = cpu_to_le32(from_kgid(to, gid));
620 break;
621 default:
622 break;
623 }
624 }
625}
626
627void posix_acl_fix_xattr_from_user(void *value, size_t size)
628{
629 struct user_namespace *user_ns = current_user_ns();
630 if (user_ns == &init_user_ns)
631 return;
632 posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
633}
634
635void posix_acl_fix_xattr_to_user(void *value, size_t size)
636{
637 struct user_namespace *user_ns = current_user_ns();
638 if (user_ns == &init_user_ns)
639 return;
640 posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
641}
642
643/*
644 * Convert from extended attribute to in-memory representation.
645 */
646struct posix_acl *
647posix_acl_from_xattr(struct user_namespace *user_ns,
648 const void *value, size_t size)
649{
650 posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
651 posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
652 int count;
653 struct posix_acl *acl;
654 struct posix_acl_entry *acl_e;
655
656 if (!value)
657 return NULL;
658 if (size < sizeof(posix_acl_xattr_header))
659 return ERR_PTR(-EINVAL);
660 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
661 return ERR_PTR(-EOPNOTSUPP);
662
663 count = posix_acl_xattr_count(size);
664 if (count < 0)
665 return ERR_PTR(-EINVAL);
666 if (count == 0)
667 return NULL;
668
669 acl = posix_acl_alloc(count, GFP_NOFS);
670 if (!acl)
671 return ERR_PTR(-ENOMEM);
672 acl_e = acl->a_entries;
673
674 for (end = entry + count; entry != end; acl_e++, entry++) {
675 acl_e->e_tag = le16_to_cpu(entry->e_tag);
676 acl_e->e_perm = le16_to_cpu(entry->e_perm);
677
678 switch(acl_e->e_tag) {
679 case ACL_USER_OBJ:
680 case ACL_GROUP_OBJ:
681 case ACL_MASK:
682 case ACL_OTHER:
683 break;
684
685 case ACL_USER:
686 acl_e->e_uid =
687 make_kuid(user_ns,
688 le32_to_cpu(entry->e_id));
689 if (!uid_valid(acl_e->e_uid))
690 goto fail;
691 break;
692 case ACL_GROUP:
693 acl_e->e_gid =
694 make_kgid(user_ns,
695 le32_to_cpu(entry->e_id));
696 if (!gid_valid(acl_e->e_gid))
697 goto fail;
698 break;
699
700 default:
701 goto fail;
702 }
703 }
704 return acl;
705
706fail:
707 posix_acl_release(acl);
708 return ERR_PTR(-EINVAL);
709}
710EXPORT_SYMBOL (posix_acl_from_xattr);
711
712/*
713 * Convert from in-memory to extended attribute representation.
714 */
715int
716posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
717 void *buffer, size_t size)
718{
719 posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
720 posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
721 int real_size, n;
722
723 real_size = posix_acl_xattr_size(acl->a_count);
724 if (!buffer)
725 return real_size;
726 if (real_size > size)
727 return -ERANGE;
728
729 ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
730
731 for (n=0; n < acl->a_count; n++, ext_entry++) {
732 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
733 ext_entry->e_tag = cpu_to_le16(acl_e->e_tag);
734 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
735 switch(acl_e->e_tag) {
736 case ACL_USER:
737 ext_entry->e_id =
738 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
739 break;
740 case ACL_GROUP:
741 ext_entry->e_id =
742 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
743 break;
744 default:
745 ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
746 break;
747 }
748 }
749 return real_size;
750}
751EXPORT_SYMBOL (posix_acl_to_xattr);
752
753static int
754posix_acl_xattr_get(struct dentry *dentry, const char *name,
755 void *value, size_t size, int type)
756{
757 struct posix_acl *acl;
758 int error;
759
760 if (!IS_POSIXACL(dentry->d_inode))
761 return -EOPNOTSUPP;
762 if (S_ISLNK(dentry->d_inode->i_mode))
763 return -EOPNOTSUPP;
764
765 acl = get_acl(dentry->d_inode, type);
766 if (IS_ERR(acl))
767 return PTR_ERR(acl);
768 if (acl == NULL)
769 return -ENODATA;
770
771 error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
772 posix_acl_release(acl);
773
774 return error;
775}
776
777static int
778posix_acl_xattr_set(struct dentry *dentry, const char *name,
779 const void *value, size_t size, int flags, int type)
780{
781 struct inode *inode = dentry->d_inode;
782 struct posix_acl *acl = NULL;
783 int ret;
784
785 if (!IS_POSIXACL(inode))
786 return -EOPNOTSUPP;
787 if (!inode->i_op->set_acl)
788 return -EOPNOTSUPP;
789
790 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
791 return value ? -EACCES : 0;
792 if (!inode_owner_or_capable(inode))
793 return -EPERM;
794
795 if (value) {
796 acl = posix_acl_from_xattr(&init_user_ns, value, size);
797 if (IS_ERR(acl))
798 return PTR_ERR(acl);
799
800 if (acl) {
801 ret = posix_acl_valid(acl);
802 if (ret)
803 goto out;
804 }
805 }
806
807 ret = inode->i_op->set_acl(inode, acl, type);
808out:
809 posix_acl_release(acl);
810 return ret;
811}
812
813static size_t
814posix_acl_xattr_list(struct dentry *dentry, char *list, size_t list_size,
815 const char *name, size_t name_len, int type)
816{
817 const char *xname;
818 size_t size;
819
820 if (!IS_POSIXACL(dentry->d_inode))
821 return -EOPNOTSUPP;
822 if (S_ISLNK(dentry->d_inode->i_mode))
823 return -EOPNOTSUPP;
824
825 if (type == ACL_TYPE_ACCESS)
826 xname = POSIX_ACL_XATTR_ACCESS;
827 else
828 xname = POSIX_ACL_XATTR_DEFAULT;
829
830 size = strlen(xname) + 1;
831 if (list && size <= list_size)
832 memcpy(list, xname, size);
833 return size;
834}
835
836const struct xattr_handler posix_acl_access_xattr_handler = {
837 .prefix = POSIX_ACL_XATTR_ACCESS,
838 .flags = ACL_TYPE_ACCESS,
839 .list = posix_acl_xattr_list,
840 .get = posix_acl_xattr_get,
841 .set = posix_acl_xattr_set,
842};
843EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler);
844
845const struct xattr_handler posix_acl_default_xattr_handler = {
846 .prefix = POSIX_ACL_XATTR_DEFAULT,
847 .flags = ACL_TYPE_DEFAULT,
848 .list = posix_acl_xattr_list,
849 .get = posix_acl_xattr_get,
850 .set = posix_acl_xattr_set,
851};
852EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler);
853
854int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type)
855{
856 int error;
857
858 if (type == ACL_TYPE_ACCESS) {
859 error = posix_acl_equiv_mode(acl, &inode->i_mode);
860 if (error < 0)
861 return 0;
862 if (error == 0)
863 acl = NULL;
864 }
865
866 inode->i_ctime = CURRENT_TIME;
867 set_cached_acl(inode, type, acl);
868 return 0;
869}
870
871int simple_acl_create(struct inode *dir, struct inode *inode)
872{
873 struct posix_acl *default_acl, *acl;
874 int error;
875
876 error = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
877 if (error)
878 return error;
879
880 set_cached_acl(inode, ACL_TYPE_DEFAULT, default_acl);
881 set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
882
883 if (default_acl)
884 posix_acl_release(default_acl);
885 if (acl)
886 posix_acl_release(acl);
887 return 0;
888}
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 2e8caa62da78..89558810381c 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -27,7 +27,6 @@
27 27
28static const struct super_operations qnx4_sops; 28static const struct super_operations qnx4_sops;
29 29
30static void qnx4_put_super(struct super_block *sb);
31static struct inode *qnx4_alloc_inode(struct super_block *sb); 30static struct inode *qnx4_alloc_inode(struct super_block *sb);
32static void qnx4_destroy_inode(struct inode *inode); 31static void qnx4_destroy_inode(struct inode *inode);
33static int qnx4_remount(struct super_block *sb, int *flags, char *data); 32static int qnx4_remount(struct super_block *sb, int *flags, char *data);
@@ -37,7 +36,6 @@ static const struct super_operations qnx4_sops =
37{ 36{
38 .alloc_inode = qnx4_alloc_inode, 37 .alloc_inode = qnx4_alloc_inode,
39 .destroy_inode = qnx4_destroy_inode, 38 .destroy_inode = qnx4_destroy_inode,
40 .put_super = qnx4_put_super,
41 .statfs = qnx4_statfs, 39 .statfs = qnx4_statfs,
42 .remount_fs = qnx4_remount, 40 .remount_fs = qnx4_remount,
43}; 41};
@@ -148,18 +146,19 @@ static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
148 * it really _is_ a qnx4 filesystem, and to check the size 146 * it really _is_ a qnx4 filesystem, and to check the size
149 * of the directory entry. 147 * of the directory entry.
150 */ 148 */
151static const char *qnx4_checkroot(struct super_block *sb) 149static const char *qnx4_checkroot(struct super_block *sb,
150 struct qnx4_super_block *s)
152{ 151{
153 struct buffer_head *bh; 152 struct buffer_head *bh;
154 struct qnx4_inode_entry *rootdir; 153 struct qnx4_inode_entry *rootdir;
155 int rd, rl; 154 int rd, rl;
156 int i, j; 155 int i, j;
157 156
158 if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') 157 if (s->RootDir.di_fname[0] != '/' || s->RootDir.di_fname[1] != '\0')
159 return "no qnx4 filesystem (no root dir)."; 158 return "no qnx4 filesystem (no root dir).";
160 QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id)); 159 QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id));
161 rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1; 160 rd = le32_to_cpu(s->RootDir.di_first_xtnt.xtnt_blk) - 1;
162 rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size); 161 rl = le32_to_cpu(s->RootDir.di_first_xtnt.xtnt_size);
163 for (j = 0; j < rl; j++) { 162 for (j = 0; j < rl; j++) {
164 bh = sb_bread(sb, rd + j); /* root dir, first block */ 163 bh = sb_bread(sb, rd + j); /* root dir, first block */
165 if (bh == NULL) 164 if (bh == NULL)
@@ -189,7 +188,6 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
189 struct inode *root; 188 struct inode *root;
190 const char *errmsg; 189 const char *errmsg;
191 struct qnx4_sb_info *qs; 190 struct qnx4_sb_info *qs;
192 int ret = -EINVAL;
193 191
194 qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); 192 qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
195 if (!qs) 193 if (!qs)
@@ -198,67 +196,50 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
198 196
199 sb_set_blocksize(s, QNX4_BLOCK_SIZE); 197 sb_set_blocksize(s, QNX4_BLOCK_SIZE);
200 198
199 s->s_op = &qnx4_sops;
200 s->s_magic = QNX4_SUPER_MAGIC;
201 s->s_flags |= MS_RDONLY; /* Yup, read-only yet */
202
201 /* Check the superblock signature. Since the qnx4 code is 203 /* Check the superblock signature. Since the qnx4 code is
202 dangerous, we should leave as quickly as possible 204 dangerous, we should leave as quickly as possible
203 if we don't belong here... */ 205 if we don't belong here... */
204 bh = sb_bread(s, 1); 206 bh = sb_bread(s, 1);
205 if (!bh) { 207 if (!bh) {
206 printk(KERN_ERR "qnx4: unable to read the superblock\n"); 208 printk(KERN_ERR "qnx4: unable to read the superblock\n");
207 goto outnobh; 209 return -EINVAL;
208 } 210 }
209 if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) {
210 if (!silent)
211 printk(KERN_ERR "qnx4: wrong fsid in superblock.\n");
212 goto out;
213 }
214 s->s_op = &qnx4_sops;
215 s->s_magic = QNX4_SUPER_MAGIC;
216 s->s_flags |= MS_RDONLY; /* Yup, read-only yet */
217 qnx4_sb(s)->sb_buf = bh;
218 qnx4_sb(s)->sb = (struct qnx4_super_block *) bh->b_data;
219
220 211
221 /* check before allocating dentries, inodes, .. */ 212 /* check before allocating dentries, inodes, .. */
222 errmsg = qnx4_checkroot(s); 213 errmsg = qnx4_checkroot(s, (struct qnx4_super_block *) bh->b_data);
214 brelse(bh);
223 if (errmsg != NULL) { 215 if (errmsg != NULL) {
224 if (!silent) 216 if (!silent)
225 printk(KERN_ERR "qnx4: %s\n", errmsg); 217 printk(KERN_ERR "qnx4: %s\n", errmsg);
226 goto out; 218 return -EINVAL;
227 } 219 }
228 220
229 /* does root not have inode number QNX4_ROOT_INO ?? */ 221 /* does root not have inode number QNX4_ROOT_INO ?? */
230 root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); 222 root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
231 if (IS_ERR(root)) { 223 if (IS_ERR(root)) {
232 printk(KERN_ERR "qnx4: get inode failed\n"); 224 printk(KERN_ERR "qnx4: get inode failed\n");
233 ret = PTR_ERR(root); 225 return PTR_ERR(root);
234 goto outb;
235 } 226 }
236 227
237 ret = -ENOMEM;
238 s->s_root = d_make_root(root); 228 s->s_root = d_make_root(root);
239 if (s->s_root == NULL) 229 if (s->s_root == NULL)
240 goto outb; 230 return -ENOMEM;
241 231
242 brelse(bh);
243 return 0; 232 return 0;
244
245 outb:
246 kfree(qs->BitMap);
247 out:
248 brelse(bh);
249 outnobh:
250 kfree(qs);
251 s->s_fs_info = NULL;
252 return ret;
253} 233}
254 234
255static void qnx4_put_super(struct super_block *sb) 235static void qnx4_kill_sb(struct super_block *sb)
256{ 236{
257 struct qnx4_sb_info *qs = qnx4_sb(sb); 237 struct qnx4_sb_info *qs = qnx4_sb(sb);
258 kfree( qs->BitMap ); 238 kill_block_super(sb);
259 kfree( qs ); 239 if (qs) {
260 sb->s_fs_info = NULL; 240 kfree(qs->BitMap);
261 return; 241 kfree(qs);
242 }
262} 243}
263 244
264static int qnx4_readpage(struct file *file, struct page *page) 245static int qnx4_readpage(struct file *file, struct page *page)
@@ -409,7 +390,7 @@ static struct file_system_type qnx4_fs_type = {
409 .owner = THIS_MODULE, 390 .owner = THIS_MODULE,
410 .name = "qnx4", 391 .name = "qnx4",
411 .mount = qnx4_mount, 392 .mount = qnx4_mount,
412 .kill_sb = kill_block_super, 393 .kill_sb = qnx4_kill_sb,
413 .fs_flags = FS_REQUIRES_DEV, 394 .fs_flags = FS_REQUIRES_DEV,
414}; 395};
415MODULE_ALIAS_FS("qnx4"); 396MODULE_ALIAS_FS("qnx4");
diff --git a/fs/qnx4/qnx4.h b/fs/qnx4/qnx4.h
index 34e2d329c97e..c9b1be2c164d 100644
--- a/fs/qnx4/qnx4.h
+++ b/fs/qnx4/qnx4.h
@@ -10,8 +10,6 @@
10#endif 10#endif
11 11
12struct qnx4_sb_info { 12struct qnx4_sb_info {
13 struct buffer_head *sb_buf; /* superblock buffer */
14 struct qnx4_super_block *sb; /* our superblock */
15 unsigned int Version; /* may be useful */ 13 unsigned int Version; /* may be useful */
16 struct qnx4_inode_entry *BitMap; /* useful */ 14 struct qnx4_inode_entry *BitMap; /* useful */
17}; 15};
diff --git a/fs/reiserfs/acl.h b/fs/reiserfs/acl.h
index f096b80e73d8..4a211f5b34b8 100644
--- a/fs/reiserfs/acl.h
+++ b/fs/reiserfs/acl.h
@@ -48,18 +48,18 @@ static inline int reiserfs_acl_count(size_t size)
48 48
49#ifdef CONFIG_REISERFS_FS_POSIX_ACL 49#ifdef CONFIG_REISERFS_FS_POSIX_ACL
50struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); 50struct posix_acl *reiserfs_get_acl(struct inode *inode, int type);
51int reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
51int reiserfs_acl_chmod(struct inode *inode); 52int reiserfs_acl_chmod(struct inode *inode);
52int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, 53int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
53 struct inode *dir, struct dentry *dentry, 54 struct inode *dir, struct dentry *dentry,
54 struct inode *inode); 55 struct inode *inode);
55int reiserfs_cache_default_acl(struct inode *dir); 56int reiserfs_cache_default_acl(struct inode *dir);
56extern const struct xattr_handler reiserfs_posix_acl_default_handler;
57extern const struct xattr_handler reiserfs_posix_acl_access_handler;
58 57
59#else 58#else
60 59
61#define reiserfs_cache_default_acl(inode) 0 60#define reiserfs_cache_default_acl(inode) 0
62#define reiserfs_get_acl NULL 61#define reiserfs_get_acl NULL
62#define reiserfs_set_acl NULL
63 63
64static inline int reiserfs_acl_chmod(struct inode *inode) 64static inline int reiserfs_acl_chmod(struct inode *inode)
65{ 65{
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index dcaafcfc23b0..ed58d843d578 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -260,4 +260,5 @@ const struct inode_operations reiserfs_file_inode_operations = {
260 .removexattr = reiserfs_removexattr, 260 .removexattr = reiserfs_removexattr,
261 .permission = reiserfs_permission, 261 .permission = reiserfs_permission,
262 .get_acl = reiserfs_get_acl, 262 .get_acl = reiserfs_get_acl,
263 .set_acl = reiserfs_set_acl,
263}; 264};
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index dc5236f6de1b..e825f8b63e6b 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1522,6 +1522,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
1522 .removexattr = reiserfs_removexattr, 1522 .removexattr = reiserfs_removexattr,
1523 .permission = reiserfs_permission, 1523 .permission = reiserfs_permission,
1524 .get_acl = reiserfs_get_acl, 1524 .get_acl = reiserfs_get_acl,
1525 .set_acl = reiserfs_set_acl,
1525}; 1526};
1526 1527
1527/* 1528/*
@@ -1538,8 +1539,6 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
1538 .listxattr = reiserfs_listxattr, 1539 .listxattr = reiserfs_listxattr,
1539 .removexattr = reiserfs_removexattr, 1540 .removexattr = reiserfs_removexattr,
1540 .permission = reiserfs_permission, 1541 .permission = reiserfs_permission,
1541 .get_acl = reiserfs_get_acl,
1542
1543}; 1542};
1544 1543
1545/* 1544/*
@@ -1553,4 +1552,5 @@ const struct inode_operations reiserfs_special_inode_operations = {
1553 .removexattr = reiserfs_removexattr, 1552 .removexattr = reiserfs_removexattr,
1554 .permission = reiserfs_permission, 1553 .permission = reiserfs_permission,
1555 .get_acl = reiserfs_get_acl, 1554 .get_acl = reiserfs_get_acl,
1555 .set_acl = reiserfs_set_acl,
1556}; 1556};
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index a958444a75fc..02b0b7d0f7d5 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -419,7 +419,7 @@ int reiserfs_proc_info_init(struct super_block *sb)
419 char *s; 419 char *s;
420 420
421 /* Some block devices use /'s */ 421 /* Some block devices use /'s */
422 strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE); 422 strlcpy(b, sb->s_id, BDEVNAME_SIZE);
423 s = strchr(b, '/'); 423 s = strchr(b, '/');
424 if (s) 424 if (s)
425 *s = '!'; 425 *s = '!';
@@ -449,7 +449,7 @@ int reiserfs_proc_info_done(struct super_block *sb)
449 char *s; 449 char *s;
450 450
451 /* Some block devices use /'s */ 451 /* Some block devices use /'s */
452 strlcpy(b, reiserfs_bdevname(sb), BDEVNAME_SIZE); 452 strlcpy(b, sb->s_id, BDEVNAME_SIZE);
453 s = strchr(b, '/'); 453 s = strchr(b, '/');
454 if (s) 454 if (s)
455 *s = '!'; 455 *s = '!';
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h
index dfb617b2bad2..8d06adf89948 100644
--- a/fs/reiserfs/reiserfs.h
+++ b/fs/reiserfs/reiserfs.h
@@ -608,14 +608,6 @@ int reiserfs_resize(struct super_block *, unsigned long);
608 608
609#define SB_DISK_JOURNAL_HEAD(s) (SB_JOURNAL(s)->j_header_bh->) 609#define SB_DISK_JOURNAL_HEAD(s) (SB_JOURNAL(s)->j_header_bh->)
610 610
611/* A safe version of the "bdevname", which returns the "s_id" field of
612 * a superblock or else "Null superblock" if the super block is NULL.
613 */
614static inline char *reiserfs_bdevname(struct super_block *s)
615{
616 return (s == NULL) ? "Null superblock" : s->s_id;
617}
618
619#define reiserfs_is_journal_aborted(journal) (unlikely (__reiserfs_is_journal_aborted (journal))) 611#define reiserfs_is_journal_aborted(journal) (unlikely (__reiserfs_is_journal_aborted (journal)))
620static inline int __reiserfs_is_journal_aborted(struct reiserfs_journal 612static inline int __reiserfs_is_journal_aborted(struct reiserfs_journal
621 *journal) 613 *journal)
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 3ead145dadc4..2c803353f8ac 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1479,7 +1479,7 @@ static int read_super_block(struct super_block *s, int offset)
1479 if (!bh) { 1479 if (!bh) {
1480 reiserfs_warning(s, "sh-2006", 1480 reiserfs_warning(s, "sh-2006",
1481 "bread failed (dev %s, block %lu, size %lu)", 1481 "bread failed (dev %s, block %lu, size %lu)",
1482 reiserfs_bdevname(s), offset / s->s_blocksize, 1482 s->s_id, offset / s->s_blocksize,
1483 s->s_blocksize); 1483 s->s_blocksize);
1484 return 1; 1484 return 1;
1485 } 1485 }
@@ -1500,7 +1500,7 @@ static int read_super_block(struct super_block *s, int offset)
1500 if (!bh) { 1500 if (!bh) {
1501 reiserfs_warning(s, "sh-2007", 1501 reiserfs_warning(s, "sh-2007",
1502 "bread failed (dev %s, block %lu, size %lu)", 1502 "bread failed (dev %s, block %lu, size %lu)",
1503 reiserfs_bdevname(s), offset / s->s_blocksize, 1503 s->s_id, offset / s->s_blocksize,
1504 s->s_blocksize); 1504 s->s_blocksize);
1505 return 1; 1505 return 1;
1506 } 1506 }
@@ -1509,7 +1509,7 @@ static int read_super_block(struct super_block *s, int offset)
1509 if (sb_blocksize(rs) != s->s_blocksize) { 1509 if (sb_blocksize(rs) != s->s_blocksize) {
1510 reiserfs_warning(s, "sh-2011", "can't find a reiserfs " 1510 reiserfs_warning(s, "sh-2011", "can't find a reiserfs "
1511 "filesystem on (dev %s, block %Lu, size %lu)", 1511 "filesystem on (dev %s, block %Lu, size %lu)",
1512 reiserfs_bdevname(s), 1512 s->s_id,
1513 (unsigned long long)bh->b_blocknr, 1513 (unsigned long long)bh->b_blocknr,
1514 s->s_blocksize); 1514 s->s_blocksize);
1515 brelse(bh); 1515 brelse(bh);
@@ -1825,7 +1825,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1825 /* try new format (64-th 1k block), which can contain reiserfs super block */ 1825 /* try new format (64-th 1k block), which can contain reiserfs super block */
1826 else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) { 1826 else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) {
1827 SWARN(silent, s, "sh-2021", "can not find reiserfs on %s", 1827 SWARN(silent, s, "sh-2021", "can not find reiserfs on %s",
1828 reiserfs_bdevname(s)); 1828 s->s_id);
1829 goto error_unlocked; 1829 goto error_unlocked;
1830 } 1830 }
1831 1831
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 8a9e2dcfe004..5cdfbd638b5c 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -50,6 +50,7 @@
50#include <linux/stat.h> 50#include <linux/stat.h>
51#include <linux/quotaops.h> 51#include <linux/quotaops.h>
52#include <linux/security.h> 52#include <linux/security.h>
53#include <linux/posix_acl_xattr.h>
53 54
54#define PRIVROOT_NAME ".reiserfs_priv" 55#define PRIVROOT_NAME ".reiserfs_priv"
55#define XAROOT_NAME "xattrs" 56#define XAROOT_NAME "xattrs"
@@ -904,8 +905,8 @@ static const struct xattr_handler *reiserfs_xattr_handlers[] = {
904 &reiserfs_xattr_security_handler, 905 &reiserfs_xattr_security_handler,
905#endif 906#endif
906#ifdef CONFIG_REISERFS_FS_POSIX_ACL 907#ifdef CONFIG_REISERFS_FS_POSIX_ACL
907 &reiserfs_posix_acl_access_handler, 908 &posix_acl_access_xattr_handler,
908 &reiserfs_posix_acl_default_handler, 909 &posix_acl_default_xattr_handler,
909#endif 910#endif
910 NULL 911 NULL
911}; 912};
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 06c04f73da65..a6ce532402dc 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -11,35 +11,19 @@
11#include "acl.h" 11#include "acl.h"
12#include <asm/uaccess.h> 12#include <asm/uaccess.h>
13 13
14static int reiserfs_set_acl(struct reiserfs_transaction_handle *th, 14static int __reiserfs_set_acl(struct reiserfs_transaction_handle *th,
15 struct inode *inode, int type, 15 struct inode *inode, int type,
16 struct posix_acl *acl); 16 struct posix_acl *acl);
17 17
18static int 18
19posix_acl_set(struct dentry *dentry, const char *name, const void *value, 19int
20 size_t size, int flags, int type) 20reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
21{ 21{
22 struct inode *inode = dentry->d_inode;
23 struct posix_acl *acl;
24 int error, error2; 22 int error, error2;
25 struct reiserfs_transaction_handle th; 23 struct reiserfs_transaction_handle th;
26 size_t jcreate_blocks; 24 size_t jcreate_blocks;
27 if (!reiserfs_posixacl(inode->i_sb)) 25 int size = acl ? posix_acl_xattr_size(acl->a_count) : 0;
28 return -EOPNOTSUPP; 26
29 if (!inode_owner_or_capable(inode))
30 return -EPERM;
31
32 if (value) {
33 acl = posix_acl_from_xattr(&init_user_ns, value, size);
34 if (IS_ERR(acl)) {
35 return PTR_ERR(acl);
36 } else if (acl) {
37 error = posix_acl_valid(acl);
38 if (error)
39 goto release_and_out;
40 }
41 } else
42 acl = NULL;
43 27
44 /* Pessimism: We can't assume that anything from the xattr root up 28 /* Pessimism: We can't assume that anything from the xattr root up
45 * has been created. */ 29 * has been created. */
@@ -51,7 +35,7 @@ posix_acl_set(struct dentry *dentry, const char *name, const void *value,
51 error = journal_begin(&th, inode->i_sb, jcreate_blocks); 35 error = journal_begin(&th, inode->i_sb, jcreate_blocks);
52 reiserfs_write_unlock(inode->i_sb); 36 reiserfs_write_unlock(inode->i_sb);
53 if (error == 0) { 37 if (error == 0) {
54 error = reiserfs_set_acl(&th, inode, type, acl); 38 error = __reiserfs_set_acl(&th, inode, type, acl);
55 reiserfs_write_lock(inode->i_sb); 39 reiserfs_write_lock(inode->i_sb);
56 error2 = journal_end(&th, inode->i_sb, jcreate_blocks); 40 error2 = journal_end(&th, inode->i_sb, jcreate_blocks);
57 reiserfs_write_unlock(inode->i_sb); 41 reiserfs_write_unlock(inode->i_sb);
@@ -59,36 +43,13 @@ posix_acl_set(struct dentry *dentry, const char *name, const void *value,
59 error = error2; 43 error = error2;
60 } 44 }
61 45
62 release_and_out:
63 posix_acl_release(acl);
64 return error;
65}
66
67static int
68posix_acl_get(struct dentry *dentry, const char *name, void *buffer,
69 size_t size, int type)
70{
71 struct posix_acl *acl;
72 int error;
73
74 if (!reiserfs_posixacl(dentry->d_sb))
75 return -EOPNOTSUPP;
76
77 acl = reiserfs_get_acl(dentry->d_inode, type);
78 if (IS_ERR(acl))
79 return PTR_ERR(acl);
80 if (acl == NULL)
81 return -ENODATA;
82 error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
83 posix_acl_release(acl);
84
85 return error; 46 return error;
86} 47}
87 48
88/* 49/*
89 * Convert from filesystem to in-memory representation. 50 * Convert from filesystem to in-memory representation.
90 */ 51 */
91static struct posix_acl *posix_acl_from_disk(const void *value, size_t size) 52static struct posix_acl *reiserfs_posix_acl_from_disk(const void *value, size_t size)
92{ 53{
93 const char *end = (char *)value + size; 54 const char *end = (char *)value + size;
94 int n, count; 55 int n, count;
@@ -158,7 +119,7 @@ static struct posix_acl *posix_acl_from_disk(const void *value, size_t size)
158/* 119/*
159 * Convert from in-memory to filesystem representation. 120 * Convert from in-memory to filesystem representation.
160 */ 121 */
161static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) 122static void *reiserfs_posix_acl_to_disk(const struct posix_acl *acl, size_t * size)
162{ 123{
163 reiserfs_acl_header *ext_acl; 124 reiserfs_acl_header *ext_acl;
164 char *e; 125 char *e;
@@ -221,10 +182,6 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
221 int size; 182 int size;
222 int retval; 183 int retval;
223 184
224 acl = get_cached_acl(inode, type);
225 if (acl != ACL_NOT_CACHED)
226 return acl;
227
228 switch (type) { 185 switch (type) {
229 case ACL_TYPE_ACCESS: 186 case ACL_TYPE_ACCESS:
230 name = POSIX_ACL_XATTR_ACCESS; 187 name = POSIX_ACL_XATTR_ACCESS;
@@ -257,7 +214,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
257 } else if (retval < 0) { 214 } else if (retval < 0) {
258 acl = ERR_PTR(retval); 215 acl = ERR_PTR(retval);
259 } else { 216 } else {
260 acl = posix_acl_from_disk(value, retval); 217 acl = reiserfs_posix_acl_from_disk(value, retval);
261 } 218 }
262 if (!IS_ERR(acl)) 219 if (!IS_ERR(acl))
263 set_cached_acl(inode, type, acl); 220 set_cached_acl(inode, type, acl);
@@ -273,7 +230,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
273 * BKL held [before 2.5.x] 230 * BKL held [before 2.5.x]
274 */ 231 */
275static int 232static int
276reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode, 233__reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
277 int type, struct posix_acl *acl) 234 int type, struct posix_acl *acl)
278{ 235{
279 char *name; 236 char *name;
@@ -281,9 +238,6 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
281 size_t size = 0; 238 size_t size = 0;
282 int error; 239 int error;
283 240
284 if (S_ISLNK(inode->i_mode))
285 return -EOPNOTSUPP;
286
287 switch (type) { 241 switch (type) {
288 case ACL_TYPE_ACCESS: 242 case ACL_TYPE_ACCESS:
289 name = POSIX_ACL_XATTR_ACCESS; 243 name = POSIX_ACL_XATTR_ACCESS;
@@ -307,7 +261,7 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
307 } 261 }
308 262
309 if (acl) { 263 if (acl) {
310 value = posix_acl_to_disk(acl, &size); 264 value = reiserfs_posix_acl_to_disk(acl, &size);
311 if (IS_ERR(value)) 265 if (IS_ERR(value))
312 return (int)PTR_ERR(value); 266 return (int)PTR_ERR(value);
313 } 267 }
@@ -343,7 +297,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
343 struct inode *dir, struct dentry *dentry, 297 struct inode *dir, struct dentry *dentry,
344 struct inode *inode) 298 struct inode *inode)
345{ 299{
346 struct posix_acl *acl; 300 struct posix_acl *default_acl, *acl;
347 int err = 0; 301 int err = 0;
348 302
349 /* ACLs only get applied to files and directories */ 303 /* ACLs only get applied to files and directories */
@@ -363,37 +317,28 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
363 goto apply_umask; 317 goto apply_umask;
364 } 318 }
365 319
366 acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT); 320 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
367 if (IS_ERR(acl)) 321 if (err)
368 return PTR_ERR(acl); 322 return err;
369 323
324 if (default_acl) {
325 err = __reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT,
326 default_acl);
327 posix_acl_release(default_acl);
328 }
370 if (acl) { 329 if (acl) {
371 /* Copy the default ACL to the default ACL of a new directory */ 330 if (!err)
372 if (S_ISDIR(inode->i_mode)) { 331 err = __reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS,
373 err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, 332 acl);
374 acl);
375 if (err)
376 goto cleanup;
377 }
378
379 /* Now we reconcile the new ACL and the mode,
380 potentially modifying both */
381 err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
382 if (err < 0)
383 return err;
384
385 /* If we need an ACL.. */
386 if (err > 0)
387 err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl);
388 cleanup:
389 posix_acl_release(acl); 333 posix_acl_release(acl);
390 } else {
391 apply_umask:
392 /* no ACL, apply umask */
393 inode->i_mode &= ~current_umask();
394 } 334 }
395 335
396 return err; 336 return err;
337
338 apply_umask:
339 /* no ACL, apply umask */
340 inode->i_mode &= ~current_umask();
341 return err;
397} 342}
398 343
399/* This is used to cache the default acl before a new object is created. 344/* This is used to cache the default acl before a new object is created.
@@ -442,84 +387,11 @@ int reiserfs_cache_default_acl(struct inode *inode)
442 */ 387 */
443int reiserfs_acl_chmod(struct inode *inode) 388int reiserfs_acl_chmod(struct inode *inode)
444{ 389{
445 struct reiserfs_transaction_handle th;
446 struct posix_acl *acl;
447 size_t size;
448 int error;
449
450 if (IS_PRIVATE(inode)) 390 if (IS_PRIVATE(inode))
451 return 0; 391 return 0;
452
453 if (S_ISLNK(inode->i_mode))
454 return -EOPNOTSUPP;
455
456 if (get_inode_sd_version(inode) == STAT_DATA_V1 || 392 if (get_inode_sd_version(inode) == STAT_DATA_V1 ||
457 !reiserfs_posixacl(inode->i_sb)) { 393 !reiserfs_posixacl(inode->i_sb))
458 return 0; 394 return 0;
459 }
460 395
461 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); 396 return posix_acl_chmod(inode, inode->i_mode);
462 if (!acl)
463 return 0;
464 if (IS_ERR(acl))
465 return PTR_ERR(acl);
466 error = posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
467 if (error)
468 return error;
469
470 size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(acl->a_count));
471 reiserfs_write_lock(inode->i_sb);
472 error = journal_begin(&th, inode->i_sb, size * 2);
473 reiserfs_write_unlock(inode->i_sb);
474 if (!error) {
475 int error2;
476 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, acl);
477 reiserfs_write_lock(inode->i_sb);
478 error2 = journal_end(&th, inode->i_sb, size * 2);
479 reiserfs_write_unlock(inode->i_sb);
480 if (error2)
481 error = error2;
482 }
483 posix_acl_release(acl);
484 return error;
485}
486
487static size_t posix_acl_access_list(struct dentry *dentry, char *list,
488 size_t list_size, const char *name,
489 size_t name_len, int type)
490{
491 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
492 if (!reiserfs_posixacl(dentry->d_sb))
493 return 0;
494 if (list && size <= list_size)
495 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
496 return size;
497} 397}
498
499const struct xattr_handler reiserfs_posix_acl_access_handler = {
500 .prefix = POSIX_ACL_XATTR_ACCESS,
501 .flags = ACL_TYPE_ACCESS,
502 .get = posix_acl_get,
503 .set = posix_acl_set,
504 .list = posix_acl_access_list,
505};
506
507static size_t posix_acl_default_list(struct dentry *dentry, char *list,
508 size_t list_size, const char *name,
509 size_t name_len, int type)
510{
511 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
512 if (!reiserfs_posixacl(dentry->d_sb))
513 return 0;
514 if (list && size <= list_size)
515 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
516 return size;
517}
518
519const struct xattr_handler reiserfs_posix_acl_default_handler = {
520 .prefix = POSIX_ACL_XATTR_DEFAULT,
521 .flags = ACL_TYPE_DEFAULT,
522 .get = posix_acl_get,
523 .set = posix_acl_set,
524 .list = posix_acl_default_list,
525};
diff --git a/fs/xattr_acl.c b/fs/xattr_acl.c
deleted file mode 100644
index 9fbea87fdb6e..000000000000
--- a/fs/xattr_acl.c
+++ /dev/null
@@ -1,180 +0,0 @@
1/*
2 * linux/fs/xattr_acl.c
3 *
4 * Almost all from linux/fs/ext2/acl.c:
5 * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
6 */
7
8#include <linux/export.h>
9#include <linux/fs.h>
10#include <linux/posix_acl_xattr.h>
11#include <linux/gfp.h>
12#include <linux/user_namespace.h>
13
14/*
15 * Fix up the uids and gids in posix acl extended attributes in place.
16 */
17static void posix_acl_fix_xattr_userns(
18 struct user_namespace *to, struct user_namespace *from,
19 void *value, size_t size)
20{
21 posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
22 posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
23 int count;
24 kuid_t uid;
25 kgid_t gid;
26
27 if (!value)
28 return;
29 if (size < sizeof(posix_acl_xattr_header))
30 return;
31 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
32 return;
33
34 count = posix_acl_xattr_count(size);
35 if (count < 0)
36 return;
37 if (count == 0)
38 return;
39
40 for (end = entry + count; entry != end; entry++) {
41 switch(le16_to_cpu(entry->e_tag)) {
42 case ACL_USER:
43 uid = make_kuid(from, le32_to_cpu(entry->e_id));
44 entry->e_id = cpu_to_le32(from_kuid(to, uid));
45 break;
46 case ACL_GROUP:
47 gid = make_kgid(from, le32_to_cpu(entry->e_id));
48 entry->e_id = cpu_to_le32(from_kgid(to, gid));
49 break;
50 default:
51 break;
52 }
53 }
54}
55
56void posix_acl_fix_xattr_from_user(void *value, size_t size)
57{
58 struct user_namespace *user_ns = current_user_ns();
59 if (user_ns == &init_user_ns)
60 return;
61 posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
62}
63
64void posix_acl_fix_xattr_to_user(void *value, size_t size)
65{
66 struct user_namespace *user_ns = current_user_ns();
67 if (user_ns == &init_user_ns)
68 return;
69 posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
70}
71
72/*
73 * Convert from extended attribute to in-memory representation.
74 */
75struct posix_acl *
76posix_acl_from_xattr(struct user_namespace *user_ns,
77 const void *value, size_t size)
78{
79 posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
80 posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
81 int count;
82 struct posix_acl *acl;
83 struct posix_acl_entry *acl_e;
84
85 if (!value)
86 return NULL;
87 if (size < sizeof(posix_acl_xattr_header))
88 return ERR_PTR(-EINVAL);
89 if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
90 return ERR_PTR(-EOPNOTSUPP);
91
92 count = posix_acl_xattr_count(size);
93 if (count < 0)
94 return ERR_PTR(-EINVAL);
95 if (count == 0)
96 return NULL;
97
98 acl = posix_acl_alloc(count, GFP_NOFS);
99 if (!acl)
100 return ERR_PTR(-ENOMEM);
101 acl_e = acl->a_entries;
102
103 for (end = entry + count; entry != end; acl_e++, entry++) {
104 acl_e->e_tag = le16_to_cpu(entry->e_tag);
105 acl_e->e_perm = le16_to_cpu(entry->e_perm);
106
107 switch(acl_e->e_tag) {
108 case ACL_USER_OBJ:
109 case ACL_GROUP_OBJ:
110 case ACL_MASK:
111 case ACL_OTHER:
112 break;
113
114 case ACL_USER:
115 acl_e->e_uid =
116 make_kuid(user_ns,
117 le32_to_cpu(entry->e_id));
118 if (!uid_valid(acl_e->e_uid))
119 goto fail;
120 break;
121 case ACL_GROUP:
122 acl_e->e_gid =
123 make_kgid(user_ns,
124 le32_to_cpu(entry->e_id));
125 if (!gid_valid(acl_e->e_gid))
126 goto fail;
127 break;
128
129 default:
130 goto fail;
131 }
132 }
133 return acl;
134
135fail:
136 posix_acl_release(acl);
137 return ERR_PTR(-EINVAL);
138}
139EXPORT_SYMBOL (posix_acl_from_xattr);
140
141/*
142 * Convert from in-memory to extended attribute representation.
143 */
144int
145posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
146 void *buffer, size_t size)
147{
148 posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
149 posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
150 int real_size, n;
151
152 real_size = posix_acl_xattr_size(acl->a_count);
153 if (!buffer)
154 return real_size;
155 if (real_size > size)
156 return -ERANGE;
157
158 ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
159
160 for (n=0; n < acl->a_count; n++, ext_entry++) {
161 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
162 ext_entry->e_tag = cpu_to_le16(acl_e->e_tag);
163 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
164 switch(acl_e->e_tag) {
165 case ACL_USER:
166 ext_entry->e_id =
167 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
168 break;
169 case ACL_GROUP:
170 ext_entry->e_id =
171 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
172 break;
173 default:
174 ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
175 break;
176 }
177 }
178 return real_size;
179}
180EXPORT_SYMBOL (posix_acl_to_xattr);
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 370eb3e121d1..0ecec1896f25 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -124,16 +124,12 @@ struct posix_acl *
124xfs_get_acl(struct inode *inode, int type) 124xfs_get_acl(struct inode *inode, int type)
125{ 125{
126 struct xfs_inode *ip = XFS_I(inode); 126 struct xfs_inode *ip = XFS_I(inode);
127 struct posix_acl *acl; 127 struct posix_acl *acl = NULL;
128 struct xfs_acl *xfs_acl; 128 struct xfs_acl *xfs_acl;
129 unsigned char *ea_name; 129 unsigned char *ea_name;
130 int error; 130 int error;
131 int len; 131 int len;
132 132
133 acl = get_cached_acl(inode, type);
134 if (acl != ACL_NOT_CACHED)
135 return acl;
136
137 trace_xfs_get_acl(ip); 133 trace_xfs_get_acl(ip);
138 134
139 switch (type) { 135 switch (type) {
@@ -164,10 +160,8 @@ xfs_get_acl(struct inode *inode, int type)
164 * cache entry, for any other error assume it is transient and 160 * cache entry, for any other error assume it is transient and
165 * leave the cache entry as ACL_NOT_CACHED. 161 * leave the cache entry as ACL_NOT_CACHED.
166 */ 162 */
167 if (error == -ENOATTR) { 163 if (error == -ENOATTR)
168 acl = NULL;
169 goto out_update_cache; 164 goto out_update_cache;
170 }
171 goto out; 165 goto out;
172 } 166 }
173 167
@@ -183,15 +177,12 @@ out:
183} 177}
184 178
185STATIC int 179STATIC int
186xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) 180__xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
187{ 181{
188 struct xfs_inode *ip = XFS_I(inode); 182 struct xfs_inode *ip = XFS_I(inode);
189 unsigned char *ea_name; 183 unsigned char *ea_name;
190 int error; 184 int error;
191 185
192 if (S_ISLNK(inode->i_mode))
193 return -EOPNOTSUPP;
194
195 switch (type) { 186 switch (type) {
196 case ACL_TYPE_ACCESS: 187 case ACL_TYPE_ACCESS:
197 ea_name = SGI_ACL_FILE; 188 ea_name = SGI_ACL_FILE;
@@ -282,131 +273,23 @@ posix_acl_default_exists(struct inode *inode)
282 return xfs_acl_exists(inode, SGI_ACL_DEFAULT); 273 return xfs_acl_exists(inode, SGI_ACL_DEFAULT);
283} 274}
284 275
285/*
286 * No need for i_mutex because the inode is not yet exposed to the VFS.
287 */
288int 276int
289xfs_inherit_acl(struct inode *inode, struct posix_acl *acl) 277xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
290{ 278{
291 umode_t mode = inode->i_mode;
292 int error = 0, inherit = 0;
293
294 if (S_ISDIR(inode->i_mode)) {
295 error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
296 if (error)
297 goto out;
298 }
299
300 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
301 if (error < 0)
302 return error;
303
304 /*
305 * If posix_acl_create returns a positive value we need to
306 * inherit a permission that can't be represented using the Unix
307 * mode bits and we actually need to set an ACL.
308 */
309 if (error > 0)
310 inherit = 1;
311
312 error = xfs_set_mode(inode, mode);
313 if (error)
314 goto out;
315
316 if (inherit)
317 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
318
319out:
320 posix_acl_release(acl);
321 return error;
322}
323
324int
325xfs_acl_chmod(struct inode *inode)
326{
327 struct posix_acl *acl;
328 int error;
329
330 if (S_ISLNK(inode->i_mode))
331 return -EOPNOTSUPP;
332
333 acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
334 if (IS_ERR(acl) || !acl)
335 return PTR_ERR(acl);
336
337 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
338 if (error)
339 return error;
340
341 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
342 posix_acl_release(acl);
343 return error;
344}
345
346static int
347xfs_xattr_acl_get(struct dentry *dentry, const char *name,
348 void *value, size_t size, int type)
349{
350 struct posix_acl *acl;
351 int error;
352
353 acl = xfs_get_acl(dentry->d_inode, type);
354 if (IS_ERR(acl))
355 return PTR_ERR(acl);
356 if (acl == NULL)
357 return -ENODATA;
358
359 error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
360 posix_acl_release(acl);
361
362 return error;
363}
364
365static int
366xfs_xattr_acl_set(struct dentry *dentry, const char *name,
367 const void *value, size_t size, int flags, int type)
368{
369 struct inode *inode = dentry->d_inode;
370 struct posix_acl *acl = NULL;
371 int error = 0; 279 int error = 0;
372 280
373 if (flags & XATTR_CREATE) 281 if (!acl)
374 return -EINVAL;
375 if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
376 return value ? -EACCES : 0;
377 if (!inode_owner_or_capable(inode))
378 return -EPERM;
379
380 if (!value)
381 goto set_acl; 282 goto set_acl;
382 283
383 acl = posix_acl_from_xattr(&init_user_ns, value, size);
384 if (!acl) {
385 /*
386 * acl_set_file(3) may request that we set default ACLs with
387 * zero length -- defend (gracefully) against that here.
388 */
389 goto out;
390 }
391 if (IS_ERR(acl)) {
392 error = PTR_ERR(acl);
393 goto out;
394 }
395
396 error = posix_acl_valid(acl);
397 if (error)
398 goto out_release;
399
400 error = -EINVAL; 284 error = -EINVAL;
401 if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb))) 285 if (acl->a_count > XFS_ACL_MAX_ENTRIES(XFS_M(inode->i_sb)))
402 goto out_release; 286 return error;
403 287
404 if (type == ACL_TYPE_ACCESS) { 288 if (type == ACL_TYPE_ACCESS) {
405 umode_t mode = inode->i_mode; 289 umode_t mode = inode->i_mode;
406 error = posix_acl_equiv_mode(acl, &mode); 290 error = posix_acl_equiv_mode(acl, &mode);
407 291
408 if (error <= 0) { 292 if (error <= 0) {
409 posix_acl_release(acl);
410 acl = NULL; 293 acl = NULL;
411 294
412 if (error < 0) 295 if (error < 0)
@@ -415,27 +298,9 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
415 298
416 error = xfs_set_mode(inode, mode); 299 error = xfs_set_mode(inode, mode);
417 if (error) 300 if (error)
418 goto out_release; 301 return error;
419 } 302 }
420 303
421 set_acl: 304 set_acl:
422 error = xfs_set_acl(inode, type, acl); 305 return __xfs_set_acl(inode, type, acl);
423 out_release:
424 posix_acl_release(acl);
425 out:
426 return error;
427} 306}
428
429const struct xattr_handler xfs_xattr_acl_access_handler = {
430 .prefix = POSIX_ACL_XATTR_ACCESS,
431 .flags = ACL_TYPE_ACCESS,
432 .get = xfs_xattr_acl_get,
433 .set = xfs_xattr_acl_set,
434};
435
436const struct xattr_handler xfs_xattr_acl_default_handler = {
437 .prefix = POSIX_ACL_XATTR_DEFAULT,
438 .flags = ACL_TYPE_DEFAULT,
439 .get = xfs_xattr_acl_get,
440 .set = xfs_xattr_acl_set,
441};
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 4016a567b83c..5dc163744511 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -60,20 +60,15 @@ struct xfs_acl {
60 60
61#ifdef CONFIG_XFS_POSIX_ACL 61#ifdef CONFIG_XFS_POSIX_ACL
62extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); 62extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
63extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); 63extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
64extern int xfs_acl_chmod(struct inode *inode);
65extern int posix_acl_access_exists(struct inode *inode); 64extern int posix_acl_access_exists(struct inode *inode);
66extern int posix_acl_default_exists(struct inode *inode); 65extern int posix_acl_default_exists(struct inode *inode);
67
68extern const struct xattr_handler xfs_xattr_acl_access_handler;
69extern const struct xattr_handler xfs_xattr_acl_default_handler;
70#else 66#else
71static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) 67static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
72{ 68{
73 return NULL; 69 return NULL;
74} 70}
75# define xfs_inherit_acl(inode, default_acl) 0 71# define xfs_set_acl NULL
76# define xfs_acl_chmod(inode) 0
77# define posix_acl_access_exists(inode) 0 72# define posix_acl_access_exists(inode) 0
78# define posix_acl_default_exists(inode) 0 73# define posix_acl_default_exists(inode) 0
79#endif /* CONFIG_XFS_POSIX_ACL */ 74#endif /* CONFIG_XFS_POSIX_ACL */
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 0ce1d759156e..f35d5c953ff9 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -123,7 +123,7 @@ xfs_vn_mknod(
123{ 123{
124 struct inode *inode; 124 struct inode *inode;
125 struct xfs_inode *ip = NULL; 125 struct xfs_inode *ip = NULL;
126 struct posix_acl *default_acl = NULL; 126 struct posix_acl *default_acl, *acl;
127 struct xfs_name name; 127 struct xfs_name name;
128 int error; 128 int error;
129 129
@@ -139,14 +139,9 @@ xfs_vn_mknod(
139 rdev = 0; 139 rdev = 0;
140 } 140 }
141 141
142 if (IS_POSIXACL(dir)) { 142 error = posix_acl_create(dir, &mode, &default_acl, &acl);
143 default_acl = xfs_get_acl(dir, ACL_TYPE_DEFAULT); 143 if (error)
144 if (IS_ERR(default_acl)) 144 return error;
145 return PTR_ERR(default_acl);
146
147 if (!default_acl)
148 mode &= ~current_umask();
149 }
150 145
151 xfs_dentry_to_name(&name, dentry, mode); 146 xfs_dentry_to_name(&name, dentry, mode);
152 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); 147 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
@@ -159,22 +154,30 @@ xfs_vn_mknod(
159 if (unlikely(error)) 154 if (unlikely(error))
160 goto out_cleanup_inode; 155 goto out_cleanup_inode;
161 156
157#ifdef CONFIG_XFS_POSIX_ACL
162 if (default_acl) { 158 if (default_acl) {
163 error = -xfs_inherit_acl(inode, default_acl); 159 error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
164 default_acl = NULL; 160 if (error)
165 if (unlikely(error))
166 goto out_cleanup_inode; 161 goto out_cleanup_inode;
167 } 162 }
168 163 if (acl) {
164 error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS);
165 if (error)
166 goto out_cleanup_inode;
167 }
168#endif
169 169
170 d_instantiate(dentry, inode); 170 d_instantiate(dentry, inode);
171 out_free_acl:
172 if (default_acl)
173 posix_acl_release(default_acl);
174 if (acl)
175 posix_acl_release(acl);
171 return -error; 176 return -error;
172 177
173 out_cleanup_inode: 178 out_cleanup_inode:
174 xfs_cleanup_inode(dir, inode, dentry); 179 xfs_cleanup_inode(dir, inode, dentry);
175 out_free_acl: 180 goto out_free_acl;
176 posix_acl_release(default_acl);
177 return -error;
178} 181}
179 182
180STATIC int 183STATIC int
@@ -391,18 +394,6 @@ xfs_vn_follow_link(
391 return NULL; 394 return NULL;
392} 395}
393 396
394STATIC void
395xfs_vn_put_link(
396 struct dentry *dentry,
397 struct nameidata *nd,
398 void *p)
399{
400 char *s = nd_get_link(nd);
401
402 if (!IS_ERR(s))
403 kfree(s);
404}
405
406STATIC int 397STATIC int
407xfs_vn_getattr( 398xfs_vn_getattr(
408 struct vfsmount *mnt, 399 struct vfsmount *mnt,
@@ -688,7 +679,7 @@ xfs_setattr_nonsize(
688 * Posix ACL code seems to care about this issue either. 679 * Posix ACL code seems to care about this issue either.
689 */ 680 */
690 if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { 681 if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
691 error = -xfs_acl_chmod(inode); 682 error = -posix_acl_chmod(inode, inode->i_mode);
692 if (error) 683 if (error)
693 return XFS_ERROR(error); 684 return XFS_ERROR(error);
694 } 685 }
@@ -1045,6 +1036,7 @@ xfs_vn_fiemap(
1045 1036
1046static const struct inode_operations xfs_inode_operations = { 1037static const struct inode_operations xfs_inode_operations = {
1047 .get_acl = xfs_get_acl, 1038 .get_acl = xfs_get_acl,
1039 .set_acl = xfs_set_acl,
1048 .getattr = xfs_vn_getattr, 1040 .getattr = xfs_vn_getattr,
1049 .setattr = xfs_vn_setattr, 1041 .setattr = xfs_vn_setattr,
1050 .setxattr = generic_setxattr, 1042 .setxattr = generic_setxattr,
@@ -1072,6 +1064,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
1072 .mknod = xfs_vn_mknod, 1064 .mknod = xfs_vn_mknod,
1073 .rename = xfs_vn_rename, 1065 .rename = xfs_vn_rename,
1074 .get_acl = xfs_get_acl, 1066 .get_acl = xfs_get_acl,
1067 .set_acl = xfs_set_acl,
1075 .getattr = xfs_vn_getattr, 1068 .getattr = xfs_vn_getattr,
1076 .setattr = xfs_vn_setattr, 1069 .setattr = xfs_vn_setattr,
1077 .setxattr = generic_setxattr, 1070 .setxattr = generic_setxattr,
@@ -1098,6 +1091,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1098 .mknod = xfs_vn_mknod, 1091 .mknod = xfs_vn_mknod,
1099 .rename = xfs_vn_rename, 1092 .rename = xfs_vn_rename,
1100 .get_acl = xfs_get_acl, 1093 .get_acl = xfs_get_acl,
1094 .set_acl = xfs_set_acl,
1101 .getattr = xfs_vn_getattr, 1095 .getattr = xfs_vn_getattr,
1102 .setattr = xfs_vn_setattr, 1096 .setattr = xfs_vn_setattr,
1103 .setxattr = generic_setxattr, 1097 .setxattr = generic_setxattr,
@@ -1110,8 +1104,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
1110static const struct inode_operations xfs_symlink_inode_operations = { 1104static const struct inode_operations xfs_symlink_inode_operations = {
1111 .readlink = generic_readlink, 1105 .readlink = generic_readlink,
1112 .follow_link = xfs_vn_follow_link, 1106 .follow_link = xfs_vn_follow_link,
1113 .put_link = xfs_vn_put_link, 1107 .put_link = kfree_put_link,
1114 .get_acl = xfs_get_acl,
1115 .getattr = xfs_vn_getattr, 1108 .getattr = xfs_vn_getattr,
1116 .setattr = xfs_vn_setattr, 1109 .setattr = xfs_vn_setattr,
1117 .setxattr = generic_setxattr, 1110 .setxattr = generic_setxattr,
diff --git a/fs/xfs/xfs_iops.h b/fs/xfs/xfs_iops.h
index d2c5057b5cc4..1c34e4335920 100644
--- a/fs/xfs/xfs_iops.h
+++ b/fs/xfs/xfs_iops.h
@@ -30,7 +30,7 @@ extern void xfs_setup_inode(struct xfs_inode *);
30/* 30/*
31 * Internal setattr interfaces. 31 * Internal setattr interfaces.
32 */ 32 */
33#define XFS_ATTR_NOACL 0x01 /* Don't call xfs_acl_chmod */ 33#define XFS_ATTR_NOACL 0x01 /* Don't call posix_acl_chmod */
34 34
35extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, 35extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap,
36 int flags); 36 int flags);
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 9d479073ba41..78ed92a46fdd 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -102,8 +102,8 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
102 &xfs_xattr_trusted_handler, 102 &xfs_xattr_trusted_handler,
103 &xfs_xattr_security_handler, 103 &xfs_xattr_security_handler,
104#ifdef CONFIG_XFS_POSIX_ACL 104#ifdef CONFIG_XFS_POSIX_ACL
105 &xfs_xattr_acl_access_handler, 105 &posix_acl_access_xattr_handler,
106 &xfs_xattr_acl_default_handler, 106 &posix_acl_default_xattr_handler,
107#endif 107#endif
108 NULL 108 NULL
109}; 109};
diff --git a/include/linux/cramfs_fs_sb.h b/include/linux/cramfs_fs_sb.h
deleted file mode 100644
index 8390693568fd..000000000000
--- a/include/linux/cramfs_fs_sb.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef _CRAMFS_FS_SB
2#define _CRAMFS_FS_SB
3
4/*
5 * cramfs super-block data in memory
6 */
7struct cramfs_sb_info {
8 unsigned long magic;
9 unsigned long size;
10 unsigned long blocks;
11 unsigned long files;
12 unsigned long flags;
13};
14
15static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb)
16{
17 return sb->s_fs_info;
18}
19
20#endif
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 085197bd8812..70e8e21c0a30 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -59,29 +59,36 @@ struct files_struct {
59 struct file __rcu * fd_array[NR_OPEN_DEFAULT]; 59 struct file __rcu * fd_array[NR_OPEN_DEFAULT];
60}; 60};
61 61
62#define rcu_dereference_check_fdtable(files, fdtfd) \
63 (rcu_dereference_check((fdtfd), \
64 lockdep_is_held(&(files)->file_lock) || \
65 atomic_read(&(files)->count) == 1 || \
66 rcu_my_thread_group_empty()))
67
68#define files_fdtable(files) \
69 (rcu_dereference_check_fdtable((files), (files)->fdt))
70
71struct file_operations; 62struct file_operations;
72struct vfsmount; 63struct vfsmount;
73struct dentry; 64struct dentry;
74 65
75extern void __init files_defer_init(void); 66extern void __init files_defer_init(void);
76 67
77static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) 68#define rcu_dereference_check_fdtable(files, fdtfd) \
69 rcu_dereference_check((fdtfd), lockdep_is_held(&(files)->file_lock))
70
71#define files_fdtable(files) \
72 rcu_dereference_check_fdtable((files), (files)->fdt)
73
74/*
75 * The caller must ensure that fd table isn't shared or hold rcu or file lock
76 */
77static inline struct file *__fcheck_files(struct files_struct *files, unsigned int fd)
78{ 78{
79 struct file * file = NULL; 79 struct fdtable *fdt = rcu_dereference_raw(files->fdt);
80 struct fdtable *fdt = files_fdtable(files);
81 80
82 if (fd < fdt->max_fds) 81 if (fd < fdt->max_fds)
83 file = rcu_dereference_check_fdtable(files, fdt->fd[fd]); 82 return rcu_dereference_raw(fdt->fd[fd]);
84 return file; 83 return NULL;
84}
85
86static inline struct file *fcheck_files(struct files_struct *files, unsigned int fd)
87{
88 rcu_lockdep_assert(rcu_read_lock_held() ||
89 lockdep_is_held(&files->file_lock),
90 "suspicious rcu_dereference_check() usage");
91 return __fcheck_files(files, fd);
85} 92}
86 93
87/* 94/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 121f11f001c0..09f553c59813 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1580,6 +1580,7 @@ struct inode_operations {
1580 struct file *, unsigned open_flag, 1580 struct file *, unsigned open_flag,
1581 umode_t create_mode, int *opened); 1581 umode_t create_mode, int *opened);
1582 int (*tmpfile) (struct inode *, struct dentry *, umode_t); 1582 int (*tmpfile) (struct inode *, struct dentry *, umode_t);
1583 int (*set_acl)(struct inode *, struct posix_acl *, int);
1583} ____cacheline_aligned; 1584} ____cacheline_aligned;
1584 1585
1585ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, 1586ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
diff --git a/include/linux/generic_acl.h b/include/linux/generic_acl.h
deleted file mode 100644
index b6d657544ef1..000000000000
--- a/include/linux/generic_acl.h
+++ /dev/null
@@ -1,14 +0,0 @@
1#ifndef LINUX_GENERIC_ACL_H
2#define LINUX_GENERIC_ACL_H
3
4#include <linux/xattr.h>
5
6struct inode;
7
8extern const struct xattr_handler generic_acl_access_handler;
9extern const struct xattr_handler generic_acl_default_handler;
10
11int generic_acl_init(struct inode *, struct inode *);
12int generic_acl_chmod(struct inode *);
13
14#endif /* LINUX_GENERIC_ACL_H */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 48997374eaf0..2b00625952a7 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -154,10 +154,6 @@ struct nfs_inode {
154 struct rb_root access_cache; 154 struct rb_root access_cache;
155 struct list_head access_cache_entry_lru; 155 struct list_head access_cache_entry_lru;
156 struct list_head access_cache_inode_lru; 156 struct list_head access_cache_inode_lru;
157#ifdef CONFIG_NFS_V3_ACL
158 struct posix_acl *acl_access;
159 struct posix_acl *acl_default;
160#endif
161 157
162 /* 158 /*
163 * This is the cookie verifier used for NFSv3 readdir 159 * This is the cookie verifier used for NFSv3 readdir
@@ -564,23 +560,17 @@ extern int nfs_readpage_async(struct nfs_open_context *, struct inode *,
564 * linux/fs/nfs3proc.c 560 * linux/fs/nfs3proc.c
565 */ 561 */
566#ifdef CONFIG_NFS_V3_ACL 562#ifdef CONFIG_NFS_V3_ACL
567extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type); 563extern struct posix_acl *nfs3_get_acl(struct inode *inode, int type);
568extern int nfs3_proc_setacl(struct inode *inode, int type, 564extern int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type);
569 struct posix_acl *acl); 565extern int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
570extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, 566 struct posix_acl *dfacl);
571 umode_t mode); 567extern const struct xattr_handler *nfs3_xattr_handlers[];
572extern void nfs3_forget_cached_acls(struct inode *inode);
573#else 568#else
574static inline int nfs3_proc_set_default_acl(struct inode *dir, 569static inline int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
575 struct inode *inode, 570 struct posix_acl *dfacl)
576 umode_t mode)
577{ 571{
578 return 0; 572 return 0;
579} 573}
580
581static inline void nfs3_forget_cached_acls(struct inode *inode)
582{
583}
584#endif /* CONFIG_NFS_V3_ACL */ 574#endif /* CONFIG_NFS_V3_ACL */
585 575
586/* 576/*
diff --git a/include/linux/nls.h b/include/linux/nls.h
index 5dc635f8d79e..520681b68208 100644
--- a/include/linux/nls.h
+++ b/include/linux/nls.h
@@ -44,11 +44,12 @@ enum utf16_endian {
44}; 44};
45 45
46/* nls_base.c */ 46/* nls_base.c */
47extern int register_nls(struct nls_table *); 47extern int __register_nls(struct nls_table *, struct module *);
48extern int unregister_nls(struct nls_table *); 48extern int unregister_nls(struct nls_table *);
49extern struct nls_table *load_nls(char *); 49extern struct nls_table *load_nls(char *);
50extern void unload_nls(struct nls_table *); 50extern void unload_nls(struct nls_table *);
51extern struct nls_table *load_nls_default(void); 51extern struct nls_table *load_nls_default(void);
52#define register_nls(nls) __register_nls((nls), THIS_MODULE)
52 53
53extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu); 54extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu);
54extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen); 55extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen);
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 833099bf8090..3e96a6a76103 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -85,12 +85,20 @@ extern int posix_acl_valid(const struct posix_acl *);
85extern int posix_acl_permission(struct inode *, const struct posix_acl *, int); 85extern int posix_acl_permission(struct inode *, const struct posix_acl *, int);
86extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t); 86extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);
87extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *); 87extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
88extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *); 88extern int __posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
89extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); 89extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
90 90
91extern struct posix_acl *get_posix_acl(struct inode *, int); 91extern struct posix_acl *get_posix_acl(struct inode *, int);
92extern int set_posix_acl(struct inode *, int, struct posix_acl *); 92extern int set_posix_acl(struct inode *, int, struct posix_acl *);
93 93
94#ifdef CONFIG_FS_POSIX_ACL
95extern int posix_acl_chmod(struct inode *, umode_t);
96extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
97 struct posix_acl **);
98
99extern int simple_set_acl(struct inode *, struct posix_acl *, int);
100extern int simple_acl_create(struct inode *, struct inode *);
101
94struct posix_acl **acl_by_type(struct inode *inode, int type); 102struct posix_acl **acl_by_type(struct inode *inode, int type);
95struct posix_acl *get_cached_acl(struct inode *inode, int type); 103struct posix_acl *get_cached_acl(struct inode *inode, int type);
96struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); 104struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type);
@@ -100,10 +108,37 @@ void forget_all_cached_acls(struct inode *inode);
100 108
101static inline void cache_no_acl(struct inode *inode) 109static inline void cache_no_acl(struct inode *inode)
102{ 110{
103#ifdef CONFIG_FS_POSIX_ACL
104 inode->i_acl = NULL; 111 inode->i_acl = NULL;
105 inode->i_default_acl = NULL; 112 inode->i_default_acl = NULL;
106#endif
107} 113}
114#else
115static inline int posix_acl_chmod(struct inode *inode, umode_t mode)
116{
117 return 0;
118}
119
120#define simple_set_acl NULL
121
122static inline int simple_acl_create(struct inode *dir, struct inode *inode)
123{
124 return 0;
125}
126static inline void cache_no_acl(struct inode *inode)
127{
128}
129
130static inline int posix_acl_create(struct inode *inode, umode_t *mode,
131 struct posix_acl **default_acl, struct posix_acl **acl)
132{
133 *default_acl = *acl = NULL;
134 return 0;
135}
136
137static inline void forget_all_cached_acls(struct inode *inode)
138{
139}
140#endif /* CONFIG_FS_POSIX_ACL */
141
142struct posix_acl *get_acl(struct inode *inode, int type);
108 143
109#endif /* __LINUX_POSIX_ACL_H */ 144#endif /* __LINUX_POSIX_ACL_H */
diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h
index ad93ad0f1db0..6f14ee295822 100644
--- a/include/linux/posix_acl_xattr.h
+++ b/include/linux/posix_acl_xattr.h
@@ -69,4 +69,7 @@ struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns,
69int posix_acl_to_xattr(struct user_namespace *user_ns, 69int posix_acl_to_xattr(struct user_namespace *user_ns,
70 const struct posix_acl *acl, void *buffer, size_t size); 70 const struct posix_acl *acl, void *buffer, size_t size);
71 71
72extern const struct xattr_handler posix_acl_access_xattr_handler;
73extern const struct xattr_handler posix_acl_default_xattr_handler;
74
72#endif /* _POSIX_ACL_XATTR_H */ 75#endif /* _POSIX_ACL_XATTR_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 3e355c688618..72bf3a01a4ee 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -449,8 +449,6 @@ static inline int rcu_read_lock_sched_held(void)
449 449
450#ifdef CONFIG_PROVE_RCU 450#ifdef CONFIG_PROVE_RCU
451 451
452int rcu_my_thread_group_empty(void);
453
454/** 452/**
455 * rcu_lockdep_assert - emit lockdep splat if specified condition not met 453 * rcu_lockdep_assert - emit lockdep splat if specified condition not met
456 * @c: condition to check 454 * @c: condition to check
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 7c098ac9068a..a8227022e3a0 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -13,7 +13,7 @@
13#include <linux/minix_fs.h> 13#include <linux/minix_fs.h>
14#include <linux/ext2_fs.h> 14#include <linux/ext2_fs.h>
15#include <linux/romfs_fs.h> 15#include <linux/romfs_fs.h>
16#include <linux/cramfs_fs.h> 16#include <uapi/linux/cramfs_fs.h>
17#include <linux/initrd.h> 17#include <linux/initrd.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 802365ccd591..c54609faf233 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -200,17 +200,6 @@ void wait_rcu_gp(call_rcu_func_t crf)
200} 200}
201EXPORT_SYMBOL_GPL(wait_rcu_gp); 201EXPORT_SYMBOL_GPL(wait_rcu_gp);
202 202
203#ifdef CONFIG_PROVE_RCU
204/*
205 * wrapper function to avoid #include problems.
206 */
207int rcu_my_thread_group_empty(void)
208{
209 return thread_group_empty(current);
210}
211EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
212#endif /* #ifdef CONFIG_PROVE_RCU */
213
214#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD 203#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
215static inline void debug_init_rcu_head(struct rcu_head *head) 204static inline void debug_init_rcu_head(struct rcu_head *head)
216{ 205{
diff --git a/mm/filemap.c b/mm/filemap.c
index 7a7f3e0db738..d56d3c145b9f 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1428,30 +1428,28 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
1428 if (!count) 1428 if (!count)
1429 goto out; /* skip atime */ 1429 goto out; /* skip atime */
1430 size = i_size_read(inode); 1430 size = i_size_read(inode);
1431 if (pos < size) { 1431 retval = filemap_write_and_wait_range(mapping, pos,
1432 retval = filemap_write_and_wait_range(mapping, pos,
1433 pos + iov_length(iov, nr_segs) - 1); 1432 pos + iov_length(iov, nr_segs) - 1);
1434 if (!retval) { 1433 if (!retval) {
1435 retval = mapping->a_ops->direct_IO(READ, iocb, 1434 retval = mapping->a_ops->direct_IO(READ, iocb,
1436 iov, pos, nr_segs); 1435 iov, pos, nr_segs);
1437 } 1436 }
1438 if (retval > 0) { 1437 if (retval > 0) {
1439 *ppos = pos + retval; 1438 *ppos = pos + retval;
1440 count -= retval; 1439 count -= retval;
1441 } 1440 }
1442 1441
1443 /* 1442 /*
1444 * Btrfs can have a short DIO read if we encounter 1443 * Btrfs can have a short DIO read if we encounter
1445 * compressed extents, so if there was an error, or if 1444 * compressed extents, so if there was an error, or if
1446 * we've already read everything we wanted to, or if 1445 * we've already read everything we wanted to, or if
1447 * there was a short read because we hit EOF, go ahead 1446 * there was a short read because we hit EOF, go ahead
1448 * and return. Otherwise fallthrough to buffered io for 1447 * and return. Otherwise fallthrough to buffered io for
1449 * the rest of the read. 1448 * the rest of the read.
1450 */ 1449 */
1451 if (retval < 0 || !count || *ppos >= size) { 1450 if (retval < 0 || !count || *ppos >= size) {
1452 file_accessed(filp); 1451 file_accessed(filp);
1453 goto out; 1452 goto out;
1454 }
1455 } 1453 }
1456 } 1454 }
1457 1455
diff --git a/mm/shmem.c b/mm/shmem.c
index 8156f95ec0cf..1f18c9d0d93e 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -45,7 +45,7 @@ static struct vfsmount *shm_mnt;
45#include <linux/xattr.h> 45#include <linux/xattr.h>
46#include <linux/exportfs.h> 46#include <linux/exportfs.h>
47#include <linux/posix_acl.h> 47#include <linux/posix_acl.h>
48#include <linux/generic_acl.h> 48#include <linux/posix_acl_xattr.h>
49#include <linux/mman.h> 49#include <linux/mman.h>
50#include <linux/string.h> 50#include <linux/string.h>
51#include <linux/slab.h> 51#include <linux/slab.h>
@@ -620,10 +620,8 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
620 } 620 }
621 621
622 setattr_copy(inode, attr); 622 setattr_copy(inode, attr);
623#ifdef CONFIG_TMPFS_POSIX_ACL
624 if (attr->ia_valid & ATTR_MODE) 623 if (attr->ia_valid & ATTR_MODE)
625 error = generic_acl_chmod(inode); 624 error = posix_acl_chmod(inode, inode->i_mode);
626#endif
627 return error; 625 return error;
628} 626}
629 627
@@ -1937,22 +1935,14 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1937 1935
1938 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); 1936 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
1939 if (inode) { 1937 if (inode) {
1940#ifdef CONFIG_TMPFS_POSIX_ACL 1938 error = simple_acl_create(dir, inode);
1941 error = generic_acl_init(inode, dir); 1939 if (error)
1942 if (error) { 1940 goto out_iput;
1943 iput(inode);
1944 return error;
1945 }
1946#endif
1947 error = security_inode_init_security(inode, dir, 1941 error = security_inode_init_security(inode, dir,
1948 &dentry->d_name, 1942 &dentry->d_name,
1949 shmem_initxattrs, NULL); 1943 shmem_initxattrs, NULL);
1950 if (error) { 1944 if (error && error != -EOPNOTSUPP)
1951 if (error != -EOPNOTSUPP) { 1945 goto out_iput;
1952 iput(inode);
1953 return error;
1954 }
1955 }
1956 1946
1957 error = 0; 1947 error = 0;
1958 dir->i_size += BOGO_DIRENT_SIZE; 1948 dir->i_size += BOGO_DIRENT_SIZE;
@@ -1961,6 +1951,9 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1961 dget(dentry); /* Extra count - pin the dentry in core */ 1951 dget(dentry); /* Extra count - pin the dentry in core */
1962 } 1952 }
1963 return error; 1953 return error;
1954out_iput:
1955 iput(inode);
1956 return error;
1964} 1957}
1965 1958
1966static int 1959static int
@@ -1974,24 +1967,17 @@ shmem_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
1974 error = security_inode_init_security(inode, dir, 1967 error = security_inode_init_security(inode, dir,
1975 NULL, 1968 NULL,
1976 shmem_initxattrs, NULL); 1969 shmem_initxattrs, NULL);
1977 if (error) { 1970 if (error && error != -EOPNOTSUPP)
1978 if (error != -EOPNOTSUPP) { 1971 goto out_iput;
1979 iput(inode); 1972 error = simple_acl_create(dir, inode);
1980 return error; 1973 if (error)
1981 } 1974 goto out_iput;
1982 }
1983#ifdef CONFIG_TMPFS_POSIX_ACL
1984 error = generic_acl_init(inode, dir);
1985 if (error) {
1986 iput(inode);
1987 return error;
1988 }
1989#else
1990 error = 0;
1991#endif
1992 d_tmpfile(dentry, inode); 1975 d_tmpfile(dentry, inode);
1993 } 1976 }
1994 return error; 1977 return error;
1978out_iput:
1979 iput(inode);
1980 return error;
1995} 1981}
1996 1982
1997static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 1983static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
@@ -2223,8 +2209,8 @@ static int shmem_initxattrs(struct inode *inode,
2223 2209
2224static const struct xattr_handler *shmem_xattr_handlers[] = { 2210static const struct xattr_handler *shmem_xattr_handlers[] = {
2225#ifdef CONFIG_TMPFS_POSIX_ACL 2211#ifdef CONFIG_TMPFS_POSIX_ACL
2226 &generic_acl_access_handler, 2212 &posix_acl_access_xattr_handler,
2227 &generic_acl_default_handler, 2213 &posix_acl_default_xattr_handler,
2228#endif 2214#endif
2229 NULL 2215 NULL
2230}; 2216};
@@ -2740,6 +2726,7 @@ static const struct inode_operations shmem_inode_operations = {
2740 .getxattr = shmem_getxattr, 2726 .getxattr = shmem_getxattr,
2741 .listxattr = shmem_listxattr, 2727 .listxattr = shmem_listxattr,
2742 .removexattr = shmem_removexattr, 2728 .removexattr = shmem_removexattr,
2729 .set_acl = simple_set_acl,
2743#endif 2730#endif
2744}; 2731};
2745 2732
@@ -2764,6 +2751,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
2764#endif 2751#endif
2765#ifdef CONFIG_TMPFS_POSIX_ACL 2752#ifdef CONFIG_TMPFS_POSIX_ACL
2766 .setattr = shmem_setattr, 2753 .setattr = shmem_setattr,
2754 .set_acl = simple_set_acl,
2767#endif 2755#endif
2768}; 2756};
2769 2757
@@ -2776,6 +2764,7 @@ static const struct inode_operations shmem_special_inode_operations = {
2776#endif 2764#endif
2777#ifdef CONFIG_TMPFS_POSIX_ACL 2765#ifdef CONFIG_TMPFS_POSIX_ACL
2778 .setattr = shmem_setattr, 2766 .setattr = shmem_setattr,
2767 .set_acl = simple_set_acl,
2779#endif 2768#endif
2780}; 2769};
2781 2770