All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Gruenbacher <andreas.gruenbacher@gmail.com>
To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-nfs@vger.kernel.org, linux-api@vger.kernel.org,
	samba-technical@lists.samba.org,
	linux-security-module@vger.kernel.org
Subject: [RFC v4 11/31] vfs: Cache base_acl objects in inodes
Date: Wed, 24 Jun 2015 23:57:00 +0200	[thread overview]
Message-ID: <1435183040-22726-12-git-send-email-agruenba@redhat.com> (raw)
In-Reply-To: <1435183040-22726-1-git-send-email-agruenba@redhat.com>

POSIX ACLs and richacls are both objects allocated by kmalloc() with a
reference count which are freed by kfree_rcu().  An inode can either cache an
access and a default POSIX ACL, or a richacl (richacls do not have default
acls).  To allow an inode to cache either of the two kinds of acls, introduce a
new base_acl type and convert i_acl and i_default_acl to that type. In most
cases, the vfs then doesn't have to care which kind of acl an inode caches (if
any).

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 drivers/staging/lustre/lustre/llite/llite_lib.c |  2 +-
 fs/f2fs/acl.c                                   |  4 ++--
 fs/inode.c                                      |  4 ++--
 fs/posix_acl.c                                  | 18 +++++++++---------
 include/linux/fs.h                              | 25 ++++++++++++++++++++++---
 include/linux/posix_acl.h                       | 12 ++++--------
 include/linux/richacl.h                         |  2 +-
 7 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index a27af78..f063b74 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1142,7 +1142,7 @@ void ll_clear_inode(struct inode *inode)
 	}
 #ifdef CONFIG_FS_POSIX_ACL
 	else if (lli->lli_posix_acl) {
-		LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1);
+		LASSERT(atomic_read(&lli->lli_posix_acl->a_base.ba_refcount) == 1);
 		LASSERT(lli->lli_remote_perms == NULL);
 		posix_acl_release(lli->lli_posix_acl);
 		lli->lli_posix_acl = NULL;
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index 4320ffa..f0cde7a 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl,
 				sizeof(struct posix_acl_entry);
 		clone = kmemdup(acl, size, flags);
 		if (clone)
-			atomic_set(&clone->a_refcount, 1);
+			atomic_set(&clone->a_base.ba_refcount, 1);
 	}
 	return clone;
 }
@@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
 	umode_t mode = *mode_p;
 	int not_equiv = 0;
 
-	/* assert(atomic_read(acl->a_refcount) == 1); */
+	/* assert(atomic_read(acl->a_base.ba_refcount) == 1); */
 
 	FOREACH_ACL_ENTRY(pa, acl, pe) {
 		switch(pa->e_tag) {
diff --git a/fs/inode.c b/fs/inode.c
index ea37cd1..ed7a6c0 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode)
 
 #ifdef CONFIG_FS_POSIX_ACL
 	if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED)
-		posix_acl_release(inode->i_acl);
+		put_base_acl(inode->i_acl);
 	if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED)
-		posix_acl_release(inode->i_default_acl);
+		put_base_acl(inode->i_default_acl);
 #endif
 	this_cpu_dec(nr_inodes);
 }
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 84bb65b8..430d687 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, int type)
 {
 	switch (type) {
 	case ACL_TYPE_ACCESS:
-		return &inode->i_acl;
+		return (struct posix_acl **)&inode->i_acl;
 	case ACL_TYPE_DEFAULT:
-		return &inode->i_default_acl;
+		return (struct posix_acl **)&inode->i_default_acl;
 	default:
 		BUG();
 	}
@@ -83,16 +83,16 @@ EXPORT_SYMBOL(forget_cached_acl);
 
 void forget_all_cached_acls(struct inode *inode)
 {
-	struct posix_acl *old_access, *old_default;
+	struct base_acl *old_access, *old_default;
 	spin_lock(&inode->i_lock);
 	old_access = inode->i_acl;
 	old_default = inode->i_default_acl;
 	inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
 	spin_unlock(&inode->i_lock);
 	if (old_access != ACL_NOT_CACHED)
-		posix_acl_release(old_access);
+		put_base_acl(old_access);
 	if (old_default != ACL_NOT_CACHED)
-		posix_acl_release(old_default);
+		put_base_acl(old_default);
 }
 EXPORT_SYMBOL(forget_all_cached_acls);
 
@@ -129,7 +129,7 @@ EXPORT_SYMBOL(get_acl);
 void
 posix_acl_init(struct posix_acl *acl, int count)
 {
-	atomic_set(&acl->a_refcount, 1);
+	atomic_set(&acl->a_base.ba_refcount, 1);
 	acl->a_count = count;
 }
 EXPORT_SYMBOL(posix_acl_init);
@@ -162,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags)
 		           sizeof(struct posix_acl_entry);
 		clone = kmemdup(acl, size, flags);
 		if (clone)
-			atomic_set(&clone->a_refcount, 1);
+			atomic_set(&clone->a_base.ba_refcount, 1);
 	}
 	return clone;
 }
@@ -384,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
 	umode_t mode = *mode_p;
 	int not_equiv = 0;
 
-	/* assert(atomic_read(acl->a_refcount) == 1); */
+	/* assert(atomic_read(acl->a_base.ba_refcount) == 1); */
 
 	FOREACH_ACL_ENTRY(pa, acl, pe) {
                 switch(pa->e_tag) {
@@ -439,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode)
 	struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL;
 	struct posix_acl_entry *pa, *pe;
 
-	/* assert(atomic_read(acl->a_refcount) == 1); */
+	/* assert(atomic_read(acl->a_base.ba_refcount) == 1); */
 
 	FOREACH_ACL_ENTRY(pa, acl, pe) {
 		switch(pa->e_tag) {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a32f37a..2f1152d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -574,6 +574,12 @@ static inline void mapping_allow_writable(struct address_space *mapping)
 #define i_size_ordered_init(inode) do { } while (0)
 #endif
 
+struct base_acl {
+	union {
+		atomic_t ba_refcount;
+		struct rcu_head ba_rcu;
+	};
+};
 struct posix_acl;
 #define ACL_NOT_CACHED ((void *)(-1))
 
@@ -593,9 +599,9 @@ struct inode {
 	kgid_t			i_gid;
 	unsigned int		i_flags;
 
-#ifdef CONFIG_FS_POSIX_ACL
-	struct posix_acl	*i_acl;
-	struct posix_acl	*i_default_acl;
+#if defined(CONFIG_FS_POSIX_ACL)
+	struct base_acl *i_acl;
+	struct base_acl *i_default_acl;
 #endif
 
 	const struct inode_operations	*i_op;
@@ -3006,4 +3012,17 @@ static inline bool dir_relax(struct inode *inode)
 	return !IS_DEADDIR(inode);
 }
 
+static inline struct base_acl *get_base_acl(struct base_acl *acl)
+{
+	if (acl)
+		atomic_inc(&acl->ba_refcount);
+	return acl;
+}
+
+static inline void put_base_acl(struct base_acl *acl)
+{
+	if (acl && atomic_dec_and_test(&acl->ba_refcount))
+		kfree_rcu(acl, ba_rcu);
+}
+
 #endif /* _LINUX_FS_H */
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 3e96a6a..2c46441 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -43,10 +43,7 @@ struct posix_acl_entry {
 };
 
 struct posix_acl {
-	union {
-		atomic_t		a_refcount;
-		struct rcu_head		a_rcu;
-	};
+	struct base_acl		a_base;
 	unsigned int		a_count;
 	struct posix_acl_entry	a_entries[0];
 };
@@ -61,8 +58,7 @@ struct posix_acl {
 static inline struct posix_acl *
 posix_acl_dup(struct posix_acl *acl)
 {
-	if (acl)
-		atomic_inc(&acl->a_refcount);
+	get_base_acl(&acl->a_base);
 	return acl;
 }
 
@@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl)
 static inline void
 posix_acl_release(struct posix_acl *acl)
 {
-	if (acl && atomic_dec_and_test(&acl->a_refcount))
-		kfree_rcu(acl, a_rcu);
+	BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0);
+	put_base_acl(&acl->a_base);
 }
 
 
diff --git a/include/linux/richacl.h b/include/linux/richacl.h
index b828615..a397bae 100644
--- a/include/linux/richacl.h
+++ b/include/linux/richacl.h
@@ -168,7 +168,7 @@ static inline struct richacl *
 richacl_get(struct richacl *acl)
 {
 	if (acl)
-		atomic_inc(&acl->a_refcount);
+		atomic_inc(&acl->a_base.ba_refcount);
 	return acl;
 }
 
-- 
2.4.2


  parent reply	other threads:[~2015-06-24 22:05 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-24 21:56 [RFC v4 00/31] Richacls Andreas Gruenbacher
2015-06-24 21:56 ` Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 01/31] vfs: Add IS_ACL() and IS_RICHACL() tests Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 02/31] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Andreas Gruenbacher
2015-06-24 21:56   ` Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 03/31] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD " Andreas Gruenbacher
2015-06-24 21:56   ` Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 04/31] vfs: Make the inode passed to inode_change_ok non-const Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 05/31] vfs: Add permission flags for setting file attributes Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 06/31] richacl: In-memory representation and helper functions Andreas Gruenbacher
2015-06-25 19:58   ` Stefan (metze) Metzmacher
2015-06-25 21:06     ` Andreas Grünbacher
2015-06-25 21:40       ` Stefan (metze) Metzmacher
2015-06-25 21:40         ` Stefan (metze) Metzmacher
2015-06-26  7:55         ` Andreas Grünbacher
2015-06-26  7:55           ` Andreas Grünbacher
2015-06-24 21:56 ` [RFC v4 07/31] richacl: Permission mapping functions Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 08/31] richacl: Compute maximum file masks from an acl Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 09/31] richacl: Update the file masks in chmod() Andreas Gruenbacher
2015-06-24 21:56   ` Andreas Gruenbacher
2015-06-24 21:56 ` [RFC v4 10/31] richacl: Permission check algorithm Andreas Gruenbacher
2015-06-24 21:56   ` Andreas Gruenbacher
2015-06-24 21:57 ` Andreas Gruenbacher [this message]
2015-06-24 21:57 ` [RFC v4 12/31] vfs: Cache richacl in struct inode Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 13/31] richacl: Check if an acl is equivalent to a file mode Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 14/31] richacl: Create-time inheritance Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 15/31] richacl: Automatic Inheritance Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 16/31] richacl: xattr mapping functions Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 17/31] vfs: Add richacl permission checking Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 18/31] ext4: Add richacl support Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 19/31] ext4: Add richacl feature flag Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 20/31] richacl: acl editing helper functions Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 21/31] richacl: Move everyone@ aces down the acl Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 22/31] richacl: Propagate everyone@ permissions to other aces Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 23/31] richacl: Set the owner permissions to the owner mask Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 24/31] richacl: Set the other permissions to the other mask Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 25/31] richacl: Isolate the owner and group classes Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 26/31] richacl: Apply the file masks to a richacl Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 27/31] richacl: Create richacl from mode values Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 28/31] nfsd: Keep list of acls to dispose of in compoundargs Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 29/31] nfsd: Use richacls as internal acl representation Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 30/31] nfsd: Add richacl support Andreas Gruenbacher
2015-06-24 21:57 ` [RFC v4 31/31] nfsd: Add support for the v4.1 dacl attribute Andreas Gruenbacher
2015-06-24 21:57   ` Andreas Gruenbacher

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=1435183040-22726-12-git-send-email-agruenba@redhat.com \
    --to=andreas.gruenbacher@gmail.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=samba-technical@lists.samba.org \
    /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 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.