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 | ||