diff options
Diffstat (limited to 'fs/9p/acl.c')
| -rw-r--r-- | fs/9p/acl.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 8b3c54a4958c..12d602351dbe 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "xattr.h" | 22 | #include "xattr.h" |
| 23 | #include "acl.h" | 23 | #include "acl.h" |
| 24 | #include "v9fs_vfs.h" | 24 | #include "v9fs_vfs.h" |
| 25 | #include "v9fs.h" | ||
| 25 | 26 | ||
| 26 | static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) | 27 | static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) |
| 27 | { | 28 | { |
| @@ -55,7 +56,14 @@ int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) | |||
| 55 | { | 56 | { |
| 56 | int retval = 0; | 57 | int retval = 0; |
| 57 | struct posix_acl *pacl, *dacl; | 58 | struct posix_acl *pacl, *dacl; |
| 59 | struct v9fs_session_info *v9ses; | ||
| 58 | 60 | ||
| 61 | v9ses = v9fs_inode2v9ses(inode); | ||
| 62 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) { | ||
| 63 | set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL); | ||
| 64 | set_cached_acl(inode, ACL_TYPE_ACCESS, NULL); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 59 | /* get the default/access acl values and cache them */ | 67 | /* get the default/access acl values and cache them */ |
| 60 | dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT); | 68 | dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT); |
| 61 | pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS); | 69 | pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS); |
| @@ -85,7 +93,18 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type) | |||
| 85 | 93 | ||
| 86 | int v9fs_check_acl(struct inode *inode, int mask) | 94 | int v9fs_check_acl(struct inode *inode, int mask) |
| 87 | { | 95 | { |
| 88 | struct posix_acl *acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); | 96 | struct posix_acl *acl; |
| 97 | struct v9fs_session_info *v9ses; | ||
| 98 | |||
| 99 | v9ses = v9fs_inode2v9ses(inode); | ||
| 100 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) { | ||
| 101 | /* | ||
| 102 | * On access = client mode get the acl | ||
| 103 | * values from the server | ||
| 104 | */ | ||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); | ||
| 89 | 108 | ||
| 90 | if (IS_ERR(acl)) | 109 | if (IS_ERR(acl)) |
| 91 | return PTR_ERR(acl); | 110 | return PTR_ERR(acl); |
| @@ -204,15 +223,41 @@ cleanup: | |||
| 204 | 223 | ||
| 205 | } | 224 | } |
| 206 | 225 | ||
| 226 | static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, | ||
| 227 | void *buffer, size_t size, int type) | ||
| 228 | { | ||
| 229 | char *full_name; | ||
| 230 | |||
| 231 | switch (type) { | ||
| 232 | case ACL_TYPE_ACCESS: | ||
| 233 | full_name = POSIX_ACL_XATTR_ACCESS; | ||
| 234 | break; | ||
| 235 | case ACL_TYPE_DEFAULT: | ||
| 236 | full_name = POSIX_ACL_XATTR_DEFAULT; | ||
| 237 | break; | ||
| 238 | default: | ||
| 239 | BUG(); | ||
| 240 | } | ||
| 241 | return v9fs_xattr_get(dentry, full_name, buffer, size); | ||
| 242 | } | ||
| 243 | |||
| 207 | static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | 244 | static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, |
| 208 | void *buffer, size_t size, int type) | 245 | void *buffer, size_t size, int type) |
| 209 | { | 246 | { |
| 247 | struct v9fs_session_info *v9ses; | ||
| 210 | struct posix_acl *acl; | 248 | struct posix_acl *acl; |
| 211 | int error; | 249 | int error; |
| 212 | 250 | ||
| 213 | if (strcmp(name, "") != 0) | 251 | if (strcmp(name, "") != 0) |
| 214 | return -EINVAL; | 252 | return -EINVAL; |
| 215 | 253 | ||
| 254 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
| 255 | /* | ||
| 256 | * We allow set/get/list of acl when access=client is not specified | ||
| 257 | */ | ||
| 258 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) | ||
| 259 | return v9fs_remote_get_acl(dentry, name, buffer, size, type); | ||
| 260 | |||
| 216 | acl = v9fs_get_cached_acl(dentry->d_inode, type); | 261 | acl = v9fs_get_cached_acl(dentry->d_inode, type); |
| 217 | if (IS_ERR(acl)) | 262 | if (IS_ERR(acl)) |
| 218 | return PTR_ERR(acl); | 263 | return PTR_ERR(acl); |
| @@ -224,16 +269,47 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | |||
| 224 | return error; | 269 | return error; |
| 225 | } | 270 | } |
| 226 | 271 | ||
| 272 | static int v9fs_remote_set_acl(struct dentry *dentry, const char *name, | ||
| 273 | const void *value, size_t size, | ||
| 274 | int flags, int type) | ||
| 275 | { | ||
| 276 | char *full_name; | ||
| 277 | |||
| 278 | switch (type) { | ||
| 279 | case ACL_TYPE_ACCESS: | ||
| 280 | full_name = POSIX_ACL_XATTR_ACCESS; | ||
| 281 | break; | ||
| 282 | case ACL_TYPE_DEFAULT: | ||
| 283 | full_name = POSIX_ACL_XATTR_DEFAULT; | ||
| 284 | break; | ||
| 285 | default: | ||
| 286 | BUG(); | ||
| 287 | } | ||
| 288 | return v9fs_xattr_set(dentry, full_name, value, size, flags); | ||
| 289 | } | ||
| 290 | |||
| 291 | |||
| 227 | static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | 292 | static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, |
| 228 | const void *value, size_t size, | 293 | const void *value, size_t size, |
| 229 | int flags, int type) | 294 | int flags, int type) |
| 230 | { | 295 | { |
| 231 | int retval; | 296 | int retval; |
| 232 | struct posix_acl *acl; | 297 | struct posix_acl *acl; |
| 298 | struct v9fs_session_info *v9ses; | ||
| 233 | struct inode *inode = dentry->d_inode; | 299 | struct inode *inode = dentry->d_inode; |
| 234 | 300 | ||
| 235 | if (strcmp(name, "") != 0) | 301 | if (strcmp(name, "") != 0) |
| 236 | return -EINVAL; | 302 | return -EINVAL; |
| 303 | |||
| 304 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
| 305 | /* | ||
| 306 | * set the attribute on the remote. Without even looking at the | ||
| 307 | * xattr value. We leave it to the server to validate | ||
| 308 | */ | ||
| 309 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) | ||
| 310 | return v9fs_remote_set_acl(dentry, name, | ||
| 311 | value, size, flags, type); | ||
| 312 | |||
| 237 | if (S_ISLNK(inode->i_mode)) | 313 | if (S_ISLNK(inode->i_mode)) |
| 238 | return -EOPNOTSUPP; | 314 | return -EOPNOTSUPP; |
| 239 | if (!is_owner_or_cap(inode)) | 315 | if (!is_owner_or_cap(inode)) |
