All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function
@ 2010-08-26 11:19 Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 2/6] fs/9p: Add xattr callbacks for POSIX ACL Aneesh Kumar K.V
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2010-08-26 11:19 UTC (permalink / raw)
  To: v9fs-developer; +Cc: linux-fsdevel, linux-kernel, Aneesh Kumar K.V

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>
---
 fs/9p/Kconfig     |   13 +++++++
 fs/9p/Makefile    |    1 +
 fs/9p/acl.c       |   95 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/9p/acl.h       |   27 +++++++++++++++
 fs/9p/vfs_inode.c |   11 +++++-
 fs/9p/vfs_super.c |    9 ++++-
 fs/9p/xattr.c     |   48 +++++++++++++++-----------
 fs/9p/xattr.h     |    4 ++
 8 files changed, 185 insertions(+), 23 deletions(-)
 create mode 100644 fs/9p/acl.c
 create mode 100644 fs/9p/acl.h

diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig
index 7952337..7e05114 100644
--- a/fs/9p/Kconfig
+++ b/fs/9p/Kconfig
@@ -17,3 +17,16 @@ config 9P_FSCACHE
 	  Choose Y here to enable persistent, read-only local
 	  caching support for 9p clients using FS-Cache
 
+
+config 9P_FS_POSIX_ACL
+	bool "9P POSIX Access Control Lists"
+	depends on 9P_FS
+	select FS_POSIX_ACL
+	help
+	  POSIX Access Control Lists (ACLs) support permissions for users and
+	  groups beyond the owner/group/world scheme.
+
+	  To learn more about Access Control Lists, visit the POSIX ACLs for
+	  Linux website <http://acl.bestbits.at/>.
+
+	  If you don't know what Access Control Lists are, say N
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index 91fba02..f8ba37e 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_9P_FS) := 9p.o
 	xattr_user.o
 
 9p-$(CONFIG_9P_FSCACHE) += cache.o
+9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
new file mode 100644
index 0000000..5de599b
--- /dev/null
+++ b/fs/9p/acl.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright IBM Corporation, 2010
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <net/9p/9p.h>
+#include <net/9p/client.h>
+#include <linux/slab.h>
+#include <linux/posix_acl_xattr.h>
+#include "xattr.h"
+
+static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
+{
+	ssize_t size;
+	void *value = NULL;
+	struct posix_acl *acl = NULL;;
+
+	size = v9fs_fid_xattr_get(fid, name, NULL, 0);
+	if (size > 0) {
+		value = kzalloc(size, GFP_NOFS);
+		if (!value)
+			return ERR_PTR(-ENOMEM);
+		size = v9fs_fid_xattr_get(fid, name, value, size);
+		if (size > 0) {
+			acl = posix_acl_from_xattr(value, size);
+			if (IS_ERR(acl))
+				goto err_out;
+		}
+	} else if (size == -ENODATA || size == 0 ||
+		   size == -ENOSYS || size == -EOPNOTSUPP) {
+		acl = NULL;
+	} else
+		acl = ERR_PTR(-EIO);
+
+err_out:
+	kfree(value);
+	return acl;
+}
+
+int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
+{
+	int retval = 0;
+	struct posix_acl *pacl, *dacl;
+
+	/* 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);
+
+	if (!IS_ERR(dacl) && !IS_ERR(pacl)) {
+		set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
+		set_cached_acl(inode, ACL_TYPE_ACCESS, pacl);
+		posix_acl_release(dacl);
+		posix_acl_release(pacl);
+	} else
+		retval = -EIO;
+
+	return retval;
+}
+
+static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl;
+	/*
+	 * 9p Always cache the acl value when
+	 * instantiating the inode (v9fs_inode_from_fid)
+	 */
+	acl = get_cached_acl(inode, type);
+	BUG_ON(acl == ACL_NOT_CACHED);
+	return acl;
+}
+
+int v9fs_check_acl(struct inode *inode, int mask)
+{
+	struct posix_acl *acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
+
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl) {
+		int error = posix_acl_permission(inode, acl, mask);
+		posix_acl_release(acl);
+		return error;
+	}
+	return -EAGAIN;
+}
diff --git a/fs/9p/acl.h b/fs/9p/acl.h
new file mode 100644
index 0000000..4c63eb1
--- /dev/null
+++ b/fs/9p/acl.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright IBM Corporation, 2010
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#ifndef FS_9P_ACL_H
+#define FS_9P_ACL_H
+
+#ifdef CONFIG_9P_FS_POSIX_ACL
+extern int v9fs_get_acl(struct inode *, struct p9_fid *);
+extern int v9fs_check_acl(struct inode *inode, int mask);
+#else
+#define v9fs_check_acl NULL
+static inline int v9fs_get_acl(struct inode *, struct p9_fid *)
+{
+	return 0;
+}
+#endif
+#endif /* FS_9P_XATTR_H */
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index b23b6a5..7f0aac1 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -36,6 +36,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/xattr.h>
+#include <linux/posix_acl.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -44,6 +45,7 @@
 #include "fid.h"
 #include "cache.h"
 #include "xattr.h"
+#include "acl.h"
 
 static const struct inode_operations v9fs_dir_inode_operations;
 static const struct inode_operations v9fs_dir_inode_operations_dotu;
@@ -498,6 +500,11 @@ v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 	v9fs_vcookie_set_qid(ret, &st->qid);
 	v9fs_cache_inode_get_cookie(ret);
 #endif
+	err = v9fs_get_acl(ret, fid);
+	if (err) {
+		iput(ret);
+		goto error;
+	}
 	kfree(st);
 	return ret;
 error:
@@ -629,7 +636,6 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
 			goto error;
 		}
 	}
-
 	/* instantiate inode and assign the unopened fid to the dentry */
 	inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
 	if (IS_ERR(inode)) {
@@ -1964,7 +1970,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
 	.getxattr = generic_getxattr,
 	.removexattr = generic_removexattr,
 	.listxattr = v9fs_listxattr,
-
+	.check_acl = v9fs_check_acl,
 };
 
 static const struct inode_operations v9fs_dir_inode_operations = {
@@ -1991,6 +1997,7 @@ static const struct inode_operations v9fs_file_inode_operations_dotl = {
 	.getxattr = generic_getxattr,
 	.removexattr = generic_removexattr,
 	.listxattr = v9fs_listxattr,
+	.check_acl = v9fs_check_acl,
 };
 
 static const struct inode_operations v9fs_symlink_inode_operations = {
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index b222953..a120a48 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -46,6 +46,7 @@
 #include "v9fs_vfs.h"
 #include "fid.h"
 #include "xattr.h"
+#include "acl.h"
 
 static const struct super_operations v9fs_super_ops, v9fs_super_ops_dotl;
 
@@ -88,6 +89,10 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
 	sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
 	    MS_NOATIME;
 
+#ifdef CONFIG_9P_FS_POSIX_ACL
+	sb->s_flags |= MS_POSIXACL;
+#endif
+
 	save_mount_options(sb, data);
 }
 
@@ -149,7 +154,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
 		goto release_sb;
 	}
 	sb->s_root = root;
-
 	if (v9fs_proto_dotl(v9ses)) {
 		struct p9_stat_dotl *st = NULL;
 		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,
 		p9stat_free(st);
 		kfree(st);
 	}
+	retval = v9fs_get_acl(inode, fid);
+	if (retval)
+		goto release_sb;
 
 	v9fs_fid_add(root, fid);
 
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index c434424..a3696c9 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -21,30 +21,13 @@
 #include "fid.h"
 #include "xattr.h"
 
-/*
- * v9fs_xattr_get()
- *
- * Copy an extended attribute into the buffer
- * provided, or compute the buffer size required.
- * Buffer is NULL to compute the size of the buffer required.
- *
- * Returns a negative error number on failure, or the number of bytes
- * used / required on success.
- */
-ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
-		       void *buffer, size_t buffer_size)
+ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
+			   void *buffer, size_t buffer_size)
 {
 	ssize_t retval;
 	int msize, read_count;
 	u64 offset = 0, attr_size;
-	struct p9_fid *fid, *attr_fid;
-
-	P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu\n",
-		__func__, name, buffer_size);
-
-	fid = v9fs_fid_lookup(dentry);
-	if (IS_ERR(fid))
-		return PTR_ERR(fid);
+	struct p9_fid *attr_fid;
 
 	attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
 	if (IS_ERR(attr_fid)) {
@@ -88,6 +71,31 @@ error:
 
 }
 
+
+/*
+ * v9fs_xattr_get()
+ *
+ * Copy an extended attribute into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
+		       void *buffer, size_t buffer_size)
+{
+	struct p9_fid *fid;
+
+	P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu\n",
+		__func__, name, buffer_size);
+	fid = v9fs_fid_lookup(dentry);
+	if (IS_ERR(fid))
+		return PTR_ERR(fid);
+
+	return v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
+}
+
 /*
  * v9fs_xattr_set()
  *
diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h
index 9ddf672..ec908c6 100644
--- a/fs/9p/xattr.h
+++ b/fs/9p/xattr.h
@@ -15,10 +15,14 @@
 #define FS_9P_XATTR_H
 
 #include <linux/xattr.h>
+#include <net/9p/9p.h>
+#include <net/9p/client.h>
 
 extern const struct xattr_handler *v9fs_xattr_handlers[];
 extern struct xattr_handler v9fs_xattr_user_handler;
 
+extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
+				  void *, size_t);
 extern ssize_t v9fs_xattr_get(struct dentry *, const char *,
 			      void *, size_t);
 extern int v9fs_xattr_set(struct dentry *, const char *,
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH -V2 2/6] fs/9p: Add xattr callbacks for POSIX ACL
  2010-08-26 11:19 [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function Aneesh Kumar K.V
@ 2010-08-26 11:19 ` Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 3/6] fs/9p: Implement setting posix acl Aneesh Kumar K.V
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2010-08-26 11:19 UTC (permalink / raw)
  To: v9fs-developer; +Cc: linux-fsdevel, linux-kernel, Aneesh Kumar K.V

This patch implement fetching POSIX ACL from the server

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/9p/acl.c   |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/9p/xattr.c |    4 +++
 fs/9p/xattr.h |    2 +
 3 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 5de599b..e122e63 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -93,3 +93,66 @@ int v9fs_check_acl(struct inode *inode, int mask)
 	}
 	return -EAGAIN;
 }
+
+static size_t v9fs_xattr_list_acl_access(struct dentry *dentry, char *list,
+					 size_t list_len, const char *name,
+					 size_t name_len, int type)
+{
+	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
+	if (list && size <= list_len)
+		memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
+	return size;
+}
+
+static size_t v9fs_xattr_list_acl_default(struct dentry *dentry, char *list,
+					  size_t list_len, const char *name,
+					  size_t name_len, int type)
+{
+	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
+	if (list && size <= list_len)
+		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
+	return size;
+}
+
+static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
+			      void *buffer, size_t size, int type)
+{
+	struct posix_acl *acl;
+	int error;
+
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+
+	acl = v9fs_get_cached_acl(dentry->d_inode, type);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl == NULL)
+		return -ENODATA;
+	error = posix_acl_to_xattr(acl, buffer, size);
+	posix_acl_release(acl);
+
+	return error;
+}
+
+static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
+			      const void *value, size_t size,
+			      int flags, int type)
+{
+	return 0;
+}
+
+const struct xattr_handler v9fs_xattr_acl_access_handler = {
+	.prefix	= POSIX_ACL_XATTR_ACCESS,
+	.flags	= ACL_TYPE_ACCESS,
+	.list	= v9fs_xattr_list_acl_access,
+	.get	= v9fs_xattr_get_acl,
+	.set	= v9fs_xattr_set_acl,
+};
+
+const struct xattr_handler v9fs_xattr_acl_default_handler = {
+	.prefix	= POSIX_ACL_XATTR_DEFAULT,
+	.flags	= ACL_TYPE_DEFAULT,
+	.list	= v9fs_xattr_list_acl_default,
+	.get	= v9fs_xattr_get_acl,
+	.set	= v9fs_xattr_set_acl,
+};
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c
index a3696c9..a9ff0ca 100644
--- a/fs/9p/xattr.c
+++ b/fs/9p/xattr.c
@@ -164,5 +164,9 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
 
 const struct xattr_handler *v9fs_xattr_handlers[] = {
 	&v9fs_xattr_user_handler,
+#ifdef CONFIG_9P_FS_POSIX_ACL
+	&v9fs_xattr_acl_access_handler,
+	&v9fs_xattr_acl_default_handler,
+#endif
 	NULL
 };
diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h
index ec908c6..eaa837c 100644
--- a/fs/9p/xattr.h
+++ b/fs/9p/xattr.h
@@ -20,6 +20,8 @@
 
 extern const struct xattr_handler *v9fs_xattr_handlers[];
 extern struct xattr_handler v9fs_xattr_user_handler;
+extern const struct xattr_handler v9fs_xattr_acl_access_handler;
+extern const struct xattr_handler v9fs_xattr_acl_default_handler;
 
 extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
 				  void *, size_t);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH -V2 3/6] fs/9p: Implement setting posix acl
  2010-08-26 11:19 [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 2/6] fs/9p: Add xattr callbacks for POSIX ACL Aneesh Kumar K.V
@ 2010-08-26 11:19 ` Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 4/6] fs/9p: Update ACL on chmod Aneesh Kumar K.V
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2010-08-26 11:19 UTC (permalink / raw)
  To: v9fs-developer; +Cc: linux-fsdevel, linux-kernel, Aneesh Kumar K.V

This patch also update mode bits, as a normal file system.
I am not sure wether we should do that, considering that
a setxattr on the server will again update the ACL/mode value

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/9p/acl.c       |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/9p/v9fs_vfs.h  |    1 +
 fs/9p/vfs_inode.c |    2 +-
 3 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index e122e63..fc06467 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -17,8 +17,11 @@
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
 #include <linux/posix_acl_xattr.h>
 #include "xattr.h"
+#include "v9fs_vfs.h"
+
 
 static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
 {
@@ -138,7 +141,77 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
 			      const void *value, size_t size,
 			      int flags, int type)
 {
-	return 0;
+	int retval;
+	struct posix_acl *acl;
+	struct inode *inode = dentry->d_inode;
+
+	if (strcmp(name, "") != 0)
+		return -EINVAL;
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	if (!is_owner_or_cap(inode))
+		return -EPERM;
+	if (value) {
+		/* update the cached acl value */
+		acl = posix_acl_from_xattr(value, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		else if (acl) {
+			retval = posix_acl_valid(acl);
+			if (retval)
+				goto err_out;
+		}
+	} else
+		acl = NULL;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = POSIX_ACL_XATTR_ACCESS;
+		if (acl) {
+			mode_t mode = inode->i_mode;
+			retval = posix_acl_equiv_mode(acl, &mode);
+			if (retval < 0)
+				goto err_out;
+			else {
+				struct iattr iattr;
+				if (retval == 0) {
+					/*
+					 * ACL can be represented
+					 * by the mode bits. So don't
+					 * update ACL.
+					 */
+					acl = NULL;
+					value = NULL;
+					size = 0;
+				}
+				/* Updte the mode bits */
+				iattr.ia_mode = ((mode & S_IALLUGO) |
+						 (inode->i_mode & ~S_IALLUGO));
+				iattr.ia_valid = ATTR_MODE;
+				/* FIXME should we update ctime ?
+				 * What is the following setxattr update the
+				 * mode ?
+				 */
+				v9fs_vfs_setattr_dotl(dentry, &iattr);
+			}
+		}
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = POSIX_ACL_XATTR_DEFAULT;
+		if (!S_ISDIR(inode->i_mode)) {
+			retval = -EINVAL;
+			goto err_out;
+		}
+		break;
+	default:
+		BUG();
+	}
+	retval = v9fs_xattr_set(dentry, name, value, size, flags);
+	if (!retval)
+		set_cached_acl(inode, type, acl);
+err_out:
+	posix_acl_release(acl);
+	return retval;
 }
 
 const struct xattr_handler v9fs_xattr_acl_access_handler = {
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index f47c6bb..6e87de5 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -64,3 +64,4 @@ int v9fs_uflags2omode(int uflags, int extended);
 
 ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
 void v9fs_blank_wstat(struct p9_wstat *wstat);
+int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 7f0aac1..8f5bf6b 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1248,7 +1248,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
  *
  */
 
-static int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
+int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 {
 	int retval;
 	struct v9fs_session_info *v9ses;
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH -V2 4/6] fs/9p: Update ACL on chmod
  2010-08-26 11:19 [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 2/6] fs/9p: Add xattr callbacks for POSIX ACL Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 3/6] fs/9p: Implement setting posix acl Aneesh Kumar K.V
@ 2010-08-26 11:19 ` Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 5/6] fs/9p: Implement create time inheritance Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 6/6] fs/9p: Add access = client option to opt in acl evaluation Aneesh Kumar K.V
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2010-08-26 11:19 UTC (permalink / raw)
  To: v9fs-developer; +Cc: linux-fsdevel, linux-kernel, Aneesh Kumar K.V

We need update the acl value on chmod

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/9p/acl.c       |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/9p/acl.h       |    5 ++++
 fs/9p/vfs_inode.c |    4 +++
 3 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index fc06467..d717487 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -97,6 +97,61 @@ int v9fs_check_acl(struct inode *inode, int mask)
 	return -EAGAIN;
 }
 
+static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl)
+{
+	int retval;
+	char *name;
+	size_t size;
+	void *buffer;
+	struct inode *inode = dentry->d_inode;
+
+	set_cached_acl(inode, type, acl);
+	/* Set a setxattr request to server */
+	size = posix_acl_xattr_size(acl->a_count);
+	buffer = kmalloc(size, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+	retval = posix_acl_to_xattr(acl, buffer, size);
+	if (retval)
+		goto err_free_out;
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = POSIX_ACL_XATTR_ACCESS;
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = POSIX_ACL_XATTR_DEFAULT;
+		break;
+	default:
+		BUG();
+	}
+	retval = v9fs_xattr_set(dentry, name, buffer, size, 0);
+err_free_out:
+	kfree(buffer);
+	return retval;
+}
+
+int v9fs_acl_chmod(struct dentry *dentry)
+{
+	int retval = 0;
+	struct posix_acl *acl, *clone;
+	struct inode *inode = dentry->d_inode;
+
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+	acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
+	if (acl) {
+		clone = posix_acl_clone(acl, GFP_KERNEL);
+		posix_acl_release(acl);
+		if (!clone)
+			return -ENOMEM;
+		retval = posix_acl_chmod_masq(clone, inode->i_mode);
+		if (!retval)
+			retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, clone);
+		posix_acl_release(clone);
+	}
+	return retval;
+}
+
 static size_t v9fs_xattr_list_acl_access(struct dentry *dentry, char *list,
 					 size_t list_len, const char *name,
 					 size_t name_len, int type)
diff --git a/fs/9p/acl.h b/fs/9p/acl.h
index 4c63eb1..2409e17 100644
--- a/fs/9p/acl.h
+++ b/fs/9p/acl.h
@@ -17,11 +17,16 @@
 #ifdef CONFIG_9P_FS_POSIX_ACL
 extern int v9fs_get_acl(struct inode *, struct p9_fid *);
 extern int v9fs_check_acl(struct inode *inode, int mask);
+extern int v9fs_acl_chmod(struct dentry *);
 #else
 #define v9fs_check_acl NULL
 static inline int v9fs_get_acl(struct inode *, struct p9_fid *)
 {
 	return 0;
 }
+static inline int v9fs_acl_chmod(struct dentry *dentry)
+{
+	return 0;
+}
 #endif
 #endif /* FS_9P_XATTR_H */
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 8f5bf6b..6fb80e5 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1238,6 +1238,10 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
 	if (retval >= 0)
 		retval = inode_setattr(dentry->d_inode, iattr);
 
+	if (!retval && (iattr->ia_valid & ATTR_MODE))
+		/* We also want to update ACL when we update mode bits */
+		retval = v9fs_acl_chmod(dentry);
+
 	return retval;
 }
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH -V2 5/6] fs/9p: Implement create time inheritance
  2010-08-26 11:19 [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function Aneesh Kumar K.V
                   ` (2 preceding siblings ...)
  2010-08-26 11:19 ` [PATCH -V2 4/6] fs/9p: Update ACL on chmod Aneesh Kumar K.V
@ 2010-08-26 11:19 ` Aneesh Kumar K.V
  2010-08-26 11:19 ` [PATCH -V2 6/6] fs/9p: Add access = client option to opt in acl evaluation Aneesh Kumar K.V
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2010-08-26 11:19 UTC (permalink / raw)
  To: v9fs-developer; +Cc: linux-fsdevel, linux-kernel, Aneesh Kumar K.V

Inherit default ACL on create

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 fs/9p/acl.c       |   52 +++++++++++++++++++++++++++++++++++++++++
 fs/9p/acl.h       |   16 ++++++++++++
 fs/9p/vfs_inode.c |   67 +++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 126 insertions(+), 9 deletions(-)

diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index d717487..e7982a1 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -152,6 +152,58 @@ int v9fs_acl_chmod(struct dentry *dentry)
 	return retval;
 }
 
+int v9fs_set_create_acl(struct dentry *dentry,
+			struct posix_acl *dpacl, struct posix_acl *pacl)
+{
+	if (dpacl)
+		v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, dpacl);
+	if (pacl)
+		v9fs_set_acl(dentry, ACL_TYPE_ACCESS, pacl);
+	posix_acl_release(dpacl);
+	posix_acl_release(pacl);
+	return 0;
+}
+
+int v9fs_acl_mode(struct inode *dir, mode_t *modep,
+		  struct posix_acl **dpacl, struct posix_acl **pacl)
+{
+	int retval = 0;
+	mode_t mode = *modep;
+	struct posix_acl *acl = NULL;
+
+	if (!S_ISLNK(mode)) {
+		acl = v9fs_get_cached_acl(dir, ACL_TYPE_DEFAULT);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		if (!acl)
+			mode &= ~current_umask();
+	}
+	if (acl) {
+		struct posix_acl *clone;
+
+		if (S_ISDIR(mode))
+			*dpacl = acl;
+		clone = posix_acl_clone(acl, GFP_NOFS);
+		retval = -ENOMEM;
+		if (!clone)
+			goto cleanup;
+
+		retval = posix_acl_create_masq(clone, &mode);
+		if (retval < 0) {
+			posix_acl_release(clone);
+			goto cleanup;
+		}
+		if (retval > 0)
+			*pacl = clone;
+	}
+	*modep  = mode;
+	return 0;
+cleanup:
+	posix_acl_release(acl);
+	return retval;
+
+}
+
 static size_t v9fs_xattr_list_acl_access(struct dentry *dentry, char *list,
 					 size_t list_len, const char *name,
 					 size_t name_len, int type)
diff --git a/fs/9p/acl.h b/fs/9p/acl.h
index 2409e17..3b9d99f 100644
--- a/fs/9p/acl.h
+++ b/fs/9p/acl.h
@@ -18,6 +18,10 @@
 extern int v9fs_get_acl(struct inode *, struct p9_fid *);
 extern int v9fs_check_acl(struct inode *inode, int mask);
 extern int v9fs_acl_chmod(struct dentry *);
+extern int v9fs_set_create_acl(struct dentry *,
+			       struct posix_acl *, struct posix_acl *);
+extern int v9fs_acl_mode(struct inode *dir, mode_t *modep,
+			 struct posix_acl **dpacl, struct posix_acl **pacl);
 #else
 #define v9fs_check_acl NULL
 static inline int v9fs_get_acl(struct inode *, struct p9_fid *)
@@ -28,5 +32,17 @@ static inline int v9fs_acl_chmod(struct dentry *dentry)
 {
 	return 0;
 }
+static inline int v9fs_set_create_acl(struct dentry *,
+				      struct posix_acl *, struct posix_acl *)
+{
+	return 0;
+}
+static inline int v9fs_acl_mode(struct inode *dir, mode_t *modep,
+				struct posix_acl **dpacl,
+				struct posix_acl **pacl)
+{
+	return 0;
+}
+
 #endif
 #endif /* FS_9P_XATTR_H */
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 6fb80e5..3e365f6 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -636,6 +636,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
 			goto error;
 		}
 	}
+
 	/* instantiate inode and assign the unopened fid to the dentry */
 	inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
 	if (IS_ERR(inode)) {
@@ -676,19 +677,21 @@ error:
  */
 
 static int
-v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode,
+v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
 		struct nameidata *nd)
 {
 	int err = 0;
 	char *name = NULL;
 	gid_t gid;
 	int flags;
+	mode_t mode;
 	struct v9fs_session_info *v9ses;
 	struct p9_fid *fid = NULL;
 	struct p9_fid *dfid, *ofid;
 	struct file *filp;
 	struct p9_qid qid;
 	struct inode *inode;
+	struct posix_acl *pacl = NULL, *dacl = NULL;
 
 	v9ses = v9fs_inode2v9ses(dir);
 	if (nd && nd->flags & LOOKUP_OPEN)
@@ -698,7 +701,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode,
 
 	name = (char *) dentry->d_name.name;
 	P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
-			"mode:0x%x\n", name, flags, mode);
+			"mode:0x%x\n", name, flags, omode);
 
 	dfid = v9fs_fid_lookup(dentry->d_parent);
 	if (IS_ERR(dfid)) {
@@ -716,6 +719,15 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode,
 	}
 
 	gid = v9fs_get_fsgid_for_create(dir);
+
+	mode = omode;
+	/* Update mode based on ACL value */
+	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
+	if (err) {
+		P9_DPRINTK(P9_DEBUG_VFS,
+			   "Failed to get acl values in creat %d\n", err);
+		goto error;
+	}
 	err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
 	if (err < 0) {
 		P9_DPRINTK(P9_DEBUG_VFS,
@@ -760,6 +772,9 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode,
 	if (err < 0)
 		goto error;
 
+	/* Now set the ACL based on the default value */
+	v9fs_set_create_acl(dentry, dacl, pacl);
+
 	/* if we are opening a file, assign the open fid to the file */
 	if (nd && nd->flags & LOOKUP_OPEN) {
 		filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created);
@@ -880,23 +895,25 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  *
  */
 
-static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry,
-					int mode)
+static int v9fs_vfs_mkdir_dotl(struct inode *dir,
+			       struct dentry *dentry, int omode)
 {
 	int err;
 	struct v9fs_session_info *v9ses;
 	struct p9_fid *fid = NULL, *dfid = NULL;
 	gid_t gid;
 	char *name;
+	mode_t mode;
 	struct inode *inode;
 	struct p9_qid qid;
 	struct dentry *dir_dentry;
+	struct posix_acl *dacl = NULL, *pacl = NULL;
 
 	P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
 	err = 0;
 	v9ses = v9fs_inode2v9ses(dir);
 
-	mode |= S_IFDIR;
+	omode |= S_IFDIR;
 	dir_dentry = v9fs_dentry_from_dir_inode(dir);
 	dfid = v9fs_fid_lookup(dir_dentry);
 	if (IS_ERR(dfid)) {
@@ -911,7 +928,14 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry,
 		P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n");
 		goto error;
 	}
-
+	mode = omode;
+	/* Update mode based on ACL value */
+	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
+	if (err) {
+		P9_DPRINTK(P9_DEBUG_VFS,
+			   "Failed to get acl values in mkdir %d\n", err);
+		goto error;
+	}
 	name = (char *) dentry->d_name.name;
 	err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
 	if (err < 0)
@@ -941,7 +965,23 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry,
 		if (err < 0)
 			goto error;
 		fid = NULL;
+	} else {
+		/*
+		 * Not in cached mode. No need to populate
+		 * inode with stat. We need to get an inode
+		 * so that we can set the acl with dentry
+		 */
+		inode = v9fs_get_inode(dir->i_sb, mode);
+		if (IS_ERR(inode)) {
+			err = PTR_ERR(inode);
+			goto error;
+		}
+		dentry->d_op = &v9fs_dentry_operations;
+		d_instantiate(dentry, inode);
 	}
+	/* Now set the ACL based on the default value */
+	v9fs_set_create_acl(dentry, dacl, pacl);
+
 error:
 	if (fid)
 		p9_client_clunk(fid);
@@ -1859,21 +1899,23 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
  *
  */
 static int
-v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode,
+v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
 		dev_t rdev)
 {
 	int err;
 	char *name;
+	mode_t mode;
 	struct v9fs_session_info *v9ses;
 	struct p9_fid *fid = NULL, *dfid = NULL;
 	struct inode *inode;
 	gid_t gid;
 	struct p9_qid qid;
 	struct dentry *dir_dentry;
+	struct posix_acl *dacl = NULL, *pacl = NULL;
 
 	P9_DPRINTK(P9_DEBUG_VFS,
 		" %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
-		dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
+		dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
 
 	if (!new_valid_dev(rdev))
 		return -EINVAL;
@@ -1893,7 +1935,14 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode,
 		P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n");
 		goto error;
 	}
-
+	mode = omode;
+	/* Update mode based on ACL value */
+	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
+	if (err) {
+		P9_DPRINTK(P9_DEBUG_VFS,
+			   "Failed to get acl values in mknod %d\n", err);
+		goto error;
+	}
 	name = (char *) dentry->d_name.name;
 
 	err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH -V2 6/6] fs/9p: Add access = client option to opt in acl evaluation.
  2010-08-26 11:19 [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function Aneesh Kumar K.V
                   ` (3 preceding siblings ...)
  2010-08-26 11:19 ` [PATCH -V2 5/6] fs/9p: Implement create time inheritance Aneesh Kumar K.V
@ 2010-08-26 11:19 ` Aneesh Kumar K.V
  4 siblings, 0 replies; 6+ messages in thread
From: Aneesh Kumar K.V @ 2010-08-26 11:19 UTC (permalink / raw)
  To: v9fs-developer; +Cc: linux-fsdevel, linux-kernel, Aneesh Kumar K.V

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 Documentation/filesystems/9p.txt |    4 +++-
 fs/9p/acl.c                      |   37 ++++++++++++++++++++++++++++++++++++-
 fs/9p/fid.c                      |    1 +
 fs/9p/v9fs.c                     |   12 ++++++++++++
 fs/9p/v9fs.h                     |    8 ++++++--
 fs/9p/vfs_inode.c                |   14 ++++++++++----
 fs/9p/vfs_super.c                |   16 +++++++++++-----
 7 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index c0236e7..1a48155 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -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.
@@ -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
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index e7982a1..96fa9fc 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -21,6 +21,7 @@
 #include <linux/posix_acl_xattr.h>
 #include "xattr.h"
 #include "v9fs_vfs.h"
+#include "v9fs.h"
 
 
 static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
@@ -85,7 +86,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);
@@ -208,7 +220,13 @@ static size_t v9fs_xattr_list_acl_access(struct dentry *dentry, char *list,
 					 size_t list_len, const char *name,
 					 size_t name_len, int type)
 {
+	struct v9fs_session_info *v9ses;
 	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
+
+	v9ses = v9fs_inode2v9ses(dentry->d_inode);
+	if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
+		return 0;
+
 	if (list && size <= list_len)
 		memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
 	return size;
@@ -218,7 +236,13 @@ static size_t v9fs_xattr_list_acl_default(struct dentry *dentry, char *list,
 					  size_t list_len, const char *name,
 					  size_t name_len, int type)
 {
+	struct v9fs_session_info *v9ses;
 	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
+
+	v9ses = v9fs_inode2v9ses(dentry->d_inode);
+	if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
+		return 0;
+
 	if (list && size <= list_len)
 		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
 	return size;
@@ -227,12 +251,17 @@ static size_t v9fs_xattr_list_acl_default(struct dentry *dentry, char *list,
 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);
+	if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
+		return -EOPNOTSUPP;
+
 	acl = v9fs_get_cached_acl(dentry->d_inode, type);
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
@@ -250,10 +279,16 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
 {
 	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);
+	if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
+		return -EOPNOTSUPP;
+
 	if (S_ISLNK(inode->i_mode))
 		return -EOPNOTSUPP;
 	if (!is_owner_or_cap(inode))
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 3585636..4876a0e 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -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;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 38dc0e0..735ff25 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -193,6 +193,8 @@ 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 if (strcmp(s, "client") == 0)
+				v9ses->flags |= V9FS_ACCESS_CLIENT;
 			else {
 				v9ses->flags |= V9FS_ACCESS_SINGLE;
 				v9ses->uid = simple_strtoul(s, &e, 10);
@@ -278,6 +280,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)) {
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 4c963c9..8bb7792 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -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 */
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 3e365f6..9040db5 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -500,10 +500,16 @@ v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 	v9fs_vcookie_set_qid(ret, &st->qid);
 	v9fs_cache_inode_get_cookie(ret);
 #endif
-	err = v9fs_get_acl(ret, fid);
-	if (err) {
-		iput(ret);
-		goto error;
+	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT) {
+		/*
+		 * On access = client mode get the acl
+		 * values from the server
+		 */
+		err = v9fs_get_acl(ret, fid);
+		if (err) {
+			iput(ret);
+			goto error;
+		}
 	}
 	kfree(st);
 	return ret;
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index a120a48..e15e9ac 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,
 	    MS_NOATIME;
 
 #ifdef CONFIG_9P_FS_POSIX_ACL
-	sb->s_flags |= MS_POSIXACL;
+	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)
+		sb->s_flags |= MS_POSIXACL;
 #endif
 
 	save_mount_options(sb, data);
@@ -178,10 +179,15 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
 		p9stat_free(st);
 		kfree(st);
 	}
-	retval = v9fs_get_acl(inode, fid);
-	if (retval)
-		goto release_sb;
-
+	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT) {
+		/*
+		 * On access = client mode get the acl
+		 * values from the server
+		 */
+		retval = v9fs_get_acl(inode, fid);
+		if (retval)
+			goto release_sb;
+	}
 	v9fs_fid_add(root, fid);
 
 	P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-08-26 11:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-26 11:19 [PATCH -V2 1/6] fs/9p: Implement POSIX ACL permission checking function Aneesh Kumar K.V
2010-08-26 11:19 ` [PATCH -V2 2/6] fs/9p: Add xattr callbacks for POSIX ACL Aneesh Kumar K.V
2010-08-26 11:19 ` [PATCH -V2 3/6] fs/9p: Implement setting posix acl Aneesh Kumar K.V
2010-08-26 11:19 ` [PATCH -V2 4/6] fs/9p: Update ACL on chmod Aneesh Kumar K.V
2010-08-26 11:19 ` [PATCH -V2 5/6] fs/9p: Implement create time inheritance Aneesh Kumar K.V
2010-08-26 11:19 ` [PATCH -V2 6/6] fs/9p: Add access = client option to opt in acl evaluation Aneesh Kumar K.V

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.