All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] UBIFS: add ACL support
@ 2015-03-25 11:46 Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 1/3] UBIFS: xattr: splite generic set/get xattr functions from ubifs_set/getxattr Sheng Yong
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Sheng Yong @ 2015-03-25 11:46 UTC (permalink / raw)
  To: dedekind1, adrian.hunter; +Cc: miaoxie, linux-mtd, hujianyang

UBIFS ACL is based on xattr. Three structures, ubifs_acl_header,
ubifs_acl_entry, and ubifs_acl_entry_short are used to format the ACL
value on flash.

ACL format between in-memory and on-flash is switched before writting
it to flash and after reading it from flash. The writting and reading
operations are implemented by generic set/get xattr functions. ACL of
a new file is inheritted from the parent directory when creating new
inode.

For xattr, generic functions of setting and getting xattr are splited
from original ubifs_setxattr and ubifs_getxattr so that ACL could use
them.

Thanks,
Sheng

Sheng Yong (3):
  UBIFS: xattr: splite generic set/get xattr functions from
    ubifs_set/getxattr
  UBIFS: ACL: add ACL support
  UBIFS: ACL: add ACL config option

 fs/ubifs/Kconfig  |  11 ++
 fs/ubifs/Makefile |   1 +
 fs/ubifs/acl.c    | 316 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ubifs/dir.c    |   7 ++
 fs/ubifs/file.c   |  14 +++
 fs/ubifs/super.c  |  15 +++
 fs/ubifs/ubifs.h  |   7 ++
 fs/ubifs/xattr.c  |  52 +++++++--
 8 files changed, 413 insertions(+), 10 deletions(-)
 create mode 100644 fs/ubifs/acl.c

-- 
1.8.3.4

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

* [RFC PATCH 1/3] UBIFS: xattr: splite generic set/get xattr functions from ubifs_set/getxattr
  2015-03-25 11:46 [RFC PATCH 0/3] UBIFS: add ACL support Sheng Yong
@ 2015-03-25 11:46 ` Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 2/3] UBIFS: ACL: add ACL support Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 3/3] UBIFS: ACL: add ACL config option Sheng Yong
  2 siblings, 0 replies; 5+ messages in thread
From: Sheng Yong @ 2015-03-25 11:46 UTC (permalink / raw)
  To: dedekind1, adrian.hunter; +Cc: miaoxie, linux-mtd, hujianyang

Splite generic set/get xattr functions from ubifs_set/getxattr. Add them
to ubifs.h so that functions outside xattr.c can use them. Because ACL is
implemented based on xattr, this is a preparation for later ACL patchset.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
---
 fs/ubifs/ubifs.h |  2 ++
 fs/ubifs/xattr.c | 25 ++++++++++++++++---------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index bc04b9c..2cb4297 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1758,6 +1758,8 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 int ubifs_removexattr(struct dentry *dentry, const char *name);
 int ubifs_init_security(struct inode *dentry, struct inode *inode,
 			const struct qstr *qstr);
+int __ubifs_setxattr(struct inode *, const char *, const void *, size_t, int);
+ssize_t __ubifs_getxattr(struct inode *, const char *, void *, size_t);
 
 /* super.c */
 struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index a92be24..c11c1f6 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -299,7 +299,7 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
 	return ERR_PTR(-EINVAL);
 }
 
-static int setxattr(struct inode *host, const char *name, const void *value,
+int __ubifs_setxattr(struct inode *host, const char *name, const void *value,
 		    size_t size, int flags)
 {
 	struct inode *inode;
@@ -366,13 +366,13 @@ int ubifs_setxattr(struct dentry *dentry, const char *name,
 	dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
 		name, dentry->d_inode->i_ino, dentry, size);
 
-	return setxattr(dentry->d_inode, name, value, size, flags);
+	return __ubifs_setxattr(dentry->d_inode, name, value, size, flags);
 }
 
-ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
-		       size_t size)
+ssize_t __ubifs_getxattr(struct inode *host, const char *name, void *buf,
+			size_t size)
 {
-	struct inode *inode, *host = dentry->d_inode;
+	struct inode *inode;
 	struct ubifs_info *c = host->i_sb->s_fs_info;
 	struct qstr nm = QSTR_INIT(name, strlen(name));
 	struct ubifs_inode *ui;
@@ -380,9 +380,6 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
 	union ubifs_key key;
 	int err;
 
-	dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
-		host->i_ino, dentry, size);
-
 	err = check_namespace(&nm);
 	if (err < 0)
 		return err;
@@ -429,6 +426,15 @@ out_unlock:
 	return err;
 }
 
+ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
+		       size_t size)
+{
+	dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
+		dentry->d_inode->i_ino, dentry, size);
+
+	return __ubifs_getxattr(dentry->d_inode, name, buf, size);
+}
+
 ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 {
 	union ubifs_key key;
@@ -638,7 +644,8 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
 		}
 		strcpy(name, XATTR_SECURITY_PREFIX);
 		strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
-		err = setxattr(inode, name, xattr->value, xattr->value_len, 0);
+		err = __ubifs_setxattr(inode, name, xattr->value,
+				       xattr->value_len, 0);
 		kfree(name);
 		if (err < 0)
 			break;
-- 
1.8.3.4

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

* [RFC PATCH 2/3] UBIFS: ACL: add ACL support
  2015-03-25 11:46 [RFC PATCH 0/3] UBIFS: add ACL support Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 1/3] UBIFS: xattr: splite generic set/get xattr functions from ubifs_set/getxattr Sheng Yong
@ 2015-03-25 11:46 ` Sheng Yong
  2015-04-07  1:14   ` Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 3/3] UBIFS: ACL: add ACL config option Sheng Yong
  2 siblings, 1 reply; 5+ messages in thread
From: Sheng Yong @ 2015-03-25 11:46 UTC (permalink / raw)
  To: dedekind1, adrian.hunter; +Cc: miaoxie, linux-mtd, hujianyang

This implements ACL functionality. ACL is based on xattr.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
---
 fs/ubifs/acl.c   | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ubifs/dir.c   |   7 ++
 fs/ubifs/file.c  |  14 +++
 fs/ubifs/super.c |  15 +++
 fs/ubifs/ubifs.h |   5 +
 fs/ubifs/xattr.c |  27 ++++-
 6 files changed, 383 insertions(+), 1 deletion(-)
 create mode 100644 fs/ubifs/acl.c

diff --git a/fs/ubifs/acl.c b/fs/ubifs/acl.c
new file mode 100644
index 0000000..a4cde8f
--- /dev/null
+++ b/fs/ubifs/acl.c
@@ -0,0 +1,316 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/*
+ * ACL is based on Extended Attribute.
+ */
+
+#include <linux/fs.h>
+#include <linux/xattr.h>
+#include <linux/posix_acl_xattr.h>
+
+#include "ubifs.h"
+
+#define UBIFS_ACL_VERSION	0x0001
+
+struct ubifs_acl_entry {
+	__le16 e_tag;
+	__le16 e_perm;
+	__le32 e_id;
+};
+
+struct ubifs_acl_entry_short {
+	__le16 e_tag;
+	__le16 e_perm;
+};
+
+struct ubifs_acl_header {
+	__le32 a_version;
+};
+
+#define UBIFS_ACL_HEADER_SZ		sizeof(struct ubifs_acl_header)
+#define UBIFS_ACL_ENTRY_SZ		sizeof(struct ubifs_acl_entry)
+#define UBIFS_ACL_ENTRY_SHORT_SZ	sizeof(struct ubifs_acl_entry_short)
+
+static inline size_t acl_size(int count)
+{
+	if (count <= 4) {
+		return UBIFS_ACL_HEADER_SZ +
+			count * UBIFS_ACL_ENTRY_SHORT_SZ;
+	} else {
+		return UBIFS_ACL_HEADER_SZ +
+			4 * UBIFS_ACL_ENTRY_SHORT_SZ +
+			(count - 4) * UBIFS_ACL_ENTRY_SZ;
+	}
+}
+
+static inline int acl_count(size_t size)
+{
+	ssize_t s;
+
+	size -= UBIFS_ACL_HEADER_SZ;
+	s = size - 4 * UBIFS_ACL_ENTRY_SHORT_SZ;
+	if (s < 0) {
+		if (size % UBIFS_ACL_ENTRY_SHORT_SZ)
+			return -1;
+		return size / UBIFS_ACL_ENTRY_SHORT_SZ;
+	} else {
+		if (s % UBIFS_ACL_ENTRY_SZ)
+			return -1;
+		return s / UBIFS_ACL_ENTRY_SZ + 4;
+	}
+}
+
+/* convert from in-memory ACL to on-flash ACL */
+static void *acl_to_flash(const struct posix_acl *acl, size_t *size, int type)
+{
+	struct ubifs_acl_header *hdr;
+	struct ubifs_acl_entry *uae;
+	int i;
+
+	*size = acl_size(acl->a_count);
+	hdr = kmalloc(*size, GFP_KERNEL);
+	if (!hdr)
+		return ERR_PTR(-ENOMEM);
+
+	hdr->a_version = cpu_to_le32(UBIFS_ACL_VERSION);
+	uae = (struct ubifs_acl_entry *) (hdr + 1);
+
+	for (i = 0; i < acl->a_count; i++) {
+		const struct posix_acl_entry *ae = &acl->a_entries[i];
+		uae->e_tag = cpu_to_le16(ae->e_tag);
+		uae->e_perm = cpu_to_le16(ae->e_perm);
+		switch (ae->e_tag) {
+		case ACL_USER_OBJ:
+		case ACL_GROUP_OBJ:
+		case ACL_MASK:
+		case ACL_OTHER:
+			/* for the 4 options, id is not used */
+			uae = (struct ubifs_acl_entry *) ((char *) uae +
+						UBIFS_ACL_ENTRY_SHORT_SZ);
+			break;
+		case ACL_USER:
+		{
+			uid_t u = from_kuid(&init_user_ns, ae->e_uid);
+			uae->e_id = cpu_to_le32(u);
+			uae = (struct ubifs_acl_entry *) ((char *) uae +
+						UBIFS_ACL_ENTRY_SZ);
+			break;
+		}
+		case ACL_GROUP:
+		{
+			gid_t g = from_kgid(&init_user_ns, ae->e_gid);
+			uae->e_id = cpu_to_le32(g);
+			uae = (struct ubifs_acl_entry *) ((char *) uae +
+						UBIFS_ACL_ENTRY_SZ);
+			break;
+		}
+		default:
+			goto fail;
+		}
+	}
+
+	return (void *) hdr;
+
+fail:
+	kfree(hdr);
+	return ERR_PTR(-EINVAL);
+}
+
+/* convert from on-flash ACL to in-memory ACL */
+static struct posix_acl *acl_from_flash(const void *value, size_t size)
+{
+	struct posix_acl *acl;
+	struct ubifs_acl_header *hdr = (struct ubifs_acl_header *) value;
+	struct ubifs_acl_entry *uae = (struct ubifs_acl_entry *) (hdr + 1);
+	const char *end = value + size;
+	int count, i;
+
+	if (!value)
+		return NULL;
+	if (size < UBIFS_ACL_HEADER_SZ)
+		return ERR_PTR(-EINVAL);
+	if (hdr->a_version != cpu_to_le32(UBIFS_ACL_VERSION))
+		return ERR_PTR(-EINVAL);
+
+	count = acl_count(size);
+	if (count < 0)
+		return ERR_PTR(-EINVAL);
+	if (count == 0)
+		return NULL;
+
+	acl = posix_acl_alloc(count, GFP_KERNEL);
+	if (!acl)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < count; i++) {
+		if ((char *) uae > end)
+			goto fail;
+
+		acl->a_entries[i].e_tag = le16_to_cpu(uae->e_tag);
+		acl->a_entries[i].e_perm = le16_to_cpu(uae->e_perm);
+		switch (acl->a_entries[i].e_tag) {
+		case ACL_USER_OBJ:
+		case ACL_GROUP_OBJ:
+		case ACL_MASK:
+		case ACL_OTHER:
+			/* for the 4 options, no id */
+			uae = (struct ubifs_acl_entry *) ((char *) uae +
+						UBIFS_ACL_ENTRY_SHORT_SZ);
+			break;
+		case ACL_USER:
+		{
+			uid_t u = le32_to_cpu(uae->e_id);
+			acl->a_entries[i].e_uid = make_kuid(&init_user_ns, u);
+			uae = (struct ubifs_acl_entry *) ((char *) uae +
+						UBIFS_ACL_ENTRY_SZ);
+			break;
+		}
+		case ACL_GROUP:
+		{
+			gid_t g = le32_to_cpu(uae->e_id);
+			acl->a_entries[i].e_gid = make_kgid(&init_user_ns, g);
+			uae = (struct ubifs_acl_entry *) ((char *) uae +
+						UBIFS_ACL_ENTRY_SZ);
+			break;
+		}
+		default:
+			goto fail;
+		}
+	}
+
+	if ((char *) uae != end)
+		goto fail;
+
+	return acl;
+
+fail:
+	posix_acl_release(acl);
+	return ERR_PTR(-EINVAL);
+}
+
+struct posix_acl *ubifs_get_acl(struct inode *inode, int type)
+{
+	struct posix_acl *acl;
+	char *name, *value = NULL;
+	int size = 0;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = XATTR_NAME_POSIX_ACL_ACCESS;
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = XATTR_NAME_POSIX_ACL_DEFAULT;
+		break;
+	default:
+		BUG();
+	}
+
+	size = __ubifs_getxattr(inode, name, NULL, 0);
+	if (size > 0) {
+		value = kmalloc(size, GFP_KERNEL);
+		if (!value)
+			return ERR_PTR(-ENOMEM);
+		size = __ubifs_getxattr(inode, name, value, size);
+	}
+	if (size > 0)
+		acl = acl_from_flash(value, size);
+	else if (size == -ENODATA)
+		acl = NULL;
+	else if (size < 0)
+		return ERR_PTR(size);
+
+	kfree(value);
+	if (!IS_ERR(acl))
+		set_cached_acl(inode, type, acl);
+
+	return acl;
+}
+
+int ubifs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+	char *name;
+	void *value = NULL;
+	size_t size = 0;
+	int err;
+
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = XATTR_NAME_POSIX_ACL_ACCESS;
+		if (acl) {
+			err = posix_acl_equiv_mode(acl, &inode->i_mode);
+			if (err < 0)
+				return err;
+			if (err == 0)
+				acl = NULL;
+		}
+		break;
+
+	case ACL_TYPE_DEFAULT:
+		name = XATTR_NAME_POSIX_ACL_DEFAULT;
+		if (!S_ISDIR(inode->i_mode))
+			return acl ? -EACCES : 0;
+		break;
+
+	default:
+		BUG();
+	}
+
+	if (acl) {
+		value = acl_to_flash(acl, &size, type);
+		if (IS_ERR(value))
+			return (int) PTR_ERR(value);
+	}
+
+	err = __ubifs_setxattr(inode, name, value, size, 0);
+	kfree(value);
+	if (!err)
+		set_cached_acl(inode, type, acl);
+	return err;
+}
+
+/*
+ * Initialize the ACLs of a new inode.
+ */
+int ubifs_init_acl(struct inode *inode, struct inode *dir)
+{
+	struct posix_acl *default_acl, *acl;
+	int err;
+
+	err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
+	if (err)
+		return err;
+
+	if (default_acl) {
+		mutex_lock(&inode->i_mutex);
+		err = ubifs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+		mutex_unlock(&inode->i_mutex);
+		posix_acl_release(default_acl);
+	}
+
+	if (acl) {
+		if (!err) {
+			mutex_lock(&inode->i_mutex);
+			err = ubifs_set_acl(inode, acl, ACL_TYPE_ACCESS);
+			mutex_unlock(&inode->i_mutex);
+		}
+		posix_acl_release(acl);
+	}
+
+	return err;
+}
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index f7e8f76..d5435dc 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -167,6 +167,9 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
 	 */
 	ui->creat_sqnum = ++c->max_sqnum;
 	spin_unlock(&c->cnt_lock);
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	ubifs_init_acl(inode, (struct inode *) dir);
+#endif
 	return inode;
 }
 
@@ -1186,6 +1189,10 @@ const struct inode_operations ubifs_dir_inode_operations = {
 	.getxattr    = ubifs_getxattr,
 	.listxattr   = ubifs_listxattr,
 	.removexattr = ubifs_removexattr,
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	.get_acl     = ubifs_get_acl,
+	.set_acl     = ubifs_set_acl,
+#endif
 };
 
 const struct file_operations ubifs_dir_operations = {
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 4855abc..1d4e498 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -54,6 +54,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/slab.h>
+#include <linux/posix_acl.h>
 
 static int read_block(struct inode *inode, void *addr, unsigned int block,
 		      struct ubifs_data_node *dn)
@@ -1226,6 +1227,11 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 		truncate_setsize(inode, new_size);
 	}
 
+	if (attr->ia_valid & ATTR_MODE)
+		err = posix_acl_chmod(inode, inode->i_mode);
+	if (err)
+		return err;
+
 	mutex_lock(&ui->ui_mutex);
 	if (attr->ia_valid & ATTR_SIZE) {
 		/* Truncation changes inode [mc]time */
@@ -1567,6 +1573,10 @@ const struct inode_operations ubifs_file_inode_operations = {
 	.getxattr    = ubifs_getxattr,
 	.listxattr   = ubifs_listxattr,
 	.removexattr = ubifs_removexattr,
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	.get_acl     = ubifs_get_acl,
+	.set_acl     = ubifs_set_acl,
+#endif
 };
 
 const struct inode_operations ubifs_symlink_inode_operations = {
@@ -1578,6 +1588,10 @@ const struct inode_operations ubifs_symlink_inode_operations = {
 	.getxattr    = ubifs_getxattr,
 	.listxattr   = ubifs_listxattr,
 	.removexattr = ubifs_removexattr,
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	.get_acl     = ubifs_get_acl,
+	.set_acl     = ubifs_set_acl,
+#endif
 };
 
 const struct file_operations ubifs_file_operations = {
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index e642067..05334e8 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -443,6 +443,9 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
 			   ubifs_compr_name(c->mount_opts.compr_type));
 	}
 
+	if (c->vfs_sb->s_flags & MS_POSIXACL)
+		seq_printf(s, ",acl");
+
 	return 0;
 }
 
@@ -928,6 +931,8 @@ enum {
 	Opt_chk_data_crc,
 	Opt_no_chk_data_crc,
 	Opt_override_compr,
+	Opt_acl,
+	Opt_noacl,
 	Opt_err,
 };
 
@@ -939,6 +944,8 @@ static const match_table_t tokens = {
 	{Opt_chk_data_crc, "chk_data_crc"},
 	{Opt_no_chk_data_crc, "no_chk_data_crc"},
 	{Opt_override_compr, "compr=%s"},
+	{Opt_acl, "acl"},
+	{Opt_noacl, "noacl"},
 	{Opt_err, NULL},
 };
 
@@ -1038,6 +1045,14 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
 			c->default_compr = c->mount_opts.compr_type;
 			break;
 		}
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+		case Opt_acl:
+			c->vfs_sb->s_flags |= MS_POSIXACL;
+			break;
+		case Opt_noacl:
+			c->vfs_sb->s_flags &= ~MS_POSIXACL;
+			break;
+#endif
 		default:
 		{
 			unsigned long flag;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 2cb4297..a72b8bf 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1761,6 +1761,11 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
 int __ubifs_setxattr(struct inode *, const char *, const void *, size_t, int);
 ssize_t __ubifs_getxattr(struct inode *, const char *, void *, size_t);
 
+/* acl.c */
+int ubifs_init_acl(struct inode *inode, struct inode *dir);
+int ubifs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+struct posix_acl *ubifs_get_acl(struct inode *inode, int type);
+
 /* super.c */
 struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
 
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index c11c1f6..2272476 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -52,7 +52,6 @@
  * in the VFS inode cache. The xentries are cached in the LNC cache (see
  * tnc.c).
  *
- * ACL support is not implemented.
  */
 
 #include "ubifs.h"
@@ -78,6 +77,10 @@ enum {
 	USER_XATTR,
 	TRUSTED_XATTR,
 	SECURITY_XATTR,
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	POSIX_ACL_DEFAULT,
+	POSIX_ACL_ACCESS,
+#endif
 };
 
 static const struct inode_operations empty_iops;
@@ -276,6 +279,18 @@ static int check_namespace(const struct qstr *nm)
 		if (nm->name[sizeof(XATTR_SECURITY_PREFIX) - 1] == '\0')
 			return -EINVAL;
 		type = SECURITY_XATTR;
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	} else if (!strncmp(nm->name, XATTR_NAME_POSIX_ACL_DEFAULT,
+			    sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
+		if (nm->name[sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1] != '\0')
+			return -EINVAL;
+		type = POSIX_ACL_DEFAULT;
+	} else if (!strncmp(nm->name, XATTR_NAME_POSIX_ACL_ACCESS,
+			    sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1)) {
+		if (nm->name[sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1] != '\0')
+			return -EINVAL;
+		type = POSIX_ACL_ACCESS;
+#endif
 	} else
 		return -EOPNOTSUPP;
 
@@ -366,6 +381,9 @@ int ubifs_setxattr(struct dentry *dentry, const char *name,
 	dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
 		name, dentry->d_inode->i_ino, dentry, size);
 
+	if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
+		return generic_setxattr(dentry, name, value, size, flags);
+
 	return __ubifs_setxattr(dentry->d_inode, name, value, size, flags);
 }
 
@@ -432,6 +450,9 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
 	dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
 		dentry->d_inode->i_ino, dentry, size);
 
+	if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
+		return generic_getxattr(dentry, name, buf, size);
+
 	return __ubifs_getxattr(dentry->d_inode, name, buf, size);
 }
 
@@ -625,6 +646,10 @@ static const struct xattr_handler ubifs_xattr_security_handler = {
 
 const struct xattr_handler *ubifs_xattr_handlers[] = {
 	&ubifs_xattr_security_handler,
+#ifdef CONFIG_UBIFS_FS_POSIX_ACL
+	&posix_acl_access_xattr_handler,
+	&posix_acl_default_xattr_handler,
+#endif
 	NULL,
 };
 
-- 
1.8.3.4

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

* [RFC PATCH 3/3] UBIFS: ACL: add ACL config option
  2015-03-25 11:46 [RFC PATCH 0/3] UBIFS: add ACL support Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 1/3] UBIFS: xattr: splite generic set/get xattr functions from ubifs_set/getxattr Sheng Yong
  2015-03-25 11:46 ` [RFC PATCH 2/3] UBIFS: ACL: add ACL support Sheng Yong
@ 2015-03-25 11:46 ` Sheng Yong
  2 siblings, 0 replies; 5+ messages in thread
From: Sheng Yong @ 2015-03-25 11:46 UTC (permalink / raw)
  To: dedekind1, adrian.hunter; +Cc: miaoxie, linux-mtd, hujianyang

Add CONFIG_UBIFS_FS_POSIX_ACL to select ACL for UBIFS.

Signed-off-by: Sheng Yong <shengyong1@huawei.com>
---
 fs/ubifs/Kconfig  | 11 +++++++++++
 fs/ubifs/Makefile |  1 +
 2 files changed, 12 insertions(+)

diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index ba66d50..3ca8e8d 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -35,3 +35,14 @@ config UBIFS_FS_ZLIB
 	default y
 	help
 	  Zlib compresses better than LZO but it is slower. Say 'Y' if unsure.
+
+config UBIFS_FS_POSIX_ACL
+	bool "UBIFS POSIX Access Control Lists"
+	depends on UBIFS_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/>.
diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 2c6f0cb..ab8aea5 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -4,3 +4,4 @@ ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o
 ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
 ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
 ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
+ubifs-$(CONFIG_UBIFS_FS_POSIX_ACL) += acl.o
-- 
1.8.3.4

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

* Re: [RFC PATCH 2/3] UBIFS: ACL: add ACL support
  2015-03-25 11:46 ` [RFC PATCH 2/3] UBIFS: ACL: add ACL support Sheng Yong
@ 2015-04-07  1:14   ` Sheng Yong
  0 siblings, 0 replies; 5+ messages in thread
From: Sheng Yong @ 2015-04-07  1:14 UTC (permalink / raw)
  To: dedekind1, adrian.hunter
  Cc: snijsure, ben.shelton, hujianyang, terry.wilcox, mkl, linux-mtd,
	gratian.crisan

# CCed some people maybe intrested in this :-)

thanks,
Sheng

On 3/25/2015 7:46 PM, Sheng Yong wrote:
> This implements ACL functionality. ACL is based on xattr.
> 
> Signed-off-by: Sheng Yong <shengyong1@huawei.com>
> ---
>  fs/ubifs/acl.c   | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  fs/ubifs/dir.c   |   7 ++
>  fs/ubifs/file.c  |  14 +++
>  fs/ubifs/super.c |  15 +++
>  fs/ubifs/ubifs.h |   5 +
>  fs/ubifs/xattr.c |  27 ++++-
>  6 files changed, 383 insertions(+), 1 deletion(-)
>  create mode 100644 fs/ubifs/acl.c
> 
> diff --git a/fs/ubifs/acl.c b/fs/ubifs/acl.c
> new file mode 100644
> index 0000000..a4cde8f
> --- /dev/null
> +++ b/fs/ubifs/acl.c
> @@ -0,0 +1,316 @@
> +/*
> + * This file is part of UBIFS.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; if not, write to the Free Software Foundation, Inc., 51
> + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +/*
> + * ACL is based on Extended Attribute.
> + */
> +
> +#include <linux/fs.h>
> +#include <linux/xattr.h>
> +#include <linux/posix_acl_xattr.h>
> +
> +#include "ubifs.h"
> +
> +#define UBIFS_ACL_VERSION	0x0001
> +
> +struct ubifs_acl_entry {
> +	__le16 e_tag;
> +	__le16 e_perm;
> +	__le32 e_id;
> +};
> +
> +struct ubifs_acl_entry_short {
> +	__le16 e_tag;
> +	__le16 e_perm;
> +};
> +
> +struct ubifs_acl_header {
> +	__le32 a_version;
> +};
> +
> +#define UBIFS_ACL_HEADER_SZ		sizeof(struct ubifs_acl_header)
> +#define UBIFS_ACL_ENTRY_SZ		sizeof(struct ubifs_acl_entry)
> +#define UBIFS_ACL_ENTRY_SHORT_SZ	sizeof(struct ubifs_acl_entry_short)
> +
> +static inline size_t acl_size(int count)
> +{
> +	if (count <= 4) {
> +		return UBIFS_ACL_HEADER_SZ +
> +			count * UBIFS_ACL_ENTRY_SHORT_SZ;
> +	} else {
> +		return UBIFS_ACL_HEADER_SZ +
> +			4 * UBIFS_ACL_ENTRY_SHORT_SZ +
> +			(count - 4) * UBIFS_ACL_ENTRY_SZ;
> +	}
> +}
> +
> +static inline int acl_count(size_t size)
> +{
> +	ssize_t s;
> +
> +	size -= UBIFS_ACL_HEADER_SZ;
> +	s = size - 4 * UBIFS_ACL_ENTRY_SHORT_SZ;
> +	if (s < 0) {
> +		if (size % UBIFS_ACL_ENTRY_SHORT_SZ)
> +			return -1;
> +		return size / UBIFS_ACL_ENTRY_SHORT_SZ;
> +	} else {
> +		if (s % UBIFS_ACL_ENTRY_SZ)
> +			return -1;
> +		return s / UBIFS_ACL_ENTRY_SZ + 4;
> +	}
> +}
> +
> +/* convert from in-memory ACL to on-flash ACL */
> +static void *acl_to_flash(const struct posix_acl *acl, size_t *size, int type)
> +{
> +	struct ubifs_acl_header *hdr;
> +	struct ubifs_acl_entry *uae;
> +	int i;
> +
> +	*size = acl_size(acl->a_count);
> +	hdr = kmalloc(*size, GFP_KERNEL);
> +	if (!hdr)
> +		return ERR_PTR(-ENOMEM);
> +
> +	hdr->a_version = cpu_to_le32(UBIFS_ACL_VERSION);
> +	uae = (struct ubifs_acl_entry *) (hdr + 1);
> +
> +	for (i = 0; i < acl->a_count; i++) {
> +		const struct posix_acl_entry *ae = &acl->a_entries[i];
> +		uae->e_tag = cpu_to_le16(ae->e_tag);
> +		uae->e_perm = cpu_to_le16(ae->e_perm);
> +		switch (ae->e_tag) {
> +		case ACL_USER_OBJ:
> +		case ACL_GROUP_OBJ:
> +		case ACL_MASK:
> +		case ACL_OTHER:
> +			/* for the 4 options, id is not used */
> +			uae = (struct ubifs_acl_entry *) ((char *) uae +
> +						UBIFS_ACL_ENTRY_SHORT_SZ);
> +			break;
> +		case ACL_USER:
> +		{
> +			uid_t u = from_kuid(&init_user_ns, ae->e_uid);
> +			uae->e_id = cpu_to_le32(u);
> +			uae = (struct ubifs_acl_entry *) ((char *) uae +
> +						UBIFS_ACL_ENTRY_SZ);
> +			break;
> +		}
> +		case ACL_GROUP:
> +		{
> +			gid_t g = from_kgid(&init_user_ns, ae->e_gid);
> +			uae->e_id = cpu_to_le32(g);
> +			uae = (struct ubifs_acl_entry *) ((char *) uae +
> +						UBIFS_ACL_ENTRY_SZ);
> +			break;
> +		}
> +		default:
> +			goto fail;
> +		}
> +	}
> +
> +	return (void *) hdr;
> +
> +fail:
> +	kfree(hdr);
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +/* convert from on-flash ACL to in-memory ACL */
> +static struct posix_acl *acl_from_flash(const void *value, size_t size)
> +{
> +	struct posix_acl *acl;
> +	struct ubifs_acl_header *hdr = (struct ubifs_acl_header *) value;
> +	struct ubifs_acl_entry *uae = (struct ubifs_acl_entry *) (hdr + 1);
> +	const char *end = value + size;
> +	int count, i;
> +
> +	if (!value)
> +		return NULL;
> +	if (size < UBIFS_ACL_HEADER_SZ)
> +		return ERR_PTR(-EINVAL);
> +	if (hdr->a_version != cpu_to_le32(UBIFS_ACL_VERSION))
> +		return ERR_PTR(-EINVAL);
> +
> +	count = acl_count(size);
> +	if (count < 0)
> +		return ERR_PTR(-EINVAL);
> +	if (count == 0)
> +		return NULL;
> +
> +	acl = posix_acl_alloc(count, GFP_KERNEL);
> +	if (!acl)
> +		return ERR_PTR(-ENOMEM);
> +
> +	for (i = 0; i < count; i++) {
> +		if ((char *) uae > end)
> +			goto fail;
> +
> +		acl->a_entries[i].e_tag = le16_to_cpu(uae->e_tag);
> +		acl->a_entries[i].e_perm = le16_to_cpu(uae->e_perm);
> +		switch (acl->a_entries[i].e_tag) {
> +		case ACL_USER_OBJ:
> +		case ACL_GROUP_OBJ:
> +		case ACL_MASK:
> +		case ACL_OTHER:
> +			/* for the 4 options, no id */
> +			uae = (struct ubifs_acl_entry *) ((char *) uae +
> +						UBIFS_ACL_ENTRY_SHORT_SZ);
> +			break;
> +		case ACL_USER:
> +		{
> +			uid_t u = le32_to_cpu(uae->e_id);
> +			acl->a_entries[i].e_uid = make_kuid(&init_user_ns, u);
> +			uae = (struct ubifs_acl_entry *) ((char *) uae +
> +						UBIFS_ACL_ENTRY_SZ);
> +			break;
> +		}
> +		case ACL_GROUP:
> +		{
> +			gid_t g = le32_to_cpu(uae->e_id);
> +			acl->a_entries[i].e_gid = make_kgid(&init_user_ns, g);
> +			uae = (struct ubifs_acl_entry *) ((char *) uae +
> +						UBIFS_ACL_ENTRY_SZ);
> +			break;
> +		}
> +		default:
> +			goto fail;
> +		}
> +	}
> +
> +	if ((char *) uae != end)
> +		goto fail;
> +
> +	return acl;
> +
> +fail:
> +	posix_acl_release(acl);
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +struct posix_acl *ubifs_get_acl(struct inode *inode, int type)
> +{
> +	struct posix_acl *acl;
> +	char *name, *value = NULL;
> +	int size = 0;
> +
> +	switch (type) {
> +	case ACL_TYPE_ACCESS:
> +		name = XATTR_NAME_POSIX_ACL_ACCESS;
> +		break;
> +	case ACL_TYPE_DEFAULT:
> +		name = XATTR_NAME_POSIX_ACL_DEFAULT;
> +		break;
> +	default:
> +		BUG();
> +	}
> +
> +	size = __ubifs_getxattr(inode, name, NULL, 0);
> +	if (size > 0) {
> +		value = kmalloc(size, GFP_KERNEL);
> +		if (!value)
> +			return ERR_PTR(-ENOMEM);
> +		size = __ubifs_getxattr(inode, name, value, size);
> +	}
> +	if (size > 0)
> +		acl = acl_from_flash(value, size);
> +	else if (size == -ENODATA)
> +		acl = NULL;
> +	else if (size < 0)
> +		return ERR_PTR(size);
> +
> +	kfree(value);
> +	if (!IS_ERR(acl))
> +		set_cached_acl(inode, type, acl);
> +
> +	return acl;
> +}
> +
> +int ubifs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
> +{
> +	char *name;
> +	void *value = NULL;
> +	size_t size = 0;
> +	int err;
> +
> +	switch (type) {
> +	case ACL_TYPE_ACCESS:
> +		name = XATTR_NAME_POSIX_ACL_ACCESS;
> +		if (acl) {
> +			err = posix_acl_equiv_mode(acl, &inode->i_mode);
> +			if (err < 0)
> +				return err;
> +			if (err == 0)
> +				acl = NULL;
> +		}
> +		break;
> +
> +	case ACL_TYPE_DEFAULT:
> +		name = XATTR_NAME_POSIX_ACL_DEFAULT;
> +		if (!S_ISDIR(inode->i_mode))
> +			return acl ? -EACCES : 0;
> +		break;
> +
> +	default:
> +		BUG();
> +	}
> +
> +	if (acl) {
> +		value = acl_to_flash(acl, &size, type);
> +		if (IS_ERR(value))
> +			return (int) PTR_ERR(value);
> +	}
> +
> +	err = __ubifs_setxattr(inode, name, value, size, 0);
> +	kfree(value);
> +	if (!err)
> +		set_cached_acl(inode, type, acl);
> +	return err;
> +}
> +
> +/*
> + * Initialize the ACLs of a new inode.
> + */
> +int ubifs_init_acl(struct inode *inode, struct inode *dir)
> +{
> +	struct posix_acl *default_acl, *acl;
> +	int err;
> +
> +	err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
> +	if (err)
> +		return err;
> +
> +	if (default_acl) {
> +		mutex_lock(&inode->i_mutex);
> +		err = ubifs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
> +		mutex_unlock(&inode->i_mutex);
> +		posix_acl_release(default_acl);
> +	}
> +
> +	if (acl) {
> +		if (!err) {
> +			mutex_lock(&inode->i_mutex);
> +			err = ubifs_set_acl(inode, acl, ACL_TYPE_ACCESS);
> +			mutex_unlock(&inode->i_mutex);
> +		}
> +		posix_acl_release(acl);
> +	}
> +
> +	return err;
> +}
> diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
> index f7e8f76..d5435dc 100644
> --- a/fs/ubifs/dir.c
> +++ b/fs/ubifs/dir.c
> @@ -167,6 +167,9 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
>  	 */
>  	ui->creat_sqnum = ++c->max_sqnum;
>  	spin_unlock(&c->cnt_lock);
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	ubifs_init_acl(inode, (struct inode *) dir);
> +#endif
>  	return inode;
>  }
>  
> @@ -1186,6 +1189,10 @@ const struct inode_operations ubifs_dir_inode_operations = {
>  	.getxattr    = ubifs_getxattr,
>  	.listxattr   = ubifs_listxattr,
>  	.removexattr = ubifs_removexattr,
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	.get_acl     = ubifs_get_acl,
> +	.set_acl     = ubifs_set_acl,
> +#endif
>  };
>  
>  const struct file_operations ubifs_dir_operations = {
> diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
> index 4855abc..1d4e498 100644
> --- a/fs/ubifs/file.c
> +++ b/fs/ubifs/file.c
> @@ -54,6 +54,7 @@
>  #include <linux/mount.h>
>  #include <linux/namei.h>
>  #include <linux/slab.h>
> +#include <linux/posix_acl.h>
>  
>  static int read_block(struct inode *inode, void *addr, unsigned int block,
>  		      struct ubifs_data_node *dn)
> @@ -1226,6 +1227,11 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
>  		truncate_setsize(inode, new_size);
>  	}
>  
> +	if (attr->ia_valid & ATTR_MODE)
> +		err = posix_acl_chmod(inode, inode->i_mode);
> +	if (err)
> +		return err;
> +
>  	mutex_lock(&ui->ui_mutex);
>  	if (attr->ia_valid & ATTR_SIZE) {
>  		/* Truncation changes inode [mc]time */
> @@ -1567,6 +1573,10 @@ const struct inode_operations ubifs_file_inode_operations = {
>  	.getxattr    = ubifs_getxattr,
>  	.listxattr   = ubifs_listxattr,
>  	.removexattr = ubifs_removexattr,
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	.get_acl     = ubifs_get_acl,
> +	.set_acl     = ubifs_set_acl,
> +#endif
>  };
>  
>  const struct inode_operations ubifs_symlink_inode_operations = {
> @@ -1578,6 +1588,10 @@ const struct inode_operations ubifs_symlink_inode_operations = {
>  	.getxattr    = ubifs_getxattr,
>  	.listxattr   = ubifs_listxattr,
>  	.removexattr = ubifs_removexattr,
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	.get_acl     = ubifs_get_acl,
> +	.set_acl     = ubifs_set_acl,
> +#endif
>  };
>  
>  const struct file_operations ubifs_file_operations = {
> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
> index e642067..05334e8 100644
> --- a/fs/ubifs/super.c
> +++ b/fs/ubifs/super.c
> @@ -443,6 +443,9 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
>  			   ubifs_compr_name(c->mount_opts.compr_type));
>  	}
>  
> +	if (c->vfs_sb->s_flags & MS_POSIXACL)
> +		seq_printf(s, ",acl");
> +
>  	return 0;
>  }
>  
> @@ -928,6 +931,8 @@ enum {
>  	Opt_chk_data_crc,
>  	Opt_no_chk_data_crc,
>  	Opt_override_compr,
> +	Opt_acl,
> +	Opt_noacl,
>  	Opt_err,
>  };
>  
> @@ -939,6 +944,8 @@ static const match_table_t tokens = {
>  	{Opt_chk_data_crc, "chk_data_crc"},
>  	{Opt_no_chk_data_crc, "no_chk_data_crc"},
>  	{Opt_override_compr, "compr=%s"},
> +	{Opt_acl, "acl"},
> +	{Opt_noacl, "noacl"},
>  	{Opt_err, NULL},
>  };
>  
> @@ -1038,6 +1045,14 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
>  			c->default_compr = c->mount_opts.compr_type;
>  			break;
>  		}
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +		case Opt_acl:
> +			c->vfs_sb->s_flags |= MS_POSIXACL;
> +			break;
> +		case Opt_noacl:
> +			c->vfs_sb->s_flags &= ~MS_POSIXACL;
> +			break;
> +#endif
>  		default:
>  		{
>  			unsigned long flag;
> diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
> index 2cb4297..a72b8bf 100644
> --- a/fs/ubifs/ubifs.h
> +++ b/fs/ubifs/ubifs.h
> @@ -1761,6 +1761,11 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
>  int __ubifs_setxattr(struct inode *, const char *, const void *, size_t, int);
>  ssize_t __ubifs_getxattr(struct inode *, const char *, void *, size_t);
>  
> +/* acl.c */
> +int ubifs_init_acl(struct inode *inode, struct inode *dir);
> +int ubifs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
> +struct posix_acl *ubifs_get_acl(struct inode *inode, int type);
> +
>  /* super.c */
>  struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
>  
> diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
> index c11c1f6..2272476 100644
> --- a/fs/ubifs/xattr.c
> +++ b/fs/ubifs/xattr.c
> @@ -52,7 +52,6 @@
>   * in the VFS inode cache. The xentries are cached in the LNC cache (see
>   * tnc.c).
>   *
> - * ACL support is not implemented.
>   */
>  
>  #include "ubifs.h"
> @@ -78,6 +77,10 @@ enum {
>  	USER_XATTR,
>  	TRUSTED_XATTR,
>  	SECURITY_XATTR,
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	POSIX_ACL_DEFAULT,
> +	POSIX_ACL_ACCESS,
> +#endif
>  };
>  
>  static const struct inode_operations empty_iops;
> @@ -276,6 +279,18 @@ static int check_namespace(const struct qstr *nm)
>  		if (nm->name[sizeof(XATTR_SECURITY_PREFIX) - 1] == '\0')
>  			return -EINVAL;
>  		type = SECURITY_XATTR;
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	} else if (!strncmp(nm->name, XATTR_NAME_POSIX_ACL_DEFAULT,
> +			    sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1)) {
> +		if (nm->name[sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1] != '\0')
> +			return -EINVAL;
> +		type = POSIX_ACL_DEFAULT;
> +	} else if (!strncmp(nm->name, XATTR_NAME_POSIX_ACL_ACCESS,
> +			    sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1)) {
> +		if (nm->name[sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1] != '\0')
> +			return -EINVAL;
> +		type = POSIX_ACL_ACCESS;
> +#endif
>  	} else
>  		return -EOPNOTSUPP;
>  
> @@ -366,6 +381,9 @@ int ubifs_setxattr(struct dentry *dentry, const char *name,
>  	dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
>  		name, dentry->d_inode->i_ino, dentry, size);
>  
> +	if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
> +		return generic_setxattr(dentry, name, value, size, flags);
> +
>  	return __ubifs_setxattr(dentry->d_inode, name, value, size, flags);
>  }
>  
> @@ -432,6 +450,9 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
>  	dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
>  		dentry->d_inode->i_ino, dentry, size);
>  
> +	if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
> +		return generic_getxattr(dentry, name, buf, size);
> +
>  	return __ubifs_getxattr(dentry->d_inode, name, buf, size);
>  }
>  
> @@ -625,6 +646,10 @@ static const struct xattr_handler ubifs_xattr_security_handler = {
>  
>  const struct xattr_handler *ubifs_xattr_handlers[] = {
>  	&ubifs_xattr_security_handler,
> +#ifdef CONFIG_UBIFS_FS_POSIX_ACL
> +	&posix_acl_access_xattr_handler,
> +	&posix_acl_default_xattr_handler,
> +#endif
>  	NULL,
>  };
>  
> 

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

end of thread, other threads:[~2015-04-07  1:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-25 11:46 [RFC PATCH 0/3] UBIFS: add ACL support Sheng Yong
2015-03-25 11:46 ` [RFC PATCH 1/3] UBIFS: xattr: splite generic set/get xattr functions from ubifs_set/getxattr Sheng Yong
2015-03-25 11:46 ` [RFC PATCH 2/3] UBIFS: ACL: add ACL support Sheng Yong
2015-04-07  1:14   ` Sheng Yong
2015-03-25 11:46 ` [RFC PATCH 3/3] UBIFS: ACL: add ACL config option Sheng Yong

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.