aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/9p.txt4
-rw-r--r--fs/9p/acl.c78
-rw-r--r--fs/9p/fid.c1
-rw-r--r--fs/9p/v9fs.c22
-rw-r--r--fs/9p/v9fs.h8
-rw-r--r--fs/9p/vfs_super.c4
6 files changed, 110 insertions, 7 deletions
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index f9765e8cf086..b22abba78fed 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -111,7 +111,7 @@ OPTIONS
111 This can be used to share devices/named pipes/sockets between 111 This can be used to share devices/named pipes/sockets between
112 hosts. This functionality will be expanded in later versions. 112 hosts. This functionality will be expanded in later versions.
113 113
114 access there are three access modes. 114 access there are four access modes.
115 user = if a user tries to access a file on v9fs 115 user = if a user tries to access a file on v9fs
116 filesystem for the first time, v9fs sends an 116 filesystem for the first time, v9fs sends an
117 attach command (Tattach) for that user. 117 attach command (Tattach) for that user.
@@ -120,6 +120,8 @@ OPTIONS
120 the files on the mounted filesystem 120 the files on the mounted filesystem
121 any = v9fs does single attach and performs all 121 any = v9fs does single attach and performs all
122 operations as one user 122 operations as one user
123 client = ACL based access check on the 9p client
124 side for access validation
123 125
124 cachetag cache tag to use the specified persistent cache. 126 cachetag cache tag to use the specified persistent cache.
125 cache tags for existing cache sessions can be listed at 127 cache tags for existing cache sessions can be listed at
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
26static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) 27static 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
86int v9fs_check_acl(struct inode *inode, int mask) 94int 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
226static 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
207static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, 244static 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
272static 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
227static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, 292static 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))
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 6406f896bf95..b00223c99d70 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -149,6 +149,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
149 switch (access) { 149 switch (access) {
150 case V9FS_ACCESS_SINGLE: 150 case V9FS_ACCESS_SINGLE:
151 case V9FS_ACCESS_USER: 151 case V9FS_ACCESS_USER:
152 case V9FS_ACCESS_CLIENT:
152 uid = current_fsuid(); 153 uid = current_fsuid();
153 any = 0; 154 any = 0;
154 break; 155 break;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 38dc0e067599..2f77cd33ba83 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -193,7 +193,17 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
193 v9ses->flags |= V9FS_ACCESS_USER; 193 v9ses->flags |= V9FS_ACCESS_USER;
194 else if (strcmp(s, "any") == 0) 194 else if (strcmp(s, "any") == 0)
195 v9ses->flags |= V9FS_ACCESS_ANY; 195 v9ses->flags |= V9FS_ACCESS_ANY;
196 else { 196 else if (strcmp(s, "client") == 0) {
197#ifdef CONFIG_9P_FS_POSIX_ACL
198 v9ses->flags |= V9FS_ACCESS_CLIENT;
199#else
200 P9_DPRINTK(P9_DEBUG_ERROR,
201 "access=client option not supported\n");
202 kfree(s);
203 ret = -EINVAL;
204 goto free_and_return;
205#endif
206 } else {
197 v9ses->flags |= V9FS_ACCESS_SINGLE; 207 v9ses->flags |= V9FS_ACCESS_SINGLE;
198 v9ses->uid = simple_strtoul(s, &e, 10); 208 v9ses->uid = simple_strtoul(s, &e, 10);
199 if (*e != '\0') 209 if (*e != '\0')
@@ -278,6 +288,16 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
278 288
279 v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; 289 v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
280 290
291 if (!v9fs_proto_dotl(v9ses) &&
292 ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
293 /*
294 * We support ACCESS_CLIENT only for dotl.
295 * Fall back to ACCESS_USER
296 */
297 v9ses->flags &= ~V9FS_ACCESS_MASK;
298 v9ses->flags |= V9FS_ACCESS_USER;
299 }
300 /*FIXME !! */
281 /* for legacy mode, fall back to V9FS_ACCESS_ANY */ 301 /* for legacy mode, fall back to V9FS_ACCESS_ANY */
282 if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) && 302 if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
283 ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) { 303 ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 4c963c9fc41f..8bb7792afe2e 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -33,13 +33,17 @@
33 * 33 *
34 * Session flags reflect options selected by users at mount time 34 * Session flags reflect options selected by users at mount time
35 */ 35 */
36#define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \
37 V9FS_ACCESS_USER | \
38 V9FS_ACCESS_CLIENT)
39#define V9FS_ACCESS_MASK V9FS_ACCESS_ANY
40
36enum p9_session_flags { 41enum p9_session_flags {
37 V9FS_PROTO_2000U = 0x01, 42 V9FS_PROTO_2000U = 0x01,
38 V9FS_PROTO_2000L = 0x02, 43 V9FS_PROTO_2000L = 0x02,
39 V9FS_ACCESS_SINGLE = 0x04, 44 V9FS_ACCESS_SINGLE = 0x04,
40 V9FS_ACCESS_USER = 0x08, 45 V9FS_ACCESS_USER = 0x08,
41 V9FS_ACCESS_ANY = 0x0C, 46 V9FS_ACCESS_CLIENT = 0x10
42 V9FS_ACCESS_MASK = 0x0C,
43}; 47};
44 48
45/* possible values of ->cache */ 49/* possible values of ->cache */
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 14da5778d44e..174643f4f901 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -90,7 +90,8 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
90 MS_NOATIME; 90 MS_NOATIME;
91 91
92#ifdef CONFIG_9P_FS_POSIX_ACL 92#ifdef CONFIG_9P_FS_POSIX_ACL
93 sb->s_flags |= MS_POSIXACL; 93 if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)
94 sb->s_flags |= MS_POSIXACL;
94#endif 95#endif
95 96
96 save_mount_options(sb, data); 97 save_mount_options(sb, data);
@@ -181,7 +182,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
181 retval = v9fs_get_acl(inode, fid); 182 retval = v9fs_get_acl(inode, fid);
182 if (retval) 183 if (retval)
183 goto release_sb; 184 goto release_sb;
184
185 v9fs_fid_add(root, fid); 185 v9fs_fid_add(root, fid);
186 186
187 P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); 187 P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");