Loading Documentation/filesystems/9p.txt +3 −1 Original line number Diff line number Diff line Loading @@ -111,7 +111,7 @@ OPTIONS This can be used to share devices/named pipes/sockets between hosts. This functionality will be expanded in later versions. access there are three access modes. access there are four access modes. user = if a user tries to access a file on v9fs filesystem for the first time, v9fs sends an attach command (Tattach) for that user. Loading @@ -120,6 +120,8 @@ OPTIONS the files on the mounted filesystem any = v9fs does single attach and performs all operations as one user client = ACL based access check on the 9p client side for access validation cachetag cache tag to use the specified persistent cache. cache tags for existing cache sessions can be listed at Loading fs/9p/acl.c +77 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "xattr.h" #include "acl.h" #include "v9fs_vfs.h" #include "v9fs.h" static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) { Loading Loading @@ -55,7 +56,14 @@ int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) { int retval = 0; struct posix_acl *pacl, *dacl; struct v9fs_session_info *v9ses; v9ses = v9fs_inode2v9ses(inode); if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) { set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL); set_cached_acl(inode, ACL_TYPE_ACCESS, NULL); return 0; } /* get the default/access acl values and cache them */ dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT); pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS); Loading Loading @@ -85,7 +93,18 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type) int v9fs_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); struct posix_acl *acl; struct v9fs_session_info *v9ses; v9ses = v9fs_inode2v9ses(inode); if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) { /* * On access = client mode get the acl * values from the server */ return 0; } acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); Loading Loading @@ -204,15 +223,41 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep, } static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { char *full_name; switch (type) { case ACL_TYPE_ACCESS: full_name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: full_name = POSIX_ACL_XATTR_DEFAULT; break; default: BUG(); } return v9fs_xattr_get(dentry, full_name, buffer, size); } static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { struct v9fs_session_info *v9ses; struct posix_acl *acl; int error; if (strcmp(name, "") != 0) return -EINVAL; v9ses = v9fs_inode2v9ses(dentry->d_inode); /* * We allow set/get/list of acl when access=client is not specified */ if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) return v9fs_remote_get_acl(dentry, name, buffer, size, type); acl = v9fs_get_cached_acl(dentry->d_inode, type); if (IS_ERR(acl)) return PTR_ERR(acl); Loading @@ -224,16 +269,47 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, return error; } static int v9fs_remote_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { char *full_name; switch (type) { case ACL_TYPE_ACCESS: full_name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: full_name = POSIX_ACL_XATTR_DEFAULT; break; default: BUG(); } return v9fs_xattr_set(dentry, full_name, value, size, flags); } static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { int retval; struct posix_acl *acl; struct v9fs_session_info *v9ses; struct inode *inode = dentry->d_inode; if (strcmp(name, "") != 0) return -EINVAL; v9ses = v9fs_inode2v9ses(dentry->d_inode); /* * set the attribute on the remote. Without even looking at the * xattr value. We leave it to the server to validate */ if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) return v9fs_remote_set_acl(dentry, name, value, size, flags, type); if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!is_owner_or_cap(inode)) Loading fs/9p/fid.c +1 −0 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) switch (access) { case V9FS_ACCESS_SINGLE: case V9FS_ACCESS_USER: case V9FS_ACCESS_CLIENT: uid = current_fsuid(); any = 0; break; Loading fs/9p/v9fs.c +21 −1 Original line number Diff line number Diff line Loading @@ -193,7 +193,17 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) v9ses->flags |= V9FS_ACCESS_USER; else if (strcmp(s, "any") == 0) v9ses->flags |= V9FS_ACCESS_ANY; else { else if (strcmp(s, "client") == 0) { #ifdef CONFIG_9P_FS_POSIX_ACL v9ses->flags |= V9FS_ACCESS_CLIENT; #else P9_DPRINTK(P9_DEBUG_ERROR, "access=client option not supported\n"); kfree(s); ret = -EINVAL; goto free_and_return; #endif } else { v9ses->flags |= V9FS_ACCESS_SINGLE; v9ses->uid = simple_strtoul(s, &e, 10); if (*e != '\0') Loading Loading @@ -278,6 +288,16 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; if (!v9fs_proto_dotl(v9ses) && ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) { /* * We support ACCESS_CLIENT only for dotl. * Fall back to ACCESS_USER */ v9ses->flags &= ~V9FS_ACCESS_MASK; v9ses->flags |= V9FS_ACCESS_USER; } /*FIXME !! */ /* for legacy mode, fall back to V9FS_ACCESS_ANY */ if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) && ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) { Loading fs/9p/v9fs.h +6 −2 Original line number Diff line number Diff line Loading @@ -33,13 +33,17 @@ * * Session flags reflect options selected by users at mount time */ #define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \ V9FS_ACCESS_USER | \ V9FS_ACCESS_CLIENT) #define V9FS_ACCESS_MASK V9FS_ACCESS_ANY enum p9_session_flags { V9FS_PROTO_2000U = 0x01, V9FS_PROTO_2000L = 0x02, V9FS_ACCESS_SINGLE = 0x04, V9FS_ACCESS_USER = 0x08, V9FS_ACCESS_ANY = 0x0C, V9FS_ACCESS_MASK = 0x0C, V9FS_ACCESS_CLIENT = 0x10 }; /* possible values of ->cache */ Loading Loading
Documentation/filesystems/9p.txt +3 −1 Original line number Diff line number Diff line Loading @@ -111,7 +111,7 @@ OPTIONS This can be used to share devices/named pipes/sockets between hosts. This functionality will be expanded in later versions. access there are three access modes. access there are four access modes. user = if a user tries to access a file on v9fs filesystem for the first time, v9fs sends an attach command (Tattach) for that user. Loading @@ -120,6 +120,8 @@ OPTIONS the files on the mounted filesystem any = v9fs does single attach and performs all operations as one user client = ACL based access check on the 9p client side for access validation cachetag cache tag to use the specified persistent cache. cache tags for existing cache sessions can be listed at Loading
fs/9p/acl.c +77 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "xattr.h" #include "acl.h" #include "v9fs_vfs.h" #include "v9fs.h" static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) { Loading Loading @@ -55,7 +56,14 @@ int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) { int retval = 0; struct posix_acl *pacl, *dacl; struct v9fs_session_info *v9ses; v9ses = v9fs_inode2v9ses(inode); if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) { set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL); set_cached_acl(inode, ACL_TYPE_ACCESS, NULL); return 0; } /* get the default/access acl values and cache them */ dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT); pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS); Loading Loading @@ -85,7 +93,18 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type) int v9fs_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); struct posix_acl *acl; struct v9fs_session_info *v9ses; v9ses = v9fs_inode2v9ses(inode); if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) { /* * On access = client mode get the acl * values from the server */ return 0; } acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl)) return PTR_ERR(acl); Loading Loading @@ -204,15 +223,41 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep, } static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { char *full_name; switch (type) { case ACL_TYPE_ACCESS: full_name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: full_name = POSIX_ACL_XATTR_DEFAULT; break; default: BUG(); } return v9fs_xattr_get(dentry, full_name, buffer, size); } static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, size_t size, int type) { struct v9fs_session_info *v9ses; struct posix_acl *acl; int error; if (strcmp(name, "") != 0) return -EINVAL; v9ses = v9fs_inode2v9ses(dentry->d_inode); /* * We allow set/get/list of acl when access=client is not specified */ if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) return v9fs_remote_get_acl(dentry, name, buffer, size, type); acl = v9fs_get_cached_acl(dentry->d_inode, type); if (IS_ERR(acl)) return PTR_ERR(acl); Loading @@ -224,16 +269,47 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, return error; } static int v9fs_remote_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { char *full_name; switch (type) { case ACL_TYPE_ACCESS: full_name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: full_name = POSIX_ACL_XATTR_DEFAULT; break; default: BUG(); } return v9fs_xattr_set(dentry, full_name, value, size, flags); } static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { int retval; struct posix_acl *acl; struct v9fs_session_info *v9ses; struct inode *inode = dentry->d_inode; if (strcmp(name, "") != 0) return -EINVAL; v9ses = v9fs_inode2v9ses(dentry->d_inode); /* * set the attribute on the remote. Without even looking at the * xattr value. We leave it to the server to validate */ if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) return v9fs_remote_set_acl(dentry, name, value, size, flags, type); if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; if (!is_owner_or_cap(inode)) Loading
fs/9p/fid.c +1 −0 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) switch (access) { case V9FS_ACCESS_SINGLE: case V9FS_ACCESS_USER: case V9FS_ACCESS_CLIENT: uid = current_fsuid(); any = 0; break; Loading
fs/9p/v9fs.c +21 −1 Original line number Diff line number Diff line Loading @@ -193,7 +193,17 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) v9ses->flags |= V9FS_ACCESS_USER; else if (strcmp(s, "any") == 0) v9ses->flags |= V9FS_ACCESS_ANY; else { else if (strcmp(s, "client") == 0) { #ifdef CONFIG_9P_FS_POSIX_ACL v9ses->flags |= V9FS_ACCESS_CLIENT; #else P9_DPRINTK(P9_DEBUG_ERROR, "access=client option not supported\n"); kfree(s); ret = -EINVAL; goto free_and_return; #endif } else { v9ses->flags |= V9FS_ACCESS_SINGLE; v9ses->uid = simple_strtoul(s, &e, 10); if (*e != '\0') Loading Loading @@ -278,6 +288,16 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; if (!v9fs_proto_dotl(v9ses) && ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) { /* * We support ACCESS_CLIENT only for dotl. * Fall back to ACCESS_USER */ v9ses->flags &= ~V9FS_ACCESS_MASK; v9ses->flags |= V9FS_ACCESS_USER; } /*FIXME !! */ /* for legacy mode, fall back to V9FS_ACCESS_ANY */ if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) && ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) { Loading
fs/9p/v9fs.h +6 −2 Original line number Diff line number Diff line Loading @@ -33,13 +33,17 @@ * * Session flags reflect options selected by users at mount time */ #define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \ V9FS_ACCESS_USER | \ V9FS_ACCESS_CLIENT) #define V9FS_ACCESS_MASK V9FS_ACCESS_ANY enum p9_session_flags { V9FS_PROTO_2000U = 0x01, V9FS_PROTO_2000L = 0x02, V9FS_ACCESS_SINGLE = 0x04, V9FS_ACCESS_USER = 0x08, V9FS_ACCESS_ANY = 0x0C, V9FS_ACCESS_MASK = 0x0C, V9FS_ACCESS_CLIENT = 0x10 }; /* possible values of ->cache */ Loading