Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932104AbaD0QRN (ORCPT ); Sun, 27 Apr 2014 12:17:13 -0400 Received: from e23smtp03.au.ibm.com ([202.81.31.145]:35429 "EHLO e23smtp03.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753525AbaD0QQI (ORCPT ); Sun, 27 Apr 2014 12:16:08 -0400 From: "Aneesh Kumar K.V" To: agruen@kernel.org, bfields@fieldses.org, akpm@linux-foundation.org, viro@zeniv.linux.org.uk, dhowells@redhat.com Cc: aneesh.kumar@linux.vnet.ibm.com, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH -V1 18/22] richacl: xattr mapping functions Date: Sun, 27 Apr 2014 21:44:49 +0530 Message-Id: <1398615293-22931-19-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1398615293-22931-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> References: <1398615293-22931-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14042716-6102-0000-0000-00000573E61F Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andreas Gruenbacher Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher Signed-off-by: Aneesh Kumar K.V --- fs/Makefile | 2 +- fs/richacl_xattr.c | 130 ++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 46 +++++++++++++++ 3 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index bed5b8a623ba..6cb7e064189d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 000000000000..e7a25e173275 --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * 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. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(struct richacl_xattr) || + xattr_acl->a_version != ACL4_XATTR_VERSION || + (xattr_acl->a_flags & ~ACL4_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + + count = le16_to_cpu(xattr_acl->a_count); + if (count > ACL4_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~ACE4_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~ACE4_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~ACE4_VALID_MASK) + goto fail_einval; + + if (((void *)xattr_ace + count * sizeof(*xattr_ace)) > (value + size)) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + ace->e_id = le32_to_cpu(xattr_ace->e_id); + + if (ace->e_flags & ~ACE4_VALID_FLAGS) + goto fail_einval; + if (ace->e_type > ACE4_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~ACE4_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer of size richacl_xattr_size(@acl) for the result + */ +void +richacl_to_xattr(const struct richacl *acl, void *buffer) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + + xattr_acl->a_version = ACL4_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags & + ACE4_VALID_FLAGS); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + xattr_ace->e_id = cpu_to_le32(ace->e_id); + xattr_ace++; + } +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 000000000000..792abccce47b --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * 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. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include + +#define RICHACL_XATTR "system.richacl" + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define ACL4_XATTR_VERSION 0 +#define ACL4_XATTR_MAX_COUNT 1024 + +extern struct richacl *richacl_from_xattr(const void *, size_t); +extern size_t richacl_xattr_size(const struct richacl *acl); +extern void richacl_to_xattr(const struct richacl *, void *); + +#endif /* __RICHACL_XATTR_H */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/