diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-28 11:38:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-28 11:38:04 -0500 |
commit | bf3d846b783327359ddc4bd4f52627b36abb4d1d (patch) | |
tree | c6b8fddbf04a2962dfcf9f487af25033f11b10b9 | |
parent | 54c0a4b46150db1571d955d598cd342c9f1d9657 (diff) | |
parent | f6500801522c61782d4990fa1ad96154cb397cd4 (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
...
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" | |||
68 | source "fs/autofs4/Kconfig" | 68 | source "fs/autofs4/Kconfig" |
69 | source "fs/fuse/Kconfig" | 69 | source "fs/fuse/Kconfig" |
70 | 70 | ||
71 | config GENERIC_ACL | ||
72 | bool | ||
73 | select FS_POSIX_ACL | ||
74 | |||
75 | menu "Caches" | 71 | menu "Caches" |
76 | 72 | ||
77 | source "fs/fscache/Kconfig" | 73 | source "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 | |||
42 | obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o | 42 | obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o |
43 | 43 | ||
44 | obj-$(CONFIG_FS_MBCACHE) += mbcache.o | 44 | obj-$(CONFIG_FS_MBCACHE) += mbcache.o |
45 | obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o | 45 | obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o |
46 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ | 46 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ |
47 | obj-$(CONFIG_GENERIC_ACL) += generic_acl.o | ||
48 | obj-$(CONFIG_COREDUMP) += coredump.o | 47 | obj-$(CONFIG_COREDUMP) += coredump.o |
49 | obj-$(CONFIG_SYSCTL) += drop_caches.o | 48 | obj-$(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 | ||
59 | static int | 54 | static 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 */ |
418 | got_root: | 413 | got_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 | */ | ||
525 | out_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 | ||
534 | static int | 515 | static 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 | ||
599 | static 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 | |||
618 | static struct file_system_type affs_fs_type = { | 611 | static 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 | }; |
625 | MODULE_ALIAS_FS("affs"); | 618 | MODULE_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 | ||
47 | static int afs_proc_rootcell_open(struct inode *inode, struct file *file); | ||
48 | static int afs_proc_rootcell_release(struct inode *inode, struct file *file); | ||
49 | static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, | 46 | static 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); |
51 | static ssize_t afs_proc_rootcell_write(struct file *file, | 48 | static 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 | ||
55 | static const struct file_operations afs_proc_rootcell_fops = { | 52 | static 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 | ||
64 | static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file); | 58 | static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file); |
65 | static int afs_proc_cell_volumes_release(struct inode *inode, | ||
66 | struct file *file); | ||
67 | static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos); | 59 | static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos); |
68 | static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, | 60 | static 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 | ||
88 | static int afs_proc_cell_vlservers_open(struct inode *inode, | 79 | static int afs_proc_cell_vlservers_open(struct inode *inode, |
89 | struct file *file); | 80 | struct file *file); |
90 | static int afs_proc_cell_vlservers_release(struct inode *inode, | ||
91 | struct file *file); | ||
92 | static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos); | 81 | static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos); |
93 | static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, | 82 | static 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 | ||
113 | static int afs_proc_cell_servers_open(struct inode *inode, struct file *file); | 101 | static int afs_proc_cell_servers_open(struct inode *inode, struct file *file); |
114 | static int afs_proc_cell_servers_release(struct inode *inode, | ||
115 | struct file *file); | ||
116 | static void *afs_proc_cell_servers_start(struct seq_file *p, loff_t *pos); | 102 | static void *afs_proc_cell_servers_start(struct seq_file *p, loff_t *pos); |
117 | static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, | 103 | static 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 | */ |
140 | int afs_proc_init(void) | 125 | int 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 | ||
161 | error_rootcell: | 140 | error_tree: |
162 | remove_proc_entry("cells", proc_afs); | 141 | remove_proc_subtree("fs/afs", NULL); |
163 | error_cells: | ||
164 | remove_proc_entry("fs/afs", NULL); | ||
165 | error_dir: | 142 | error_dir: |
166 | _leave(" = -ENOMEM"); | 143 | _leave(" = -ENOMEM"); |
167 | return -ENOMEM; | 144 | return -ENOMEM; |
@@ -172,9 +149,7 @@ error_dir: | |||
172 | */ | 149 | */ |
173 | void afs_proc_cleanup(void) | 150 | void 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 | */ | ||
325 | static int afs_proc_rootcell_open(struct inode *inode, struct file *file) | ||
326 | { | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int afs_proc_rootcell_release(struct inode *inode, struct file *file) | ||
331 | { | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, | 297 | static 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 | */ |
388 | int afs_proc_cell_setup(struct afs_cell *cell) | 350 | int 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 | ||
416 | error_volumes: | 371 | error_tree: |
417 | remove_proc_entry("vlservers", cell->proc_dir); | 372 | remove_proc_subtree(cell->name, proc_afs); |
418 | error_vlservers: | ||
419 | remove_proc_entry("servers", cell->proc_dir); | ||
420 | error_servers: | ||
421 | remove_proc_entry(cell->name, proc_afs); | ||
422 | error_dir: | 373 | error_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 | */ | ||
468 | static 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 | */ | ||
574 | static 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 | */ | ||
678 | static 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 | ||
79 | static 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 | */ |
103 | static int btrfs_set_acl(struct btrfs_trans_handle *trans, | 75 | static 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 | ||
161 | static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, | 133 | int 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); | ||
186 | out: | ||
187 | posix_acl_release(acl); | ||
188 | |||
189 | return ret; | ||
190 | } | 136 | } |
191 | 137 | ||
192 | /* | 138 | /* |
@@ -197,83 +143,31 @@ out: | |||
197 | int btrfs_init_acl(struct btrfs_trans_handle *trans, | 143 | int 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 | } |
238 | failed: | ||
239 | posix_acl_release(acl); | ||
240 | |||
241 | return ret; | ||
242 | } | ||
243 | 169 | ||
244 | int 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 | |||
267 | const 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 | |||
274 | const 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 |
3901 | struct posix_acl *btrfs_get_acl(struct inode *inode, int type); | 3901 | struct posix_acl *btrfs_get_acl(struct inode *inode, int type); |
3902 | int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); | ||
3902 | int btrfs_init_acl(struct btrfs_trans_handle *trans, | 3903 | int btrfs_init_acl(struct btrfs_trans_handle *trans, |
3903 | struct inode *inode, struct inode *dir); | 3904 | struct inode *inode, struct inode *dir); |
3904 | int 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 | ||
3907 | static inline int btrfs_init_acl(struct btrfs_trans_handle *trans, | 3908 | static 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 | } |
3912 | static 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 | }; |
8658 | static const struct inode_operations btrfs_dir_ro_inode_operations = { | 8659 | static 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 | }; |
8733 | static const struct inode_operations btrfs_special_inode_operations = { | 8736 | static 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 | }; |
8744 | static const struct inode_operations btrfs_symlink_inode_operations = { | 8748 | static 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 | ||
2688 | static long btrfs_ioctl_file_extent_same(struct file *file, | 2688 | static 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 | |||
2802 | next: | ||
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 | */ |
314 | const struct xattr_handler *btrfs_xattr_handlers[] = { | 315 | const 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 | ||
24 | extern const struct xattr_handler btrfs_xattr_acl_access_handler; | ||
25 | extern const struct xattr_handler btrfs_xattr_acl_default_handler; | ||
26 | extern const struct xattr_handler *btrfs_xattr_handlers[]; | 24 | extern const struct xattr_handler *btrfs_xattr_handlers[]; |
27 | 25 | ||
28 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | 26 | extern 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 | */ | ||
31 | struct 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 | |||
39 | static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb) | ||
40 | { | ||
41 | return sb->s_fs_info; | ||
42 | } | ||
43 | |||
28 | static const struct super_operations cramfs_ops; | 44 | static const struct super_operations cramfs_ops; |
29 | static const struct inode_operations cramfs_dir_inode_operations; | 45 | static const struct inode_operations cramfs_dir_inode_operations; |
30 | static const struct file_operations cramfs_directory_operations; | 46 | static 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 | ||
222 | static void cramfs_put_super(struct super_block *sb) | 238 | static 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 | ||
228 | static int cramfs_remount(struct super_block *sb, int *flags, char *data) | 245 | static 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; |
325 | out: | ||
326 | kfree(sbi); | ||
327 | sb->s_fs_info = NULL; | ||
328 | return -EINVAL; | ||
329 | } | 342 | } |
330 | 343 | ||
331 | static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 344 | static 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 | ||
552 | static const struct super_operations cramfs_ops = { | 565 | static 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 | }; |
571 | MODULE_ALIAS_FS("cramfs"); | 583 | MODULE_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 */ |
7 | int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen); | 2 | int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen); |
8 | int cramfs_uncompress_init(void); | 3 | int cramfs_uncompress_init(void); |
9 | void cramfs_uncompress_exit(void); | 4 | void 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 | ||
24 | static z_stream stream; | 24 | static z_stream stream; |
25 | static int initialized; | 25 | static 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 | */ |
3119 | static char *__dentry_path(struct dentry *dentry, char *buf, int buflen) | 3119 | static 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(); |
3126 | restart: | 3130 | restart: |
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 | ||
662 | static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, | 662 | static 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); |
685 | out: | 683 | out: |
686 | kfree(lower_buf); | 684 | kfree(lower_buf); |
687 | return rc; | 685 | return rc ? ERR_PTR(rc) : buf; |
688 | } | 686 | } |
689 | 687 | ||
690 | static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 688 | static 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 | ||
29 | static 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 | |||
29 | static struct file_system_type efs_fs_type = { | 36 | static 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 | }; |
36 | MODULE_ALIAS_FS("efs"); | 43 | MODULE_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 | ||
108 | static void efs_put_super(struct super_block *s) | ||
109 | { | ||
110 | kfree(s->s_fs_info); | ||
111 | s->s_fs_info = NULL; | ||
112 | } | ||
113 | |||
114 | static int efs_remount(struct super_block *sb, int *flags, char *data) | 115 | static 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) | |||
120 | static const struct super_operations efs_superblock_operations = { | 121 | static 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 | |||
335 | out_no_fs_ul: | ||
336 | out_no_fs: | ||
337 | s->s_fs_info = NULL; | ||
338 | kfree(sb); | ||
339 | return ret; | ||
340 | } | 331 | } |
341 | 332 | ||
342 | static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) { | 333 | static 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 | */ |
350 | struct eventfd_ctx *eventfd_ctx_fdget(int fd) | 350 | struct 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 | } |
363 | EXPORT_SYMBOL_GPL(eventfd_ctx_fdget); | 360 | EXPORT_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 | */ |
192 | static int | 185 | int |
193 | ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 186 | ext2_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) | |||
250 | int | 238 | int |
251 | ext2_init_acl(struct inode *inode, struct inode *dir) | 239 | ext2_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 | } | ||
279 | cleanup: | ||
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 | */ | ||
298 | int | ||
299 | ext2_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); |
322 | static size_t | 251 | } |
323 | ext2_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 | |||
335 | static size_t | ||
336 | ext2_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 | |||
348 | static int | ||
349 | ext2_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 | |||
371 | static int | ||
372 | ext2_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 | |||
399 | release_and_out: | ||
400 | posix_acl_release(acl); | ||
401 | return error; | 257 | return error; |
402 | } | 258 | } |
403 | |||
404 | const 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 | |||
412 | const 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 */ |
57 | extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); | 57 | extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); |
58 | extern int ext2_acl_chmod (struct inode *); | 58 | extern int ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
59 | extern int ext2_init_acl (struct inode *, struct inode *); | 59 | extern 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 | ||
66 | static inline int | ||
67 | ext2_acl_chmod (struct inode *inode) | ||
68 | { | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static inline int ext2_init_acl (struct inode *inode, struct inode *dir) | 66 | static 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; | |||
103 | static const struct xattr_handler *ext2_xattr_handler_map[] = { | 103 | static 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 | ||
58 | extern const struct xattr_handler ext2_xattr_user_handler; | 58 | extern const struct xattr_handler ext2_xattr_user_handler; |
59 | extern const struct xattr_handler ext2_xattr_trusted_handler; | 59 | extern const struct xattr_handler ext2_xattr_trusted_handler; |
60 | extern const struct xattr_handler ext2_xattr_acl_access_handler; | ||
61 | extern const struct xattr_handler ext2_xattr_acl_default_handler; | ||
62 | extern const struct xattr_handler ext2_xattr_security_handler; | 60 | extern const struct xattr_handler ext2_xattr_security_handler; |
63 | 61 | ||
64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); | 62 | extern 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 | */ |
192 | static int | 185 | static int |
193 | ext3_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 | */ | ||
252 | int | 236 | int |
253 | ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | 237 | ext3_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 | } | ||
283 | cleanup: | ||
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 | */ | ||
302 | int | ||
303 | ext3_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; | ||
320 | retry: | 242 | retry: |
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; |
333 | out: | ||
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 | */ |
341 | static size_t | 259 | int |
342 | ext3_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, | 260 | ext3_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 | |||
354 | static size_t | ||
355 | ext3_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 | |||
367 | static int | ||
368 | ext3_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 | |||
390 | static int | ||
391 | ext3_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 | |||
418 | retry: | ||
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 | ||
427 | release_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 | |||
432 | const 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 | |||
440 | const 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 */ |
57 | extern struct posix_acl *ext3_get_acl(struct inode *inode, int type); | 57 | extern struct posix_acl *ext3_get_acl(struct inode *inode, int type); |
58 | extern int ext3_acl_chmod (struct inode *); | 58 | extern int ext3_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
59 | extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); | 59 | extern 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 | |
65 | static inline int | ||
66 | ext3_acl_chmod(struct inode *inode) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | 65 | ||
71 | static inline int | 66 | static inline int |
72 | ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | 67 | ext3_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 | ||
3370 | err_out: | 3370 | err_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 | ||
2574 | const struct inode_operations ext3_special_inode_operations = { | 2575 | const 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; | |||
102 | static const struct xattr_handler *ext3_xattr_handler_map[] = { | 102 | static 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 | ||
61 | extern const struct xattr_handler ext3_xattr_user_handler; | 61 | extern const struct xattr_handler ext3_xattr_user_handler; |
62 | extern const struct xattr_handler ext3_xattr_trusted_handler; | 62 | extern const struct xattr_handler ext3_xattr_trusted_handler; |
63 | extern const struct xattr_handler ext3_xattr_acl_access_handler; | ||
64 | extern const struct xattr_handler ext3_xattr_acl_default_handler; | ||
65 | extern const struct xattr_handler ext3_xattr_security_handler; | 63 | extern const struct xattr_handler ext3_xattr_security_handler; |
66 | 64 | ||
67 | extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); | 65 | extern 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 | */ |
198 | static int | 191 | static int |
199 | ext4_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 | */ | ||
257 | int | 241 | int |
258 | ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | 242 | ext4_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 | } | ||
288 | cleanup: | ||
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 | */ | ||
307 | int | ||
308 | ext4_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; | ||
326 | retry: | 247 | retry: |
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; |
339 | out: | ||
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 | */ |
347 | static size_t | 266 | int |
348 | ext4_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, | 267 | ext4_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 | |||
360 | static size_t | ||
361 | ext4_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 | |||
373 | static int | ||
374 | ext4_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 | |||
396 | static int | ||
397 | ext4_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 | ||
424 | retry: | 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 | |||
436 | release_and_out: | ||
437 | posix_acl_release(acl); | ||
438 | return error; | 287 | return error; |
439 | } | 288 | } |
440 | |||
441 | const 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 | |||
449 | const 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 */ |
57 | struct posix_acl *ext4_get_acl(struct inode *inode, int type); | 57 | struct posix_acl *ext4_get_acl(struct inode *inode, int type); |
58 | extern int ext4_acl_chmod(struct inode *); | 58 | int ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
59 | extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); | 59 | extern 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 | |
65 | static inline int | ||
66 | ext4_acl_chmod(struct inode *inode) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | 65 | ||
71 | static inline int | 66 | static inline int |
72 | ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | 67 | ext4_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 | ||
4672 | err_out: | 4672 | err_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; | |||
95 | static const struct xattr_handler *ext4_xattr_handler_map[] = { | 95 | static 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 | ||
97 | extern const struct xattr_handler ext4_xattr_user_handler; | 97 | extern const struct xattr_handler ext4_xattr_user_handler; |
98 | extern const struct xattr_handler ext4_xattr_trusted_handler; | 98 | extern const struct xattr_handler ext4_xattr_trusted_handler; |
99 | extern const struct xattr_handler ext4_xattr_acl_access_handler; | ||
100 | extern const struct xattr_handler ext4_xattr_acl_default_handler; | ||
101 | extern const struct xattr_handler ext4_xattr_security_handler; | 99 | extern const struct xattr_handler ext4_xattr_security_handler; |
102 | 100 | ||
103 | extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); | 101 | extern 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 | |||
23 | static inline size_t f2fs_acl_size(int count) | 20 | static 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 | ||
168 | struct posix_acl *f2fs_get_acl(struct inode *inode, int type) | 165 | struct 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 | ||
208 | static int f2fs_set_acl(struct inode *inode, int type, | 197 | static 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 | ||
264 | int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage) | 247 | int 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); | ||
293 | cleanup: | ||
294 | posix_acl_release(acl); | ||
295 | return error; | ||
296 | } | 250 | } |
297 | 251 | ||
298 | int f2fs_acl_chmod(struct inode *inode) | 252 | int 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 | } | |
323 | static 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 | |||
342 | static 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 | |||
365 | static 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 | |||
395 | release_and_out: | ||
396 | posix_acl_release(acl); | ||
397 | return error; | 273 | return error; |
398 | } | 274 | } |
399 | |||
400 | const 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 | |||
408 | const 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 | ||
39 | extern struct posix_acl *f2fs_get_acl(struct inode *, int); | 39 | extern struct posix_acl *f2fs_get_acl(struct inode *, int); |
40 | extern int f2fs_acl_chmod(struct inode *); | 40 | extern int f2fs_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
41 | extern int f2fs_init_acl(struct inode *, struct inode *, struct page *); | 41 | extern 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 | ||
47 | static inline int f2fs_acl_chmod(struct inode *inode) | ||
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static inline int f2fs_init_acl(struct inode *inode, struct inode *dir, | 47 | static 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 = { | |||
216 | static const struct xattr_handler *f2fs_xattr_handler_map[] = { | 217 | static 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[] = { | |||
229 | const struct xattr_handler *f2fs_xattr_handlers[] = { | 230 | const 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 |
109 | extern const struct xattr_handler f2fs_xattr_user_handler; | 109 | extern const struct xattr_handler f2fs_xattr_user_handler; |
110 | extern const struct xattr_handler f2fs_xattr_trusted_handler; | 110 | extern const struct xattr_handler f2fs_xattr_trusted_handler; |
111 | extern const struct xattr_handler f2fs_xattr_acl_access_handler; | ||
112 | extern const struct xattr_handler f2fs_xattr_acl_default_handler; | ||
113 | extern const struct xattr_handler f2fs_xattr_advise_handler; | 111 | extern const struct xattr_handler f2fs_xattr_advise_handler; |
114 | extern const struct xattr_handler f2fs_xattr_security_handler; | 112 | extern const struct xattr_handler f2fs_xattr_security_handler; |
115 | 113 | ||
@@ -348,21 +348,16 @@ out: | |||
348 | return NULL; | 348 | return NULL; |
349 | } | 349 | } |
350 | 350 | ||
351 | static void close_files(struct files_struct * files) | 351 | static 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 | ||
386 | struct files_struct *get_files_struct(struct task_struct *task) | 383 | struct 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 | ||
399 | void put_files_struct(struct files_struct *files) | 396 | void 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 | ||
648 | struct file *fget(unsigned int fd) | 640 | static 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 | ||
658 | struct file *fget(unsigned int fd) | ||
659 | { | ||
660 | return __fget(fd, FMODE_PATH); | ||
661 | } | ||
666 | EXPORT_SYMBOL(fget); | 662 | EXPORT_SYMBOL(fget); |
667 | 663 | ||
668 | struct file *fget_raw(unsigned int fd) | 664 | struct 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 | |||
685 | EXPORT_SYMBOL(fget_raw); | 668 | EXPORT_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 | */ |
703 | struct file *fget_light(unsigned int fd, int *fput_needed) | 686 | struct 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 | } |
704 | struct file *fget_light(unsigned int fd, int *fput_needed) | ||
705 | { | ||
706 | return __fget_light(fd, FMODE_PATH, fput_needed); | ||
707 | } | ||
729 | EXPORT_SYMBOL(fget_light); | 708 | EXPORT_SYMBOL(fget_light); |
730 | 709 | ||
731 | struct file *fget_raw_light(unsigned int fd, int *fput_needed) | 710 | struct 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 | ||
755 | void set_close_on_exec(unsigned int fd, int flag) | 715 | void 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 | |||
17 | static size_t | ||
18 | generic_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 | |||
46 | static int | ||
47 | generic_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 | |||
65 | static int | ||
66 | generic_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; | ||
109 | failed: | ||
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 | */ | ||
120 | int | ||
121 | generic_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 | */ | ||
151 | int | ||
152 | generic_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 | |||
170 | const 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 | |||
178 | const 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 | ||
83 | static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl) | 79 | int 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); | ||
103 | out: | ||
104 | kfree(data); | ||
105 | return error; | ||
106 | } | ||
107 | |||
108 | int 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; | ||
144 | munge: | ||
145 | error = gfs2_set_mode(inode, mode); | ||
146 | out: | ||
147 | posix_acl_release(acl); | ||
148 | return error; | ||
149 | } | ||
150 | |||
151 | int 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 | |||
179 | out: | ||
180 | posix_acl_release(acl); | ||
181 | return error; | ||
182 | } | ||
183 | |||
184 | static 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 | |||
193 | static 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 | |||
221 | static 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 | ||
286 | set_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 | } |
294 | out_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); | ||
296 | out: | 129 | out: |
130 | kfree(data); | ||
297 | return error; | 131 | return error; |
298 | } | 132 | } |
299 | |||
300 | const 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 | ||
19 | extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); | 19 | extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); |
20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); | 20 | extern int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | ||
22 | extern 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); |
755 | fail_free_acls: | ||
756 | if (default_acl) | ||
757 | posix_acl_release(default_acl); | ||
758 | if (acl) | ||
759 | posix_acl_release(acl); | ||
760 | fail_free_vfs_inode: | ||
741 | free_inode_nonrcu(inode); | 761 | free_inode_nonrcu(inode); |
742 | inode = NULL; | 762 | inode = NULL; |
743 | fail_gunlock: | 763 | fail_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 | ||
1724 | out: | 1745 | out: |
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 | ||
1884 | const struct inode_operations gfs2_dir_iops = { | 1906 | const 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 = { | |||
1500 | const struct xattr_handler *gfs2_xattr_handlers[] = { | 1501 | const 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 */ |
14 | struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type); | 14 | struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type); |
15 | extern int hfsplus_posix_acl_chmod(struct inode *); | 15 | int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, |
16 | int type); | ||
16 | extern int hfsplus_init_posix_acl(struct inode *, struct inode *); | 17 | extern 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 | |
21 | static inline int hfsplus_posix_acl_chmod(struct inode *inode) | ||
22 | { | ||
23 | return 0; | ||
24 | } | ||
25 | 22 | ||
26 | static inline int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) | 23 | static 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 | ||
59 | static int hfsplus_set_posix_acl(struct inode *inode, | 57 | int 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: | |||
115 | int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) | 111 | int 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 | |||
151 | init_acl_cleanup: | ||
152 | posix_acl_release(acl); | ||
153 | return err; | ||
154 | } | ||
155 | |||
156 | int 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 | |||
179 | static 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 | |||
207 | static 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) | |
241 | end_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 | |||
246 | static 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 | |||
260 | const 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 | |||
268 | const 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 | ||
54 | static 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 | |||
101 | static 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 | |||
130 | static void hfsplus_init_header_node(struct inode *attr_file, | 55 | static 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 @@ | |||
14 | extern const struct xattr_handler hfsplus_xattr_osx_handler; | 14 | extern const struct xattr_handler hfsplus_xattr_osx_handler; |
15 | extern const struct xattr_handler hfsplus_xattr_user_handler; | 15 | extern const struct xattr_handler hfsplus_xattr_user_handler; |
16 | extern const struct xattr_handler hfsplus_xattr_trusted_handler; | 16 | extern const struct xattr_handler hfsplus_xattr_trusted_handler; |
17 | extern const struct xattr_handler hfsplus_xattr_acl_access_handler; | ||
18 | extern const struct xattr_handler hfsplus_xattr_acl_default_handler; | ||
19 | extern const struct xattr_handler hfsplus_xattr_security_handler; | 17 | extern const struct xattr_handler hfsplus_xattr_security_handler; |
20 | 18 | ||
21 | extern const struct xattr_handler *hfsplus_xattr_handlers[]; | 19 | extern 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 | ||
235 | static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 231 | int 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 | ||
278 | int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode) | 271 | int 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 | |||
328 | int 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 | |||
346 | static 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 | |||
356 | static 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 | |||
366 | static 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 | |||
386 | static 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 | |||
415 | const 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 | |||
423 | const 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 | ||
29 | struct posix_acl *jffs2_get_acl(struct inode *inode, int type); | 29 | struct posix_acl *jffs2_get_acl(struct inode *inode, int type); |
30 | extern int jffs2_acl_chmod(struct inode *); | 30 | int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
31 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, umode_t *); | 31 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, umode_t *); |
32 | extern int jffs2_init_acl_post(struct inode *); | 32 | extern int jffs2_init_acl_post(struct inode *); |
33 | 33 | ||
34 | extern const struct xattr_handler jffs2_acl_access_xattr_handler; | ||
35 | extern 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 = | |||
66 | const struct inode_operations jffs2_file_inode_operations = | 66 | const 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 | ||
191 | int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) | 191 | int 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 | ||
75 | static int jfs_set_acl(tid_t tid, struct inode *inode, int type, | 75 | static 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 | ||
118 | int 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 | |||
117 | int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) | 133 | int 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); | ||
140 | cleanup: | ||
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 | |||
151 | int 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 | ||
23 | struct posix_acl *jfs_get_acl(struct inode *inode, int type); | 23 | struct posix_acl *jfs_get_acl(struct inode *inode, int type); |
24 | int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); | ||
24 | int jfs_init_acl(tid_t, struct inode *, struct inode *); | 25 | int jfs_init_acl(tid_t, struct inode *, struct inode *); |
25 | int 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 | ||
35 | static 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); | |||
61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); | 61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); |
62 | extern int jfs_removexattr(struct dentry *, const char *); | 62 | extern int jfs_removexattr(struct dentry *, const char *); |
63 | 63 | ||
64 | extern const struct xattr_handler *jfs_xattr_handlers[]; | ||
65 | |||
64 | #ifdef CONFIG_JFS_SECURITY | 66 | #ifdef CONFIG_JFS_SECURITY |
65 | extern int jfs_init_security(tid_t, struct inode *, struct inode *, | 67 | extern 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 | ||
48 | MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); | 49 | MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); |
49 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); | 50 | MODULE_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 | */ | ||
674 | static 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 | */ |
738 | static int can_set_xattr(struct inode *inode, const char *name, | 672 | static 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 | */ | ||
1050 | const 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 |
1092 | static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, | 1060 | static 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) | |||
74 | static inline int is_mounted(struct vfsmount *mnt) | 74 | static 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 | ||
80 | extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *); | 80 | extern 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 | ||
13 | ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size) | 13 | struct 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 | |||
52 | ssize_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 | |||
81 | int 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 | |||
104 | int 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 | |||
119 | static 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 | |||
131 | void 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 | |||
140 | static 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); | ||
162 | out: | ||
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 | |||
169 | static 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 | |||
185 | struct 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 | ||
280 | getout: | 109 | getout: |
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 | ||
292 | static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | 116 | int 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 | ||
376 | int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl) | 201 | int 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: | |||
417 | int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, | 236 | int 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); | ||
437 | out_release_dfacl: | ||
438 | posix_acl_release(dfacl); | ||
439 | return error; | 252 | return error; |
440 | } | 253 | } |
254 | |||
255 | const 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 | |||
317 | nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 317 | nfs3_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 | |||
395 | out_release_acls: | ||
396 | posix_acl_release(acl); | ||
397 | posix_acl_release(default_acl); | ||
391 | out: | 398 | out: |
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: | |||
572 | static int | 579 | static int |
573 | nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) | 580 | nfs3_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 | |||
608 | out_release_acls: | ||
609 | posix_acl_release(acl); | ||
610 | posix_acl_release(default_acl); | ||
598 | out: | 611 | out: |
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 | |||
691 | nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 704 | nfs3_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 | |||
753 | out_release_acls: | ||
754 | posix_acl_release(acl); | ||
755 | posix_acl_release(default_acl); | ||
736 | out: | 756 | out: |
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 | ||
913 | static const struct inode_operations nfs3_file_inode_operations = { | 937 | static 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 | ||
923 | const struct nfs_rpc_ops nfs_v3_clientops = { | 951 | const 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 | ||
17 | static int __init init_nfs_v3(void) | 20 | static 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> | 38 | struct nfs4_acl; |
39 | struct svc_fh; | ||
40 | struct 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); | |||
45 | int nfs4_acl_get_whotype(char *, u32); | 47 | int nfs4_acl_get_whotype(char *, u32); |
46 | int nfs4_acl_write_who(int who, char *p); | 48 | int nfs4_acl_write_who(int who, char *p); |
47 | 49 | ||
48 | #define NFS4_ACL_TYPE_DEFAULT 0x01 | 50 | int 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); | |
52 | struct nfs4_acl *nfs4_acl_posix_to_nfsv4(struct posix_acl *, | ||
53 | struct posix_acl *, unsigned int flags); | ||
54 | int 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) | |||
30 | static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, | 30 | static __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 | |||
128 | out: | ||
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; |
134 | out_drop_write: | ||
135 | fh_drop_write(fh); | ||
136 | out_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) | |||
29 | static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, | 29 | static __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 | |||
113 | out_drop_write: | ||
114 | fh_drop_write(fh); | ||
115 | out_errno: | ||
116 | nfserr = nfserrno(error); | ||
117 | out: | ||
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 *); | |||
130 | static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, | 135 | static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, |
131 | unsigned int); | 136 | unsigned int); |
132 | 137 | ||
133 | struct nfs4_acl * | 138 | int |
134 | nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl, | 139 | nfsd4_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 | ||
165 | struct posix_acl_summary { | 184 | struct posix_acl_summary { |
@@ -719,8 +738,9 @@ static void process_one_v4_ace(struct posix_acl_state *state, | |||
719 | } | 738 | } |
720 | } | 739 | } |
721 | 740 | ||
722 | int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl, | 741 | static 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 | ||
804 | nfsd4_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 | |||
843 | out_release: | ||
844 | posix_acl_release(pacl); | ||
845 | posix_acl_release(dpacl); | ||
846 | out_nfserr: | ||
847 | if (host_error == -EOPNOTSUPP) | ||
848 | return nfserr_attrnotsupp; | ||
849 | else | ||
850 | return nfserrno(host_error); | ||
851 | } | ||
852 | |||
853 | |||
783 | static short | 854 | static short |
784 | ace2type(struct nfs4_ace *ace) | 855 | ace2type(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 | ||
801 | EXPORT_SYMBOL(nfs4_acl_posix_to_nfsv4); | ||
802 | EXPORT_SYMBOL(nfs4_acl_nfsv4_to_posix); | ||
803 | |||
804 | struct nfs4_acl * | 872 | struct nfs4_acl * |
805 | nfs4_acl_new(int n) | 873 | nfs4_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 | |||
866 | EXPORT_SYMBOL(nfs4_acl_new); | ||
867 | EXPORT_SYMBOL(nfs4_acl_get_whotype); | ||
868 | EXPORT_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) | ||
474 | static 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) |
495 | static int | ||
496 | set_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); | ||
516 | out: | ||
517 | kfree(buf); | ||
518 | return error; | ||
519 | } | ||
520 | |||
521 | __be32 | ||
522 | nfsd4_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 | |||
555 | out_release: | ||
556 | posix_acl_release(pacl); | ||
557 | posix_acl_release(dpacl); | ||
558 | out_nfserr: | ||
559 | if (host_error == -EOPNOTSUPP) | ||
560 | return nfserr_attrnotsupp; | ||
561 | else | ||
562 | return nfserrno(host_error); | ||
563 | } | ||
564 | |||
565 | static 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 | |||
583 | int | ||
584 | nfsd4_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) | ||
2289 | struct posix_acl * | ||
2290 | nfsd_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 | |||
2321 | int | ||
2322 | nfsd_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 | |||
2372 | getout: | ||
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); |
53 | int nfsd_mountpoint(struct dentry *, struct svc_export *); | 53 | int 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 *); | ||
57 | int 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) | ||
105 | struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); | ||
106 | int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *); | ||
107 | #endif | ||
108 | |||
109 | static inline int fh_want_write(struct svc_fh *fh) | 101 | static 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 | ||
589 | static int __init init_nls_macceltic(void) | 588 | static 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 | ||
519 | static int __init init_nls_maccenteuro(void) | 518 | static 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 | ||
589 | static int __init init_nls_maccroatian(void) | 588 | static 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 | ||
484 | static int __init init_nls_maccyrillic(void) | 483 | static 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 | ||
554 | static int __init init_nls_macgaelic(void) | 553 | static 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 | ||
484 | static int __init init_nls_macgreek(void) | 483 | static 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 | ||
589 | static int __init init_nls_maciceland(void) | 588 | static 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 | ||
519 | static int __init init_nls_macinuit(void) | 518 | static 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 | ||
624 | static int __init init_nls_macroman(void) | 623 | static 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 | ||
589 | static int __init init_nls_macromanian(void) | 588 | static 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 | ||
589 | static int __init init_nls_macturkish(void) | 588 | static 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 | ||
154 | static int __init init_nls_ascii(void) | 153 | static 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 | } |
233 | EXPORT_SYMBOL(utf16s_to_utf8s); | 233 | EXPORT_SYMBOL(utf16s_to_utf8s); |
234 | 234 | ||
235 | int register_nls(struct nls_table * nls) | 235 | int __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 | } |
256 | EXPORT_SYMBOL(__register_nls); | ||
255 | 257 | ||
256 | int unregister_nls(struct nls_table * nls) | 258 | int 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 | ||
541 | EXPORT_SYMBOL(register_nls); | ||
542 | EXPORT_SYMBOL(unregister_nls); | 543 | EXPORT_SYMBOL(unregister_nls); |
543 | EXPORT_SYMBOL(unload_nls); | 544 | EXPORT_SYMBOL(unload_nls); |
544 | EXPORT_SYMBOL(load_nls); | 545 | EXPORT_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 | ||
335 | static int __init init_nls_cp1250(void) | 334 | static 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 | ||
289 | static int __init init_nls_cp1251(void) | 288 | static 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 | ||
371 | static int __init init_nls_cp1255(void) | 370 | static 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 | ||
375 | static int __init init_nls_cp437(void) | 374 | static 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 | ||
338 | static int __init init_nls_cp737(void) | 337 | static 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 | ||
307 | static int __init init_nls_cp775(void) | 306 | static 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 | ||
303 | static int __init init_nls_cp850(void) | 302 | static 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 | ||
325 | static int __init init_nls_cp852(void) | 324 | static 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 | ||
287 | static int __init init_nls_cp855(void) | 286 | static 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 | ||
289 | static int __init init_nls_cp857(void) | 288 | static 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 | ||
352 | static int __init init_nls_cp860(void) | 351 | static 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 | ||
375 | static int __init init_nls_cp861(void) | 374 | static 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 | ||
409 | static int __init init_nls_cp862(void) | 408 | static 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 | ||
369 | static int __init init_nls_cp863(void) | 368 | static 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 | ||
395 | static int __init init_nls_cp864(void) | 394 | static 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 | ||
375 | static int __init init_nls_cp865(void) | 374 | static 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 | ||
293 | static int __init init_nls_cp866(void) | 292 | static 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 | ||
303 | static int __init init_nls_cp869(void) | 302 | static 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 | ||
262 | static int __init init_nls_cp874(void) | 261 | static 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 | ||
7920 | static int __init init_nls_cp932(void) | 7919 | static 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 | ||
11098 | static int __init init_nls_cp936(void) | 11097 | static 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 | ||
13933 | static int __init init_nls_cp949(void) | 13932 | static 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 | ||
9469 | static int __init init_nls_cp950(void) | 9468 | static 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 | ||
559 | static int __init init_nls_euc_jp(void) | 558 | static 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 | ||
245 | static int __init init_nls_iso8859_1(void) | 244 | static 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 | ||
273 | static int __init init_nls_iso8859_13(void) | 272 | static 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 | ||
329 | static int __init init_nls_iso8859_14(void) | 328 | static 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 | ||
295 | static int __init init_nls_iso8859_15(void) | 294 | static 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 | ||
296 | static int __init init_nls_iso8859_2(void) | 295 | static 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 | ||
296 | static int __init init_nls_iso8859_3(void) | 295 | static 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 | ||
296 | static int __init init_nls_iso8859_4(void) | 295 | static 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 | ||
260 | static int __init init_nls_iso8859_5(void) | 259 | static 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 | ||
251 | static int __init init_nls_iso8859_6(void) | 250 | static 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 | ||
305 | static int __init init_nls_iso8859_7(void) | 304 | static 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 | ||
260 | static int __init init_nls_iso8859_9(void) | 259 | static 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 | ||
311 | static int __init init_nls_koi8_r(void) | 310 | static 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 | ||
61 | static int __init init_nls_koi8_ru(void) | 60 | static 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 | ||
318 | static int __init init_nls_koi8_u(void) | 317 | static 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 | ||
52 | static int __init init_nls_utf8(void) | 51 | static 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 | */ | ||
167 | static 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 | */ |
253 | static int ocfs2_set_acl(handle_t *handle, | 223 | int 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 | ||
286 | int 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 | |||
316 | struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type) | 291 | struct 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 | |||
338 | int 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 | */ | ||
366 | int 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 | } | ||
420 | cleanup: | ||
421 | posix_acl_release(acl); | ||
422 | return ret; | ||
423 | } | ||
424 | |||
425 | static 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 | |||
443 | static 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 | |||
461 | static 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 | |||
484 | static 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 | |||
514 | cleanup: | ||
515 | posix_acl_release(acl); | ||
516 | return ret; | ||
517 | } | ||
518 | |||
519 | const 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 | |||
527 | const 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 | ||
29 | struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type); | 29 | struct posix_acl *ocfs2_iop_get_acl(struct inode *inode, int type); |
30 | extern int ocfs2_acl_chmod(struct inode *); | 30 | int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
31 | extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *, | 31 | int 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 | ||
2667 | const struct inode_operations ocfs2_special_file_iops = { | 2668 | const 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; |
421 | leave: | 437 | leave: |
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 | ||
50 | struct ocfs2_cow_context { | 51 | struct 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 | } |
4310 | out: | 4321 | out: |
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 | ||
100 | const struct xattr_handler *ocfs2_xattr_handlers[] = { | 100 | const 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[] = { | |||
109 | static const struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = { | 109 | static 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 | */ |
7191 | int ocfs2_init_security_and_acl(struct inode *dir, | 7191 | int 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 { | |||
40 | extern const struct xattr_handler ocfs2_xattr_user_handler; | 40 | extern const struct xattr_handler ocfs2_xattr_user_handler; |
41 | extern const struct xattr_handler ocfs2_xattr_trusted_handler; | 41 | extern const struct xattr_handler ocfs2_xattr_trusted_handler; |
42 | extern const struct xattr_handler ocfs2_xattr_security_handler; | 42 | extern const struct xattr_handler ocfs2_xattr_security_handler; |
43 | extern const struct xattr_handler ocfs2_xattr_acl_access_handler; | ||
44 | extern const struct xattr_handler ocfs2_xattr_acl_default_handler; | ||
45 | extern const struct xattr_handler *ocfs2_xattr_handlers[]; | 43 | extern const struct xattr_handler *ocfs2_xattr_handlers[]; |
46 | 44 | ||
47 | ssize_t ocfs2_listxattr(struct dentry *, char *, size_t); | 45 | ssize_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); |
97 | int ocfs2_init_security_and_acl(struct inode *dir, | 95 | int 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 | ||
25 | struct posix_acl **acl_by_type(struct inode *inode, int type) | 24 | struct 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 | } |
98 | EXPORT_SYMBOL(forget_all_cached_acls); | 97 | EXPORT_SYMBOL(forget_all_cached_acls); |
99 | 98 | ||
99 | struct 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 | } | ||
124 | EXPORT_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 | */ |
405 | static int posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) | 431 | static 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 | ||
450 | int | 476 | int |
451 | posix_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 | } |
466 | EXPORT_SYMBOL(posix_acl_create); | 492 | EXPORT_SYMBOL(__posix_acl_create); |
467 | 493 | ||
468 | int | 494 | int |
469 | posix_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 | } |
510 | EXPORT_SYMBOL(__posix_acl_chmod); | ||
511 | |||
512 | int | ||
513 | posix_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 | } | ||
484 | EXPORT_SYMBOL(posix_acl_chmod); | 534 | EXPORT_SYMBOL(posix_acl_chmod); |
535 | |||
536 | int | ||
537 | posix_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 | |||
578 | no_acl: | ||
579 | *default_acl = NULL; | ||
580 | *acl = NULL; | ||
581 | return 0; | ||
582 | } | ||
583 | EXPORT_SYMBOL_GPL(posix_acl_create); | ||
584 | |||
585 | /* | ||
586 | * Fix up the uids and gids in posix acl extended attributes in place. | ||
587 | */ | ||
588 | static 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 | |||
627 | void 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 | |||
635 | void 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 | */ | ||
646 | struct posix_acl * | ||
647 | posix_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 | |||
706 | fail: | ||
707 | posix_acl_release(acl); | ||
708 | return ERR_PTR(-EINVAL); | ||
709 | } | ||
710 | EXPORT_SYMBOL (posix_acl_from_xattr); | ||
711 | |||
712 | /* | ||
713 | * Convert from in-memory to extended attribute representation. | ||
714 | */ | ||
715 | int | ||
716 | posix_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 | } | ||
751 | EXPORT_SYMBOL (posix_acl_to_xattr); | ||
752 | |||
753 | static int | ||
754 | posix_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 | |||
777 | static int | ||
778 | posix_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); | ||
808 | out: | ||
809 | posix_acl_release(acl); | ||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | static size_t | ||
814 | posix_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 | |||
836 | const 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 | }; | ||
843 | EXPORT_SYMBOL_GPL(posix_acl_access_xattr_handler); | ||
844 | |||
845 | const 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 | }; | ||
852 | EXPORT_SYMBOL_GPL(posix_acl_default_xattr_handler); | ||
853 | |||
854 | int 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 | |||
871 | int 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 | ||
28 | static const struct super_operations qnx4_sops; | 28 | static const struct super_operations qnx4_sops; |
29 | 29 | ||
30 | static void qnx4_put_super(struct super_block *sb); | ||
31 | static struct inode *qnx4_alloc_inode(struct super_block *sb); | 30 | static struct inode *qnx4_alloc_inode(struct super_block *sb); |
32 | static void qnx4_destroy_inode(struct inode *inode); | 31 | static void qnx4_destroy_inode(struct inode *inode); |
33 | static int qnx4_remount(struct super_block *sb, int *flags, char *data); | 32 | static 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 | */ |
151 | static const char *qnx4_checkroot(struct super_block *sb) | 149 | static 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 | ||
255 | static void qnx4_put_super(struct super_block *sb) | 235 | static 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 | ||
264 | static int qnx4_readpage(struct file *file, struct page *page) | 245 | static 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 | }; |
415 | MODULE_ALIAS_FS("qnx4"); | 396 | MODULE_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 | ||
12 | struct qnx4_sb_info { | 12 | struct 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 |
50 | struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); | 50 | struct posix_acl *reiserfs_get_acl(struct inode *inode, int type); |
51 | int reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); | ||
51 | int reiserfs_acl_chmod(struct inode *inode); | 52 | int reiserfs_acl_chmod(struct inode *inode); |
52 | int reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, | 53 | int 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); |
55 | int reiserfs_cache_default_acl(struct inode *dir); | 56 | int reiserfs_cache_default_acl(struct inode *dir); |
56 | extern const struct xattr_handler reiserfs_posix_acl_default_handler; | ||
57 | extern 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 | ||
64 | static inline int reiserfs_acl_chmod(struct inode *inode) | 64 | static 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 | */ | ||
614 | static 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))) |
620 | static inline int __reiserfs_is_journal_aborted(struct reiserfs_journal | 612 | static 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 | ||
14 | static int reiserfs_set_acl(struct reiserfs_transaction_handle *th, | 14 | static 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 | ||
18 | static int | 18 | |
19 | posix_acl_set(struct dentry *dentry, const char *name, const void *value, | 19 | int |
20 | size_t size, int flags, int type) | 20 | reiserfs_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 | |||
67 | static int | ||
68 | posix_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 | */ |
91 | static struct posix_acl *posix_acl_from_disk(const void *value, size_t size) | 52 | static 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 | */ |
161 | static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) | 122 | static 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 | */ |
275 | static int | 232 | static int |
276 | reiserfs_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 | */ |
443 | int reiserfs_acl_chmod(struct inode *inode) | 388 | int 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 | |||
487 | static 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 | |||
499 | const 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 | |||
507 | static 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 | |||
519 | const 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 | */ | ||
17 | static 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 | |||
56 | void 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 | |||
64 | void 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 | */ | ||
75 | struct posix_acl * | ||
76 | posix_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 | |||
135 | fail: | ||
136 | posix_acl_release(acl); | ||
137 | return ERR_PTR(-EINVAL); | ||
138 | } | ||
139 | EXPORT_SYMBOL (posix_acl_from_xattr); | ||
140 | |||
141 | /* | ||
142 | * Convert from in-memory to extended attribute representation. | ||
143 | */ | ||
144 | int | ||
145 | posix_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 | } | ||
180 | EXPORT_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 * | |||
124 | xfs_get_acl(struct inode *inode, int type) | 124 | xfs_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 | ||
185 | STATIC int | 179 | STATIC int |
186 | xfs_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 | */ | ||
288 | int | 276 | int |
289 | xfs_inherit_acl(struct inode *inode, struct posix_acl *acl) | 277 | xfs_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 | |||
319 | out: | ||
320 | posix_acl_release(acl); | ||
321 | return error; | ||
322 | } | ||
323 | |||
324 | int | ||
325 | xfs_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 | |||
346 | static int | ||
347 | xfs_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 | |||
365 | static int | ||
366 | xfs_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 | |||
429 | const 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 | |||
436 | const 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 |
62 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); | 62 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); |
63 | extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); | 63 | extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
64 | extern int xfs_acl_chmod(struct inode *inode); | ||
65 | extern int posix_acl_access_exists(struct inode *inode); | 64 | extern int posix_acl_access_exists(struct inode *inode); |
66 | extern int posix_acl_default_exists(struct inode *inode); | 65 | extern int posix_acl_default_exists(struct inode *inode); |
67 | |||
68 | extern const struct xattr_handler xfs_xattr_acl_access_handler; | ||
69 | extern const struct xattr_handler xfs_xattr_acl_default_handler; | ||
70 | #else | 66 | #else |
71 | static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) | 67 | static 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 | ||
180 | STATIC int | 183 | STATIC int |
@@ -391,18 +394,6 @@ xfs_vn_follow_link( | |||
391 | return NULL; | 394 | return NULL; |
392 | } | 395 | } |
393 | 396 | ||
394 | STATIC void | ||
395 | xfs_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 | |||
406 | STATIC int | 397 | STATIC int |
407 | xfs_vn_getattr( | 398 | xfs_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 | ||
1046 | static const struct inode_operations xfs_inode_operations = { | 1037 | static 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 = { | |||
1110 | static const struct inode_operations xfs_symlink_inode_operations = { | 1104 | static 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 | ||
35 | extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, | 35 | extern 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 | */ | ||
7 | struct 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 | |||
15 | static 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 | |||
71 | struct file_operations; | 62 | struct file_operations; |
72 | struct vfsmount; | 63 | struct vfsmount; |
73 | struct dentry; | 64 | struct dentry; |
74 | 65 | ||
75 | extern void __init files_defer_init(void); | 66 | extern void __init files_defer_init(void); |
76 | 67 | ||
77 | static 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 | */ | ||
77 | static 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 | |||
86 | static 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 | ||
1585 | ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, | 1586 | ssize_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 | |||
6 | struct inode; | ||
7 | |||
8 | extern const struct xattr_handler generic_acl_access_handler; | ||
9 | extern const struct xattr_handler generic_acl_default_handler; | ||
10 | |||
11 | int generic_acl_init(struct inode *, struct inode *); | ||
12 | int 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 |
567 | extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type); | 563 | extern struct posix_acl *nfs3_get_acl(struct inode *inode, int type); |
568 | extern int nfs3_proc_setacl(struct inode *inode, int type, | 564 | extern int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
569 | struct posix_acl *acl); | 565 | extern int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, |
570 | extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, | 566 | struct posix_acl *dfacl); |
571 | umode_t mode); | 567 | extern const struct xattr_handler *nfs3_xattr_handlers[]; |
572 | extern void nfs3_forget_cached_acls(struct inode *inode); | ||
573 | #else | 568 | #else |
574 | static inline int nfs3_proc_set_default_acl(struct inode *dir, | 569 | static 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 | |||
581 | static 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 */ |
47 | extern int register_nls(struct nls_table *); | 47 | extern int __register_nls(struct nls_table *, struct module *); |
48 | extern int unregister_nls(struct nls_table *); | 48 | extern int unregister_nls(struct nls_table *); |
49 | extern struct nls_table *load_nls(char *); | 49 | extern struct nls_table *load_nls(char *); |
50 | extern void unload_nls(struct nls_table *); | 50 | extern void unload_nls(struct nls_table *); |
51 | extern struct nls_table *load_nls_default(void); | 51 | extern struct nls_table *load_nls_default(void); |
52 | #define register_nls(nls) __register_nls((nls), THIS_MODULE) | ||
52 | 53 | ||
53 | extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu); | 54 | extern int utf8_to_utf32(const u8 *s, int len, unicode_t *pu); |
54 | extern int utf32_to_utf8(unicode_t u, u8 *s, int maxlen); | 55 | extern 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 *); | |||
85 | extern int posix_acl_permission(struct inode *, const struct posix_acl *, int); | 85 | extern int posix_acl_permission(struct inode *, const struct posix_acl *, int); |
86 | extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t); | 86 | extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t); |
87 | extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *); | 87 | extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *); |
88 | extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *); | 88 | extern int __posix_acl_create(struct posix_acl **, gfp_t, umode_t *); |
89 | extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); | 89 | extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); |
90 | 90 | ||
91 | extern struct posix_acl *get_posix_acl(struct inode *, int); | 91 | extern struct posix_acl *get_posix_acl(struct inode *, int); |
92 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); | 92 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); |
93 | 93 | ||
94 | #ifdef CONFIG_FS_POSIX_ACL | ||
95 | extern int posix_acl_chmod(struct inode *, umode_t); | ||
96 | extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, | ||
97 | struct posix_acl **); | ||
98 | |||
99 | extern int simple_set_acl(struct inode *, struct posix_acl *, int); | ||
100 | extern int simple_acl_create(struct inode *, struct inode *); | ||
101 | |||
94 | struct posix_acl **acl_by_type(struct inode *inode, int type); | 102 | struct posix_acl **acl_by_type(struct inode *inode, int type); |
95 | struct posix_acl *get_cached_acl(struct inode *inode, int type); | 103 | struct posix_acl *get_cached_acl(struct inode *inode, int type); |
96 | struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); | 104 | struct 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 | ||
101 | static inline void cache_no_acl(struct inode *inode) | 109 | static 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 | ||
115 | static inline int posix_acl_chmod(struct inode *inode, umode_t mode) | ||
116 | { | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | #define simple_set_acl NULL | ||
121 | |||
122 | static inline int simple_acl_create(struct inode *dir, struct inode *inode) | ||
123 | { | ||
124 | return 0; | ||
125 | } | ||
126 | static inline void cache_no_acl(struct inode *inode) | ||
127 | { | ||
128 | } | ||
129 | |||
130 | static 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 | |||
137 | static inline void forget_all_cached_acls(struct inode *inode) | ||
138 | { | ||
139 | } | ||
140 | #endif /* CONFIG_FS_POSIX_ACL */ | ||
141 | |||
142 | struct 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, | |||
69 | int posix_acl_to_xattr(struct user_namespace *user_ns, | 69 | int 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 | ||
72 | extern const struct xattr_handler posix_acl_access_xattr_handler; | ||
73 | extern 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 | ||
452 | int 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 | } |
201 | EXPORT_SYMBOL_GPL(wait_rcu_gp); | 201 | EXPORT_SYMBOL_GPL(wait_rcu_gp); |
202 | 202 | ||
203 | #ifdef CONFIG_PROVE_RCU | ||
204 | /* | ||
205 | * wrapper function to avoid #include problems. | ||
206 | */ | ||
207 | int rcu_my_thread_group_empty(void) | ||
208 | { | ||
209 | return thread_group_empty(current); | ||
210 | } | ||
211 | EXPORT_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 |
215 | static inline void debug_init_rcu_head(struct rcu_head *head) | 204 | static 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; |
1954 | out_iput: | ||
1955 | iput(inode); | ||
1956 | return error; | ||
1964 | } | 1957 | } |
1965 | 1958 | ||
1966 | static int | 1959 | static 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; |
1978 | out_iput: | ||
1979 | iput(inode); | ||
1980 | return error; | ||
1995 | } | 1981 | } |
1996 | 1982 | ||
1997 | static int shmem_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 1983 | static 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 | ||
2224 | static const struct xattr_handler *shmem_xattr_handlers[] = { | 2210 | static 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 | ||