From patchwork Sun Apr 27 16:14:49 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Aneesh Kumar K.V" X-Patchwork-Id: 4072121 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BB7CD9F169 for ; Sun, 27 Apr 2014 16:22:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B881120270 for ; Sun, 27 Apr 2014 16:22:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9A10420266 for ; Sun, 27 Apr 2014 16:22:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753976AbaD0QQq (ORCPT ); Sun, 27 Apr 2014 12:16:46 -0400 Received: from e23smtp03.au.ibm.com ([202.81.31.145]:35430 "EHLO e23smtp03.au.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753527AbaD0QQI (ORCPT ); Sun, 27 Apr 2014 12:16:08 -0400 Received: from /spool/local by e23smtp03.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 28 Apr 2014 02:16:07 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp03.au.ibm.com (202.81.31.209) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 28 Apr 2014 02:16:05 +1000 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [9.190.234.120]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id 5430C357804F; Mon, 28 Apr 2014 02:16:05 +1000 (EST) Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s3RFt7mX7602548; Mon, 28 Apr 2014 01:55:07 +1000 Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s3RGG4Lt032636; Mon, 28 Apr 2014 02:16:04 +1000 Received: from skywalker.in.ibm.com ([9.79.196.205]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s3RGF2CX031555; Mon, 28 Apr 2014 02:16:01 +1000 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-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 */