diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2009-10-02 07:00:00 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2009-12-03 06:47:35 -0500 |
commit | 479c427dd60fe1aadbbf2e6cbf2f84942baeb210 (patch) | |
tree | 0f51cf8e107d599c2e5c3b63bcdb2b17243dc7c4 /fs/gfs2/acl.c | |
parent | 69dca42464962d8d0989b7e09877ba644c9cba66 (diff) |
GFS2: Clean up ACLs
To prepare for support for caching of ACLs, this cleans up the GFS2
ACL support by pushing the xattr code back into xattr.c and changing
the acl_get function into one which only returns ACLs so that we
can drop the caching function into it shortly.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/acl.c')
-rw-r--r-- | fs/gfs2/acl.c | 164 |
1 files changed, 83 insertions, 81 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 1be314837d31..bd0fce964c41 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -27,53 +27,40 @@ | |||
27 | #include "trans.h" | 27 | #include "trans.h" |
28 | #include "util.h" | 28 | #include "util.h" |
29 | 29 | ||
30 | static int acl_get(struct gfs2_inode *ip, const char *name, | 30 | static const char *gfs2_acl_name(int type) |
31 | struct posix_acl **acl, struct gfs2_ea_location *el, | ||
32 | char **datap, unsigned int *lenp) | ||
33 | { | 31 | { |
34 | char *data; | 32 | switch (type) { |
35 | unsigned int len; | 33 | case ACL_TYPE_ACCESS: |
36 | int error; | 34 | return GFS2_POSIX_ACL_ACCESS; |
35 | case ACL_TYPE_DEFAULT: | ||
36 | return GFS2_POSIX_ACL_DEFAULT; | ||
37 | } | ||
38 | return NULL; | ||
39 | } | ||
37 | 40 | ||
38 | el->el_bh = NULL; | 41 | static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type) |
42 | { | ||
43 | struct posix_acl *acl; | ||
44 | const char *name; | ||
45 | char *data; | ||
46 | int len; | ||
39 | 47 | ||
40 | if (!ip->i_eattr) | 48 | if (!ip->i_eattr) |
41 | return 0; | 49 | return NULL; |
42 | |||
43 | error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el); | ||
44 | if (error) | ||
45 | return error; | ||
46 | if (!el->el_ea) | ||
47 | return 0; | ||
48 | if (!GFS2_EA_DATA_LEN(el->el_ea)) | ||
49 | goto out; | ||
50 | |||
51 | len = GFS2_EA_DATA_LEN(el->el_ea); | ||
52 | data = kmalloc(len, GFP_NOFS); | ||
53 | error = -ENOMEM; | ||
54 | if (!data) | ||
55 | goto out; | ||
56 | 50 | ||
57 | error = gfs2_ea_get_copy(ip, el, data, len); | 51 | name = gfs2_acl_name(type); |
58 | if (error < 0) | 52 | if (name == NULL) |
59 | goto out_kfree; | 53 | return ERR_PTR(-EINVAL); |
60 | error = 0; | ||
61 | 54 | ||
62 | if (acl) { | 55 | len = gfs2_xattr_acl_get(ip, name, &data); |
63 | *acl = posix_acl_from_xattr(data, len); | 56 | if (len < 0) |
64 | if (IS_ERR(*acl)) | 57 | return ERR_PTR(len); |
65 | error = PTR_ERR(*acl); | 58 | if (len == 0) |
66 | } | 59 | return NULL; |
67 | 60 | ||
68 | out_kfree: | 61 | acl = posix_acl_from_xattr(data, len); |
69 | if (error || !datap) { | 62 | kfree(data); |
70 | kfree(data); | 63 | return acl; |
71 | } else { | ||
72 | *datap = data; | ||
73 | *lenp = len; | ||
74 | } | ||
75 | out: | ||
76 | return error; | ||
77 | } | 64 | } |
78 | 65 | ||
79 | /** | 66 | /** |
@@ -86,14 +73,12 @@ out: | |||
86 | 73 | ||
87 | int gfs2_check_acl(struct inode *inode, int mask) | 74 | int gfs2_check_acl(struct inode *inode, int mask) |
88 | { | 75 | { |
89 | struct gfs2_ea_location el; | 76 | struct posix_acl *acl; |
90 | struct posix_acl *acl = NULL; | ||
91 | int error; | 77 | int error; |
92 | 78 | ||
93 | error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL); | 79 | acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); |
94 | brelse(el.el_bh); | 80 | if (IS_ERR(acl)) |
95 | if (error) | 81 | return PTR_ERR(acl); |
96 | return error; | ||
97 | 82 | ||
98 | if (acl) { | 83 | if (acl) { |
99 | error = posix_acl_permission(inode, acl, mask); | 84 | error = posix_acl_permission(inode, acl, mask); |
@@ -120,32 +105,57 @@ static int gfs2_set_mode(struct inode *inode, mode_t mode) | |||
120 | return error; | 105 | return error; |
121 | } | 106 | } |
122 | 107 | ||
123 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | 108 | static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl) |
124 | { | 109 | { |
125 | struct gfs2_ea_location el; | ||
126 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
127 | struct posix_acl *acl = NULL, *clone; | ||
128 | mode_t mode = ip->i_inode.i_mode; | ||
129 | char *data = NULL; | ||
130 | unsigned int len; | ||
131 | int error; | 110 | int error; |
111 | int len; | ||
112 | char *data; | ||
113 | const char *name = gfs2_acl_name(type); | ||
114 | |||
115 | BUG_ON(name == NULL); | ||
116 | len = posix_acl_to_xattr(acl, NULL, 0); | ||
117 | if (len == 0) | ||
118 | return 0; | ||
119 | data = kmalloc(len, GFP_NOFS); | ||
120 | if (data == NULL) | ||
121 | return -ENOMEM; | ||
122 | error = posix_acl_to_xattr(acl, data, len); | ||
123 | if (error < 0) | ||
124 | goto out; | ||
125 | error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, data, len, 0); | ||
126 | out: | ||
127 | kfree(data); | ||
128 | return error; | ||
129 | } | ||
130 | |||
131 | int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) | ||
132 | { | ||
133 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
134 | struct posix_acl *acl, *clone; | ||
135 | mode_t mode = inode->i_mode; | ||
136 | int error = 0; | ||
132 | 137 | ||
133 | if (!sdp->sd_args.ar_posix_acl) | 138 | if (!sdp->sd_args.ar_posix_acl) |
134 | return 0; | 139 | return 0; |
135 | if (S_ISLNK(ip->i_inode.i_mode)) | 140 | if (S_ISLNK(inode->i_mode)) |
136 | return 0; | 141 | return 0; |
137 | 142 | ||
138 | error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len); | 143 | acl = gfs2_acl_get(dip, ACL_TYPE_DEFAULT); |
139 | brelse(el.el_bh); | 144 | if (IS_ERR(acl)) |
140 | if (error) | 145 | return PTR_ERR(acl); |
141 | return error; | ||
142 | if (!acl) { | 146 | if (!acl) { |
143 | mode &= ~current_umask(); | 147 | mode &= ~current_umask(); |
144 | if (mode != ip->i_inode.i_mode) | 148 | if (mode != inode->i_mode) |
145 | error = gfs2_set_mode(&ip->i_inode, mode); | 149 | error = gfs2_set_mode(inode, mode); |
146 | return error; | 150 | return error; |
147 | } | 151 | } |
148 | 152 | ||
153 | if (S_ISDIR(inode->i_mode)) { | ||
154 | error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl); | ||
155 | if (error) | ||
156 | goto out; | ||
157 | } | ||
158 | |||
149 | clone = posix_acl_clone(acl, GFP_NOFS); | 159 | clone = posix_acl_clone(acl, GFP_NOFS); |
150 | error = -ENOMEM; | 160 | error = -ENOMEM; |
151 | if (!clone) | 161 | if (!clone) |
@@ -153,43 +163,32 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
153 | posix_acl_release(acl); | 163 | posix_acl_release(acl); |
154 | acl = clone; | 164 | acl = clone; |
155 | 165 | ||
156 | if (S_ISDIR(ip->i_inode.i_mode)) { | ||
157 | error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS, | ||
158 | GFS2_POSIX_ACL_DEFAULT, data, len, 0); | ||
159 | if (error) | ||
160 | goto out; | ||
161 | } | ||
162 | |||
163 | error = posix_acl_create_masq(acl, &mode); | 166 | error = posix_acl_create_masq(acl, &mode); |
164 | if (error < 0) | 167 | if (error < 0) |
165 | goto out; | 168 | goto out; |
166 | if (error == 0) | 169 | if (error == 0) |
167 | goto munge; | 170 | goto munge; |
168 | 171 | ||
169 | posix_acl_to_xattr(acl, data, len); | 172 | error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl); |
170 | error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS, | ||
171 | GFS2_POSIX_ACL_ACCESS, data, len, 0); | ||
172 | if (error) | 173 | if (error) |
173 | goto out; | 174 | goto out; |
174 | munge: | 175 | munge: |
175 | error = gfs2_set_mode(&ip->i_inode, mode); | 176 | error = gfs2_set_mode(inode, mode); |
176 | out: | 177 | out: |
177 | posix_acl_release(acl); | 178 | posix_acl_release(acl); |
178 | kfree(data); | ||
179 | return error; | 179 | return error; |
180 | } | 180 | } |
181 | 181 | ||
182 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | 182 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) |
183 | { | 183 | { |
184 | struct posix_acl *acl = NULL, *clone; | 184 | struct posix_acl *acl, *clone; |
185 | struct gfs2_ea_location el; | ||
186 | char *data; | 185 | char *data; |
187 | unsigned int len; | 186 | unsigned int len; |
188 | int error; | 187 | int error; |
189 | 188 | ||
190 | error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len); | 189 | acl = gfs2_acl_get(ip, ACL_TYPE_ACCESS); |
191 | if (error) | 190 | if (IS_ERR(acl)) |
192 | goto out_brelse; | 191 | return PTR_ERR(acl); |
193 | if (!acl) | 192 | if (!acl) |
194 | return gfs2_setattr_simple(ip, attr); | 193 | return gfs2_setattr_simple(ip, attr); |
195 | 194 | ||
@@ -202,15 +201,18 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
202 | 201 | ||
203 | error = posix_acl_chmod_masq(acl, attr->ia_mode); | 202 | error = posix_acl_chmod_masq(acl, attr->ia_mode); |
204 | if (!error) { | 203 | if (!error) { |
204 | len = posix_acl_to_xattr(acl, NULL, 0); | ||
205 | data = kmalloc(len, GFP_NOFS); | ||
206 | error = -ENOMEM; | ||
207 | if (data == NULL) | ||
208 | goto out; | ||
205 | posix_acl_to_xattr(acl, data, len); | 209 | posix_acl_to_xattr(acl, data, len); |
206 | error = gfs2_ea_acl_chmod(ip, &el, attr, data); | 210 | error = gfs2_xattr_acl_chmod(ip, attr, data); |
211 | kfree(data); | ||
207 | } | 212 | } |
208 | 213 | ||
209 | out: | 214 | out: |
210 | posix_acl_release(acl); | 215 | posix_acl_release(acl); |
211 | kfree(data); | ||
212 | out_brelse: | ||
213 | brelse(el.el_bh); | ||
214 | return error; | 216 | return error; |
215 | } | 217 | } |
216 | 218 | ||