aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2010-09-27 14:57:39 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2010-10-28 10:08:46 -0400
commit85ff872d3f4a62d076d698bd1fa15ca2a4d7c100 (patch)
tree16d74f328ccb0b81470b1fbc4cad1b37e4df7ab8 /fs/9p
parent8e44a0805fc9d77475060280136aa491aa7d7060 (diff)
fs/9p: Implement POSIX ACL permission checking function
The ACL value is fetched as a part of inode initialization from the server and the permission checking function use the cached value of the ACL Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/Kconfig13
-rw-r--r--fs/9p/Makefile1
-rw-r--r--fs/9p/acl.c96
-rw-r--r--fs/9p/acl.h27
-rw-r--r--fs/9p/vfs_inode.c10
-rw-r--r--fs/9p/vfs_super.c9
-rw-r--r--fs/9p/xattr.c48
-rw-r--r--fs/9p/xattr.h4
8 files changed, 186 insertions, 22 deletions
diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig
index 795233702a4e..7e0511476797 100644
--- a/fs/9p/Kconfig
+++ b/fs/9p/Kconfig
@@ -17,3 +17,16 @@ config 9P_FSCACHE
17 Choose Y here to enable persistent, read-only local 17 Choose Y here to enable persistent, read-only local
18 caching support for 9p clients using FS-Cache 18 caching support for 9p clients using FS-Cache
19 19
20
21config 9P_FS_POSIX_ACL
22 bool "9P POSIX Access Control Lists"
23 depends on 9P_FS
24 select FS_POSIX_ACL
25 help
26 POSIX Access Control Lists (ACLs) support permissions for users and
27 groups beyond the owner/group/world scheme.
28
29 To learn more about Access Control Lists, visit the POSIX ACLs for
30 Linux website <http://acl.bestbits.at/>.
31
32 If you don't know what Access Control Lists are, say N
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index 91fba025fcbe..f8ba37effd1b 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_9P_FS) := 9p.o
13 xattr_user.o 13 xattr_user.o
14 14
159p-$(CONFIG_9P_FSCACHE) += cache.o 159p-$(CONFIG_9P_FSCACHE) += cache.o
169p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
new file mode 100644
index 000000000000..a8c013615a22
--- /dev/null
+++ b/fs/9p/acl.c
@@ -0,0 +1,96 @@
1/*
2 * Copyright IBM Corporation, 2010
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/fs.h>
17#include <net/9p/9p.h>
18#include <net/9p/client.h>
19#include <linux/slab.h>
20#include <linux/posix_acl_xattr.h>
21#include "xattr.h"
22#include "acl.h"
23
24static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
25{
26 ssize_t size;
27 void *value = NULL;
28 struct posix_acl *acl = NULL;;
29
30 size = v9fs_fid_xattr_get(fid, name, NULL, 0);
31 if (size > 0) {
32 value = kzalloc(size, GFP_NOFS);
33 if (!value)
34 return ERR_PTR(-ENOMEM);
35 size = v9fs_fid_xattr_get(fid, name, value, size);
36 if (size > 0) {
37 acl = posix_acl_from_xattr(value, size);
38 if (IS_ERR(acl))
39 goto err_out;
40 }
41 } else if (size == -ENODATA || size == 0 ||
42 size == -ENOSYS || size == -EOPNOTSUPP) {
43 acl = NULL;
44 } else
45 acl = ERR_PTR(-EIO);
46
47err_out:
48 kfree(value);
49 return acl;
50}
51
52int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
53{
54 int retval = 0;
55 struct posix_acl *pacl, *dacl;
56
57 /* get the default/access acl values and cache them */
58 dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT);
59 pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS);
60
61 if (!IS_ERR(dacl) && !IS_ERR(pacl)) {
62 set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
63 set_cached_acl(inode, ACL_TYPE_ACCESS, pacl);
64 posix_acl_release(dacl);
65 posix_acl_release(pacl);
66 } else
67 retval = -EIO;
68
69 return retval;
70}
71
72static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
73{
74 struct posix_acl *acl;
75 /*
76 * 9p Always cache the acl value when
77 * instantiating the inode (v9fs_inode_from_fid)
78 */
79 acl = get_cached_acl(inode, type);
80 BUG_ON(acl == ACL_NOT_CACHED);
81 return acl;
82}
83
84int v9fs_check_acl(struct inode *inode, int mask)
85{
86 struct posix_acl *acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
87
88 if (IS_ERR(acl))
89 return PTR_ERR(acl);
90 if (acl) {
91 int error = posix_acl_permission(inode, acl, mask);
92 posix_acl_release(acl);
93 return error;
94 }
95 return -EAGAIN;
96}
diff --git a/fs/9p/acl.h b/fs/9p/acl.h
new file mode 100644
index 000000000000..b1414f7c82e0
--- /dev/null
+++ b/fs/9p/acl.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright IBM Corporation, 2010
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14#ifndef FS_9P_ACL_H
15#define FS_9P_ACL_H
16
17#ifdef CONFIG_9P_FS_POSIX_ACL
18extern int v9fs_get_acl(struct inode *, struct p9_fid *);
19extern int v9fs_check_acl(struct inode *inode, int mask);
20#else
21#define v9fs_check_acl NULL
22static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
23{
24 return 0;
25}
26#endif
27#endif /* FS_9P_XATTR_H */
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index c3d200d41dca..1249b8323961 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -36,6 +36,7 @@
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/xattr.h> 38#include <linux/xattr.h>
39#include <linux/posix_acl.h>
39#include <net/9p/9p.h> 40#include <net/9p/9p.h>
40#include <net/9p/client.h> 41#include <net/9p/client.h>
41 42
@@ -44,6 +45,7 @@
44#include "fid.h" 45#include "fid.h"
45#include "cache.h" 46#include "cache.h"
46#include "xattr.h" 47#include "xattr.h"
48#include "acl.h"
47 49
48static const struct inode_operations v9fs_dir_inode_operations; 50static const struct inode_operations v9fs_dir_inode_operations;
49static const struct inode_operations v9fs_dir_inode_operations_dotu; 51static const struct inode_operations v9fs_dir_inode_operations_dotu;
@@ -500,6 +502,11 @@ v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
500 v9fs_vcookie_set_qid(ret, &st->qid); 502 v9fs_vcookie_set_qid(ret, &st->qid);
501 v9fs_cache_inode_get_cookie(ret); 503 v9fs_cache_inode_get_cookie(ret);
502#endif 504#endif
505 err = v9fs_get_acl(ret, fid);
506 if (err) {
507 iput(ret);
508 goto error;
509 }
503 kfree(st); 510 kfree(st);
504 return ret; 511 return ret;
505error: 512error:
@@ -1959,7 +1966,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
1959 .getxattr = generic_getxattr, 1966 .getxattr = generic_getxattr,
1960 .removexattr = generic_removexattr, 1967 .removexattr = generic_removexattr,
1961 .listxattr = v9fs_listxattr, 1968 .listxattr = v9fs_listxattr,
1962 1969 .check_acl = v9fs_check_acl,
1963}; 1970};
1964 1971
1965static const struct inode_operations v9fs_dir_inode_operations = { 1972static const struct inode_operations v9fs_dir_inode_operations = {
@@ -1986,6 +1993,7 @@ static const struct inode_operations v9fs_file_inode_operations_dotl = {
1986 .getxattr = generic_getxattr, 1993 .getxattr = generic_getxattr,
1987 .removexattr = generic_removexattr, 1994 .removexattr = generic_removexattr,
1988 .listxattr = v9fs_listxattr, 1995 .listxattr = v9fs_listxattr,
1996 .check_acl = v9fs_check_acl,
1989}; 1997};
1990 1998
1991static const struct inode_operations v9fs_symlink_inode_operations = { 1999static const struct inode_operations v9fs_symlink_inode_operations = {
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 1d12ba0ed3db..14da5778d44e 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -46,6 +46,7 @@
46#include "v9fs_vfs.h" 46#include "v9fs_vfs.h"
47#include "fid.h" 47#include "fid.h"
48#include "xattr.h" 48#include "xattr.h"
49#include "acl.h"
49 50
50static const struct super_operations v9fs_super_ops, v9fs_super_ops_dotl; 51static const struct super_operations v9fs_super_ops, v9fs_super_ops_dotl;
51 52
@@ -88,6 +89,10 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
88 sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | 89 sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
89 MS_NOATIME; 90 MS_NOATIME;
90 91
92#ifdef CONFIG_9P_FS_POSIX_ACL
93 sb->s_flags |= MS_POSIXACL;
94#endif
95
91 save_mount_options(sb, data); 96 save_mount_options(sb, data);
92} 97}
93 98
@@ -149,7 +154,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
149 goto release_sb; 154 goto release_sb;
150 } 155 }
151 sb->s_root = root; 156 sb->s_root = root;
152
153 if (v9fs_proto_dotl(v9ses)) { 157 if (v9fs_proto_dotl(v9ses)) {
154 struct p9_stat_dotl *st = NULL; 158 struct p9_stat_dotl *st = NULL;
155 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 159 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
@@ -174,6 +178,9 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
174 p9stat_free(st); 178 p9stat_free(st);
175 kfree(st); 179 kfree(st);
176 } 180 }
181 retval = v9fs_get_acl(inode, fid);
182 if (retval)
183 goto release_sb;
177 184
178 v9fs_fid_add(root, fid); 185 v9fs_fid_add(root, fid);
179 186
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index f88e5c2dc873..67ac6cfc1a07 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -21,30 +21,13 @@
21#include "fid.h" 21#include "fid.h"
22#include "xattr.h" 22#include "xattr.h"
23 23
24/* 24ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
25 * v9fs_xattr_get() 25 void *buffer, size_t buffer_size)
26 *
27 * Copy an extended attribute into the buffer
28 * provided, or compute the buffer size required.
29 * Buffer is NULL to compute the size of the buffer required.
30 *
31 * Returns a negative error number on failure, or the number of bytes
32 * used / required on success.
33 */
34ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
35 void *buffer, size_t buffer_size)
36{ 26{
37 ssize_t retval; 27 ssize_t retval;
38 int msize, read_count; 28 int msize, read_count;
39 u64 offset = 0, attr_size; 29 u64 offset = 0, attr_size;
40 struct p9_fid *fid, *attr_fid; 30 struct p9_fid *attr_fid;
41
42 P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu\n",
43 __func__, name, buffer_size);
44
45 fid = v9fs_fid_lookup(dentry);
46 if (IS_ERR(fid))
47 return PTR_ERR(fid);
48 31
49 attr_fid = p9_client_xattrwalk(fid, name, &attr_size); 32 attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
50 if (IS_ERR(attr_fid)) { 33 if (IS_ERR(attr_fid)) {
@@ -88,6 +71,31 @@ error:
88 71
89} 72}
90 73
74
75/*
76 * v9fs_xattr_get()
77 *
78 * Copy an extended attribute into the buffer
79 * provided, or compute the buffer size required.
80 * Buffer is NULL to compute the size of the buffer required.
81 *
82 * Returns a negative error number on failure, or the number of bytes
83 * used / required on success.
84 */
85ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
86 void *buffer, size_t buffer_size)
87{
88 struct p9_fid *fid;
89
90 P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu\n",
91 __func__, name, buffer_size);
92 fid = v9fs_fid_lookup(dentry);
93 if (IS_ERR(fid))
94 return PTR_ERR(fid);
95
96 return v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
97}
98
91/* 99/*
92 * v9fs_xattr_set() 100 * v9fs_xattr_set()
93 * 101 *
diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h
index 9ddf672ae5c4..ec908c693342 100644
--- a/fs/9p/xattr.h
+++ b/fs/9p/xattr.h
@@ -15,10 +15,14 @@
15#define FS_9P_XATTR_H 15#define FS_9P_XATTR_H
16 16
17#include <linux/xattr.h> 17#include <linux/xattr.h>
18#include <net/9p/9p.h>
19#include <net/9p/client.h>
18 20
19extern const struct xattr_handler *v9fs_xattr_handlers[]; 21extern const struct xattr_handler *v9fs_xattr_handlers[];
20extern struct xattr_handler v9fs_xattr_user_handler; 22extern struct xattr_handler v9fs_xattr_user_handler;
21 23
24extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
25 void *, size_t);
22extern ssize_t v9fs_xattr_get(struct dentry *, const char *, 26extern ssize_t v9fs_xattr_get(struct dentry *, const char *,
23 void *, size_t); 27 void *, size_t);
24extern int v9fs_xattr_set(struct dentry *, const char *, 28extern int v9fs_xattr_set(struct dentry *, const char *,