Root/
1 | /* |
2 | * Copyright (C) International Business Machines Corp., 2002-2004 |
3 | * Copyright (C) Andreas Gruenbacher, 2001 |
4 | * Copyright (C) Linus Torvalds, 1991, 1992 |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
14 | * the GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | #include <linux/sched.h> |
22 | #include <linux/slab.h> |
23 | #include <linux/fs.h> |
24 | #include <linux/posix_acl_xattr.h> |
25 | #include "jfs_incore.h" |
26 | #include "jfs_txnmgr.h" |
27 | #include "jfs_xattr.h" |
28 | #include "jfs_acl.h" |
29 | |
30 | static struct posix_acl *jfs_get_acl(struct inode *inode, int type) |
31 | { |
32 | struct posix_acl *acl; |
33 | char *ea_name; |
34 | int size; |
35 | char *value = NULL; |
36 | |
37 | acl = get_cached_acl(inode, type); |
38 | if (acl != ACL_NOT_CACHED) |
39 | return acl; |
40 | |
41 | switch(type) { |
42 | case ACL_TYPE_ACCESS: |
43 | ea_name = POSIX_ACL_XATTR_ACCESS; |
44 | break; |
45 | case ACL_TYPE_DEFAULT: |
46 | ea_name = POSIX_ACL_XATTR_DEFAULT; |
47 | break; |
48 | default: |
49 | return ERR_PTR(-EINVAL); |
50 | } |
51 | |
52 | size = __jfs_getxattr(inode, ea_name, NULL, 0); |
53 | |
54 | if (size > 0) { |
55 | value = kmalloc(size, GFP_KERNEL); |
56 | if (!value) |
57 | return ERR_PTR(-ENOMEM); |
58 | size = __jfs_getxattr(inode, ea_name, value, size); |
59 | } |
60 | |
61 | if (size < 0) { |
62 | if (size == -ENODATA) |
63 | acl = NULL; |
64 | else |
65 | acl = ERR_PTR(size); |
66 | } else { |
67 | acl = posix_acl_from_xattr(value, size); |
68 | } |
69 | kfree(value); |
70 | if (!IS_ERR(acl)) |
71 | set_cached_acl(inode, type, acl); |
72 | return acl; |
73 | } |
74 | |
75 | static int jfs_set_acl(tid_t tid, struct inode *inode, int type, |
76 | struct posix_acl *acl) |
77 | { |
78 | char *ea_name; |
79 | int rc; |
80 | int size = 0; |
81 | char *value = NULL; |
82 | |
83 | if (S_ISLNK(inode->i_mode)) |
84 | return -EOPNOTSUPP; |
85 | |
86 | switch(type) { |
87 | case ACL_TYPE_ACCESS: |
88 | ea_name = POSIX_ACL_XATTR_ACCESS; |
89 | break; |
90 | case ACL_TYPE_DEFAULT: |
91 | ea_name = POSIX_ACL_XATTR_DEFAULT; |
92 | if (!S_ISDIR(inode->i_mode)) |
93 | return acl ? -EACCES : 0; |
94 | break; |
95 | default: |
96 | return -EINVAL; |
97 | } |
98 | if (acl) { |
99 | size = posix_acl_xattr_size(acl->a_count); |
100 | value = kmalloc(size, GFP_KERNEL); |
101 | if (!value) |
102 | return -ENOMEM; |
103 | rc = posix_acl_to_xattr(acl, value, size); |
104 | if (rc < 0) |
105 | goto out; |
106 | } |
107 | rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0); |
108 | out: |
109 | kfree(value); |
110 | |
111 | if (!rc) |
112 | set_cached_acl(inode, type, acl); |
113 | |
114 | return rc; |
115 | } |
116 | |
117 | int jfs_check_acl(struct inode *inode, int mask) |
118 | { |
119 | struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); |
120 | |
121 | if (IS_ERR(acl)) |
122 | return PTR_ERR(acl); |
123 | if (acl) { |
124 | int error = posix_acl_permission(inode, acl, mask); |
125 | posix_acl_release(acl); |
126 | return error; |
127 | } |
128 | |
129 | return -EAGAIN; |
130 | } |
131 | |
132 | int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) |
133 | { |
134 | struct posix_acl *acl = NULL; |
135 | struct posix_acl *clone; |
136 | mode_t mode; |
137 | int rc = 0; |
138 | |
139 | if (S_ISLNK(inode->i_mode)) |
140 | return 0; |
141 | |
142 | acl = jfs_get_acl(dir, ACL_TYPE_DEFAULT); |
143 | if (IS_ERR(acl)) |
144 | return PTR_ERR(acl); |
145 | |
146 | if (acl) { |
147 | if (S_ISDIR(inode->i_mode)) { |
148 | rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); |
149 | if (rc) |
150 | goto cleanup; |
151 | } |
152 | clone = posix_acl_clone(acl, GFP_KERNEL); |
153 | if (!clone) { |
154 | rc = -ENOMEM; |
155 | goto cleanup; |
156 | } |
157 | mode = inode->i_mode; |
158 | rc = posix_acl_create_masq(clone, &mode); |
159 | if (rc >= 0) { |
160 | inode->i_mode = mode; |
161 | if (rc > 0) |
162 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, |
163 | clone); |
164 | } |
165 | posix_acl_release(clone); |
166 | cleanup: |
167 | posix_acl_release(acl); |
168 | } else |
169 | inode->i_mode &= ~current_umask(); |
170 | |
171 | JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | |
172 | inode->i_mode; |
173 | |
174 | return rc; |
175 | } |
176 | |
177 | int jfs_acl_chmod(struct inode *inode) |
178 | { |
179 | struct posix_acl *acl, *clone; |
180 | int rc; |
181 | |
182 | if (S_ISLNK(inode->i_mode)) |
183 | return -EOPNOTSUPP; |
184 | |
185 | acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); |
186 | if (IS_ERR(acl) || !acl) |
187 | return PTR_ERR(acl); |
188 | |
189 | clone = posix_acl_clone(acl, GFP_KERNEL); |
190 | posix_acl_release(acl); |
191 | if (!clone) |
192 | return -ENOMEM; |
193 | |
194 | rc = posix_acl_chmod_masq(clone, inode->i_mode); |
195 | if (!rc) { |
196 | tid_t tid = txBegin(inode->i_sb, 0); |
197 | mutex_lock(&JFS_IP(inode)->commit_mutex); |
198 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); |
199 | if (!rc) |
200 | rc = txCommit(tid, 1, &inode, 0); |
201 | txEnd(tid); |
202 | mutex_unlock(&JFS_IP(inode)->commit_mutex); |
203 | } |
204 | |
205 | posix_acl_release(clone); |
206 | return rc; |
207 | } |
208 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9