diff options
Diffstat (limited to 'fs/gfs2/acl.c')
| -rw-r--r-- | fs/gfs2/acl.c | 106 |
1 files changed, 46 insertions, 60 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index fa881bdc3d85..3fc4e3ac7d84 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
| @@ -19,8 +19,7 @@ | |||
| 19 | #include "gfs2.h" | 19 | #include "gfs2.h" |
| 20 | #include "incore.h" | 20 | #include "incore.h" |
| 21 | #include "acl.h" | 21 | #include "acl.h" |
| 22 | #include "eaops.h" | 22 | #include "xattr.h" |
| 23 | #include "eattr.h" | ||
| 24 | #include "glock.h" | 23 | #include "glock.h" |
| 25 | #include "inode.h" | 24 | #include "inode.h" |
| 26 | #include "meta_io.h" | 25 | #include "meta_io.h" |
| @@ -31,8 +30,7 @@ | |||
| 31 | #define ACL_DEFAULT 0 | 30 | #define ACL_DEFAULT 0 |
| 32 | 31 | ||
| 33 | int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, | 32 | int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, |
| 34 | struct gfs2_ea_request *er, | 33 | struct gfs2_ea_request *er, int *remove, mode_t *mode) |
| 35 | int *remove, mode_t *mode) | ||
| 36 | { | 34 | { |
| 37 | struct posix_acl *acl; | 35 | struct posix_acl *acl; |
| 38 | int error; | 36 | int error; |
| @@ -83,30 +81,20 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access) | |||
| 83 | return 0; | 81 | return 0; |
| 84 | } | 82 | } |
| 85 | 83 | ||
| 86 | static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl, | 84 | static int acl_get(struct gfs2_inode *ip, const char *name, |
| 87 | struct gfs2_ea_location *el, char **data, unsigned int *len) | 85 | struct posix_acl **acl, struct gfs2_ea_location *el, |
| 86 | char **datap, unsigned int *lenp) | ||
| 88 | { | 87 | { |
| 89 | struct gfs2_ea_request er; | 88 | char *data; |
| 90 | struct gfs2_ea_location el_this; | 89 | unsigned int len; |
| 91 | int error; | 90 | int error; |
| 92 | 91 | ||
| 92 | el->el_bh = NULL; | ||
| 93 | |||
| 93 | if (!ip->i_eattr) | 94 | if (!ip->i_eattr) |
| 94 | return 0; | 95 | return 0; |
| 95 | 96 | ||
| 96 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 97 | error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el); |
| 97 | if (access) { | ||
| 98 | er.er_name = GFS2_POSIX_ACL_ACCESS; | ||
| 99 | er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN; | ||
| 100 | } else { | ||
| 101 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | ||
| 102 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | ||
| 103 | } | ||
| 104 | er.er_type = GFS2_EATYPE_SYS; | ||
| 105 | |||
| 106 | if (!el) | ||
| 107 | el = &el_this; | ||
| 108 | |||
| 109 | error = gfs2_ea_find(ip, &er, el); | ||
| 110 | if (error) | 98 | if (error) |
| 111 | return error; | 99 | return error; |
| 112 | if (!el->el_ea) | 100 | if (!el->el_ea) |
| @@ -114,32 +102,31 @@ static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl, | |||
| 114 | if (!GFS2_EA_DATA_LEN(el->el_ea)) | 102 | if (!GFS2_EA_DATA_LEN(el->el_ea)) |
| 115 | goto out; | 103 | goto out; |
| 116 | 104 | ||
| 117 | er.er_data_len = GFS2_EA_DATA_LEN(el->el_ea); | 105 | len = GFS2_EA_DATA_LEN(el->el_ea); |
| 118 | er.er_data = kmalloc(er.er_data_len, GFP_NOFS); | 106 | data = kmalloc(len, GFP_NOFS); |
| 119 | error = -ENOMEM; | 107 | error = -ENOMEM; |
| 120 | if (!er.er_data) | 108 | if (!data) |
| 121 | goto out; | 109 | goto out; |
| 122 | 110 | ||
| 123 | error = gfs2_ea_get_copy(ip, el, er.er_data); | 111 | error = gfs2_ea_get_copy(ip, el, data, len); |
| 124 | if (error) | 112 | if (error < 0) |
| 125 | goto out_kfree; | 113 | goto out_kfree; |
| 114 | error = 0; | ||
| 126 | 115 | ||
| 127 | if (acl) { | 116 | if (acl) { |
| 128 | *acl = posix_acl_from_xattr(er.er_data, er.er_data_len); | 117 | *acl = posix_acl_from_xattr(data, len); |
| 129 | if (IS_ERR(*acl)) | 118 | if (IS_ERR(*acl)) |
| 130 | error = PTR_ERR(*acl); | 119 | error = PTR_ERR(*acl); |
| 131 | } | 120 | } |
| 132 | 121 | ||
| 133 | out_kfree: | 122 | out_kfree: |
| 134 | if (error || !data) | 123 | if (error || !datap) { |
| 135 | kfree(er.er_data); | 124 | kfree(data); |
| 136 | else { | 125 | } else { |
| 137 | *data = er.er_data; | 126 | *datap = data; |
| 138 | *len = er.er_data_len; | 127 | *lenp = len; |
| 139 | } | 128 | } |
| 140 | out: | 129 | out: |
| 141 | if (error || el == &el_this) | ||
| 142 | brelse(el->el_bh); | ||
| 143 | return error; | 130 | return error; |
| 144 | } | 131 | } |
| 145 | 132 | ||
| @@ -153,10 +140,12 @@ out: | |||
| 153 | 140 | ||
| 154 | int gfs2_check_acl(struct inode *inode, int mask) | 141 | int gfs2_check_acl(struct inode *inode, int mask) |
| 155 | { | 142 | { |
| 143 | struct gfs2_ea_location el; | ||
| 156 | struct posix_acl *acl = NULL; | 144 | struct posix_acl *acl = NULL; |
| 157 | int error; | 145 | int error; |
| 158 | 146 | ||
| 159 | error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL); | 147 | error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL); |
| 148 | brelse(el.el_bh); | ||
| 160 | if (error) | 149 | if (error) |
| 161 | return error; | 150 | return error; |
| 162 | 151 | ||
| @@ -196,10 +185,12 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode) | |||
| 196 | 185 | ||
| 197 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | 186 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) |
| 198 | { | 187 | { |
| 188 | struct gfs2_ea_location el; | ||
| 199 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 189 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
| 200 | struct posix_acl *acl = NULL, *clone; | 190 | struct posix_acl *acl = NULL, *clone; |
| 201 | struct gfs2_ea_request er; | ||
| 202 | mode_t mode = ip->i_inode.i_mode; | 191 | mode_t mode = ip->i_inode.i_mode; |
| 192 | char *data = NULL; | ||
| 193 | unsigned int len; | ||
| 203 | int error; | 194 | int error; |
| 204 | 195 | ||
| 205 | if (!sdp->sd_args.ar_posix_acl) | 196 | if (!sdp->sd_args.ar_posix_acl) |
| @@ -207,11 +198,8 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
| 207 | if (S_ISLNK(ip->i_inode.i_mode)) | 198 | if (S_ISLNK(ip->i_inode.i_mode)) |
| 208 | return 0; | 199 | return 0; |
| 209 | 200 | ||
| 210 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 201 | error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len); |
| 211 | er.er_type = GFS2_EATYPE_SYS; | 202 | brelse(el.el_bh); |
| 212 | |||
| 213 | error = acl_get(dip, ACL_DEFAULT, &acl, NULL, | ||
| 214 | &er.er_data, &er.er_data_len); | ||
| 215 | if (error) | 203 | if (error) |
| 216 | return error; | 204 | return error; |
| 217 | if (!acl) { | 205 | if (!acl) { |
| @@ -229,9 +217,8 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
| 229 | acl = clone; | 217 | acl = clone; |
| 230 | 218 | ||
| 231 | if (S_ISDIR(ip->i_inode.i_mode)) { | 219 | if (S_ISDIR(ip->i_inode.i_mode)) { |
| 232 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | 220 | error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS, |
| 233 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | 221 | GFS2_POSIX_ACL_DEFAULT, data, len, 0); |
| 234 | error = gfs2_system_eaops.eo_set(ip, &er); | ||
| 235 | if (error) | 222 | if (error) |
| 236 | goto out; | 223 | goto out; |
| 237 | } | 224 | } |
| @@ -239,21 +226,19 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
| 239 | error = posix_acl_create_masq(acl, &mode); | 226 | error = posix_acl_create_masq(acl, &mode); |
| 240 | if (error < 0) | 227 | if (error < 0) |
| 241 | goto out; | 228 | goto out; |
| 242 | if (error > 0) { | 229 | if (error == 0) |
| 243 | er.er_name = GFS2_POSIX_ACL_ACCESS; | 230 | goto munge; |
| 244 | er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN; | ||
| 245 | posix_acl_to_xattr(acl, er.er_data, er.er_data_len); | ||
| 246 | er.er_mode = mode; | ||
| 247 | er.er_flags = GFS2_ERF_MODE; | ||
| 248 | error = gfs2_system_eaops.eo_set(ip, &er); | ||
| 249 | if (error) | ||
| 250 | goto out; | ||
| 251 | } else | ||
| 252 | munge_mode(ip, mode); | ||
| 253 | 231 | ||
| 232 | posix_acl_to_xattr(acl, data, len); | ||
| 233 | error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS, | ||
| 234 | GFS2_POSIX_ACL_ACCESS, data, len, 0); | ||
| 235 | if (error) | ||
| 236 | goto out; | ||
| 237 | munge: | ||
| 238 | error = munge_mode(ip, mode); | ||
| 254 | out: | 239 | out: |
| 255 | posix_acl_release(acl); | 240 | posix_acl_release(acl); |
| 256 | kfree(er.er_data); | 241 | kfree(data); |
| 257 | return error; | 242 | return error; |
| 258 | } | 243 | } |
| 259 | 244 | ||
| @@ -265,9 +250,9 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
| 265 | unsigned int len; | 250 | unsigned int len; |
| 266 | int error; | 251 | int error; |
| 267 | 252 | ||
| 268 | error = acl_get(ip, ACL_ACCESS, &acl, &el, &data, &len); | 253 | error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len); |
| 269 | if (error) | 254 | if (error) |
| 270 | return error; | 255 | goto out_brelse; |
| 271 | if (!acl) | 256 | if (!acl) |
| 272 | return gfs2_setattr_simple(ip, attr); | 257 | return gfs2_setattr_simple(ip, attr); |
| 273 | 258 | ||
| @@ -286,8 +271,9 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
| 286 | 271 | ||
| 287 | out: | 272 | out: |
| 288 | posix_acl_release(acl); | 273 | posix_acl_release(acl); |
| 289 | brelse(el.el_bh); | ||
| 290 | kfree(data); | 274 | kfree(data); |
| 275 | out_brelse: | ||
| 276 | brelse(el.el_bh); | ||
| 291 | return error; | 277 | return error; |
| 292 | } | 278 | } |
| 293 | 279 | ||
