diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/9p/acl.c | 55 | ||||
| -rw-r--r-- | fs/9p/acl.h | 5 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 6 |
3 files changed, 66 insertions, 0 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index cad38bc1710e..8f2acde74c05 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c | |||
| @@ -97,6 +97,61 @@ int v9fs_check_acl(struct inode *inode, int mask) | |||
| 97 | return -EAGAIN; | 97 | return -EAGAIN; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl) | ||
| 101 | { | ||
| 102 | int retval; | ||
| 103 | char *name; | ||
| 104 | size_t size; | ||
| 105 | void *buffer; | ||
| 106 | struct inode *inode = dentry->d_inode; | ||
| 107 | |||
| 108 | set_cached_acl(inode, type, acl); | ||
| 109 | /* Set a setxattr request to server */ | ||
| 110 | size = posix_acl_xattr_size(acl->a_count); | ||
| 111 | buffer = kmalloc(size, GFP_KERNEL); | ||
| 112 | if (!buffer) | ||
| 113 | return -ENOMEM; | ||
| 114 | retval = posix_acl_to_xattr(acl, buffer, size); | ||
| 115 | if (retval < 0) | ||
| 116 | goto err_free_out; | ||
| 117 | switch (type) { | ||
| 118 | case ACL_TYPE_ACCESS: | ||
| 119 | name = POSIX_ACL_XATTR_ACCESS; | ||
| 120 | break; | ||
| 121 | case ACL_TYPE_DEFAULT: | ||
| 122 | name = POSIX_ACL_XATTR_DEFAULT; | ||
| 123 | break; | ||
| 124 | default: | ||
| 125 | BUG(); | ||
| 126 | } | ||
| 127 | retval = v9fs_xattr_set(dentry, name, buffer, size, 0); | ||
| 128 | err_free_out: | ||
| 129 | kfree(buffer); | ||
| 130 | return retval; | ||
| 131 | } | ||
| 132 | |||
| 133 | int v9fs_acl_chmod(struct dentry *dentry) | ||
| 134 | { | ||
| 135 | int retval = 0; | ||
| 136 | struct posix_acl *acl, *clone; | ||
| 137 | struct inode *inode = dentry->d_inode; | ||
| 138 | |||
| 139 | if (S_ISLNK(inode->i_mode)) | ||
| 140 | return -EOPNOTSUPP; | ||
| 141 | acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); | ||
| 142 | if (acl) { | ||
| 143 | clone = posix_acl_clone(acl, GFP_KERNEL); | ||
| 144 | posix_acl_release(acl); | ||
| 145 | if (!clone) | ||
| 146 | return -ENOMEM; | ||
| 147 | retval = posix_acl_chmod_masq(clone, inode->i_mode); | ||
| 148 | if (!retval) | ||
| 149 | retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, clone); | ||
| 150 | posix_acl_release(clone); | ||
| 151 | } | ||
| 152 | return retval; | ||
| 153 | } | ||
| 154 | |||
| 100 | static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | 155 | static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, |
| 101 | void *buffer, size_t size, int type) | 156 | void *buffer, size_t size, int type) |
| 102 | { | 157 | { |
diff --git a/fs/9p/acl.h b/fs/9p/acl.h index b1414f7c82e0..0adcc4326d18 100644 --- a/fs/9p/acl.h +++ b/fs/9p/acl.h | |||
| @@ -17,11 +17,16 @@ | |||
| 17 | #ifdef CONFIG_9P_FS_POSIX_ACL | 17 | #ifdef CONFIG_9P_FS_POSIX_ACL |
| 18 | extern int v9fs_get_acl(struct inode *, struct p9_fid *); | 18 | extern int v9fs_get_acl(struct inode *, struct p9_fid *); |
| 19 | extern int v9fs_check_acl(struct inode *inode, int mask); | 19 | extern int v9fs_check_acl(struct inode *inode, int mask); |
| 20 | extern int v9fs_acl_chmod(struct dentry *); | ||
| 20 | #else | 21 | #else |
| 21 | #define v9fs_check_acl NULL | 22 | #define v9fs_check_acl NULL |
| 22 | static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) | 23 | static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) |
| 23 | { | 24 | { |
| 24 | return 0; | 25 | return 0; |
| 25 | } | 26 | } |
| 27 | static inline int v9fs_acl_chmod(struct dentry *dentry) | ||
| 28 | { | ||
| 29 | return 0; | ||
| 30 | } | ||
| 26 | #endif | 31 | #endif |
| 27 | #endif /* FS_9P_XATTR_H */ | 32 | #endif /* FS_9P_XATTR_H */ |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 4b67bf1fb1d5..bdc64d1c22fb 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -1284,6 +1284,12 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) | |||
| 1284 | 1284 | ||
| 1285 | setattr_copy(dentry->d_inode, iattr); | 1285 | setattr_copy(dentry->d_inode, iattr); |
| 1286 | mark_inode_dirty(dentry->d_inode); | 1286 | mark_inode_dirty(dentry->d_inode); |
| 1287 | if (iattr->ia_valid & ATTR_MODE) { | ||
| 1288 | /* We also want to update ACL when we update mode bits */ | ||
| 1289 | retval = v9fs_acl_chmod(dentry); | ||
| 1290 | if (retval < 0) | ||
| 1291 | return retval; | ||
| 1292 | } | ||
| 1287 | return 0; | 1293 | return 0; |
| 1288 | } | 1294 | } |
| 1289 | 1295 | ||
