From: Boaz harrosh <boaz@plexistor.com>
To: linux-fsdevel <linux-fsdevel@vger.kernel.org>,
Anna Schumaker <Anna.Schumaker@netapp.com>,
Al Viro <viro@zeniv.linux.org.uk>
Cc: Ric Wheeler <rwheeler@redhat.com>,
Miklos Szeredi <mszeredi@redhat.com>,
Steven Whitehouse <swhiteho@redhat.com>,
Jefff moyer <jmoyer@redhat.com>,
Amir Goldstein <amir73il@gmail.com>,
Amit Golander <Amit.Golander@netapp.com>,
Sagi Manole <sagim@netapp.com>
Subject: [RFC PATCH 15/17] zuf: ACL support
Date: Tue, 19 Feb 2019 13:51:34 +0200 [thread overview]
Message-ID: <20190219115136.29952-16-boaz@plexistor.com> (raw)
In-Reply-To: <20190219115136.29952-1-boaz@plexistor.com>
From: Boaz Harrosh <boazh@netapp.com>
The ACL support is all in Kernel. There is no new API
with zusFS.
We define the internal structure of the ACL inside
an opec xattr and store via the xattr zus_api.
TODO:
Future FSs that has their own ACL on-disk-format, Or
Network zusFS that have their own verifiers for the ACL
will need to establish an alternative API for the acl.
Signed-off-by: Boaz Harrosh <boazh@netapp.com>
---
fs/zuf/Makefile | 2 +-
fs/zuf/_extern.h | 9 ++
fs/zuf/_pr.h | 1 +
fs/zuf/acl.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++
fs/zuf/file.c | 2 +
fs/zuf/inode.c | 11 ++
fs/zuf/namei.c | 4 +
fs/zuf/zuf.h | 6 +
8 files changed, 317 insertions(+), 1 deletion(-)
create mode 100644 fs/zuf/acl.c
diff --git a/fs/zuf/Makefile b/fs/zuf/Makefile
index 5d638760a82f..f53504b47c2a 100644
--- a/fs/zuf/Makefile
+++ b/fs/zuf/Makefile
@@ -17,7 +17,7 @@ zuf-y += md.o t1.o t2.o
zuf-y += zuf-core.o zuf-root.o
# Main FS
-zuf-y += xattr.o
+zuf-y += acl.o xattr.o
zuf-y += rw.o mmap.o ioctl.o
zuf-y += super.o inode.o directory.o namei.o file.o symlink.o
zuf-y += module.o
diff --git a/fs/zuf/_extern.h b/fs/zuf/_extern.h
index 1f4b39911a5d..2e515af0bb22 100644
--- a/fs/zuf/_extern.h
+++ b/fs/zuf/_extern.h
@@ -83,6 +83,15 @@ int __zuf_setxattr(struct inode *inode, int type, const char *name,
ssize_t zuf_listxattr(struct dentry *dentry, char *buffer, size_t size);
extern const struct xattr_handler *zuf_xattr_handlers[];
+/* acl.c */
+int zuf_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+struct posix_acl *zuf_get_acl(struct inode *inode, int type);
+int zuf_acls_create_pre(struct inode *dir, struct inode *inode,
+ struct posix_acl **user_acl);
+int zuf_acls_create_post(struct inode *dir, struct inode *inode,
+ struct posix_acl *acl);
+extern const struct xattr_handler zuf_acl_access_xattr_handler;
+extern const struct xattr_handler zuf_acl_default_xattr_handler;
/* super.c */
int zuf_init_inodecache(void);
diff --git a/fs/zuf/_pr.h b/fs/zuf/_pr.h
index 04b99f57f2b5..7d7e4808dcf0 100644
--- a/fs/zuf/_pr.h
+++ b/fs/zuf/_pr.h
@@ -43,6 +43,7 @@
#define zuf_dbg_rw(s, args ...) zuf_chan_debug("rw ", s, ##args)
#define zuf_dbg_t1(s, args ...) zuf_chan_debug("t1 ", s, ##args)
#define zuf_dbg_xattr(s, args ...) zuf_chan_debug("xattr", s, ##args)
+#define zuf_dbg_acl(s, args ...) zuf_chan_debug("acl ", s, ##args)
#define zuf_dbg_t2(s, args ...) zuf_chan_debug("t2dbg", s, ##args)
#define zuf_dbg_t2_rw(s, args ...) zuf_chan_debug("t2grw", s, ##args)
#define zuf_dbg_core(s, args ...) zuf_chan_debug("core ", s, ##args)
diff --git a/fs/zuf/acl.c b/fs/zuf/acl.c
new file mode 100644
index 000000000000..ccea8ce455fb
--- /dev/null
+++ b/fs/zuf/acl.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Access Control List
+ *
+ * Copyright (c) 2018 NetApp Inc. All rights reserved.
+ *
+ * ZUFS-License: GPL-2.0. See module.c for LICENSE details.
+ *
+ * Authors:
+ * Boaz Harrosh <boazh@netapp.com>
+ */
+
+#include <linux/fs.h>
+#include <linux/posix_acl_xattr.h>
+#include <linux/xattr.h>
+#include "zuf.h"
+
+static void _acl_to_value(const struct posix_acl *acl, void *value)
+{
+ int n;
+ struct zuf_acl *macl = value;
+
+ zuf_dbg_acl("acl->count=%d\n", acl->a_count);
+
+ for (n = 0; n < acl->a_count; n++) {
+ const struct posix_acl_entry *entry = &acl->a_entries[n];
+
+ zuf_dbg_acl("aclno=%d tag=0x%x perm=0x%x\n",
+ n, entry->e_tag, entry->e_perm);
+
+ macl->tag = cpu_to_le16(entry->e_tag);
+ macl->perm = cpu_to_le16(entry->e_perm);
+
+ switch (entry->e_tag) {
+ case ACL_USER:
+ macl->id = cpu_to_le32(__kuid_val(entry->e_uid));
+ break;
+ case ACL_GROUP:
+ macl->id = cpu_to_le32(__kgid_val(entry->e_gid));
+ break;
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_MASK:
+ case ACL_OTHER:
+ break;
+ default:
+ zuf_dbg_err("e_tag=0x%x\n", entry->e_tag);
+ return;
+ }
+ macl++;
+ }
+}
+
+int zuf_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+ char *name = NULL;
+ void *buf;
+ int err;
+ size_t size;
+
+ zuf_dbg_acl("[%ld] acl=%p type=0x%x\n", inode->i_ino, acl, type);
+
+ switch (type) {
+ case ACL_TYPE_ACCESS: {
+ struct zus_inode *zi = ZUII(inode)->zi;
+
+ name = XATTR_POSIX_ACL_ACCESS;
+ if (acl) {
+ err = posix_acl_update_mode(inode, &inode->i_mode,
+ &acl);
+ if (err < 0)
+ return err;
+
+ inode->i_ctime = current_time(inode);
+ timespec_to_mt(&zi->i_ctime, &inode->i_ctime);
+ }
+ zi->i_mode = cpu_to_le16(inode->i_mode);
+ break;
+ }
+ case ACL_TYPE_DEFAULT:
+ name = XATTR_POSIX_ACL_DEFAULT;
+ if (!S_ISDIR(inode->i_mode))
+ return acl ? -EACCES : 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ size = acl ? acl->a_count * sizeof(struct zuf_acl) : 0;
+ buf = kmalloc(size, GFP_KERNEL);
+ if (unlikely(!buf))
+ return -ENOMEM;
+
+ if (acl)
+ _acl_to_value(acl, buf);
+
+ err = __zuf_setxattr(inode, ZUF_XF_SYSTEM, name, buf, size, 0);
+ if (!err)
+ set_cached_acl(inode, type, acl);
+
+ kfree(buf);
+ return err;
+}
+
+static struct posix_acl *_value_to_acl(void *value, size_t size)
+{
+ int n, count;
+ struct posix_acl *acl;
+ struct zuf_acl *macl = value;
+ void *end = value + size;
+
+ if (!value)
+ return NULL;
+
+ count = size / sizeof(struct zuf_acl);
+ if (count < 0)
+ return ERR_PTR(-EINVAL);
+ if (count == 0)
+ return NULL;
+
+ acl = posix_acl_alloc(count, GFP_NOFS);
+ if (unlikely(!acl))
+ return ERR_PTR(-ENOMEM);
+
+ for (n = 0; n < count; n++) {
+ if (end < (void *)macl + sizeof(struct zuf_acl))
+ goto fail;
+
+ zuf_dbg_acl("aclno=%d tag=0x%x perm=0x%x id=0x%x\n",
+ n, le16_to_cpu(macl->tag), le16_to_cpu(macl->perm),
+ le32_to_cpu(macl->id));
+
+ acl->a_entries[n].e_tag = le16_to_cpu(macl->tag);
+ acl->a_entries[n].e_perm = le16_to_cpu(macl->perm);
+
+ switch (acl->a_entries[n].e_tag) {
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_MASK:
+ case ACL_OTHER:
+ macl++;
+ break;
+ case ACL_USER:
+ acl->a_entries[n].e_uid =
+ KUIDT_INIT(le32_to_cpu(macl->id));
+ macl++;
+ if (end < (void *)macl)
+ goto fail;
+ break;
+ case ACL_GROUP:
+ acl->a_entries[n].e_gid =
+ KGIDT_INIT(le32_to_cpu(macl->id));
+ macl++;
+ if (end < (void *)macl)
+ goto fail;
+ break;
+
+ default:
+ goto fail;
+ }
+ }
+ if (macl != end)
+ goto fail;
+ return acl;
+
+fail:
+ posix_acl_release(acl);
+ return ERR_PTR(-EINVAL);
+}
+
+struct posix_acl *zuf_get_acl(struct inode *inode, int type)
+{
+ struct zuf_inode_info *zii = ZUII(inode);
+ char *name = NULL;
+ void *buf;
+ struct posix_acl *acl = NULL;
+ int ret;
+
+ zuf_dbg_acl("[%ld] type=0x%x\n", inode->i_ino, type);
+
+ buf = (void *)__get_free_page(GFP_KERNEL);
+ if (unlikely(!buf))
+ return ERR_PTR(-ENOMEM);
+
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ name = XATTR_POSIX_ACL_ACCESS;
+ break;
+ case ACL_TYPE_DEFAULT:
+ name = XATTR_POSIX_ACL_DEFAULT;
+ break;
+ default:
+ WARN_ON(1);
+ return ERR_PTR(-EINVAL);
+ }
+
+ zuf_smr_lock(zii);
+
+ ret = __zuf_getxattr(inode, ZUF_XF_SYSTEM, name, buf, PAGE_SIZE);
+ if (likely(ret > 0)) {
+ acl = _value_to_acl(buf, ret);
+ } else if (ret != -ENODATA) {
+ if (ret != 0)
+ zuf_dbg_err("failed to getattr ret=%d\n", ret);
+ acl = ERR_PTR(ret);
+ }
+
+ if (!IS_ERR(acl))
+ set_cached_acl(inode, type, acl);
+
+ zuf_smr_unlock(zii);
+
+ free_page((ulong)buf);
+
+ return acl;
+}
+
+/* Used by creation of new inodes */
+int zuf_acls_create_pre(struct inode *dir, struct inode *inode,
+ struct posix_acl **user_acl)
+{
+ struct posix_acl *acl;
+
+ if (!IS_POSIXACL(dir))
+ return 0;
+
+ zuf_dbg_acl("[%ld] i_ino=%ld i_mode=o%o\n",
+ dir->i_ino, inode->i_ino, inode->i_mode);
+
+ if (S_ISLNK(inode->i_mode))
+ return 0;
+
+ acl = get_acl(dir, ACL_TYPE_DEFAULT);
+ if (IS_ERR(acl))
+ return PTR_ERR(acl);
+ if (!acl)
+ inode->i_mode &= ~current_umask();
+ else
+ *user_acl = acl;
+
+ return 0;
+}
+
+int zuf_acls_create_post(struct inode *dir, struct inode *inode,
+ struct posix_acl *acl)
+{
+ int err;
+
+ zuf_dbg_acl("[%ld] i_ino=%ld i_mode=o%o\n",
+ dir->i_ino, inode->i_ino, inode->i_mode);
+
+ if (S_ISDIR(inode->i_mode)) {
+ err = zuf_set_acl(inode, acl, ACL_TYPE_DEFAULT);
+ if (err)
+ goto cleanup;
+ }
+ err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
+ if (unlikely(err < 0))
+ return err;
+
+ zus_zi(inode)->i_mode = cpu_to_le16(inode->i_mode);
+ if (err > 0) { /* This is an extended ACL */
+ err = zuf_set_acl(inode, acl, ACL_TYPE_ACCESS);
+ } else {
+ /* NOTE: Boaz think we will cry over this... */
+ struct zufs_ioc_attr ioc_attr = {
+ .hdr.in_len = sizeof(ioc_attr),
+ .hdr.out_len = sizeof(ioc_attr),
+ .hdr.operation = ZUFS_OP_SETATTR,
+ .zus_ii = ZUII(inode)->zus_ii,
+ .zuf_attr = STATX_MODE,
+ };
+
+ err = zufc_dispatch(ZUF_ROOT(SBI(inode->i_sb)),
+ &ioc_attr.hdr, NULL, 0);
+ if (unlikely(err && err != -EINTR))
+ zuf_err("zufc_dispatch failed => %d\n", err);
+ }
+
+cleanup:
+ posix_acl_release(acl);
+ return err;
+}
diff --git a/fs/zuf/file.c b/fs/zuf/file.c
index 814a75105321..0ec87ec4d078 100644
--- a/fs/zuf/file.c
+++ b/fs/zuf/file.c
@@ -521,5 +521,7 @@ const struct inode_operations zuf_file_inode_operations = {
.getattr = zuf_getattr,
.update_time = zuf_update_time,
.fiemap = tozu_fiemap,
+ .get_acl = zuf_get_acl,
+ .set_acl = zuf_set_acl,
.listxattr = zuf_listxattr,
};
diff --git a/fs/zuf/inode.c b/fs/zuf/inode.c
index 73f94e7062e5..3b9e78feab06 100644
--- a/fs/zuf/inode.c
+++ b/fs/zuf/inode.c
@@ -342,6 +342,7 @@ struct inode *zuf_new_inode(struct inode *dir, umode_t mode,
.flags = tmpfile ? ZI_TMPFILE : 0,
.str.len = qstr->len,
};
+ struct posix_acl *acl = NULL;
struct inode *inode;
struct zus_inode *zi = NULL;
struct page *pages[2];
@@ -366,6 +367,10 @@ struct inode *zuf_new_inode(struct inode *dir, umode_t mode,
if (err && err != -EOPNOTSUPP)
goto fail;
+ err = zuf_acls_create_pre(dir, inode, &acl);
+ if (unlikely(err))
+ goto fail;
+
zuf_set_inode_flags(inode, &ioc_new_inode.zi);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
@@ -406,6 +411,12 @@ struct inode *zuf_new_inode(struct inode *dir, umode_t mode,
zuf_dbg_verbose("allocating inode %ld (zi=%p)\n", _zi_ino(zi), zi);
+ if (acl && !symname) {
+ err = zuf_acls_create_post(dir, inode, acl);
+ if (unlikely(err))
+ goto fail;
+ }
+
err = insert_inode_locked(inode);
if (unlikely(err)) {
zuf_dbg_err("[%ld:%s] generation=%lld insert_inode_locked => %d\n",
diff --git a/fs/zuf/namei.c b/fs/zuf/namei.c
index 803069423674..a33745c328b9 100644
--- a/fs/zuf/namei.c
+++ b/fs/zuf/namei.c
@@ -420,6 +420,8 @@ const struct inode_operations zuf_dir_inode_operations = {
.setattr = zuf_setattr,
.getattr = zuf_getattr,
.update_time = zuf_update_time,
+ .get_acl = zuf_get_acl,
+ .set_acl = zuf_set_acl,
.listxattr = zuf_listxattr,
};
@@ -427,5 +429,7 @@ const struct inode_operations zuf_special_inode_operations = {
.setattr = zuf_setattr,
.getattr = zuf_getattr,
.update_time = zuf_update_time,
+ .get_acl = zuf_get_acl,
+ .set_acl = zuf_set_acl,
.listxattr = zuf_listxattr,
};
diff --git a/fs/zuf/zuf.h b/fs/zuf/zuf.h
index 13b246189d8b..b6347dc6eb6a 100644
--- a/fs/zuf/zuf.h
+++ b/fs/zuf/zuf.h
@@ -335,6 +335,12 @@ enum { ZUF_XF_SECURITY = 1,
ZUF_XF_USER = 4,
};
+struct zuf_acl {
+ __le16 tag;
+ __le16 perm;
+ __le32 id;
+} __packed;
+
enum big_alloc_type { ba_stack, ba_kmalloc, ba_vmalloc };
static inline
--
2.20.1
next prev parent reply other threads:[~2019-02-19 11:52 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-19 11:51 [RFC PATCH 00/17] zuf: ZUFS Zero-copy User-mode FileSystem Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 01/17] fs: Add the ZUF filesystem to the build + License Boaz harrosh
2019-02-20 11:03 ` Greg KH
2019-02-20 14:55 ` Boaz Harrosh
2019-02-20 19:40 ` Greg KH
2019-02-26 17:55 ` Schumaker, Anna
2019-02-28 16:42 ` Boaz Harrosh
2019-02-19 11:51 ` [RFC PATCH 02/17] zuf: Preliminary Documentation Boaz harrosh
2019-02-20 8:27 ` Miklos Szeredi
2019-02-20 14:24 ` Boaz Harrosh
2019-02-19 11:51 ` [RFC PATCH 03/17] zuf: zuf-rootfs Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 04/17] zuf: zuf-core The ZTs Boaz harrosh
2019-02-26 18:34 ` Schumaker, Anna
2019-02-28 17:01 ` Boaz Harrosh
2019-02-19 11:51 ` [RFC PATCH 05/17] zuf: Multy Devices Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 06/17] zuf: mounting Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 07/17] zuf: Namei and directory operations Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 08/17] zuf: readdir operation Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 09/17] zuf: symlink Boaz harrosh
2019-02-20 11:05 ` Greg KH
2019-02-20 14:12 ` Boaz Harrosh
2019-02-19 11:51 ` [RFC PATCH 10/17] zuf: More file operation Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 11/17] zuf: Write/Read implementation Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 12/17] zuf: mmap & sync Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 13/17] zuf: ioctl implementation Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 14/17] zuf: xattr implementation Boaz harrosh
2019-02-19 11:51 ` Boaz harrosh [this message]
2019-02-19 11:51 ` [RFC PATCH 16/17] zuf: Special IOCTL fadvise (TODO) Boaz harrosh
2019-02-19 11:51 ` [RFC PATCH 17/17] zuf: Support for dynamic-debug of zusFSs Boaz harrosh
2019-02-19 12:15 ` [RFC PATCH 00/17] zuf: ZUFS Zero-copy User-mode FileSystem Matthew Wilcox
2019-02-19 19:15 ` Boaz Harrosh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190219115136.29952-16-boaz@plexistor.com \
--to=boaz@plexistor.com \
--cc=Amit.Golander@netapp.com \
--cc=Anna.Schumaker@netapp.com \
--cc=amir73il@gmail.com \
--cc=jmoyer@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=mszeredi@redhat.com \
--cc=rwheeler@redhat.com \
--cc=sagim@netapp.com \
--cc=swhiteho@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).