linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
@ 2019-04-16 17:49 Al Viro
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                   ` (2 more replies)
  0 siblings, 3 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:49 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-fsdevel, linux-kernel

	We have a lot of boilerplate in ->destroy_inode()
instances, and several filesystems got the things wrong
in that area.  The patchset below attempts to deal with that.

	New method (void ->free_inode(inode)) is introduced,
and RCU-delayed parts of ->destroy_inode() are moved there.
The change is backwards-compatible - unmodified filesystem
will behave as it used to.  Rules:
	->destroy_inode		->free_inode
	f			g		f(), rcu-delayed g()
	f			NULL		f()
	NULL			g		rcu-delayed g()
	NULL			NULL		rcu-delayed free_inode_nonrcu()
IOW, NULL/NULL acts as NULL/free_inode_nonrcu.

	For a lot of filesystems ->destroy_inode() used to consist
only of call_rcu(foo_i_callback, &inode->i_rcu).  Those simply get
rid of ->destroy_inode() and have the callback (with saner prototype)
become their ->free_inode().

	Filesystems with NULL ->destroy_inode() are simply left as-is
and so are the filesystems that don't have RCU-delayed call (pipefs,
xfs, btrfs-tests).

	Filesystems that have both synchronous work and RCU-delayed
call of a callback are more interesting.  In any case, the callback
can be converted to ->free_inode().  Sometimes that's all we can
reasonably do there - the rest is left in ->destroy_inode() and that's
it.  However, for some of those we can do more:
	* some of the synchronous stuff can just as well live in
RCU callback; such can be moved to ->free_inode().
	* some of the synchronous stuff is a better fit for ->evict_inode();
e.g. the code that's undoing something done after the ->alloc_inode() or
sanity checks on the inode state.
	I've done that in the obvious cases; the few non-obvious are up to
fs maintainers - they can be done as followups at any point.

The series lives in vfs.git#work.icache; patchbomb in followups.  Overview:

* a couple of missed fixes for ->i_link freed to early; -stable fodder:
      securityfs: fix use-after-free on symlink traversal
      apparmorfs: fix use-after-free on symlink traversal
* infrastructure:
      new inode method: ->free_inode()
* simple conversions (->destroy_inode() consisting only of call_rcu())
      spufs: switch to ->free_inode()
      erofs: switch to ->free_inode()
      9p: switch to ->free_inode()
      adfs: switch to ->free_inode()
      affs: switch to ->free_inode()
      befs: switch to ->free_inode()
      bfs: switch to ->free_inode()
      bdev: switch to ->free_inode()
      cifs: switch to ->free_inode()
      debugfs: switch to ->free_inode()
      efs: switch to ->free_inode()
      ext2: switch to ->free_inode()
      f2fs: switch to ->free_inode()
      fat: switch to ->free_inode()
      freevxfs: switch to ->free_inode()
      gfs2: switch to ->free_inode()
      hfs: switch to ->free_inode()
      hfsplus: switch to ->free_inode()
      hostfs: switch to ->free_inode()
      hpfs: switch to ->free_inode()
      isofs: switch to ->free_inode()
      jffs2: switch to ->free_inode()
      minix: switch to ->free_inode()
      nfs{,4}: switch to ->free_inode()
      nilfs2: switch to ->free_inode()
      dlmfs: switch to ->free_inode()
      ocfs2: switch to ->free_inode()
      openpromfs: switch to ->free_inode()
      procfs: switch to ->free_inode()
      qnx4: switch to ->free_inode()
      qnx6: switch to ->free_inode()
      reiserfs: convert to ->free_inode()
      romfs: convert to ->free_inode()
      squashfs: switch to ->free_inode()
      ubifs: switch to ->free_inode()
      udf: switch to ->free_inode()
      sysv: switch to ->free_inode()
      coda: switch to ->free_inode()
      ufs: switch to ->free_inode()
      mqueue: switch to ->free_inode()
      bpf: switch to ->free_inode()
      rpcpipe: switch to ->free_inode()
      apparmor: switch to ->free_inode()
      securityfs: switch to ->free_inode()
      ntfs: switch to ->free_inode()
* cases where ->destroy_inode() contains both synchronous and delayed
parts; fuse, jfs have their ->destroy_inode() dissolved and
I'd like an ACK from their maintainers:
      dax: make use of ->free_inode()
      afs: switch to use of ->free_inode()
      btrfs: use ->free_inode()
      ceph: use ->free_inode()
      ecryptfs: make use of ->free_inode()
      ext4: make use of ->free_inode()
      fuse: switch to ->free_inode()
      jfs: switch to ->free_inode()
      overlayfs: make use of ->free_inode()
      hugetlb: make use of ->free_inode()
      shmem: make use of ->free_inode()
      orangefs: make use of ->free_inode()
* sockets: sockfs is a case where everything can be moved to ->free_inode();
we are RCU-delaying the freeing of socket_wq anyway, so we might as well
combine that with freeing the socket_alloc itself.  That allows to get
rid of separate allocations for those, which simplifies the things nicely.
We obviously need an ACK from networking folks on the last pair of commits.
      sockfs: switch to ->free_inode()
      coallocate socket->wq with socket itself

I have *not* included an update of vfs.txt into that branch, since
there's a big patchset converting it to a different format.  I have
a tentative variant of documentation on the tail-end of inode lifecycle,
but it still needs more work; I want to sort out the situation with
writeback for "don't retain inodes in icache" case first...

Diffstat:
 Documentation/filesystems/Locking         |  2 ++
 Documentation/filesystems/porting         | 17 ++++++++++
 arch/powerpc/platforms/cell/spufs/inode.c | 10 ++----
 drivers/dax/super.c                       |  7 ++--
 drivers/net/tap.c                         |  5 ++-
 drivers/net/tun.c                         |  8 ++---
 drivers/staging/erofs/super.c             | 10 ++----
 fs/9p/v9fs_vfs.h                          |  2 +-
 fs/9p/vfs_inode.c                         | 10 ++----
 fs/9p/vfs_super.c                         |  4 +--
 fs/adfs/super.c                           | 10 ++----
 fs/affs/super.c                           | 10 ++----
 fs/afs/super.c                            |  9 +++---
 fs/aio.c                                  |  4 +--
 fs/befs/linuxvfs.c                        | 12 ++-----
 fs/bfs/inode.c                            | 10 ++----
 fs/block_dev.c                            | 14 ++------
 fs/btrfs/ctree.h                          |  1 +
 fs/btrfs/inode.c                          |  7 ++--
 fs/btrfs/super.c                          |  1 +
 fs/ceph/inode.c                           |  5 +--
 fs/ceph/super.c                           |  1 +
 fs/ceph/super.h                           |  1 +
 fs/cifs/cifsfs.c                          | 12 ++-----
 fs/coda/inode.c                           | 10 ++----
 fs/debugfs/inode.c                        | 10 ++----
 fs/ecryptfs/super.c                       |  5 ++-
 fs/efs/super.c                            | 10 ++----
 fs/ext2/super.c                           | 10 ++----
 fs/ext4/super.c                           |  5 ++-
 fs/f2fs/super.c                           | 10 ++----
 fs/fat/inode.c                            | 10 ++----
 fs/freevxfs/vxfs_super.c                  | 11 ++-----
 fs/fuse/inode.c                           | 24 ++++++--------
 fs/gfs2/super.c                           | 12 ++-----
 fs/hfs/super.c                            | 10 ++----
 fs/hfsplus/super.c                        | 13 ++------
 fs/hostfs/hostfs_kern.c                   | 10 ++----
 fs/hpfs/super.c                           | 10 ++----
 fs/hugetlbfs/inode.c                      |  5 ++-
 fs/inode.c                                | 54 ++++++++++++++++++-------------
 fs/isofs/inode.c                          | 10 ++----
 fs/jffs2/super.c                          | 10 ++----
 fs/jfs/inode.c                            | 13 ++++++++
 fs/jfs/super.c                            | 24 ++------------
 fs/minix/inode.c                          | 10 ++----
 fs/nfs/inode.c                            | 10 ++----
 fs/nfs/internal.h                         |  2 +-
 fs/nfs/nfs4super.c                        |  2 +-
 fs/nfs/super.c                            |  2 +-
 fs/nilfs2/nilfs.h                         |  2 --
 fs/nilfs2/super.c                         | 11 ++-----
 fs/ntfs/inode.c                           | 17 +++-------
 fs/ntfs/inode.h                           |  2 +-
 fs/ntfs/super.c                           |  2 +-
 fs/ocfs2/dlmfs/dlmfs.c                    | 10 ++----
 fs/ocfs2/super.c                          | 12 ++-----
 fs/openpromfs/inode.c                     | 10 ++----
 fs/orangefs/super.c                       |  9 ++----
 fs/overlayfs/super.c                      | 13 ++++----
 fs/proc/inode.c                           | 10 ++----
 fs/qnx4/inode.c                           | 12 ++-----
 fs/qnx6/inode.c                           | 12 ++-----
 fs/reiserfs/super.c                       | 10 ++----
 fs/romfs/super.c                          | 11 ++-----
 fs/squashfs/super.c                       | 11 ++-----
 fs/sysv/inode.c                           | 10 ++----
 fs/ubifs/super.c                          | 10 ++----
 fs/udf/super.c                            | 10 ++----
 fs/ufs/super.c                            | 10 ++----
 include/linux/fs.h                        |  1 +
 include/linux/if_tap.h                    |  1 -
 include/linux/net.h                       |  4 +--
 include/net/sock.h                        |  4 +--
 ipc/mqueue.c                              | 10 ++----
 kernel/bpf/inode.c                        | 10 ++----
 lib/iov_iter.c                            |  4 +++
 mm/shmem.c                                |  5 ++-
 net/core/sock.c                           |  2 +-
 net/socket.c                              | 23 ++++---------
 net/sunrpc/rpc_pipe.c                     | 11 ++-----
 security/apparmor/apparmorfs.c            |  7 ++--
 security/inode.c                          |  7 ++--
 83 files changed, 241 insertions(+), 516 deletions(-)

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

* [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal
  2019-04-16 17:49 [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Al Viro
@ 2019-04-16 17:52 ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 02/62] apparmorfs: " Al Viro
                     ` (60 more replies)
  2019-04-16 18:01 ` [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Linus Torvalds
  2019-04-17 15:55 ` David Sterba
  2 siblings, 61 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

symlink body shouldn't be freed without an RCU delay.  Switch securityfs
to ->destroy_inode() and use of call_rcu(); free both the inode and symlink
body in the callback.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 security/inode.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/security/inode.c b/security/inode.c
index b7772a9b315e..421dd72b5876 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -27,17 +27,22 @@
 static struct vfsmount *mount;
 static int mount_count;
 
-static void securityfs_evict_inode(struct inode *inode)
+static void securityfs_i_callback(struct rcu_head *head)
 {
-	truncate_inode_pages_final(&inode->i_data);
-	clear_inode(inode);
+	struct inode *inode = container_of(head, struct inode, i_rcu);
 	if (S_ISLNK(inode->i_mode))
 		kfree(inode->i_link);
+	free_inode_nonrcu(inode);
+}
+
+static void securityfs_destroy_inode(struct inode *inode)
+{
+	call_rcu(&inode->i_rcu, securityfs_i_callback);
 }
 
 static const struct super_operations securityfs_super_operations = {
 	.statfs		= simple_statfs,
-	.evict_inode	= securityfs_evict_inode,
+	.destroy_inode	= securityfs_destroy_inode,
 };
 
 static int fill_super(struct super_block *sb, void *data, int silent)
-- 
2.11.0


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

* [RFC PATCH 02/62] apparmorfs: fix use-after-free on symlink traversal
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 03/62] new inode method: ->free_inode() Al Viro
                     ` (59 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

symlink body shouldn't be freed without an RCU delay.  Switch apparmorfs
to ->destroy_inode() and use of call_rcu(); free both the inode and symlink
body in the callback.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 security/apparmor/apparmorfs.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index fefee040bf79..b9298d2e8165 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -123,17 +123,22 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
 	return 0;
 }
 
-static void aafs_evict_inode(struct inode *inode)
+static void aafs_i_callback(struct rcu_head *head)
 {
-	truncate_inode_pages_final(&inode->i_data);
-	clear_inode(inode);
+	struct inode *inode = container_of(head, struct inode, i_rcu);
 	if (S_ISLNK(inode->i_mode))
 		kfree(inode->i_link);
+	free_inode_nonrcu(inode);
+}
+
+static void aafs_destroy_inode(struct inode *inode)
+{
+	call_rcu(&inode->i_rcu, aafs_i_callback);
 }
 
 static const struct super_operations aafs_super_ops = {
 	.statfs = simple_statfs,
-	.evict_inode = aafs_evict_inode,
+	.destroy_inode = aafs_destroy_inode,
 	.show_path = aafs_show_path,
 };
 
-- 
2.11.0


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

* [RFC PATCH 03/62] new inode method: ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
  2019-04-16 17:52   ` [RFC PATCH 02/62] apparmorfs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 04/62] spufs: switch to ->free_inode() Al Viro
                     ` (58 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

A lot of ->destroy_inode() instances end with call_rcu() of a callback
that does RCU-delayed part of freeing.  Introduce a new method for
doing just that, with saner signature.

Rules:
->destroy_inode		->free_inode
	f			g		immediate call of f(),
						RCU-delayed call of g()
	f			NULL		immediate call of f(),
						no RCU-delayed calls
	NULL			g		RCU-delayed call of g()
	NULL			NULL		RCU-delayed default freeing

IOW, NULL ->free_inode gives the same behaviour as now.

Note that NULL, NULL is equivalent to NULL, free_inode_nonrcu; we could
mandate the latter form, but that would have very little benefit beyond
making rules a bit more symmetric.  It would break backwards compatibility,
require extra boilerplate and expected semantics for (NULL, NULL) pair
would have no use whatsoever...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 Documentation/filesystems/Locking |  2 ++
 Documentation/filesystems/porting | 17 ++++++++++++
 fs/inode.c                        | 54 +++++++++++++++++++++++----------------
 include/linux/fs.h                |  1 +
 4 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index efea228ccd8a..7b20c385cc02 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -118,6 +118,7 @@ set:		exclusive
 --------------------------- super_operations ---------------------------
 prototypes:
 	struct inode *(*alloc_inode)(struct super_block *sb);
+	void (*free_inode)(struct inode *);
 	void (*destroy_inode)(struct inode *);
 	void (*dirty_inode) (struct inode *, int flags);
 	int (*write_inode) (struct inode *, struct writeback_control *wbc);
@@ -139,6 +140,7 @@ locking rules:
 	All may block [not true, see below]
 			s_umount
 alloc_inode:
+free_inode:				called from RCU callback
 destroy_inode:
 dirty_inode:
 write_inode:
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index cf43bc4dbf31..9d80f9e0855e 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -638,3 +638,20 @@ in your dentry operations instead.
 	inode to d_splice_alias() will also do the right thing (equivalent of
 	d_add(dentry, NULL); return NULL;), so that kind of special cases
 	also doesn't need a separate treatment.
+--
+[strongly recommended]
+	take the RCU-delayed parts of ->destroy_inode() into a new method -
+	->free_inode().  If ->destroy_inode() becomes empty - all the better,
+	just get rid of it.  Synchronous work (e.g. the stuff that can't
+	be done from an RCU callback, or any WARN_ON() where we want the
+	stack trace) *might* be movable to ->evict_inode(); however,
+	that goes only for the things that are not needed to balance something
+	done by ->alloc_inode().  IOW, if it's cleaning up the stuff that
+	might have accumulated over the life of in-core inode, ->evict_inode()
+	might be a fit.
+
+	Rules for inode destruction:
+		* if ->destroy_inode() is non-NULL, it gets called
+		* if ->free_inode() is non-NULL, it gets scheduled by call_rcu()
+		* combination of NULL ->destroy_inode and NULL ->free_inode is
+		  treated as NULL/free_inode_nonrcu, to preserve the compatibility.
diff --git a/fs/inode.c b/fs/inode.c
index e9d97add2b36..fb45590d284e 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -202,12 +202,28 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 }
 EXPORT_SYMBOL(inode_init_always);
 
+void free_inode_nonrcu(struct inode *inode)
+{
+	kmem_cache_free(inode_cachep, inode);
+}
+EXPORT_SYMBOL(free_inode_nonrcu);
+
+static void i_callback(struct rcu_head *head)
+{
+	struct inode *inode = container_of(head, struct inode, i_rcu);
+	if (inode->i_sb->s_op->free_inode)
+		inode->i_sb->s_op->free_inode(inode);
+	else
+		free_inode_nonrcu(inode);
+}
+
 static struct inode *alloc_inode(struct super_block *sb)
 {
+	const struct super_operations *ops = sb->s_op;
 	struct inode *inode;
 
-	if (sb->s_op->alloc_inode)
-		inode = sb->s_op->alloc_inode(sb);
+	if (ops->alloc_inode)
+		inode = ops->alloc_inode(sb);
 	else
 		inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL);
 
@@ -215,22 +231,18 @@ static struct inode *alloc_inode(struct super_block *sb)
 		return NULL;
 
 	if (unlikely(inode_init_always(sb, inode))) {
-		if (inode->i_sb->s_op->destroy_inode)
-			inode->i_sb->s_op->destroy_inode(inode);
-		else
-			kmem_cache_free(inode_cachep, inode);
+		if (ops->destroy_inode) {
+			ops->destroy_inode(inode);
+			if (!ops->free_inode)
+				return NULL;
+		}
+		i_callback(&inode->i_rcu);
 		return NULL;
 	}
 
 	return inode;
 }
 
-void free_inode_nonrcu(struct inode *inode)
-{
-	kmem_cache_free(inode_cachep, inode);
-}
-EXPORT_SYMBOL(free_inode_nonrcu);
-
 void __destroy_inode(struct inode *inode)
 {
 	BUG_ON(inode_has_buffers(inode));
@@ -253,20 +265,18 @@ void __destroy_inode(struct inode *inode)
 }
 EXPORT_SYMBOL(__destroy_inode);
 
-static void i_callback(struct rcu_head *head)
-{
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	kmem_cache_free(inode_cachep, inode);
-}
-
 static void destroy_inode(struct inode *inode)
 {
+	const struct super_operations *ops = inode->i_sb->s_op;
+
 	BUG_ON(!list_empty(&inode->i_lru));
 	__destroy_inode(inode);
-	if (inode->i_sb->s_op->destroy_inode)
-		inode->i_sb->s_op->destroy_inode(inode);
-	else
-		call_rcu(&inode->i_rcu, i_callback);
+	if (ops->destroy_inode) {
+		ops->destroy_inode(inode);
+		if (!ops->free_inode)
+			return;
+	}
+	call_rcu(&inode->i_rcu, i_callback);
 }
 
 /**
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd28e7679089..2e9b9f87caca 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1903,6 +1903,7 @@ extern loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
 struct super_operations {
    	struct inode *(*alloc_inode)(struct super_block *sb);
 	void (*destroy_inode)(struct inode *);
+	void (*free_inode)(struct inode *);
 
    	void (*dirty_inode) (struct inode *, int flags);
 	int (*write_inode) (struct inode *, struct writeback_control *wbc);
-- 
2.11.0


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

* [RFC PATCH 04/62] spufs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
  2019-04-16 17:52   ` [RFC PATCH 02/62] apparmorfs: " Al Viro
  2019-04-16 17:52   ` [RFC PATCH 03/62] new inode method: ->free_inode() Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 05/62] erofs: " Al Viro
                     ` (57 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/powerpc/platforms/cell/spufs/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index db329d4bf1c3..c1a75216050a 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -71,17 +71,11 @@ spufs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void spufs_i_callback(struct rcu_head *head)
+static void spufs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(spufs_inode_cache, SPUFS_I(inode));
 }
 
-static void spufs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, spufs_i_callback);
-}
-
 static void
 spufs_init_once(void *p)
 {
@@ -739,7 +733,7 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
 	struct spufs_sb_info *info;
 	static const struct super_operations s_ops = {
 		.alloc_inode = spufs_alloc_inode,
-		.destroy_inode = spufs_destroy_inode,
+		.free_inode = spufs_free_inode,
 		.statfs = simple_statfs,
 		.evict_inode = spufs_evict_inode,
 		.show_options = spufs_show_options,
-- 
2.11.0


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

* [RFC PATCH 05/62] erofs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (2 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 04/62] spufs: switch to ->free_inode() Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-18 14:01     ` Gao Xiang
  2019-04-16 17:52   ` [RFC PATCH 06/62] 9p: " Al Viro
                     ` (56 subsequent siblings)
  60 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/staging/erofs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c
index 15c784fba879..700cbd460807 100644
--- a/drivers/staging/erofs/super.c
+++ b/drivers/staging/erofs/super.c
@@ -57,9 +57,8 @@ static struct inode *alloc_inode(struct super_block *sb)
 	return &vi->vfs_inode;
 }
 
-static void i_callback(struct rcu_head *head)
+static void free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct erofs_vnode *vi = EROFS_V(inode);
 
 	/* be careful RCU symlink path (see ext4_inode_info->i_data)! */
@@ -71,11 +70,6 @@ static void i_callback(struct rcu_head *head)
 	kmem_cache_free(erofs_inode_cachep, vi);
 }
 
-static void destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, i_callback);
-}
-
 static int superblock_read(struct super_block *sb)
 {
 	struct erofs_sb_info *sbi;
@@ -668,7 +662,7 @@ static int erofs_remount(struct super_block *sb, int *flags, char *data)
 const struct super_operations erofs_sops = {
 	.put_super = erofs_put_super,
 	.alloc_inode = alloc_inode,
-	.destroy_inode = destroy_inode,
+	.free_inode = free_inode,
 	.statfs = erofs_statfs,
 	.show_options = erofs_show_options,
 	.remount_fs = erofs_remount,
-- 
2.11.0


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

* [RFC PATCH 06/62] 9p: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (3 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 05/62] erofs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 07/62] adfs: " Al Viro
                     ` (55 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/9p/v9fs_vfs.h  |  2 +-
 fs/9p/vfs_inode.c | 10 ++--------
 fs/9p/vfs_super.c |  4 ++--
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index aaee1e6584e6..60cd4ba04afc 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -58,7 +58,7 @@ extern const struct file_operations v9fs_mmap_file_operations_dotl;
 extern struct kmem_cache *v9fs_inode_cache;
 
 struct inode *v9fs_alloc_inode(struct super_block *sb);
-void v9fs_destroy_inode(struct inode *inode);
+void v9fs_free_inode(struct inode *inode);
 struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t);
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
 		    struct inode *inode, umode_t mode, dev_t);
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 72b779bc0942..24050e866e64 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -253,21 +253,15 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
 }
 
 /**
- * v9fs_destroy_inode - destroy an inode
+ * v9fs_free_inode - destroy an inode
  *
  */
 
-static void v9fs_i_callback(struct rcu_head *head)
+void v9fs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
 }
 
-void v9fs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, v9fs_i_callback);
-}
-
 int v9fs_init_inode(struct v9fs_session_info *v9ses,
 		    struct inode *inode, umode_t mode, dev_t rdev)
 {
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index d13d35cf69c0..67d1b965adcd 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -344,7 +344,7 @@ static int v9fs_write_inode_dotl(struct inode *inode,
 
 static const struct super_operations v9fs_super_ops = {
 	.alloc_inode = v9fs_alloc_inode,
-	.destroy_inode = v9fs_destroy_inode,
+	.free_inode = v9fs_free_inode,
 	.statfs = simple_statfs,
 	.evict_inode = v9fs_evict_inode,
 	.show_options = v9fs_show_options,
@@ -354,7 +354,7 @@ static const struct super_operations v9fs_super_ops = {
 
 static const struct super_operations v9fs_super_ops_dotl = {
 	.alloc_inode = v9fs_alloc_inode,
-	.destroy_inode = v9fs_destroy_inode,
+	.free_inode = v9fs_free_inode,
 	.statfs = v9fs_statfs,
 	.drop_inode = v9fs_drop_inode,
 	.evict_inode = v9fs_evict_inode,
-- 
2.11.0


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

* [RFC PATCH 07/62] adfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (4 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 06/62] 9p: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 08/62] affs: " Al Viro
                     ` (54 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/adfs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 7e099a7a4eb1..2a83655c408f 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -248,17 +248,11 @@ static struct inode *adfs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void adfs_i_callback(struct rcu_head *head)
+static void adfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(adfs_inode_cachep, ADFS_I(inode));
 }
 
-static void adfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, adfs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct adfs_inode_info *ei = (struct adfs_inode_info *) foo;
@@ -290,7 +284,7 @@ static void destroy_inodecache(void)
 
 static const struct super_operations adfs_sops = {
 	.alloc_inode	= adfs_alloc_inode,
-	.destroy_inode	= adfs_destroy_inode,
+	.free_inode	= adfs_free_inode,
 	.drop_inode	= generic_delete_inode,
 	.write_inode	= adfs_write_inode,
 	.put_super	= adfs_put_super,
-- 
2.11.0


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

* [RFC PATCH 08/62] affs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (5 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 07/62] adfs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 09/62] befs: " Al Viro
                     ` (53 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/affs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/affs/super.c b/fs/affs/super.c
index d1ad11a8a4a5..d58217f0baaa 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -111,17 +111,11 @@ static struct inode *affs_alloc_inode(struct super_block *sb)
 	return &i->vfs_inode;
 }
 
-static void affs_i_callback(struct rcu_head *head)
+static void affs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(affs_inode_cachep, AFFS_I(inode));
 }
 
-static void affs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, affs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct affs_inode_info *ei = (struct affs_inode_info *) foo;
@@ -155,7 +149,7 @@ static void destroy_inodecache(void)
 
 static const struct super_operations affs_sops = {
 	.alloc_inode	= affs_alloc_inode,
-	.destroy_inode	= affs_destroy_inode,
+	.free_inode	= affs_free_inode,
 	.write_inode	= affs_write_inode,
 	.evict_inode	= affs_evict_inode,
 	.put_super	= affs_put_super,
-- 
2.11.0


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

* [RFC PATCH 09/62] befs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (6 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 08/62] affs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 10/62] bfs: " Al Viro
                     ` (52 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/befs/linuxvfs.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 4700b4534439..e273850c95af 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -44,7 +44,7 @@ static struct dentry *befs_lookup(struct inode *, struct dentry *,
 				  unsigned int);
 static struct inode *befs_iget(struct super_block *, unsigned long);
 static struct inode *befs_alloc_inode(struct super_block *sb);
-static void befs_destroy_inode(struct inode *inode);
+static void befs_free_inode(struct inode *inode);
 static void befs_destroy_inodecache(void);
 static int befs_symlink_readpage(struct file *, struct page *);
 static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
@@ -64,7 +64,7 @@ static struct dentry *befs_get_parent(struct dentry *child);
 
 static const struct super_operations befs_sops = {
 	.alloc_inode	= befs_alloc_inode,	/* allocate a new inode */
-	.destroy_inode	= befs_destroy_inode, /* deallocate an inode */
+	.free_inode	= befs_free_inode, /* deallocate an inode */
 	.put_super	= befs_put_super,	/* uninit super */
 	.statfs		= befs_statfs,	/* statfs */
 	.remount_fs	= befs_remount,
@@ -281,17 +281,11 @@ befs_alloc_inode(struct super_block *sb)
 	return &bi->vfs_inode;
 }
 
-static void befs_i_callback(struct rcu_head *head)
+static void befs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(befs_inode_cachep, BEFS_I(inode));
 }
 
-static void befs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, befs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct befs_inode_info *bi = (struct befs_inode_info *) foo;
-- 
2.11.0


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

* [RFC PATCH 10/62] bfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (7 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 09/62] befs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 11/62] bdev: " Al Viro
                     ` (51 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/bfs/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index d136b2aaafb3..dc0cd2aa3d65 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -245,17 +245,11 @@ static struct inode *bfs_alloc_inode(struct super_block *sb)
 	return &bi->vfs_inode;
 }
 
-static void bfs_i_callback(struct rcu_head *head)
+static void bfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(bfs_inode_cachep, BFS_I(inode));
 }
 
-static void bfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, bfs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct bfs_inode_info *bi = foo;
@@ -287,7 +281,7 @@ static void destroy_inodecache(void)
 
 static const struct super_operations bfs_sops = {
 	.alloc_inode	= bfs_alloc_inode,
-	.destroy_inode	= bfs_destroy_inode,
+	.free_inode	= bfs_free_inode,
 	.write_inode	= bfs_write_inode,
 	.evict_inode	= bfs_evict_inode,
 	.put_super	= bfs_put_super,
-- 
2.11.0


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

* [RFC PATCH 11/62] bdev: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (8 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 10/62] bfs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 12/62] cifs: " Al Viro
                     ` (50 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/block_dev.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 78d3257435c0..9d5fd05dd643 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -789,17 +789,9 @@ static struct inode *bdev_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void bdev_i_callback(struct rcu_head *head)
+static void bdev_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	struct bdev_inode *bdi = BDEV_I(inode);
-
-	kmem_cache_free(bdev_cachep, bdi);
-}
-
-static void bdev_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, bdev_i_callback);
+	kmem_cache_free(bdev_cachep, BDEV_I(inode));
 }
 
 static void init_once(void *foo)
@@ -839,7 +831,7 @@ static void bdev_evict_inode(struct inode *inode)
 static const struct super_operations bdev_sops = {
 	.statfs = simple_statfs,
 	.alloc_inode = bdev_alloc_inode,
-	.destroy_inode = bdev_destroy_inode,
+	.free_inode = bdev_free_inode,
 	.drop_inode = generic_delete_inode,
 	.evict_inode = bdev_evict_inode,
 };
-- 
2.11.0


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

* [RFC PATCH 12/62] cifs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (9 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 11/62] bdev: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 13/62] debugfs: " Al Viro
                     ` (49 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/cifs/cifsfs.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index a05bf1d6e1d0..877174761efb 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -315,16 +315,10 @@ cifs_alloc_inode(struct super_block *sb)
 	return &cifs_inode->vfs_inode;
 }
 
-static void cifs_i_callback(struct rcu_head *head)
-{
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
-}
-
 static void
-cifs_destroy_inode(struct inode *inode)
+cifs_free_inode(struct inode *inode)
 {
-	call_rcu(&inode->i_rcu, cifs_i_callback);
+	kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
 }
 
 static void
@@ -630,7 +624,7 @@ static int cifs_drop_inode(struct inode *inode)
 static const struct super_operations cifs_super_ops = {
 	.statfs = cifs_statfs,
 	.alloc_inode = cifs_alloc_inode,
-	.destroy_inode = cifs_destroy_inode,
+	.free_inode = cifs_free_inode,
 	.drop_inode	= cifs_drop_inode,
 	.evict_inode	= cifs_evict_inode,
 /*	.delete_inode	= cifs_delete_inode,  */  /* Do not need above
-- 
2.11.0


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

* [RFC PATCH 13/62] debugfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (10 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 12/62] cifs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 14/62] efs: " Al Viro
                     ` (48 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index f25daa207421..414fa4752047 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -163,24 +163,18 @@ static int debugfs_show_options(struct seq_file *m, struct dentry *root)
 	return 0;
 }
 
-static void debugfs_i_callback(struct rcu_head *head)
+static void debugfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	if (S_ISLNK(inode->i_mode))
 		kfree(inode->i_link);
 	free_inode_nonrcu(inode);
 }
 
-static void debugfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, debugfs_i_callback);
-}
-
 static const struct super_operations debugfs_super_operations = {
 	.statfs		= simple_statfs,
 	.remount_fs	= debugfs_remount,
 	.show_options	= debugfs_show_options,
-	.destroy_inode	= debugfs_destroy_inode,
+	.free_inode	= debugfs_free_inode,
 };
 
 static void debugfs_release_dentry(struct dentry *dentry)
-- 
2.11.0


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

* [RFC PATCH 14/62] efs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (11 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 13/62] debugfs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 15/62] ext2: " Al Viro
                     ` (47 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/efs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/efs/super.c b/fs/efs/super.c
index 6ffb7ba1547a..867fc24dee20 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -74,17 +74,11 @@ static struct inode *efs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void efs_i_callback(struct rcu_head *head)
+static void efs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(efs_inode_cachep, INODE_INFO(inode));
 }
 
-static void efs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, efs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct efs_inode_info *ei = (struct efs_inode_info *) foo;
@@ -122,7 +116,7 @@ static int efs_remount(struct super_block *sb, int *flags, char *data)
 
 static const struct super_operations efs_superblock_operations = {
 	.alloc_inode	= efs_alloc_inode,
-	.destroy_inode	= efs_destroy_inode,
+	.free_inode	= efs_free_inode,
 	.statfs		= efs_statfs,
 	.remount_fs	= efs_remount,
 };
-- 
2.11.0


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

* [RFC PATCH 15/62] ext2: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (12 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 14/62] efs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 16/62] f2fs: " Al Viro
                     ` (46 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ext2/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 0128010a0874..3988633789cb 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -192,17 +192,11 @@ static struct inode *ext2_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void ext2_i_callback(struct rcu_head *head)
+static void ext2_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(ext2_inode_cachep, EXT2_I(inode));
 }
 
-static void ext2_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, ext2_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct ext2_inode_info *ei = (struct ext2_inode_info *) foo;
@@ -351,7 +345,7 @@ static const struct quotactl_ops ext2_quotactl_ops = {
 
 static const struct super_operations ext2_sops = {
 	.alloc_inode	= ext2_alloc_inode,
-	.destroy_inode	= ext2_destroy_inode,
+	.free_inode	= ext2_free_in_core_inode,
 	.write_inode	= ext2_write_inode,
 	.evict_inode	= ext2_evict_inode,
 	.put_super	= ext2_put_super,
-- 
2.11.0


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

* [RFC PATCH 16/62] f2fs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (13 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 15/62] ext2: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-20  2:52     ` Chao Yu
  2019-04-16 17:52   ` [RFC PATCH 17/62] fat: " Al Viro
                     ` (45 subsequent siblings)
  60 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/f2fs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index f2aaa2cc6b3e..9924eac76254 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1000,17 +1000,11 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)
 	f2fs_inode_dirtied(inode, false);
 }
 
-static void f2fs_i_callback(struct rcu_head *head)
+static void f2fs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(f2fs_inode_cachep, F2FS_I(inode));
 }
 
-static void f2fs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, f2fs_i_callback);
-}
-
 static void destroy_percpu_info(struct f2fs_sb_info *sbi)
 {
 	percpu_counter_destroy(&sbi->alloc_valid_block_count);
@@ -2166,8 +2160,8 @@ void f2fs_quota_off_umount(struct super_block *sb)
 
 static const struct super_operations f2fs_sops = {
 	.alloc_inode	= f2fs_alloc_inode,
+	.free_inode	= f2fs_free_inode,
 	.drop_inode	= f2fs_drop_inode,
-	.destroy_inode	= f2fs_destroy_inode,
 	.write_inode	= f2fs_write_inode,
 	.dirty_inode	= f2fs_dirty_inode,
 	.show_options	= f2fs_show_options,
-- 
2.11.0


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

* [RFC PATCH 17/62] fat: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (14 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 16/62] f2fs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 18/62] freevxfs: " Al Viro
                     ` (44 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/fat/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 79bb0e73a65f..ba93d1373306 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -746,17 +746,11 @@ static struct inode *fat_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void fat_i_callback(struct rcu_head *head)
+static void fat_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
 }
 
-static void fat_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, fat_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
@@ -920,7 +914,7 @@ EXPORT_SYMBOL_GPL(fat_sync_inode);
 static int fat_show_options(struct seq_file *m, struct dentry *root);
 static const struct super_operations fat_sops = {
 	.alloc_inode	= fat_alloc_inode,
-	.destroy_inode	= fat_destroy_inode,
+	.free_inode	= fat_free_inode,
 	.write_inode	= fat_write_inode,
 	.evict_inode	= fat_evict_inode,
 	.put_super	= fat_put_super,
-- 
2.11.0


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

* [RFC PATCH 18/62] freevxfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (15 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 17/62] fat: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 19/62] gfs2: " Al Viro
                     ` (43 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/freevxfs/vxfs_super.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 48b24bb50d02..a89f68c3cbed 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -131,21 +131,14 @@ static struct inode *vxfs_alloc_inode(struct super_block *sb)
 	return &vi->vfs_inode;
 }
 
-static void vxfs_i_callback(struct rcu_head *head)
+static void vxfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-
 	kmem_cache_free(vxfs_inode_cachep, VXFS_INO(inode));
 }
 
-static void vxfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, vxfs_i_callback);
-}
-
 static const struct super_operations vxfs_super_ops = {
 	.alloc_inode		= vxfs_alloc_inode,
-	.destroy_inode		= vxfs_destroy_inode,
+	.free_inode		= vxfs_free_inode,
 	.evict_inode		= vxfs_evict_inode,
 	.put_super		= vxfs_put_super,
 	.statfs			= vxfs_statfs,
-- 
2.11.0


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

* [RFC PATCH 19/62] gfs2: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (16 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 18/62] freevxfs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 20/62] hfs: " Al Viro
                     ` (42 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

... and use GFS2_I() to get the containing gfs2_inode by inode;
yes, we can feed the address of the first member of structure
to kmem_cache_free(), but let's do it in an obviously safe way.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/gfs2/super.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index ca71163ff7cf..7b8d2306b3d3 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1736,20 +1736,14 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
 	return &ip->i_inode;
 }
 
-static void gfs2_i_callback(struct rcu_head *head)
+static void gfs2_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	kmem_cache_free(gfs2_inode_cachep, inode);
-}
-
-static void gfs2_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, gfs2_i_callback);
+	kmem_cache_free(gfs2_inode_cachep, GFS2_I(inode));
 }
 
 const struct super_operations gfs2_super_ops = {
 	.alloc_inode		= gfs2_alloc_inode,
-	.destroy_inode		= gfs2_destroy_inode,
+	.free_inode		= gfs2_free_inode,
 	.write_inode		= gfs2_write_inode,
 	.dirty_inode		= gfs2_dirty_inode,
 	.evict_inode		= gfs2_evict_inode,
-- 
2.11.0


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

* [RFC PATCH 20/62] hfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (17 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 19/62] gfs2: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:52   ` [RFC PATCH 21/62] hfsplus: " Al Viro
                     ` (41 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/hfs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 173876782f73..c33324686d89 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -167,20 +167,14 @@ static struct inode *hfs_alloc_inode(struct super_block *sb)
 	return i ? &i->vfs_inode : NULL;
 }
 
-static void hfs_i_callback(struct rcu_head *head)
+static void hfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(hfs_inode_cachep, HFS_I(inode));
 }
 
-static void hfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, hfs_i_callback);
-}
-
 static const struct super_operations hfs_super_operations = {
 	.alloc_inode	= hfs_alloc_inode,
-	.destroy_inode	= hfs_destroy_inode,
+	.free_inode	= hfs_free_inode,
 	.write_inode	= hfs_write_inode,
 	.evict_inode	= hfs_evict_inode,
 	.put_super	= hfs_put_super,
-- 
2.11.0


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

* [RFC PATCH 21/62] hfsplus: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (18 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 20/62] hfs: " Al Viro
@ 2019-04-16 17:52   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 22/62] hostfs: " Al Viro
                     ` (40 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/hfsplus/super.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index eb4535eba95d..0cc5feff76cd 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -18,7 +18,7 @@
 #include <linux/nls.h>
 
 static struct inode *hfsplus_alloc_inode(struct super_block *sb);
-static void hfsplus_destroy_inode(struct inode *inode);
+static void hfsplus_free_inode(struct inode *inode);
 
 #include "hfsplus_fs.h"
 #include "xattr.h"
@@ -361,7 +361,7 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
 
 static const struct super_operations hfsplus_sops = {
 	.alloc_inode	= hfsplus_alloc_inode,
-	.destroy_inode	= hfsplus_destroy_inode,
+	.free_inode	= hfsplus_free_inode,
 	.write_inode	= hfsplus_write_inode,
 	.evict_inode	= hfsplus_evict_inode,
 	.put_super	= hfsplus_put_super,
@@ -628,18 +628,11 @@ static struct inode *hfsplus_alloc_inode(struct super_block *sb)
 	return i ? &i->vfs_inode : NULL;
 }
 
-static void hfsplus_i_callback(struct rcu_head *head)
+static void hfsplus_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-
 	kmem_cache_free(hfsplus_inode_cachep, HFSPLUS_I(inode));
 }
 
-static void hfsplus_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, hfsplus_i_callback);
-}
-
 #define HFSPLUS_INODE_SIZE	sizeof(struct hfsplus_inode_info)
 
 static struct dentry *hfsplus_mount(struct file_system_type *fs_type,
-- 
2.11.0


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

* [RFC PATCH 22/62] hostfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (19 preceding siblings ...)
  2019-04-16 17:52   ` [RFC PATCH 21/62] hfsplus: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 23/62] hpfs: " Al Viro
                     ` (39 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/hostfs/hostfs_kern.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 444c7b170359..5a7eb0c79839 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -243,17 +243,11 @@ static void hostfs_evict_inode(struct inode *inode)
 	}
 }
 
-static void hostfs_i_callback(struct rcu_head *head)
+static void hostfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kfree(HOSTFS_I(inode));
 }
 
-static void hostfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, hostfs_i_callback);
-}
-
 static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
 {
 	const char *root_path = root->d_sb->s_fs_info;
@@ -270,7 +264,7 @@ static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
 
 static const struct super_operations hostfs_sbops = {
 	.alloc_inode	= hostfs_alloc_inode,
-	.destroy_inode	= hostfs_destroy_inode,
+	.free_inode	= hostfs_free_inode,
 	.evict_inode	= hostfs_evict_inode,
 	.statfs		= hostfs_statfs,
 	.show_options	= hostfs_show_options,
-- 
2.11.0


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

* [RFC PATCH 23/62] hpfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (20 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 22/62] hostfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 24/62] isofs: " Al Viro
                     ` (38 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/hpfs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index f2c3ebcd309c..ed4264bca790 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -238,17 +238,11 @@ static struct inode *hpfs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void hpfs_i_callback(struct rcu_head *head)
+static void hpfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode));
 }
 
-static void hpfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, hpfs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
@@ -532,7 +526,7 @@ static int hpfs_show_options(struct seq_file *seq, struct dentry *root)
 static const struct super_operations hpfs_sops =
 {
 	.alloc_inode	= hpfs_alloc_inode,
-	.destroy_inode	= hpfs_destroy_inode,
+	.free_inode	= hpfs_free_inode,
 	.evict_inode	= hpfs_evict_inode,
 	.put_super	= hpfs_put_super,
 	.statfs		= hpfs_statfs,
-- 
2.11.0


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

* [RFC PATCH 24/62] isofs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (21 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 23/62] hpfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 25/62] jffs2: " Al Viro
                     ` (37 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/isofs/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 488a9e7f8f66..603b052a3c94 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -72,17 +72,11 @@ static struct inode *isofs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void isofs_i_callback(struct rcu_head *head)
+static void isofs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
 }
 
-static void isofs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, isofs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct iso_inode_info *ei = foo;
@@ -122,7 +116,7 @@ static int isofs_remount(struct super_block *sb, int *flags, char *data)
 
 static const struct super_operations isofs_sops = {
 	.alloc_inode	= isofs_alloc_inode,
-	.destroy_inode	= isofs_destroy_inode,
+	.free_inode	= isofs_free_inode,
 	.put_super	= isofs_put_super,
 	.statfs		= isofs_statfs,
 	.remount_fs	= isofs_remount,
-- 
2.11.0


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

* [RFC PATCH 25/62] jffs2: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (22 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 24/62] isofs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 26/62] minix: " Al Viro
                     ` (36 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/jffs2/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 05d892c79339..af4aa6599473 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -44,20 +44,14 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb)
 	return &f->vfs_inode;
 }
 
-static void jffs2_i_callback(struct rcu_head *head)
+static void jffs2_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
 
 	kfree(f->target);
 	kmem_cache_free(jffs2_inode_cachep, f);
 }
 
-static void jffs2_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, jffs2_i_callback);
-}
-
 static void jffs2_i_init_once(void *foo)
 {
 	struct jffs2_inode_info *f = foo;
@@ -258,7 +252,7 @@ static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
 static const struct super_operations jffs2_super_operations =
 {
 	.alloc_inode =	jffs2_alloc_inode,
-	.destroy_inode =jffs2_destroy_inode,
+	.free_inode =	jffs2_free_inode,
 	.put_super =	jffs2_put_super,
 	.statfs =	jffs2_statfs,
 	.remount_fs =	jffs2_remount_fs,
-- 
2.11.0


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

* [RFC PATCH 26/62] minix: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (23 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 25/62] jffs2: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 27/62] nfs{,4}: " Al Viro
                     ` (35 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/minix/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 72e308c3e66b..101200761f61 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -68,17 +68,11 @@ static struct inode *minix_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void minix_i_callback(struct rcu_head *head)
+static void minix_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(minix_inode_cachep, minix_i(inode));
 }
 
-static void minix_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, minix_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct minix_inode_info *ei = (struct minix_inode_info *) foo;
@@ -110,7 +104,7 @@ static void destroy_inodecache(void)
 
 static const struct super_operations minix_sops = {
 	.alloc_inode	= minix_alloc_inode,
-	.destroy_inode	= minix_destroy_inode,
+	.free_inode	= minix_free_in_core_inode,
 	.write_inode	= minix_write_inode,
 	.evict_inode	= minix_evict_inode,
 	.put_super	= minix_put_super,
-- 
2.11.0


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

* [RFC PATCH 27/62] nfs{,4}: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (24 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 26/62] minix: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 28/62] nilfs2: " Al Viro
                     ` (34 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/nfs/inode.c     | 10 ++--------
 fs/nfs/internal.h  |  2 +-
 fs/nfs/nfs4super.c |  2 +-
 fs/nfs/super.c     |  2 +-
 4 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 414a90d48493..f61af8307dc8 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -2055,17 +2055,11 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
 }
 EXPORT_SYMBOL_GPL(nfs_alloc_inode);
 
-static void nfs_i_callback(struct rcu_head *head)
+void nfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
 }
-
-void nfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, nfs_i_callback);
-}
-EXPORT_SYMBOL_GPL(nfs_destroy_inode);
+EXPORT_SYMBOL_GPL(nfs_free_inode);
 
 static inline void nfs4_init_once(struct nfs_inode *nfsi)
 {
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index c7cf23ae6597..331a0504eaf8 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -381,7 +381,7 @@ int nfs_check_flags(int);
 /* inode.c */
 extern struct workqueue_struct *nfsiod_workqueue;
 extern struct inode *nfs_alloc_inode(struct super_block *sb);
-extern void nfs_destroy_inode(struct inode *);
+extern void nfs_free_inode(struct inode *);
 extern int nfs_write_inode(struct inode *, struct writeback_control *);
 extern int nfs_drop_inode(struct inode *);
 extern void nfs_clear_inode(struct inode *);
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 6fb7cb6b3f4b..689977e148cb 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -50,7 +50,7 @@ struct file_system_type nfs4_referral_fs_type = {
 
 static const struct super_operations nfs4_sops = {
 	.alloc_inode	= nfs_alloc_inode,
-	.destroy_inode	= nfs_destroy_inode,
+	.free_inode	= nfs_free_inode,
 	.write_inode	= nfs4_write_inode,
 	.drop_inode	= nfs_drop_inode,
 	.statfs		= nfs_statfs,
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 23790c7b2289..aec4e2c4b02f 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -309,7 +309,7 @@ struct file_system_type nfs_xdev_fs_type = {
 
 const struct super_operations nfs_sops = {
 	.alloc_inode	= nfs_alloc_inode,
-	.destroy_inode	= nfs_destroy_inode,
+	.free_inode	= nfs_free_inode,
 	.write_inode	= nfs_write_inode,
 	.drop_inode	= nfs_drop_inode,
 	.statfs		= nfs_statfs,
-- 
2.11.0


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

* [RFC PATCH 28/62] nilfs2: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (25 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 27/62] nfs{,4}: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 29/62] dlmfs: " Al Viro
                     ` (33 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

kill an extern that went stale 9 years ago, while we are at it...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/nilfs2/nilfs.h |  2 --
 fs/nilfs2/super.c | 11 ++---------
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index a2f247b6a209..42395ba52da6 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -252,7 +252,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *,
 void nilfs_inode_add_blocks(struct inode *inode, int n);
 void nilfs_inode_sub_blocks(struct inode *inode, int n);
 extern struct inode *nilfs_new_inode(struct inode *, umode_t);
-extern void nilfs_free_inode(struct inode *);
 extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 extern void nilfs_set_inode_flags(struct inode *);
 extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *);
@@ -289,7 +288,6 @@ static inline int nilfs_mark_inode_dirty_sync(struct inode *inode)
 
 /* super.c */
 extern struct inode *nilfs_alloc_inode(struct super_block *);
-extern void nilfs_destroy_inode(struct inode *);
 
 extern __printf(3, 4)
 void __nilfs_msg(struct super_block *sb, const char *level,
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 26290aa1023f..5729ee86da9a 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -155,21 +155,14 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
 	return &ii->vfs_inode;
 }
 
-static void nilfs_i_callback(struct rcu_head *head)
+static void nilfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-
 	if (nilfs_is_metadata_file_inode(inode))
 		nilfs_mdt_destroy(inode);
 
 	kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
 }
 
-void nilfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, nilfs_i_callback);
-}
-
 static int nilfs_sync_super(struct super_block *sb, int flag)
 {
 	struct the_nilfs *nilfs = sb->s_fs_info;
@@ -686,7 +679,7 @@ static int nilfs_show_options(struct seq_file *seq, struct dentry *dentry)
 
 static const struct super_operations nilfs_sops = {
 	.alloc_inode    = nilfs_alloc_inode,
-	.destroy_inode  = nilfs_destroy_inode,
+	.free_inode     = nilfs_free_inode,
 	.dirty_inode    = nilfs_dirty_inode,
 	.evict_inode    = nilfs_evict_inode,
 	.put_super      = nilfs_put_super,
-- 
2.11.0


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

* [RFC PATCH 29/62] dlmfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (26 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 28/62] nilfs2: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 30/62] ocfs2: " Al Viro
                     ` (32 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ocfs2/dlmfs/dlmfs.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c
index 8decbe95dcec..98885181e1fe 100644
--- a/fs/ocfs2/dlmfs/dlmfs.c
+++ b/fs/ocfs2/dlmfs/dlmfs.c
@@ -349,17 +349,11 @@ static struct inode *dlmfs_alloc_inode(struct super_block *sb)
 	return &ip->ip_vfs_inode;
 }
 
-static void dlmfs_i_callback(struct rcu_head *head)
+static void dlmfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(dlmfs_inode_cache, DLMFS_I(inode));
 }
 
-static void dlmfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, dlmfs_i_callback);
-}
-
 static void dlmfs_evict_inode(struct inode *inode)
 {
 	int status;
@@ -605,7 +599,7 @@ static const struct inode_operations dlmfs_root_inode_operations = {
 static const struct super_operations dlmfs_ops = {
 	.statfs		= simple_statfs,
 	.alloc_inode	= dlmfs_alloc_inode,
-	.destroy_inode	= dlmfs_destroy_inode,
+	.free_inode	= dlmfs_free_inode,
 	.evict_inode	= dlmfs_evict_inode,
 	.drop_inode	= generic_delete_inode,
 };
-- 
2.11.0


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

* [RFC PATCH 30/62] ocfs2: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (27 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 29/62] dlmfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 31/62] openpromfs: " Al Viro
                     ` (31 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ocfs2/super.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 96ae7cedd487..7982a93e630f 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -134,7 +134,7 @@ static int ocfs2_get_sector(struct super_block *sb,
 			    int block,
 			    int sect_size);
 static struct inode *ocfs2_alloc_inode(struct super_block *sb);
-static void ocfs2_destroy_inode(struct inode *inode);
+static void ocfs2_free_inode(struct inode *inode);
 static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend);
 static int ocfs2_enable_quotas(struct ocfs2_super *osb);
 static void ocfs2_disable_quotas(struct ocfs2_super *osb);
@@ -147,7 +147,7 @@ static struct dquot **ocfs2_get_dquots(struct inode *inode)
 static const struct super_operations ocfs2_sops = {
 	.statfs		= ocfs2_statfs,
 	.alloc_inode	= ocfs2_alloc_inode,
-	.destroy_inode	= ocfs2_destroy_inode,
+	.free_inode	= ocfs2_free_inode,
 	.drop_inode	= ocfs2_drop_inode,
 	.evict_inode	= ocfs2_evict_inode,
 	.sync_fs	= ocfs2_sync_fs,
@@ -575,17 +575,11 @@ static struct inode *ocfs2_alloc_inode(struct super_block *sb)
 	return &oi->vfs_inode;
 }
 
-static void ocfs2_i_callback(struct rcu_head *head)
+static void ocfs2_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
 }
 
-static void ocfs2_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, ocfs2_i_callback);
-}
-
 static unsigned long long ocfs2_max_file_offset(unsigned int bbits,
 						unsigned int cbits)
 {
-- 
2.11.0


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

* [RFC PATCH 31/62] openpromfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (28 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 30/62] ocfs2: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 32/62] procfs: " Al Viro
                     ` (30 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/openpromfs/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 1b2d0d2fe2ee..46655e454c55 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -336,17 +336,11 @@ static struct inode *openprom_alloc_inode(struct super_block *sb)
 	return &oi->vfs_inode;
 }
 
-static void openprom_i_callback(struct rcu_head *head)
+static void openprom_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(op_inode_cachep, OP_I(inode));
 }
 
-static void openprom_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, openprom_i_callback);
-}
-
 static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
 {
 	struct inode *inode;
@@ -375,7 +369,7 @@ static int openprom_remount(struct super_block *sb, int *flags, char *data)
 
 static const struct super_operations openprom_sops = {
 	.alloc_inode	= openprom_alloc_inode,
-	.destroy_inode	= openprom_destroy_inode,
+	.free_inode	= openprom_free_inode,
 	.statfs		= simple_statfs,
 	.remount_fs	= openprom_remount,
 };
-- 
2.11.0


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

* [RFC PATCH 32/62] procfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (29 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 31/62] openpromfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 33/62] qnx4: " Al Viro
                     ` (29 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/proc/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index fc7e38def174..5f8d215b3fd0 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -72,17 +72,11 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void proc_i_callback(struct rcu_head *head)
+static void proc_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(proc_inode_cachep, PROC_I(inode));
 }
 
-static void proc_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, proc_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct proc_inode *ei = (struct proc_inode *) foo;
@@ -123,7 +117,7 @@ static int proc_show_options(struct seq_file *seq, struct dentry *root)
 
 const struct super_operations proc_sops = {
 	.alloc_inode	= proc_alloc_inode,
-	.destroy_inode	= proc_destroy_inode,
+	.free_inode	= proc_free_inode,
 	.drop_inode	= generic_delete_inode,
 	.evict_inode	= proc_evict_inode,
 	.statfs		= simple_statfs,
-- 
2.11.0


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

* [RFC PATCH 33/62] qnx4: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (30 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 32/62] procfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 34/62] qnx6: " Al Viro
                     ` (28 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/qnx4/inode.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 3d46fe302fcb..48c70aa4a3ec 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -28,14 +28,14 @@
 static const struct super_operations qnx4_sops;
 
 static struct inode *qnx4_alloc_inode(struct super_block *sb);
-static void qnx4_destroy_inode(struct inode *inode);
+static void qnx4_free_inode(struct inode *inode);
 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
 static int qnx4_statfs(struct dentry *, struct kstatfs *);
 
 static const struct super_operations qnx4_sops =
 {
 	.alloc_inode	= qnx4_alloc_inode,
-	.destroy_inode	= qnx4_destroy_inode,
+	.free_inode	= qnx4_free_inode,
 	.statfs		= qnx4_statfs,
 	.remount_fs	= qnx4_remount,
 };
@@ -342,17 +342,11 @@ static struct inode *qnx4_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void qnx4_i_callback(struct rcu_head *head)
+static void qnx4_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
 }
 
-static void qnx4_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, qnx4_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
-- 
2.11.0


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

* [RFC PATCH 34/62] qnx6: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (31 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 33/62] qnx4: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 35/62] reiserfs: convert " Al Viro
                     ` (27 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/qnx6/inode.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c
index 4aeb26bcb4d0..59cf45f6be49 100644
--- a/fs/qnx6/inode.c
+++ b/fs/qnx6/inode.c
@@ -29,14 +29,14 @@ static const struct super_operations qnx6_sops;
 
 static void qnx6_put_super(struct super_block *sb);
 static struct inode *qnx6_alloc_inode(struct super_block *sb);
-static void qnx6_destroy_inode(struct inode *inode);
+static void qnx6_free_inode(struct inode *inode);
 static int qnx6_remount(struct super_block *sb, int *flags, char *data);
 static int qnx6_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int qnx6_show_options(struct seq_file *seq, struct dentry *root);
 
 static const struct super_operations qnx6_sops = {
 	.alloc_inode	= qnx6_alloc_inode,
-	.destroy_inode	= qnx6_destroy_inode,
+	.free_inode	= qnx6_free_inode,
 	.put_super	= qnx6_put_super,
 	.statfs		= qnx6_statfs,
 	.remount_fs	= qnx6_remount,
@@ -602,17 +602,11 @@ static struct inode *qnx6_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void qnx6_i_callback(struct rcu_head *head)
+static void qnx6_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(qnx6_inode_cachep, QNX6_I(inode));
 }
 
-static void qnx6_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, qnx6_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct qnx6_inode_info *ei = (struct qnx6_inode_info *) foo;
-- 
2.11.0


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

* [RFC PATCH 35/62] reiserfs: convert to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (32 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 34/62] qnx6: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 36/62] romfs: " Al Viro
                     ` (26 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/reiserfs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 1fc934d24459..ab028ea0e561 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -650,17 +650,11 @@ static struct inode *reiserfs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void reiserfs_i_callback(struct rcu_head *head)
+static void reiserfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
 }
 
-static void reiserfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, reiserfs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
@@ -815,7 +809,7 @@ static struct dquot **reiserfs_get_dquots(struct inode *inode)
 
 static const struct super_operations reiserfs_sops = {
 	.alloc_inode = reiserfs_alloc_inode,
-	.destroy_inode = reiserfs_destroy_inode,
+	.free_inode = reiserfs_free_inode,
 	.write_inode = reiserfs_write_inode,
 	.dirty_inode = reiserfs_dirty_inode,
 	.evict_inode = reiserfs_evict_inode,
-- 
2.11.0


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

* [RFC PATCH 36/62] romfs: convert to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (33 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 35/62] reiserfs: convert " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 37/62] squashfs: switch " Al Viro
                     ` (25 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/romfs/super.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 6ccb51993a76..7d580f7c3f1d 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -381,18 +381,11 @@ static struct inode *romfs_alloc_inode(struct super_block *sb)
 /*
  * return a spent inode to the slab cache
  */
-static void romfs_i_callback(struct rcu_head *head)
+static void romfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-
 	kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));
 }
 
-static void romfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, romfs_i_callback);
-}
-
 /*
  * get filesystem statistics
  */
@@ -439,7 +432,7 @@ static int romfs_remount(struct super_block *sb, int *flags, char *data)
 
 static const struct super_operations romfs_super_ops = {
 	.alloc_inode	= romfs_alloc_inode,
-	.destroy_inode	= romfs_destroy_inode,
+	.free_inode	= romfs_free_inode,
 	.statfs		= romfs_statfs,
 	.remount_fs	= romfs_remount,
 };
-- 
2.11.0


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

* [RFC PATCH 37/62] squashfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (34 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 36/62] romfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 38/62] ubifs: " Al Viro
                     ` (24 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/squashfs/super.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 40e657386fa5..767046d9f65d 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -473,18 +473,11 @@ static struct inode *squashfs_alloc_inode(struct super_block *sb)
 }
 
 
-static void squashfs_i_callback(struct rcu_head *head)
+static void squashfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode));
 }
 
-static void squashfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, squashfs_i_callback);
-}
-
-
 static struct file_system_type squashfs_fs_type = {
 	.owner = THIS_MODULE,
 	.name = "squashfs",
@@ -496,7 +489,7 @@ MODULE_ALIAS_FS("squashfs");
 
 static const struct super_operations squashfs_super_ops = {
 	.alloc_inode = squashfs_alloc_inode,
-	.destroy_inode = squashfs_destroy_inode,
+	.free_inode = squashfs_free_inode,
 	.statfs = squashfs_statfs,
 	.put_super = squashfs_put_super,
 	.remount_fs = squashfs_remount
-- 
2.11.0


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

* [RFC PATCH 38/62] ubifs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (35 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 37/62] squashfs: switch " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 39/62] udf: " Al Viro
                     ` (23 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ubifs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 12628184772c..c2307c423638 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -272,19 +272,13 @@ static struct inode *ubifs_alloc_inode(struct super_block *sb)
 	return &ui->vfs_inode;
 };
 
-static void ubifs_i_callback(struct rcu_head *head)
+static void ubifs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct ubifs_inode *ui = ubifs_inode(inode);
 	kfree(ui->data);
 	kmem_cache_free(ubifs_inode_slab, ui);
 }
 
-static void ubifs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, ubifs_i_callback);
-}
-
 /*
  * Note, Linux write-back code calls this without 'i_mutex'.
  */
@@ -1977,7 +1971,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 
 const struct super_operations ubifs_super_operations = {
 	.alloc_inode   = ubifs_alloc_inode,
-	.destroy_inode = ubifs_destroy_inode,
+	.free_inode    = ubifs_free_inode,
 	.put_super     = ubifs_put_super,
 	.write_inode   = ubifs_write_inode,
 	.evict_inode   = ubifs_evict_inode,
-- 
2.11.0


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

* [RFC PATCH 39/62] udf: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (36 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 38/62] ubifs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 40/62] sysv: " Al Viro
                     ` (22 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/udf/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/udf/super.c b/fs/udf/super.c
index ffd8038ff728..f64691f2168a 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -161,17 +161,11 @@ static struct inode *udf_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void udf_i_callback(struct rcu_head *head)
+static void udf_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(udf_inode_cachep, UDF_I(inode));
 }
 
-static void udf_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, udf_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct udf_inode_info *ei = (struct udf_inode_info *)foo;
@@ -206,7 +200,7 @@ static void destroy_inodecache(void)
 /* Superblock operations */
 static const struct super_operations udf_sb_ops = {
 	.alloc_inode	= udf_alloc_inode,
-	.destroy_inode	= udf_destroy_inode,
+	.free_inode	= udf_free_in_core_inode,
 	.write_inode	= udf_write_inode,
 	.evict_inode	= udf_evict_inode,
 	.put_super	= udf_put_super,
-- 
2.11.0


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

* [RFC PATCH 40/62] sysv: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (37 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 39/62] udf: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 41/62] coda: " Al Viro
                     ` (21 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/sysv/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 273736f41be3..02b1d9d0c182 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -313,17 +313,11 @@ static struct inode *sysv_alloc_inode(struct super_block *sb)
 	return &si->vfs_inode;
 }
 
-static void sysv_i_callback(struct rcu_head *head)
+static void sysv_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(sysv_inode_cachep, SYSV_I(inode));
 }
 
-static void sysv_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, sysv_i_callback);
-}
-
 static void init_once(void *p)
 {
 	struct sysv_inode_info *si = (struct sysv_inode_info *)p;
@@ -333,7 +327,7 @@ static void init_once(void *p)
 
 const struct super_operations sysv_sops = {
 	.alloc_inode	= sysv_alloc_inode,
-	.destroy_inode	= sysv_destroy_inode,
+	.free_inode	= sysv_free_in_core_inode,
 	.write_inode	= sysv_write_inode,
 	.evict_inode	= sysv_evict_inode,
 	.put_super	= sysv_put_super,
-- 
2.11.0


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

* [RFC PATCH 41/62] coda: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (38 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 40/62] sysv: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 42/62] ufs: " Al Viro
                     ` (20 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/coda/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 97424cf206c0..23f6ebd08e80 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -54,17 +54,11 @@ static struct inode *coda_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void coda_i_callback(struct rcu_head *head)
+static void coda_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(coda_inode_cachep, ITOC(inode));
 }
 
-static void coda_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, coda_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct coda_inode_info *ei = (struct coda_inode_info *) foo;
@@ -104,7 +98,7 @@ static int coda_remount(struct super_block *sb, int *flags, char *data)
 static const struct super_operations coda_super_operations =
 {
 	.alloc_inode	= coda_alloc_inode,
-	.destroy_inode	= coda_destroy_inode,
+	.free_inode	= coda_free_inode,
 	.evict_inode	= coda_evict_inode,
 	.put_super	= coda_put_super,
 	.statfs		= coda_statfs,
-- 
2.11.0


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

* [RFC PATCH 42/62] ufs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (39 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 41/62] coda: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 43/62] mqueue: " Al Viro
                     ` (19 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ufs/super.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index a4e07e910f1b..84c0c5178cd2 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1449,17 +1449,11 @@ static struct inode *ufs_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void ufs_i_callback(struct rcu_head *head)
+static void ufs_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(ufs_inode_cachep, UFS_I(inode));
 }
 
-static void ufs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, ufs_i_callback);
-}
-
 static void init_once(void *foo)
 {
 	struct ufs_inode_info *ei = (struct ufs_inode_info *) foo;
@@ -1494,7 +1488,7 @@ static void destroy_inodecache(void)
 
 static const struct super_operations ufs_super_ops = {
 	.alloc_inode	= ufs_alloc_inode,
-	.destroy_inode	= ufs_destroy_inode,
+	.free_inode	= ufs_free_in_core_inode,
 	.write_inode	= ufs_write_inode,
 	.evict_inode	= ufs_evict_inode,
 	.put_super	= ufs_put_super,
-- 
2.11.0


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

* [RFC PATCH 43/62] mqueue: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (40 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 42/62] ufs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 44/62] bpf: " Al Viro
                     ` (18 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 ipc/mqueue.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index aea30530c472..ba44164ea1f9 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -419,17 +419,11 @@ static struct inode *mqueue_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void mqueue_i_callback(struct rcu_head *head)
+static void mqueue_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(mqueue_inode_cachep, MQUEUE_I(inode));
 }
 
-static void mqueue_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, mqueue_i_callback);
-}
-
 static void mqueue_evict_inode(struct inode *inode)
 {
 	struct mqueue_inode_info *info;
@@ -1562,7 +1556,7 @@ static const struct file_operations mqueue_file_operations = {
 
 static const struct super_operations mqueue_super_ops = {
 	.alloc_inode = mqueue_alloc_inode,
-	.destroy_inode = mqueue_destroy_inode,
+	.free_inode = mqueue_free_inode,
 	.evict_inode = mqueue_evict_inode,
 	.statfs = simple_statfs,
 };
-- 
2.11.0


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

* [RFC PATCH 44/62] bpf: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (41 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 43/62] mqueue: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 18:07     ` Alexei Starovoitov
  2019-04-16 17:53   ` [RFC PATCH 45/62] rpcpipe: " Al Viro
                     ` (17 subsequent siblings)
  60 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 kernel/bpf/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index 4a8f390a2b82..bc53e5b20ddc 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -566,9 +566,8 @@ static int bpf_show_options(struct seq_file *m, struct dentry *root)
 	return 0;
 }
 
-static void bpf_destroy_inode_deferred(struct rcu_head *head)
+static void bpf_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	enum bpf_type type;
 
 	if (S_ISLNK(inode->i_mode))
@@ -578,16 +577,11 @@ static void bpf_destroy_inode_deferred(struct rcu_head *head)
 	free_inode_nonrcu(inode);
 }
 
-static void bpf_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, bpf_destroy_inode_deferred);
-}
-
 static const struct super_operations bpf_super_ops = {
 	.statfs		= simple_statfs,
 	.drop_inode	= generic_delete_inode,
 	.show_options	= bpf_show_options,
-	.destroy_inode	= bpf_destroy_inode,
+	.free_inode	= bpf_free_inode,
 };
 
 enum {
-- 
2.11.0


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

* [RFC PATCH 45/62] rpcpipe: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (42 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 44/62] bpf: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 46/62] apparmor: " Al Viro
                     ` (16 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 net/sunrpc/rpc_pipe.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 69663681bf9d..979d23646e33 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -202,18 +202,11 @@ rpc_alloc_inode(struct super_block *sb)
 }
 
 static void
-rpc_i_callback(struct rcu_head *head)
+rpc_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(rpc_inode_cachep, RPC_I(inode));
 }
 
-static void
-rpc_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, rpc_i_callback);
-}
-
 static int
 rpc_pipe_open(struct inode *inode, struct file *filp)
 {
@@ -1123,7 +1116,7 @@ void rpc_remove_cache_dir(struct dentry *dentry)
  */
 static const struct super_operations s_ops = {
 	.alloc_inode	= rpc_alloc_inode,
-	.destroy_inode	= rpc_destroy_inode,
+	.free_inode	= rpc_free_inode,
 	.statfs		= simple_statfs,
 };
 
-- 
2.11.0


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

* [RFC PATCH 46/62] apparmor: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (43 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 45/62] rpcpipe: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 47/62] securityfs: " Al Viro
                     ` (15 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 security/apparmor/apparmorfs.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index b9298d2e8165..9ab5613fe07c 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -123,22 +123,16 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
 	return 0;
 }
 
-static void aafs_i_callback(struct rcu_head *head)
+static void aafs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	if (S_ISLNK(inode->i_mode))
 		kfree(inode->i_link);
 	free_inode_nonrcu(inode);
 }
 
-static void aafs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, aafs_i_callback);
-}
-
 static const struct super_operations aafs_super_ops = {
 	.statfs = simple_statfs,
-	.destroy_inode = aafs_destroy_inode,
+	.free_inode = aafs_free_inode,
 	.show_path = aafs_show_path,
 };
 
-- 
2.11.0


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

* [RFC PATCH 47/62] securityfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (44 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 46/62] apparmor: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 48/62] ntfs: " Al Viro
                     ` (14 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 security/inode.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/security/inode.c b/security/inode.c
index 421dd72b5876..aacc4dabba7d 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -27,22 +27,16 @@
 static struct vfsmount *mount;
 static int mount_count;
 
-static void securityfs_i_callback(struct rcu_head *head)
+static void securityfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	if (S_ISLNK(inode->i_mode))
 		kfree(inode->i_link);
 	free_inode_nonrcu(inode);
 }
 
-static void securityfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, securityfs_i_callback);
-}
-
 static const struct super_operations securityfs_super_operations = {
 	.statfs		= simple_statfs,
-	.destroy_inode	= securityfs_destroy_inode,
+	.free_inode	= securityfs_free_inode,
 };
 
 static int fill_super(struct super_block *sb, void *data, int silent)
-- 
2.11.0


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

* [RFC PATCH 48/62] ntfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (45 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 47/62] securityfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 49/62] dax: make use of ->free_inode() Al Viro
                     ` (13 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

move the synchronous stuff from ->destroy_inode() to ->evict_inode(),
turn the RCU-delayed part into ->free_inode()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ntfs/inode.c | 17 ++++-------------
 fs/ntfs/inode.h |  2 +-
 fs/ntfs/super.c |  2 +-
 3 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index bd3221cbdd95..fb1a2b49a5da 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -332,23 +332,11 @@ struct inode *ntfs_alloc_big_inode(struct super_block *sb)
 	return NULL;
 }
 
-static void ntfs_i_callback(struct rcu_head *head)
+void ntfs_free_big_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(ntfs_big_inode_cache, NTFS_I(inode));
 }
 
-void ntfs_destroy_big_inode(struct inode *inode)
-{
-	ntfs_inode *ni = NTFS_I(inode);
-
-	ntfs_debug("Entering.");
-	BUG_ON(ni->page);
-	if (!atomic_dec_and_test(&ni->count))
-		BUG();
-	call_rcu(&inode->i_rcu, ntfs_i_callback);
-}
-
 static inline ntfs_inode *ntfs_alloc_extent_inode(void)
 {
 	ntfs_inode *ni;
@@ -2287,6 +2275,9 @@ void ntfs_evict_big_inode(struct inode *vi)
 			ni->ext.base_ntfs_ino = NULL;
 		}
 	}
+	BUG_ON(ni->page);
+	if (!atomic_dec_and_test(&ni->count))
+		BUG();
 	return;
 }
 
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index b3c3469de6cb..58c8fd2948d3 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -278,7 +278,7 @@ extern struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name,
 		u32 name_len);
 
 extern struct inode *ntfs_alloc_big_inode(struct super_block *sb);
-extern void ntfs_destroy_big_inode(struct inode *inode);
+extern void ntfs_free_big_inode(struct inode *inode);
 extern void ntfs_evict_big_inode(struct inode *vi);
 
 extern void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni);
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index bb7159f697f2..887ea8b3b000 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2676,7 +2676,7 @@ static int ntfs_write_inode(struct inode *vi, struct writeback_control *wbc)
  */
 static const struct super_operations ntfs_sops = {
 	.alloc_inode	= ntfs_alloc_big_inode,	  /* VFS: Allocate new inode. */
-	.destroy_inode	= ntfs_destroy_big_inode, /* VFS: Deallocate inode. */
+	.free_inode	= ntfs_free_big_inode, /* VFS: Deallocate inode. */
 #ifdef NTFS_RW
 	.write_inode	= ntfs_write_inode,	/* VFS: Write dirty inode to
 						   disk. */
-- 
2.11.0


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

* [RFC PATCH 49/62] dax: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (46 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 48/62] ntfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-18 12:16     ` Jan Kara
  2019-04-16 17:53   ` [RFC PATCH 50/62] afs: switch to " Al Viro
                     ` (12 subsequent siblings)
  60 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

we might want to drop ->destroy_inode() there - it's used only for
WARN_ON() now, and AFAICS that could be moved to ->evict_inode()
if we had one...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/dax/super.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 0a339b85133e..bbd57ca0634a 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -412,11 +412,9 @@ static struct dax_device *to_dax_dev(struct inode *inode)
 	return container_of(inode, struct dax_device, inode);
 }
 
-static void dax_i_callback(struct rcu_head *head)
+static void dax_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct dax_device *dax_dev = to_dax_dev(inode);
-
 	kfree(dax_dev->host);
 	dax_dev->host = NULL;
 	if (inode->i_rdev)
@@ -427,16 +425,15 @@ static void dax_i_callback(struct rcu_head *head)
 static void dax_destroy_inode(struct inode *inode)
 {
 	struct dax_device *dax_dev = to_dax_dev(inode);
-
 	WARN_ONCE(test_bit(DAXDEV_ALIVE, &dax_dev->flags),
 			"kill_dax() must be called before final iput()\n");
-	call_rcu(&inode->i_rcu, dax_i_callback);
 }
 
 static const struct super_operations dax_sops = {
 	.statfs = simple_statfs,
 	.alloc_inode = dax_alloc_inode,
 	.destroy_inode = dax_destroy_inode,
+	.free_inode = dax_free_inode,
 	.drop_inode = generic_delete_inode,
 };
 
-- 
2.11.0


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

* [RFC PATCH 50/62] afs: switch to use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (47 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 49/62] dax: make use of ->free_inode() Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 51/62] btrfs: use ->free_inode() Al Viro
                     ` (11 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

debugging printks left in ->destroy_inode() and so's the
update of inode count; we could take the latter to RCU-delayed
part (would take only moving the check on module exit past
rcu_barrier() there), but debugging output ought to either
stay where it is or go into ->evict_inode()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/afs/super.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/fs/afs/super.c b/fs/afs/super.c
index 5adf012b8e27..bab89763119b 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -33,6 +33,7 @@ static void afs_i_init_once(void *foo);
 static void afs_kill_super(struct super_block *sb);
 static struct inode *afs_alloc_inode(struct super_block *sb);
 static void afs_destroy_inode(struct inode *inode);
+static void afs_free_inode(struct inode *inode);
 static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int afs_show_devname(struct seq_file *m, struct dentry *root);
 static int afs_show_options(struct seq_file *m, struct dentry *root);
@@ -56,6 +57,7 @@ static const struct super_operations afs_super_ops = {
 	.alloc_inode	= afs_alloc_inode,
 	.drop_inode	= afs_drop_inode,
 	.destroy_inode	= afs_destroy_inode,
+	.free_inode	= afs_free_inode,
 	.evict_inode	= afs_evict_inode,
 	.show_devname	= afs_show_devname,
 	.show_options	= afs_show_options,
@@ -660,11 +662,9 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
 	return &vnode->vfs_inode;
 }
 
-static void afs_i_callback(struct rcu_head *head)
+static void afs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	struct afs_vnode *vnode = AFS_FS_I(inode);
-	kmem_cache_free(afs_inode_cachep, vnode);
+	kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode));
 }
 
 /*
@@ -680,7 +680,6 @@ static void afs_destroy_inode(struct inode *inode)
 
 	ASSERTCMP(vnode->cb_interest, ==, NULL);
 
-	call_rcu(&inode->i_rcu, afs_i_callback);
 	atomic_dec(&afs_count_active_inodes);
 }
 
-- 
2.11.0


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

* [RFC PATCH 51/62] btrfs: use ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (48 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 50/62] afs: switch to " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 52/62] ceph: " Al Viro
                     ` (10 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

a lot of stuff remains in ->destroy_inode()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/btrfs/ctree.h | 1 +
 fs/btrfs/inode.c | 7 ++-----
 fs/btrfs/super.c | 1 +
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b3642367a595..5260a9263d73 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3267,6 +3267,7 @@ void btrfs_evict_inode(struct inode *inode);
 int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
 struct inode *btrfs_alloc_inode(struct super_block *sb);
 void btrfs_destroy_inode(struct inode *inode);
+void btrfs_free_inode(struct inode *inode);
 int btrfs_drop_inode(struct inode *inode);
 int __init btrfs_init_cachep(void);
 void __cold btrfs_destroy_cachep(void);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 82fdda8ff5ab..aeb31c2dc14e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -9206,9 +9206,8 @@ void btrfs_test_destroy_inode(struct inode *inode)
 }
 #endif
 
-static void btrfs_i_callback(struct rcu_head *head)
+void btrfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
 }
 
@@ -9234,7 +9233,7 @@ void btrfs_destroy_inode(struct inode *inode)
 	 * created.
 	 */
 	if (!root)
-		goto free;
+		return;
 
 	while (1) {
 		ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1);
@@ -9252,8 +9251,6 @@ void btrfs_destroy_inode(struct inode *inode)
 	btrfs_qgroup_check_reserved_leak(inode);
 	inode_tree_del(inode);
 	btrfs_drop_extent_cache(BTRFS_I(inode), 0, (u64)-1, 0);
-free:
-	call_rcu(&inode->i_rcu, btrfs_i_callback);
 }
 
 int btrfs_drop_inode(struct inode *inode)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 120e4340792a..236f812091a3 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -2298,6 +2298,7 @@ static const struct super_operations btrfs_super_ops = {
 	.show_devname	= btrfs_show_devname,
 	.alloc_inode	= btrfs_alloc_inode,
 	.destroy_inode	= btrfs_destroy_inode,
+	.free_inode	= btrfs_free_inode,
 	.statfs		= btrfs_statfs,
 	.remount_fs	= btrfs_remount,
 	.freeze_fs	= btrfs_freeze,
-- 
2.11.0


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

* [RFC PATCH 52/62] ceph: use ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (49 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 51/62] btrfs: use ->free_inode() Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 53/62] ecryptfs: make use of ->free_inode() Al Viro
                     ` (9 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

a lot of non-delayed work in this case; all of that is left in
->destroy_inode()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ceph/inode.c | 5 +----
 fs/ceph/super.c | 1 +
 fs/ceph/super.h | 1 +
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 2d61ddda9bf5..dc0a36d0adf8 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -519,9 +519,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
 	return &ci->vfs_inode;
 }
 
-static void ceph_i_callback(struct rcu_head *head)
+void ceph_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct ceph_inode_info *ci = ceph_inode(inode);
 
 	kfree(ci->i_symlink);
@@ -581,8 +580,6 @@ void ceph_destroy_inode(struct inode *inode)
 		ceph_buffer_put(ci->i_xattrs.prealloc_blob);
 
 	ceph_put_string(rcu_dereference_raw(ci->i_layout.pool_ns));
-
-	call_rcu(&inode->i_rcu, ceph_i_callback);
 }
 
 int ceph_drop_inode(struct inode *inode)
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 6d5bb2f74612..285edda4fc3b 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -848,6 +848,7 @@ static void ceph_umount_begin(struct super_block *sb)
 static const struct super_operations ceph_super_ops = {
 	.alloc_inode	= ceph_alloc_inode,
 	.destroy_inode	= ceph_destroy_inode,
+	.free_inode	= ceph_free_inode,
 	.write_inode    = ceph_write_inode,
 	.drop_inode	= ceph_drop_inode,
 	.sync_fs        = ceph_sync_fs,
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 16c03188578e..c5b4a05905c0 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -874,6 +874,7 @@ extern const struct inode_operations ceph_file_iops;
 
 extern struct inode *ceph_alloc_inode(struct super_block *sb);
 extern void ceph_destroy_inode(struct inode *inode);
+extern void ceph_free_inode(struct inode *inode);
 extern int ceph_drop_inode(struct inode *inode);
 
 extern struct inode *ceph_get_inode(struct super_block *sb,
-- 
2.11.0


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

* [RFC PATCH 53/62] ecryptfs: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (50 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 52/62] ceph: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 54/62] ext4: " Al Viro
                     ` (8 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

no idea if crypto destruction could be moved there as well

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ecryptfs/super.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 85411ceb0508..c3e511f2b6c0 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -67,9 +67,8 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
 	return inode;
 }
 
-static void ecryptfs_i_callback(struct rcu_head *head)
+static void ecryptfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct ecryptfs_inode_info *inode_info;
 	inode_info = ecryptfs_inode_to_private(inode);
 
@@ -92,7 +91,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
 	inode_info = ecryptfs_inode_to_private(inode);
 	BUG_ON(inode_info->lower_file);
 	ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
-	call_rcu(&inode->i_rcu, ecryptfs_i_callback);
 }
 
 /**
@@ -186,6 +184,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct dentry *root)
 const struct super_operations ecryptfs_sops = {
 	.alloc_inode = ecryptfs_alloc_inode,
 	.destroy_inode = ecryptfs_destroy_inode,
+	.free_inode = ecryptfs_free_inode,
 	.statfs = ecryptfs_statfs,
 	.remount_fs = NULL,
 	.evict_inode = ecryptfs_evict_inode,
-- 
2.11.0


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

* [RFC PATCH 54/62] ext4: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (51 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 53/62] ecryptfs: make use of ->free_inode() Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-18 12:10     ` Jan Kara
  2019-04-16 17:53   ` [RFC PATCH 55/62] fuse: switch to ->free_inode() Al Viro
                     ` (7 subsequent siblings)
  60 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

the rest of this ->destroy_inode() instance could probably be folded
into ext4_evict_inode()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/ext4/super.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 6ed4eb81e674..981f702848e7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1107,9 +1107,8 @@ static int ext4_drop_inode(struct inode *inode)
 	return drop;
 }
 
-static void ext4_i_callback(struct rcu_head *head)
+static void ext4_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
 }
 
@@ -1124,7 +1123,6 @@ static void ext4_destroy_inode(struct inode *inode)
 				true);
 		dump_stack();
 	}
-	call_rcu(&inode->i_rcu, ext4_i_callback);
 }
 
 static void init_once(void *foo)
@@ -1402,6 +1400,7 @@ static const struct quotactl_ops ext4_qctl_operations = {
 
 static const struct super_operations ext4_sops = {
 	.alloc_inode	= ext4_alloc_inode,
+	.free_inode	= ext4_free_in_core_inode,
 	.destroy_inode	= ext4_destroy_inode,
 	.write_inode	= ext4_write_inode,
 	.dirty_inode	= ext4_dirty_inode,
-- 
2.11.0


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

* [RFC PATCH 55/62] fuse: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (52 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 54/62] ext4: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 56/62] jfs: " Al Viro
                     ` (6 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

fuse_destroy_inode() is gone - sanity checks that need the stack
trace of the caller get moved into ->evict_inode(), the rest joins
the RCU-delayed part which becomes ->free_inode().

While we are at it, don't just pass the address of what happens
to be the first member of structure to kmem_cache_free() -
get_fuse_inode() is there for purpose and it gives the proper
container_of() use.  No behaviour change, but verifying correctness
is easier that way.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/fuse/inode.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index ec5d9953dfb6..f485d09d14df 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -107,34 +107,30 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
 	return inode;
 }
 
-static void fuse_i_callback(struct rcu_head *head)
-{
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	kmem_cache_free(fuse_inode_cachep, inode);
-}
-
-static void fuse_destroy_inode(struct inode *inode)
+static void fuse_free_inode(struct inode *inode)
 {
 	struct fuse_inode *fi = get_fuse_inode(inode);
-	if (S_ISREG(inode->i_mode) && !is_bad_inode(inode)) {
-		WARN_ON(!list_empty(&fi->write_files));
-		WARN_ON(!list_empty(&fi->queued_writes));
-	}
+
 	mutex_destroy(&fi->mutex);
 	kfree(fi->forget);
-	call_rcu(&inode->i_rcu, fuse_i_callback);
+	kmem_cache_free(fuse_inode_cachep, fi);
 }
 
 static void fuse_evict_inode(struct inode *inode)
 {
+	struct fuse_inode *fi = get_fuse_inode(inode);
+
 	truncate_inode_pages_final(&inode->i_data);
 	clear_inode(inode);
 	if (inode->i_sb->s_flags & SB_ACTIVE) {
 		struct fuse_conn *fc = get_fuse_conn(inode);
-		struct fuse_inode *fi = get_fuse_inode(inode);
 		fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup);
 		fi->forget = NULL;
 	}
+	if (S_ISREG(inode->i_mode) && !is_bad_inode(inode)) {
+		WARN_ON(!list_empty(&fi->write_files));
+		WARN_ON(!list_empty(&fi->queued_writes));
+	}
 }
 
 static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -814,7 +810,7 @@ static const struct export_operations fuse_export_operations = {
 
 static const struct super_operations fuse_super_operations = {
 	.alloc_inode    = fuse_alloc_inode,
-	.destroy_inode  = fuse_destroy_inode,
+	.free_inode     = fuse_free_inode,
 	.evict_inode	= fuse_evict_inode,
 	.write_inode	= fuse_write_inode,
 	.drop_inode	= generic_delete_inode,
-- 
2.11.0


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

* [RFC PATCH 56/62] jfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (53 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 55/62] fuse: switch to ->free_inode() Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 57/62] overlayfs: make use of ->free_inode() Al Viro
                     ` (5 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

synchronous part can be moved to ->evict_inode(), the rest -
->free_inode() fodder

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/jfs/inode.c | 13 +++++++++++++
 fs/jfs/super.c | 24 +++---------------------
 2 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 805ae9e8944a..f2b92b292abe 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -31,6 +31,7 @@
 #include "jfs_extent.h"
 #include "jfs_unicode.h"
 #include "jfs_debug.h"
+#include "jfs_dmap.h"
 
 
 struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
@@ -150,6 +151,8 @@ int jfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 
 void jfs_evict_inode(struct inode *inode)
 {
+	struct jfs_inode_info *ji = JFS_IP(inode);
+
 	jfs_info("In jfs_evict_inode, inode = 0x%p", inode);
 
 	if (!inode->i_nlink && !is_bad_inode(inode)) {
@@ -173,6 +176,16 @@ void jfs_evict_inode(struct inode *inode)
 	}
 	clear_inode(inode);
 	dquot_drop(inode);
+
+	BUG_ON(!list_empty(&ji->anon_inode_list));
+
+	spin_lock_irq(&ji->ag_lock);
+	if (ji->active_ag != -1) {
+		struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
+		atomic_dec(&bmap->db_active[ji->active_ag]);
+		ji->active_ag = -1;
+	}
+	spin_unlock_irq(&ji->ag_lock);
 }
 
 void jfs_dirty_inode(struct inode *inode, int flags)
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 65d8fc87ab11..9454831bbd71 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -124,27 +124,9 @@ static struct inode *jfs_alloc_inode(struct super_block *sb)
 	return &jfs_inode->vfs_inode;
 }
 
-static void jfs_i_callback(struct rcu_head *head)
+static void jfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	struct jfs_inode_info *ji = JFS_IP(inode);
-	kmem_cache_free(jfs_inode_cachep, ji);
-}
-
-static void jfs_destroy_inode(struct inode *inode)
-{
-	struct jfs_inode_info *ji = JFS_IP(inode);
-
-	BUG_ON(!list_empty(&ji->anon_inode_list));
-
-	spin_lock_irq(&ji->ag_lock);
-	if (ji->active_ag != -1) {
-		struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
-		atomic_dec(&bmap->db_active[ji->active_ag]);
-		ji->active_ag = -1;
-	}
-	spin_unlock_irq(&ji->ag_lock);
-	call_rcu(&inode->i_rcu, jfs_i_callback);
+	kmem_cache_free(jfs_inode_cachep, JFS_IP(inode));
 }
 
 static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -912,7 +894,7 @@ static int jfs_quota_off(struct super_block *sb, int type)
 
 static const struct super_operations jfs_super_operations = {
 	.alloc_inode	= jfs_alloc_inode,
-	.destroy_inode	= jfs_destroy_inode,
+	.free_inode	= jfs_free_inode,
 	.dirty_inode	= jfs_dirty_inode,
 	.write_inode	= jfs_write_inode,
 	.evict_inode	= jfs_evict_inode,
-- 
2.11.0


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

* [RFC PATCH 57/62] overlayfs: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (54 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 56/62] jfs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 58/62] hugetlb: " Al Viro
                     ` (4 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

synchronous parts are left in ->destroy_inode()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/overlayfs/super.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 0116735cc321..5ec4fc2f5d7e 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -190,11 +190,13 @@ static struct inode *ovl_alloc_inode(struct super_block *sb)
 	return &oi->vfs_inode;
 }
 
-static void ovl_i_callback(struct rcu_head *head)
+static void ovl_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
+	struct ovl_inode *oi = OVL_I(inode);
 
-	kmem_cache_free(ovl_inode_cachep, OVL_I(inode));
+	kfree(oi->redirect);
+	mutex_destroy(&oi->lock);
+	kmem_cache_free(ovl_inode_cachep, oi);
 }
 
 static void ovl_destroy_inode(struct inode *inode)
@@ -207,10 +209,6 @@ static void ovl_destroy_inode(struct inode *inode)
 		ovl_dir_cache_free(inode);
 	else
 		iput(oi->lowerdata);
-	kfree(oi->redirect);
-	mutex_destroy(&oi->lock);
-
-	call_rcu(&inode->i_rcu, ovl_i_callback);
 }
 
 static void ovl_free_fs(struct ovl_fs *ofs)
@@ -377,6 +375,7 @@ static int ovl_remount(struct super_block *sb, int *flags, char *data)
 
 static const struct super_operations ovl_super_operations = {
 	.alloc_inode	= ovl_alloc_inode,
+	.free_inode	= ovl_free_inode,
 	.destroy_inode	= ovl_destroy_inode,
 	.drop_inode	= generic_delete_inode,
 	.put_super	= ovl_put_super,
-- 
2.11.0


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

* [RFC PATCH 58/62] hugetlb: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (55 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 57/62] overlayfs: make use of ->free_inode() Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 59/62] shmem: " Al Viro
                     ` (3 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

moving synchronous parts of ->destroy_inode() to ->evict_inode() is
not possible here - they are balancing the stuff done in ->alloc_inode(),
not the things acquired while using it or sanity checks.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/hugetlbfs/inode.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 9285dd4f4b1c..c74ef4426282 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1051,9 +1051,8 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
 	return &p->vfs_inode;
 }
 
-static void hugetlbfs_i_callback(struct rcu_head *head)
+static void hugetlbfs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
 }
 
@@ -1061,7 +1060,6 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
 {
 	hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
 	mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
-	call_rcu(&inode->i_rcu, hugetlbfs_i_callback);
 }
 
 static const struct address_space_operations hugetlbfs_aops = {
@@ -1108,6 +1106,7 @@ static const struct inode_operations hugetlbfs_inode_operations = {
 
 static const struct super_operations hugetlbfs_ops = {
 	.alloc_inode    = hugetlbfs_alloc_inode,
+	.free_inode     = hugetlbfs_free_inode,
 	.destroy_inode  = hugetlbfs_destroy_inode,
 	.evict_inode	= hugetlbfs_evict_inode,
 	.statfs		= hugetlbfs_statfs,
-- 
2.11.0


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

* [RFC PATCH 59/62] shmem: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (56 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 58/62] hugetlb: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 60/62] orangefs: " Al Viro
                     ` (2 subsequent siblings)
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

same situation as for hugetlbfs

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 mm/shmem.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index b3db3779a30a..dbb7a6dadba7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3635,9 +3635,8 @@ static struct inode *shmem_alloc_inode(struct super_block *sb)
 	return &info->vfs_inode;
 }
 
-static void shmem_destroy_callback(struct rcu_head *head)
+static void shmem_free_in_core_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
 	if (S_ISLNK(inode->i_mode))
 		kfree(inode->i_link);
 	kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
@@ -3647,7 +3646,6 @@ static void shmem_destroy_inode(struct inode *inode)
 {
 	if (S_ISREG(inode->i_mode))
 		mpol_free_shared_policy(&SHMEM_I(inode)->policy);
-	call_rcu(&inode->i_rcu, shmem_destroy_callback);
 }
 
 static void shmem_init_inode(void *foo)
@@ -3738,6 +3736,7 @@ static const struct inode_operations shmem_special_inode_operations = {
 
 static const struct super_operations shmem_ops = {
 	.alloc_inode	= shmem_alloc_inode,
+	.free_inode	= shmem_free_in_core_inode,
 	.destroy_inode	= shmem_destroy_inode,
 #ifdef CONFIG_TMPFS
 	.statfs		= shmem_statfs,
-- 
2.11.0


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

* [RFC PATCH 60/62] orangefs: make use of ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (57 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 59/62] shmem: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-22 21:14     ` Mike Marshall
  2019-04-16 17:53   ` [RFC PATCH 61/62] sockfs: switch to ->free_inode() Al Viro
  2019-04-16 17:53   ` [RFC PATCH 62/62] coallocate socket->wq with socket itself Al Viro
  60 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/orangefs/super.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c
index dfaee90d30bd..3784f7e8b603 100644
--- a/fs/orangefs/super.c
+++ b/fs/orangefs/super.c
@@ -124,11 +124,9 @@ static struct inode *orangefs_alloc_inode(struct super_block *sb)
 	return &orangefs_inode->vfs_inode;
 }
 
-static void orangefs_i_callback(struct rcu_head *head)
+static void orangefs_free_inode(struct inode *inode)
 {
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
-	kmem_cache_free(orangefs_inode_cache, orangefs_inode);
+	kmem_cache_free(orangefs_inode_cache, ORANGEFS_I(inode));
 }
 
 static void orangefs_destroy_inode(struct inode *inode)
@@ -138,8 +136,6 @@ static void orangefs_destroy_inode(struct inode *inode)
 	gossip_debug(GOSSIP_SUPER_DEBUG,
 			"%s: deallocated %p destroying inode %pU\n",
 			__func__, orangefs_inode, get_khandle_from_ino(inode));
-
-	call_rcu(&inode->i_rcu, orangefs_i_callback);
 }
 
 /*
@@ -299,6 +295,7 @@ void fsid_key_table_finalize(void)
 
 static const struct super_operations orangefs_s_ops = {
 	.alloc_inode = orangefs_alloc_inode,
+	.free_inode = orangefs_free_inode,
 	.destroy_inode = orangefs_destroy_inode,
 	.drop_inode = generic_delete_inode,
 	.statfs = orangefs_statfs,
-- 
2.11.0


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

* [RFC PATCH 61/62] sockfs: switch to ->free_inode()
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (58 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 60/62] orangefs: " Al Viro
@ 2019-04-16 17:53   ` Al Viro
  2019-04-16 17:53   ` [RFC PATCH 62/62] coallocate socket->wq with socket itself Al Viro
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

we do have an RCU-delayed part there already (freeing the wq),
so it's not like the pipe situation; moreover, it might be
worth considering coallocating wq with the rest of struct sock_alloc.
->sk_wq in struct sock would remain a pointer as it is, but
the object it normally points to would be coallocated with
struct socket...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 net/socket.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 8255f5bda0aa..6953a049fb82 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -263,12 +263,12 @@ static struct inode *sock_alloc_inode(struct super_block *sb)
 	return &ei->vfs_inode;
 }
 
-static void sock_destroy_inode(struct inode *inode)
+static void sock_free_inode(struct inode *inode)
 {
 	struct socket_alloc *ei;
 
 	ei = container_of(inode, struct socket_alloc, vfs_inode);
-	kfree_rcu(ei->socket.wq, rcu);
+	kfree(ei->socket.wq);
 	kmem_cache_free(sock_inode_cachep, ei);
 }
 
@@ -293,7 +293,7 @@ static void init_inodecache(void)
 
 static const struct super_operations sockfs_ops = {
 	.alloc_inode	= sock_alloc_inode,
-	.destroy_inode	= sock_destroy_inode,
+	.free_inode	= sock_free_inode,
 	.statfs		= simple_statfs,
 };
 
-- 
2.11.0


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

* [RFC PATCH 62/62] coallocate socket->wq with socket itself
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
                     ` (59 preceding siblings ...)
  2019-04-16 17:53   ` [RFC PATCH 61/62] sockfs: switch to ->free_inode() Al Viro
@ 2019-04-16 17:53   ` Al Viro
  60 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-04-16 17:53 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

From: Al Viro <viro@zeniv.linux.org.uk>

socket->wq is assign-once, set when we are initializing both
struct socket it's in and struct socket_wq it points to.  As the
matter of fact, the only reason for separate allocation was the
ability to RCU-delay freeing of socket_wq.  RCU-delaying the
freeing of socket itself gets rid of that need, so we can just
fold struct socket_wq into the end of struct socket and simplify
the life both for sock_alloc_inode() (one allocation instead of
two) and for tun/tap oddballs, where we used to embed struct socket
and struct socket_wq into the same structure (now - embedding just
the struct socket).

Note that reference to struct socket_wq in struct sock does remain
a reference - that's unchanged.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 drivers/net/tap.c      |  5 ++---
 drivers/net/tun.c      |  8 +++-----
 include/linux/if_tap.h |  1 -
 include/linux/net.h    |  4 ++--
 include/net/sock.h     |  4 ++--
 net/core/sock.c        |  2 +-
 net/socket.c           | 19 +++++--------------
 7 files changed, 15 insertions(+), 28 deletions(-)

diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 2ea9b4976f4a..249bfd85b65c 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -519,8 +519,7 @@ static int tap_open(struct inode *inode, struct file *file)
 		goto err;
 	}
 
-	RCU_INIT_POINTER(q->sock.wq, &q->wq);
-	init_waitqueue_head(&q->wq.wait);
+	init_waitqueue_head(&q->sock.wq.wait);
 	q->sock.type = SOCK_RAW;
 	q->sock.state = SS_CONNECTED;
 	q->sock.file = file;
@@ -578,7 +577,7 @@ static __poll_t tap_poll(struct file *file, poll_table *wait)
 		goto out;
 
 	mask = 0;
-	poll_wait(file, &q->wq.wait, wait);
+	poll_wait(file, &q->sock.wq.wait, wait);
 
 	if (!ptr_ring_empty(&q->ring))
 		mask |= EPOLLIN | EPOLLRDNORM;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e9ca1c088d0b..f404d1588e9c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -169,7 +169,6 @@ struct tun_pcpu_stats {
 struct tun_file {
 	struct sock sk;
 	struct socket socket;
-	struct socket_wq wq;
 	struct tun_struct __rcu *tun;
 	struct fasync_struct *fasync;
 	/* only used for fasnyc */
@@ -2174,7 +2173,7 @@ static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)
 		goto out;
 	}
 
-	add_wait_queue(&tfile->wq.wait, &wait);
+	add_wait_queue(&tfile->socket.wq.wait, &wait);
 
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -2194,7 +2193,7 @@ static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err)
 	}
 
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&tfile->wq.wait, &wait);
+	remove_wait_queue(&tfile->socket.wq.wait, &wait);
 
 out:
 	*err = error;
@@ -3417,8 +3416,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 	tfile->flags = 0;
 	tfile->ifindex = 0;
 
-	init_waitqueue_head(&tfile->wq.wait);
-	RCU_INIT_POINTER(tfile->socket.wq, &tfile->wq);
+	init_waitqueue_head(&tfile->socket.wq.wait);
 
 	tfile->socket.file = file;
 	tfile->socket.ops = &tun_socket_ops;
diff --git a/include/linux/if_tap.h b/include/linux/if_tap.h
index 8e66866c11be..915a187cfabd 100644
--- a/include/linux/if_tap.h
+++ b/include/linux/if_tap.h
@@ -62,7 +62,6 @@ struct tap_dev {
 struct tap_queue {
 	struct sock sk;
 	struct socket sock;
-	struct socket_wq wq;
 	int vnet_hdr_sz;
 	struct tap_dev __rcu *tap;
 	struct file *file;
diff --git a/include/linux/net.h b/include/linux/net.h
index c606c72311d0..6979057c7c86 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -120,11 +120,11 @@ struct socket {
 
 	unsigned long		flags;
 
-	struct socket_wq	*wq;
-
 	struct file		*file;
 	struct sock		*sk;
 	const struct proto_ops	*ops;
+
+	struct socket_wq	wq;
 };
 
 struct vm_area_struct;
diff --git a/include/net/sock.h b/include/net/sock.h
index 8de5ee258b93..0e1975b6202f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1811,7 +1811,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
 {
 	WARN_ON(parent->sk);
 	write_lock_bh(&sk->sk_callback_lock);
-	rcu_assign_pointer(sk->sk_wq, parent->wq);
+	rcu_assign_pointer(sk->sk_wq, &parent->wq);
 	parent->sk = sk;
 	sk_set_socket(sk, parent);
 	sk->sk_uid = SOCK_INODE(parent)->i_uid;
@@ -2095,7 +2095,7 @@ static inline void sock_poll_wait(struct file *filp, struct socket *sock,
 				  poll_table *p)
 {
 	if (!poll_does_not_wait(p)) {
-		poll_wait(filp, &sock->wq->wait, p);
+		poll_wait(filp, &sock->wq.wait, p);
 		/* We need to be sure we are in sync with the
 		 * socket flags modification.
 		 *
diff --git a/net/core/sock.c b/net/core/sock.c
index 782343bb925b..11af1ee7d542 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2842,7 +2842,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
 
 	if (sock) {
 		sk->sk_type	=	sock->type;
-		RCU_INIT_POINTER(sk->sk_wq, sock->wq);
+		RCU_INIT_POINTER(sk->sk_wq, &sock->wq);
 		sock->sk	=	sk;
 		sk->sk_uid	=	SOCK_INODE(sock)->i_uid;
 	} else {
diff --git a/net/socket.c b/net/socket.c
index 6953a049fb82..7d3d043fc56f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -239,20 +239,13 @@ static struct kmem_cache *sock_inode_cachep __ro_after_init;
 static struct inode *sock_alloc_inode(struct super_block *sb)
 {
 	struct socket_alloc *ei;
-	struct socket_wq *wq;
 
 	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
 	if (!ei)
 		return NULL;
-	wq = kmalloc(sizeof(*wq), GFP_KERNEL);
-	if (!wq) {
-		kmem_cache_free(sock_inode_cachep, ei);
-		return NULL;
-	}
-	init_waitqueue_head(&wq->wait);
-	wq->fasync_list = NULL;
-	wq->flags = 0;
-	ei->socket.wq = wq;
+	init_waitqueue_head(&ei->socket.wq.wait);
+	ei->socket.wq.fasync_list = NULL;
+	ei->socket.wq.flags = 0;
 
 	ei->socket.state = SS_UNCONNECTED;
 	ei->socket.flags = 0;
@@ -268,7 +261,6 @@ static void sock_free_inode(struct inode *inode)
 	struct socket_alloc *ei;
 
 	ei = container_of(inode, struct socket_alloc, vfs_inode);
-	kfree(ei->socket.wq);
 	kmem_cache_free(sock_inode_cachep, ei);
 }
 
@@ -604,7 +596,7 @@ static void __sock_release(struct socket *sock, struct inode *inode)
 		module_put(owner);
 	}
 
-	if (sock->wq->fasync_list)
+	if (sock->wq.fasync_list)
 		pr_err("%s: fasync list not empty!\n", __func__);
 
 	if (!sock->file) {
@@ -1263,13 +1255,12 @@ static int sock_fasync(int fd, struct file *filp, int on)
 {
 	struct socket *sock = filp->private_data;
 	struct sock *sk = sock->sk;
-	struct socket_wq *wq;
+	struct socket_wq *wq = &sock->wq;
 
 	if (sk == NULL)
 		return -EINVAL;
 
 	lock_sock(sk);
-	wq = sock->wq;
 	fasync_helper(fd, filp, on, &wq->fasync_list);
 
 	if (!wq->fasync_list)
-- 
2.11.0


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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-16 17:49 [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Al Viro
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
@ 2019-04-16 18:01 ` Linus Torvalds
  2019-04-30  3:09   ` Al Viro
  2019-04-17 15:55 ` David Sterba
  2 siblings, 1 reply; 82+ messages in thread
From: Linus Torvalds @ 2019-04-16 18:01 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-fsdevel, Linux List Kernel Mailing

On Tue, Apr 16, 2019 at 10:49 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
>  83 files changed, 241 insertions(+), 516 deletions(-)

I think this single line is pretty convincing on its own. Ignoring
docs and fs/inode.c, we have

 80 files changed, 190 insertions(+), 494 deletions(-)

IOW, just over 300 lines of boiler plate code removed.

The additions are

 - Ten more lines of actual code in fs/inode.c (and that's not
actually added complexity, it looks simpler if anything - most of it
is the new "i_callback()" helper function)

 - 19 lines of doc updates.

So it absolutely looks fine to me.

I only skimmed through the actual filesystem (and one networking)
patches, but they looked like trivial conversions to a better
interface.

                    Linus

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

* Re: [RFC PATCH 44/62] bpf: switch to ->free_inode()
  2019-04-16 17:53   ` [RFC PATCH 44/62] bpf: " Al Viro
@ 2019-04-16 18:07     ` Alexei Starovoitov
  2019-04-16 21:34       ` Song Liu
  0 siblings, 1 reply; 82+ messages in thread
From: Alexei Starovoitov @ 2019-04-16 18:07 UTC (permalink / raw)
  To: Al Viro, Daniel Borkmann, bpf; +Cc: Linus Torvalds, LKML, Linux-Fsdevel

On Tue, Apr 16, 2019 at 10:55 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> From: Al Viro <viro@zeniv.linux.org.uk>
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Acked-by: Alexei Starovoitov <ast@kernel.org>

> ---
>  kernel/bpf/inode.c | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
> index 4a8f390a2b82..bc53e5b20ddc 100644
> --- a/kernel/bpf/inode.c
> +++ b/kernel/bpf/inode.c
> @@ -566,9 +566,8 @@ static int bpf_show_options(struct seq_file *m, struct dentry *root)
>         return 0;
>  }
>
> -static void bpf_destroy_inode_deferred(struct rcu_head *head)
> +static void bpf_free_inode(struct inode *inode)
>  {
> -       struct inode *inode = container_of(head, struct inode, i_rcu);
>         enum bpf_type type;
>
>         if (S_ISLNK(inode->i_mode))
> @@ -578,16 +577,11 @@ static void bpf_destroy_inode_deferred(struct rcu_head *head)
>         free_inode_nonrcu(inode);
>  }
>
> -static void bpf_destroy_inode(struct inode *inode)
> -{
> -       call_rcu(&inode->i_rcu, bpf_destroy_inode_deferred);
> -}
> -
>  static const struct super_operations bpf_super_ops = {
>         .statfs         = simple_statfs,
>         .drop_inode     = generic_delete_inode,
>         .show_options   = bpf_show_options,
> -       .destroy_inode  = bpf_destroy_inode,
> +       .free_inode     = bpf_free_inode,
>  };
>
>  enum {
> --
> 2.11.0
>

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

* Re: [RFC PATCH 44/62] bpf: switch to ->free_inode()
  2019-04-16 18:07     ` Alexei Starovoitov
@ 2019-04-16 21:34       ` Song Liu
  0 siblings, 0 replies; 82+ messages in thread
From: Song Liu @ 2019-04-16 21:34 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Al Viro, Daniel Borkmann, bpf, Linus Torvalds, LKML, Linux-Fsdevel

On Tue, Apr 16, 2019 at 11:07 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Tue, Apr 16, 2019 at 10:55 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
> >
> > From: Al Viro <viro@zeniv.linux.org.uk>
> >
> > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
>
> Acked-by: Alexei Starovoitov <ast@kernel.org>

Acked-by: Song Liu <songliubraving@fb.com>

>
> > ---
> >  kernel/bpf/inode.c | 10 ++--------
> >  1 file changed, 2 insertions(+), 8 deletions(-)
> >
> > diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
> > index 4a8f390a2b82..bc53e5b20ddc 100644
> > --- a/kernel/bpf/inode.c
> > +++ b/kernel/bpf/inode.c
> > @@ -566,9 +566,8 @@ static int bpf_show_options(struct seq_file *m, struct dentry *root)
> >         return 0;
> >  }
> >
> > -static void bpf_destroy_inode_deferred(struct rcu_head *head)
> > +static void bpf_free_inode(struct inode *inode)
> >  {
> > -       struct inode *inode = container_of(head, struct inode, i_rcu);
> >         enum bpf_type type;
> >
> >         if (S_ISLNK(inode->i_mode))
> > @@ -578,16 +577,11 @@ static void bpf_destroy_inode_deferred(struct rcu_head *head)
> >         free_inode_nonrcu(inode);
> >  }
> >
> > -static void bpf_destroy_inode(struct inode *inode)
> > -{
> > -       call_rcu(&inode->i_rcu, bpf_destroy_inode_deferred);
> > -}
> > -
> >  static const struct super_operations bpf_super_ops = {
> >         .statfs         = simple_statfs,
> >         .drop_inode     = generic_delete_inode,
> >         .show_options   = bpf_show_options,
> > -       .destroy_inode  = bpf_destroy_inode,
> > +       .free_inode     = bpf_free_inode,
> >  };
> >
> >  enum {
> > --
> > 2.11.0
> >

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-16 17:49 [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Al Viro
  2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
  2019-04-16 18:01 ` [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Linus Torvalds
@ 2019-04-17 15:55 ` David Sterba
  2 siblings, 0 replies; 82+ messages in thread
From: David Sterba @ 2019-04-17 15:55 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, linux-fsdevel, linux-kernel

On Tue, Apr 16, 2019 at 06:49:00PM +0100, Al Viro wrote:
> 	We have a lot of boilerplate in ->destroy_inode()
> instances, and several filesystems got the things wrong
> in that area.  The patchset below attempts to deal with that.
> 
> 	New method (void ->free_inode(inode)) is introduced,
> and RCU-delayed parts of ->destroy_inode() are moved there.
> The change is backwards-compatible - unmodified filesystem
> will behave as it used to.  Rules:
> 	->destroy_inode		->free_inode
> 	f			g		f(), rcu-delayed g()
> 	f			NULL		f()
> 	NULL			g		rcu-delayed g()
> 	NULL			NULL		rcu-delayed free_inode_nonrcu()
> IOW, NULL/NULL acts as NULL/free_inode_nonrcu.
> 
> 	For a lot of filesystems ->destroy_inode() used to consist
> only of call_rcu(foo_i_callback, &inode->i_rcu).  Those simply get
> rid of ->destroy_inode() and have the callback (with saner prototype)
> become their ->free_inode().

The simplified API looks good to me. For btrfs and affs bits:

Acked-by: David Sterba <dsterba@suse.com>

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

* Re: [RFC PATCH 54/62] ext4: make use of ->free_inode()
  2019-04-16 17:53   ` [RFC PATCH 54/62] ext4: " Al Viro
@ 2019-04-18 12:10     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2019-04-18 12:10 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, linux-kernel, linux-fsdevel

On Tue 16-04-19 18:53:32, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
> 
> the rest of this ->destroy_inode() instance could probably be folded
> into ext4_evict_inode()
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

You're right about the possibility of moving the check to
ext4_evict_inode() (probably ext4_clear_inode() would be the best). But we
can leave that for later.

								Honza

> ---
>  fs/ext4/super.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 6ed4eb81e674..981f702848e7 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -1107,9 +1107,8 @@ static int ext4_drop_inode(struct inode *inode)
>  	return drop;
>  }
>  
> -static void ext4_i_callback(struct rcu_head *head)
> +static void ext4_free_in_core_inode(struct inode *inode)
>  {
> -	struct inode *inode = container_of(head, struct inode, i_rcu);
>  	kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
>  }
>  
> @@ -1124,7 +1123,6 @@ static void ext4_destroy_inode(struct inode *inode)
>  				true);
>  		dump_stack();
>  	}
> -	call_rcu(&inode->i_rcu, ext4_i_callback);
>  }
>  
>  static void init_once(void *foo)
> @@ -1402,6 +1400,7 @@ static const struct quotactl_ops ext4_qctl_operations = {
>  
>  static const struct super_operations ext4_sops = {
>  	.alloc_inode	= ext4_alloc_inode,
> +	.free_inode	= ext4_free_in_core_inode,
>  	.destroy_inode	= ext4_destroy_inode,
>  	.write_inode	= ext4_write_inode,
>  	.dirty_inode	= ext4_dirty_inode,
> -- 
> 2.11.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

* Re: [RFC PATCH 49/62] dax: make use of ->free_inode()
  2019-04-16 17:53   ` [RFC PATCH 49/62] dax: make use of ->free_inode() Al Viro
@ 2019-04-18 12:16     ` Jan Kara
  2019-04-18 16:58       ` Dan Williams
  0 siblings, 1 reply; 82+ messages in thread
From: Jan Kara @ 2019-04-18 12:16 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, linux-kernel, linux-fsdevel, Dan Williams

On Tue 16-04-19 18:53:27, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
> 
> we might want to drop ->destroy_inode() there - it's used only for
> WARN_ON() now, and AFAICS that could be moved to ->evict_inode()
> if we had one...
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
>  drivers/dax/super.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)

Added Dan to CC since I'm not sure how closely he follows fsdevel. The
patch looks good to me FWIW so feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza


> 
> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 0a339b85133e..bbd57ca0634a 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
> @@ -412,11 +412,9 @@ static struct dax_device *to_dax_dev(struct inode *inode)
>  	return container_of(inode, struct dax_device, inode);
>  }
>  
> -static void dax_i_callback(struct rcu_head *head)
> +static void dax_free_inode(struct inode *inode)
>  {
> -	struct inode *inode = container_of(head, struct inode, i_rcu);
>  	struct dax_device *dax_dev = to_dax_dev(inode);
> -
>  	kfree(dax_dev->host);
>  	dax_dev->host = NULL;
>  	if (inode->i_rdev)
> @@ -427,16 +425,15 @@ static void dax_i_callback(struct rcu_head *head)
>  static void dax_destroy_inode(struct inode *inode)
>  {
>  	struct dax_device *dax_dev = to_dax_dev(inode);
> -
>  	WARN_ONCE(test_bit(DAXDEV_ALIVE, &dax_dev->flags),
>  			"kill_dax() must be called before final iput()\n");
> -	call_rcu(&inode->i_rcu, dax_i_callback);
>  }
>  
>  static const struct super_operations dax_sops = {
>  	.statfs = simple_statfs,
>  	.alloc_inode = dax_alloc_inode,
>  	.destroy_inode = dax_destroy_inode,
> +	.free_inode = dax_free_inode,
>  	.drop_inode = generic_delete_inode,
>  };
>  
> -- 
> 2.11.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

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

* Re: [RFC PATCH 05/62] erofs: switch to ->free_inode()
  2019-04-16 17:52   ` [RFC PATCH 05/62] erofs: " Al Viro
@ 2019-04-18 14:01     ` Gao Xiang
  0 siblings, 0 replies; 82+ messages in thread
From: Gao Xiang @ 2019-04-18 14:01 UTC (permalink / raw)
  To: Al Viro
  Cc: Linus Torvalds, linux-kernel, linux-fsdevel, linux-erofs,
	Chao Yu, Miao Xie



On 2019/4/17 1:52, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

It seems more clear than before :) Thanks for taking erofs into consideration as well,

Acked-by: Gao Xiang <gaoxiang25@huawei.com>

Thanks,
Gao Xiang

> ---
>  drivers/staging/erofs/super.c | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c
> index 15c784fba879..700cbd460807 100644
> --- a/drivers/staging/erofs/super.c
> +++ b/drivers/staging/erofs/super.c
> @@ -57,9 +57,8 @@ static struct inode *alloc_inode(struct super_block *sb)
>  	return &vi->vfs_inode;
>  }
>  
> -static void i_callback(struct rcu_head *head)
> +static void free_inode(struct inode *inode)
>  {
> -	struct inode *inode = container_of(head, struct inode, i_rcu);
>  	struct erofs_vnode *vi = EROFS_V(inode);
>  
>  	/* be careful RCU symlink path (see ext4_inode_info->i_data)! */
> @@ -71,11 +70,6 @@ static void i_callback(struct rcu_head *head)
>  	kmem_cache_free(erofs_inode_cachep, vi);
>  }
>  
> -static void destroy_inode(struct inode *inode)
> -{
> -	call_rcu(&inode->i_rcu, i_callback);
> -}
> -
>  static int superblock_read(struct super_block *sb)
>  {
>  	struct erofs_sb_info *sbi;
> @@ -668,7 +662,7 @@ static int erofs_remount(struct super_block *sb, int *flags, char *data)
>  const struct super_operations erofs_sops = {
>  	.put_super = erofs_put_super,
>  	.alloc_inode = alloc_inode,
> -	.destroy_inode = destroy_inode,
> +	.free_inode = free_inode,
>  	.statfs = erofs_statfs,
>  	.show_options = erofs_show_options,
>  	.remount_fs = erofs_remount,
> 

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

* Re: [RFC PATCH 49/62] dax: make use of ->free_inode()
  2019-04-18 12:16     ` Jan Kara
@ 2019-04-18 16:58       ` Dan Williams
  0 siblings, 0 replies; 82+ messages in thread
From: Dan Williams @ 2019-04-18 16:58 UTC (permalink / raw)
  To: Jan Kara
  Cc: Al Viro, Linus Torvalds, Linux Kernel Mailing List, linux-fsdevel

On Thu, Apr 18, 2019 at 5:16 AM Jan Kara <jack@suse.cz> wrote:
>
> On Tue 16-04-19 18:53:27, Al Viro wrote:
> > From: Al Viro <viro@zeniv.linux.org.uk>
> >
> > we might want to drop ->destroy_inode() there - it's used only for
> > WARN_ON() now, and AFAICS that could be moved to ->evict_inode()
> > if we had one...
> >
> > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> > ---
> >  drivers/dax/super.c | 7 ++-----
> >  1 file changed, 2 insertions(+), 5 deletions(-)
>
> Added Dan to CC since I'm not sure how closely he follows fsdevel. The
> patch looks good to me FWIW so feel free to add:
>
> Reviewed-by: Jan Kara <jack@suse.cz>

Thanks Jan.

Acked-by: Dan Williams <dan.j.williams@intel.com>

Al, I assume you'll merge this with the other free_inode changes.

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

* Re: [RFC PATCH 16/62] f2fs: switch to ->free_inode()
  2019-04-16 17:52   ` [RFC PATCH 16/62] f2fs: " Al Viro
@ 2019-04-20  2:52     ` Chao Yu
  0 siblings, 0 replies; 82+ messages in thread
From: Chao Yu @ 2019-04-20  2:52 UTC (permalink / raw)
  To: Al Viro, Linus Torvalds; +Cc: linux-kernel, linux-fsdevel

On 2019/4/17 1:52, Al Viro wrote:
> From: Al Viro <viro@zeniv.linux.org.uk>
> 
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Acked-by: Chao Yu <yuchao0@huawei.com>

Thanks,

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

* Re: [RFC PATCH 60/62] orangefs: make use of ->free_inode()
  2019-04-16 17:53   ` [RFC PATCH 60/62] orangefs: " Al Viro
@ 2019-04-22 21:14     ` Mike Marshall
  2019-04-22 21:56       ` Linus Torvalds
  0 siblings, 1 reply; 82+ messages in thread
From: Mike Marshall @ 2019-04-22 21:14 UTC (permalink / raw)
  To: Al Viro, Martin Brandenburg; +Cc: Linus Torvalds, LKML, linux-fsdevel

Hi Al...

I applied your "new inode method: ->free_inode()" and
"orangefs: make use of ->free_inode()" to our pagecache
branch (I hope to get it pulled in the next merge window).

I had to modify your "orangefs: make use of ->free_inode()" a
little, since Martin Brandenburg had already modified orangefs_i_callback
for the pagecache branch. I don't know for sure that my modifications
aren't nonsense :-) but I do know for sure that everything runs
with no xfstests regressions. I'll see what Martin thinks about
my changes...

orangefs_destroy_inode is pretty much a no-op now, so I guess
we'll get rid of it...

Acked-by: Mike Marshall <hubcap@omnibond.com>

Thanks...

-Mike


[root@vm1 linux]# git diff HEAD^ fs/orangefs/super.c
diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c
index 8fa30c13b7ed..f82ac9373443 100644
--- a/fs/orangefs/super.c
+++ b/fs/orangefs/super.c
@@ -125,20 +125,18 @@ static struct inode *orangefs_alloc_inode(struct
super_block *sb)
        return &orangefs_inode->vfs_inode;
 }

-static void orangefs_i_callback(struct rcu_head *head)
+static void orangefs_free_inode(struct inode *inode)
 {
-       struct inode *inode = container_of(head, struct inode, i_rcu);
-       struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
        struct orangefs_cached_xattr *cx;
        struct hlist_node *tmp;
        int i;

-       hash_for_each_safe(orangefs_inode->xattr_cache, i, tmp, cx, node) {
+       hash_for_each_safe(ORANGEFS_I(inode)->xattr_cache, i, tmp, cx, node) {
                hlist_del(&cx->node);
                kfree(cx);
        }

-       kmem_cache_free(orangefs_inode_cache, orangefs_inode);
+       kmem_cache_free(orangefs_inode_cache, ORANGEFS_I(inode));
 }

 static void orangefs_destroy_inode(struct inode *inode)
@@ -148,8 +146,6 @@ static void orangefs_destroy_inode(struct inode *inode)
        gossip_debug(GOSSIP_SUPER_DEBUG,
                        "%s: deallocated %p destroying inode %pU\n",
                        __func__, orangefs_inode, get_khandle_from_ino(inode));
-
-       call_rcu(&inode->i_rcu, orangefs_i_callback);
 }

 static int orangefs_write_inode(struct inode *inode,
@@ -316,6 +312,7 @@ void fsid_key_table_finalize(void)

 static const struct super_operations orangefs_s_ops = {
        .alloc_inode = orangefs_alloc_inode,
+       .free_inode = orangefs_free_inode,
        .destroy_inode = orangefs_destroy_inode,
        .write_inode = orangefs_write_inode,
        .drop_inode = generic_delete_inode,

On Tue, Apr 16, 2019 at 1:55 PM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> From: Al Viro <viro@zeniv.linux.org.uk>
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
>  fs/orangefs/super.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c
> index dfaee90d30bd..3784f7e8b603 100644
> --- a/fs/orangefs/super.c
> +++ b/fs/orangefs/super.c
> @@ -124,11 +124,9 @@ static struct inode *orangefs_alloc_inode(struct super_block *sb)
>         return &orangefs_inode->vfs_inode;
>  }
>
> -static void orangefs_i_callback(struct rcu_head *head)
> +static void orangefs_free_inode(struct inode *inode)
>  {
> -       struct inode *inode = container_of(head, struct inode, i_rcu);
> -       struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
> -       kmem_cache_free(orangefs_inode_cache, orangefs_inode);
> +       kmem_cache_free(orangefs_inode_cache, ORANGEFS_I(inode));
>  }
>
>  static void orangefs_destroy_inode(struct inode *inode)
> @@ -138,8 +136,6 @@ static void orangefs_destroy_inode(struct inode *inode)
>         gossip_debug(GOSSIP_SUPER_DEBUG,
>                         "%s: deallocated %p destroying inode %pU\n",
>                         __func__, orangefs_inode, get_khandle_from_ino(inode));
> -
> -       call_rcu(&inode->i_rcu, orangefs_i_callback);
>  }
>
>  /*
> @@ -299,6 +295,7 @@ void fsid_key_table_finalize(void)
>
>  static const struct super_operations orangefs_s_ops = {
>         .alloc_inode = orangefs_alloc_inode,
> +       .free_inode = orangefs_free_inode,
>         .destroy_inode = orangefs_destroy_inode,
>         .drop_inode = generic_delete_inode,
>         .statfs = orangefs_statfs,
> --
> 2.11.0
>

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

* Re: [RFC PATCH 60/62] orangefs: make use of ->free_inode()
  2019-04-22 21:14     ` Mike Marshall
@ 2019-04-22 21:56       ` Linus Torvalds
  2019-04-22 23:10         ` Al Viro
  0 siblings, 1 reply; 82+ messages in thread
From: Linus Torvalds @ 2019-04-22 21:56 UTC (permalink / raw)
  To: Mike Marshall; +Cc: Al Viro, Martin Brandenburg, LKML, linux-fsdevel

On Mon, Apr 22, 2019 at 2:14 PM Mike Marshall <hubcap@omnibond.com> wrote:
>
> I applied your "new inode method: ->free_inode()" and
> "orangefs: make use of ->free_inode()" to our pagecache
> branch (I hope to get it pulled in the next merge window).

Actually, please don't.

Exactly because this needs that common vfs patch, I'd really prefer to
get it all through Al's tree, rather than have individual filesystems
apply their own copies of the common infrastructure commit, and then
apply their changes on top of that.

I can easily handle any trivial conflicts this causes, so that's not a
reason to have each filesystem do it either.

So if this is at the top of your tree, can you just "git reset" it
away and I'll get all the filesystems (and the common infrastructure
commit) all together from Al.

                 Linus

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

* Re: [RFC PATCH 60/62] orangefs: make use of ->free_inode()
  2019-04-22 21:56       ` Linus Torvalds
@ 2019-04-22 23:10         ` Al Viro
  2019-04-22 23:17           ` Mike Marshall
  0 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-22 23:10 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Mike Marshall, Martin Brandenburg, LKML, linux-fsdevel

On Mon, Apr 22, 2019 at 02:56:57PM -0700, Linus Torvalds wrote:
> On Mon, Apr 22, 2019 at 2:14 PM Mike Marshall <hubcap@omnibond.com> wrote:
> >
> > I applied your "new inode method: ->free_inode()" and
> > "orangefs: make use of ->free_inode()" to our pagecache
> > branch (I hope to get it pulled in the next merge window).
> 
> Actually, please don't.
> 
> Exactly because this needs that common vfs patch, I'd really prefer to
> get it all through Al's tree, rather than have individual filesystems
> apply their own copies of the common infrastructure commit, and then
> apply their changes on top of that.
> 
> I can easily handle any trivial conflicts this causes, so that's not a
> reason to have each filesystem do it either.
> 
> So if this is at the top of your tree, can you just "git reset" it
> away and I'll get all the filesystems (and the common infrastructure
> commit) all together from Al.

What's more, seeing the changes in orangefs tree I would rather have
static void orangefs_free_inode(struct inode *inode)
{
	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
	kmem_cache_free(orangefs_inode_cache, orangefs_inode);
}

in that series; not only less noise on merge, but with additional
uses of orangefs_inode in the body from orangefs tree changes
keeping the local variable clearly makes sense...

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

* Re: [RFC PATCH 60/62] orangefs: make use of ->free_inode()
  2019-04-22 23:10         ` Al Viro
@ 2019-04-22 23:17           ` Mike Marshall
  0 siblings, 0 replies; 82+ messages in thread
From: Mike Marshall @ 2019-04-22 23:17 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, Martin Brandenburg, LKML, linux-fsdevel

Hi Linus and Al...

I just wanted Al to know I tested his patch and acked it and that it
there would be
a conflict if our pagecache code got pulled... I wasn't suggesting that I
should get that one part of Al's patch pulled...

>> I can easily handle any trivial conflicts this causes...

Thanks :-)

-Mike

On Mon, Apr 22, 2019 at 7:10 PM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> On Mon, Apr 22, 2019 at 02:56:57PM -0700, Linus Torvalds wrote:
> > On Mon, Apr 22, 2019 at 2:14 PM Mike Marshall <hubcap@omnibond.com> wrote:
> > >
> > > I applied your "new inode method: ->free_inode()" and
> > > "orangefs: make use of ->free_inode()" to our pagecache
> > > branch (I hope to get it pulled in the next merge window).
> >
> > Actually, please don't.
> >
> > Exactly because this needs that common vfs patch, I'd really prefer to
> > get it all through Al's tree, rather than have individual filesystems
> > apply their own copies of the common infrastructure commit, and then
> > apply their changes on top of that.
> >
> > I can easily handle any trivial conflicts this causes, so that's not a
> > reason to have each filesystem do it either.
> >
> > So if this is at the top of your tree, can you just "git reset" it
> > away and I'll get all the filesystems (and the common infrastructure
> > commit) all together from Al.
>
> What's more, seeing the changes in orangefs tree I would rather have
> static void orangefs_free_inode(struct inode *inode)
> {
>         struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
>         kmem_cache_free(orangefs_inode_cache, orangefs_inode);
> }
>
> in that series; not only less noise on merge, but with additional
> uses of orangefs_inode in the body from orangefs tree changes
> keeping the local variable clearly makes sense...

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-16 18:01 ` [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Linus Torvalds
@ 2019-04-30  3:09   ` Al Viro
       [not found]     ` <CAHk-=wiMvCR0iENUVorfU-3EMC7G8RNSeHSQrz9tndP1uSg2BQ@mail.gmail.com>
  2019-04-30  4:18     ` Andreas Dilger
  0 siblings, 2 replies; 82+ messages in thread
From: Al Viro @ 2019-04-30  3:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-fsdevel, Linux List Kernel Mailing

On Tue, Apr 16, 2019 at 11:01:16AM -0700, Linus Torvalds wrote:
> On Tue, Apr 16, 2019 at 10:49 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
> >
> >  83 files changed, 241 insertions(+), 516 deletions(-)
> 
> I think this single line is pretty convincing on its own. Ignoring
> docs and fs/inode.c, we have
> 
>  80 files changed, 190 insertions(+), 494 deletions(-)
> 
> IOW, just over 300 lines of boiler plate code removed.
> 
> The additions are
> 
>  - Ten more lines of actual code in fs/inode.c (and that's not
> actually added complexity, it looks simpler if anything - most of it
> is the new "i_callback()" helper function)
> 
>  - 19 lines of doc updates.
> 
> So it absolutely looks fine to me.
> 
> I only skimmed through the actual filesystem (and one networking)
> patches, but they looked like trivial conversions to a better
> interface.

... except that this callback can (and always could) get executed after
freeing struct super_block.  So we can't just dereference ->i_sb->s_op
and expect to survive; the table ->s_op pointed to will still be there,
but ->i_sb might very well have been freed, with all its contents overwritten.
We need to copy the callback into struct inode itself, unfortunately.
The following incremental fixes it; I'm going to fold it into the first
commit in there.

diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 9d80f9e0855e..b8d3ddd8b8db 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -655,3 +655,11 @@ in your dentry operations instead.
 		* if ->free_inode() is non-NULL, it gets scheduled by call_rcu()
 		* combination of NULL ->destroy_inode and NULL ->free_inode is
 		  treated as NULL/free_inode_nonrcu, to preserve the compatibility.
+
+	Note that the callback (be it via ->free_inode() or explicit call_rcu()
+	in ->destroy_inode()) is *NOT* ordered wrt superblock destruction;
+	as the matter of fact, the superblock and all associated structures
+	might be already gone.  The filesystem driver is guaranteed to be still
+	there, but that's it.  Freeing memory in the callback is fine; doing
+	more than that is possible, but requires a lot of care and is best
+	avoided.
diff --git a/fs/inode.c b/fs/inode.c
index fb45590d284e..855dad43b11d 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -164,6 +164,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 	inode->i_wb_frn_avg_time = 0;
 	inode->i_wb_frn_history = 0;
 #endif
+	inode->free_inode = sb->s_op->free_inode;
 
 	if (security_inode_alloc(inode))
 		goto out;
@@ -211,8 +212,8 @@ EXPORT_SYMBOL(free_inode_nonrcu);
 static void i_callback(struct rcu_head *head)
 {
 	struct inode *inode = container_of(head, struct inode, i_rcu);
-	if (inode->i_sb->s_op->free_inode)
-		inode->i_sb->s_op->free_inode(inode);
+	if (inode->free_inode)
+		inode->free_inode(inode);
 	else
 		free_inode_nonrcu(inode);
 }
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2e9b9f87caca..5ed6b39e588e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -718,6 +718,7 @@ struct inode {
 #endif
 
 	void			*i_private; /* fs or device private pointer */
+	void (*free_inode)(struct inode *);
 } __randomize_layout;
 
 static inline unsigned int i_blocksize(const struct inode *node)

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
       [not found]     ` <CAHk-=wiMvCR0iENUVorfU-3EMC7G8RNSeHSQrz9tndP1uSg2BQ@mail.gmail.com>
@ 2019-04-30  4:00       ` Al Viro
  2019-05-01  1:59         ` Al Viro
  0 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-30  4:00 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-fsdevel, Linux List Kernel Mailing

On Mon, Apr 29, 2019 at 08:37:29PM -0700, Linus Torvalds wrote:
> On Mon, Apr 29, 2019, 20:09 Al Viro <viro@zeniv.linux.org.uk> wrote:
> 
> >
> > ... except that this callback can (and always could) get executed after
> > freeing struct super_block.
> >
> 
> Ugh.
> 
> That food looks nasty. Shouldn't the super block freeing wait for the
> filesystem to be all done instead? Do a rcu synchronization or something?
> 
> Adding that pointer looks really wrong to me. I'd much rather delay the sb
> freeing. Is there some reason that can't be done that I'm missing?

Where would you put that synchronize_rcu()?  Doing that before ->put_super()
is too early - inode references might be dropped in there.  OTOH, doing
that after that point means that while struct super_block itself will be
there, any number of data structures hanging from it might be not.

So we are still very limited in what we can do inside ->free_inode()
instance *and* we get bunch of synchronize_rcu() for no good reason.

Note that for normal lockless accesses (lockless ->d_revalidate(), ->d_hash(),
etc.) we are just fine with having struct super_block freeing RCU-delayed
(along with any data structures we might need) - the superblock had
been seen at some point after we'd taken rcu_read_lock(), so its
freeing won't happen until we drop it.  So we don't need synchronize_rcu()
for that.

Here the problem is that we are dealing with another RCU callback;
synchronize_rcu() would be needed for it, but it will only protect that
intermediate dereference of ->i_sb; any rcu-delayed stuff scheduled
from inside ->put_super() would not be ordered wrt ->free_inode().
And if we are doing that just for the sake of that one dereference,
we might as well do it before scheduling i_callback().

PS: we *are* guaranteed that module will still be there (unregister_filesystem()
does synchronize_rcu() and rcu_barrier() is done before kmem_cache_destroy()
in assorted exit_foo_fs()).

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-30  3:09   ` Al Viro
       [not found]     ` <CAHk-=wiMvCR0iENUVorfU-3EMC7G8RNSeHSQrz9tndP1uSg2BQ@mail.gmail.com>
@ 2019-04-30  4:18     ` Andreas Dilger
  2019-04-30  4:26       ` Al Viro
  1 sibling, 1 reply; 82+ messages in thread
From: Andreas Dilger @ 2019-04-30  4:18 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, linux-fsdevel, Linux List Kernel Mailing

[-- Attachment #1: Type: text/plain, Size: 2162 bytes --]

On Apr 29, 2019, at 9:09 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> 
> On Tue, Apr 16, 2019 at 11:01:16AM -0700, Linus Torvalds wrote:
>> 
>> I only skimmed through the actual filesystem (and one networking)
>> patches, but they looked like trivial conversions to a better
>> interface.
> 
> ... except that this callback can (and always could) get executed after
> freeing struct super_block.  So we can't just dereference ->i_sb->s_op
> and expect to survive; the table ->s_op pointed to will still be there,
> but ->i_sb might very well have been freed, with all its contents overwritten.
> We need to copy the callback into struct inode itself, unfortunately.
> The following incremental fixes it; I'm going to fold it into the first
> commit in there.
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index fb45590d284e..855dad43b11d 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -164,6 +164,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
> 	inode->i_wb_frn_avg_time = 0;
> 	inode->i_wb_frn_history = 0;
> #endif
> +	inode->free_inode = sb->s_op->free_inode;
> 
> 	if (security_inode_alloc(inode))
> 		goto out;
> @@ -211,8 +212,8 @@ EXPORT_SYMBOL(free_inode_nonrcu);
> static void i_callback(struct rcu_head *head)
> {
> 	struct inode *inode = container_of(head, struct inode, i_rcu);
> -	if (inode->i_sb->s_op->free_inode)
> -		inode->i_sb->s_op->free_inode(inode);
> +	if (inode->free_inode)
> +		inode->free_inode(inode);
> 	else
> 		free_inode_nonrcu(inode);
> }
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 2e9b9f87caca..5ed6b39e588e 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -718,6 +718,7 @@ struct inode {
> #endif
> 
> 	void			*i_private; /* fs or device private pointer */
> +	void (*free_inode)(struct inode *);

It seems like a waste to increase the size of every struct inode just to access
a static pointer.  Is this the only place that ->free_inode() is called?  Why
not move the ->free_inode() pointer into inode->i_fop->free_inode() so that it
is still directly accessible at this point.

Cheers, Andreas






[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 873 bytes --]

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-30  4:18     ` Andreas Dilger
@ 2019-04-30  4:26       ` Al Viro
  2019-04-30  5:26         ` Andreas Dilger
  0 siblings, 1 reply; 82+ messages in thread
From: Al Viro @ 2019-04-30  4:26 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: Linus Torvalds, linux-fsdevel, Linux List Kernel Mailing

On Mon, Apr 29, 2019 at 10:18:04PM -0600, Andreas Dilger wrote:
> > 
> > 	void			*i_private; /* fs or device private pointer */
> > +	void (*free_inode)(struct inode *);
> 
> It seems like a waste to increase the size of every struct inode just to access
> a static pointer.  Is this the only place that ->free_inode() is called?  Why
> not move the ->free_inode() pointer into inode->i_fop->free_inode() so that it
> is still directly accessible at this point.

i_op, surely?  In any case, increasing sizeof(struct inode) is not a problem -
if anything, I'd turn ->i_fop into an anon union with that.  As in,

diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 9d80f9e0855e..b8d3ddd8b8db 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -655,3 +655,11 @@ in your dentry operations instead.
 		* if ->free_inode() is non-NULL, it gets scheduled by call_rcu()
 		* combination of NULL ->destroy_inode and NULL ->free_inode is
 		  treated as NULL/free_inode_nonrcu, to preserve the compatibility.
+
+	Note that the callback (be it via ->free_inode() or explicit call_rcu()
+	in ->destroy_inode()) is *NOT* ordered wrt superblock destruction;
+	as the matter of fact, the superblock and all associated structures
+	might be already gone.  The filesystem driver is guaranteed to be still
+	there, but that's it.  Freeing memory in the callback is fine; doing
+	more than that is possible, but requires a lot of care and is best
+	avoided.
diff --git a/fs/inode.c b/fs/inode.c
index fb45590d284e..627e1766503a 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -211,8 +211,8 @@ EXPORT_SYMBOL(free_inode_nonrcu);
 static void i_callback(struct rcu_head *head)
 {
 	struct inode *inode = container_of(head, struct inode, i_rcu);
-	if (inode->i_sb->s_op->free_inode)
-		inode->i_sb->s_op->free_inode(inode);
+	if (inode->free_inode)
+		inode->free_inode(inode);
 	else
 		free_inode_nonrcu(inode);
 }
@@ -236,6 +236,7 @@ static struct inode *alloc_inode(struct super_block *sb)
 			if (!ops->free_inode)
 				return NULL;
 		}
+		inode->free_inode = ops->free_inode;
 		i_callback(&inode->i_rcu);
 		return NULL;
 	}
@@ -276,6 +277,7 @@ static void destroy_inode(struct inode *inode)
 		if (!ops->free_inode)
 			return;
 	}
+	inode->free_inode = ops->free_inode;
 	call_rcu(&inode->i_rcu, i_callback);
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2e9b9f87caca..92732286b748 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -694,7 +694,10 @@ struct inode {
 #ifdef CONFIG_IMA
 	atomic_t		i_readcount; /* struct files open RO */
 #endif
-	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
+	union {
+		const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
+		void (*free_inode)(struct inode *);
+	};
 	struct file_lock_context	*i_flctx;
 	struct address_space	i_data;
 	struct list_head	i_devices;

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-30  4:26       ` Al Viro
@ 2019-04-30  5:26         ` Andreas Dilger
  0 siblings, 0 replies; 82+ messages in thread
From: Andreas Dilger @ 2019-04-30  5:26 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, linux-fsdevel, Linux List Kernel Mailing

[-- Attachment #1: Type: text/plain, Size: 2519 bytes --]


> On Apr 29, 2019, at 10:26 PM, Al Viro <viro@zeniv.linux.org.uk> wrote:
> 
> On Mon, Apr 29, 2019 at 10:18:04PM -0600, Andreas Dilger wrote:
>>> 
>>> 	void			*i_private; /* fs or device private pointer */
>>> +	void (*free_inode)(struct inode *);
>> 
>> It seems like a waste to increase the size of every struct inode just to access
>> a static pointer.  Is this the only place that ->free_inode() is called?  Why
>> not move the ->free_inode() pointer into inode->i_fop->free_inode() so that it
>> is still directly accessible at this point.
> 
> i_op, surely?

Yes, i_op is what I was thinking.

> In any case, increasing sizeof(struct inode) is not a problem -

> if anything, I'd turn ->i_fop into an anon union with that.  As in,
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index fb45590d284e..627e1766503a 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -211,8 +211,8 @@ EXPORT_SYMBOL(free_inode_nonrcu);
> static void i_callback(struct rcu_head *head)
> {
> 	struct inode *inode = container_of(head, struct inode, i_rcu);
> -	if (inode->i_sb->s_op->free_inode)
> -		inode->i_sb->s_op->free_inode(inode);
> +	if (inode->free_inode)
> +		inode->free_inode(inode);
> 	else
> 		free_inode_nonrcu(inode);
> }
> @@ -236,6 +236,7 @@ static struct inode *alloc_inode(struct super_block *sb)
> 			if (!ops->free_inode)
> 				return NULL;
> 		}
> +		inode->free_inode = ops->free_inode;
> 		i_callback(&inode->i_rcu);
> 		return NULL;
> 	}

> @@ -276,6 +277,7 @@ static void destroy_inode(struct inode *inode)
> 		if (!ops->free_inode)
> 			return;
> 	}
> +	inode->free_inode = ops->free_inode;
> 	call_rcu(&inode->i_rcu, i_callback);
> }

This seems like kind of a hack.  I guess your goal is to have ->free_inode
accessible regardless of whether the filesystem has installed its own ->i_op
methods or not, and i_fop is no longer used by this point.

That said, this seems better than increasing the size of struct inode.

> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 2e9b9f87caca..92732286b748 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -694,7 +694,10 @@ struct inode {
> #ifdef CONFIG_IMA
> 	atomic_t		i_readcount; /* struct files open RO */
> #endif
> -	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
> +	union {
> +		const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
> +		void (*free_inode)(struct inode *);
> +	};


Cheers, Andreas






[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 873 bytes --]

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

* Re: [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode()
  2019-04-30  4:00       ` Al Viro
@ 2019-05-01  1:59         ` Al Viro
  0 siblings, 0 replies; 82+ messages in thread
From: Al Viro @ 2019-05-01  1:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-fsdevel, Linux List Kernel Mailing

On Tue, Apr 30, 2019 at 05:00:43AM +0100, Al Viro wrote:

> Where would you put that synchronize_rcu()?  Doing that before ->put_super()
> is too early - inode references might be dropped in there.  OTOH, doing
> that after that point means that while struct super_block itself will be
> there, any number of data structures hanging from it might be not.
> 
> So we are still very limited in what we can do inside ->free_inode()
> instance *and* we get bunch of synchronize_rcu() for no good reason.
> 
> Note that for normal lockless accesses (lockless ->d_revalidate(), ->d_hash(),
> etc.) we are just fine with having struct super_block freeing RCU-delayed
> (along with any data structures we might need) - the superblock had
> been seen at some point after we'd taken rcu_read_lock(), so its
> freeing won't happen until we drop it.  So we don't need synchronize_rcu()
> for that.
> 
> Here the problem is that we are dealing with another RCU callback;
> synchronize_rcu() would be needed for it, but it will only protect that
> intermediate dereference of ->i_sb; any rcu-delayed stuff scheduled
> from inside ->put_super() would not be ordered wrt ->free_inode().
> And if we are doing that just for the sake of that one dereference,
> we might as well do it before scheduling i_callback().
> 
> PS: we *are* guaranteed that module will still be there (unregister_filesystem()
> does synchronize_rcu() and rcu_barrier() is done before kmem_cache_destroy()
> in assorted exit_foo_fs()).

After playing with that for a while, I think that adding barriers on
superblock freeing (or shutdown) should wait, assuming we do them at
all.

Right now no ->free_inode() instances look at superblock or anything
associated with it; moreover, there's no good candidate code that
could be moved there and would benefit from such access.  So we
don't have any material to see what could be useful to protect.

Access to ->i_sb->s_op->free_inode itself is the only exception and
moving that to before the rcu delay is both less invasive and a _lot_
more robust than playing with synchronize_rcu().  We can do that
without growing struct inode or storing it for long periods -
->i_fop is only accessed for struct inode with positive refcount,
so we can put that into anon union with the ->free_inode value,
setting it just before we schedule execution of i_callback()
(and before the direct call of the same in alloc_inode() failure
exit).

IMO the following is the sane incremental for the coming window purposes;
if we get a convincing case for ->free_inode() doing something that could
benefit from being ordered wrt parts of fs shutdown, we can always deal
with synchronize_rcu() later.  Existing instances will be fine, and IMO
separating RCU-delayed parts of inode destruction from the rest is
worthwhile on its own.

Objections?

diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 9d80f9e0855e..b8d3ddd8b8db 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -655,3 +655,11 @@ in your dentry operations instead.
 		* if ->free_inode() is non-NULL, it gets scheduled by call_rcu()
 		* combination of NULL ->destroy_inode and NULL ->free_inode is
 		  treated as NULL/free_inode_nonrcu, to preserve the compatibility.
+
+	Note that the callback (be it via ->free_inode() or explicit call_rcu()
+	in ->destroy_inode()) is *NOT* ordered wrt superblock destruction;
+	as the matter of fact, the superblock and all associated structures
+	might be already gone.  The filesystem driver is guaranteed to be still
+	there, but that's it.  Freeing memory in the callback is fine; doing
+	more than that is possible, but requires a lot of care and is best
+	avoided.
diff --git a/fs/inode.c b/fs/inode.c
index fb45590d284e..627e1766503a 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -211,8 +211,8 @@ EXPORT_SYMBOL(free_inode_nonrcu);
 static void i_callback(struct rcu_head *head)
 {
 	struct inode *inode = container_of(head, struct inode, i_rcu);
-	if (inode->i_sb->s_op->free_inode)
-		inode->i_sb->s_op->free_inode(inode);
+	if (inode->free_inode)
+		inode->free_inode(inode);
 	else
 		free_inode_nonrcu(inode);
 }
@@ -236,6 +236,7 @@ static struct inode *alloc_inode(struct super_block *sb)
 			if (!ops->free_inode)
 				return NULL;
 		}
+		inode->free_inode = ops->free_inode;
 		i_callback(&inode->i_rcu);
 		return NULL;
 	}
@@ -276,6 +277,7 @@ static void destroy_inode(struct inode *inode)
 		if (!ops->free_inode)
 			return;
 	}
+	inode->free_inode = ops->free_inode;
 	call_rcu(&inode->i_rcu, i_callback);
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2e9b9f87caca..92732286b748 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -694,7 +694,10 @@ struct inode {
 #ifdef CONFIG_IMA
 	atomic_t		i_readcount; /* struct files open RO */
 #endif
-	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
+	union {
+		const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
+		void (*free_inode)(struct inode *);
+	};
 	struct file_lock_context	*i_flctx;
 	struct address_space	i_data;
 	struct list_head	i_devices;

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

end of thread, other threads:[~2019-05-01  1:59 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-16 17:49 [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Al Viro
2019-04-16 17:52 ` [RFC PATCH 01/62] securityfs: fix use-after-free on symlink traversal Al Viro
2019-04-16 17:52   ` [RFC PATCH 02/62] apparmorfs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 03/62] new inode method: ->free_inode() Al Viro
2019-04-16 17:52   ` [RFC PATCH 04/62] spufs: switch to ->free_inode() Al Viro
2019-04-16 17:52   ` [RFC PATCH 05/62] erofs: " Al Viro
2019-04-18 14:01     ` Gao Xiang
2019-04-16 17:52   ` [RFC PATCH 06/62] 9p: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 07/62] adfs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 08/62] affs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 09/62] befs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 10/62] bfs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 11/62] bdev: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 12/62] cifs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 13/62] debugfs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 14/62] efs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 15/62] ext2: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 16/62] f2fs: " Al Viro
2019-04-20  2:52     ` Chao Yu
2019-04-16 17:52   ` [RFC PATCH 17/62] fat: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 18/62] freevxfs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 19/62] gfs2: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 20/62] hfs: " Al Viro
2019-04-16 17:52   ` [RFC PATCH 21/62] hfsplus: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 22/62] hostfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 23/62] hpfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 24/62] isofs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 25/62] jffs2: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 26/62] minix: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 27/62] nfs{,4}: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 28/62] nilfs2: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 29/62] dlmfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 30/62] ocfs2: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 31/62] openpromfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 32/62] procfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 33/62] qnx4: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 34/62] qnx6: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 35/62] reiserfs: convert " Al Viro
2019-04-16 17:53   ` [RFC PATCH 36/62] romfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 37/62] squashfs: switch " Al Viro
2019-04-16 17:53   ` [RFC PATCH 38/62] ubifs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 39/62] udf: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 40/62] sysv: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 41/62] coda: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 42/62] ufs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 43/62] mqueue: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 44/62] bpf: " Al Viro
2019-04-16 18:07     ` Alexei Starovoitov
2019-04-16 21:34       ` Song Liu
2019-04-16 17:53   ` [RFC PATCH 45/62] rpcpipe: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 46/62] apparmor: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 47/62] securityfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 48/62] ntfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 49/62] dax: make use of ->free_inode() Al Viro
2019-04-18 12:16     ` Jan Kara
2019-04-18 16:58       ` Dan Williams
2019-04-16 17:53   ` [RFC PATCH 50/62] afs: switch to " Al Viro
2019-04-16 17:53   ` [RFC PATCH 51/62] btrfs: use ->free_inode() Al Viro
2019-04-16 17:53   ` [RFC PATCH 52/62] ceph: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 53/62] ecryptfs: make use of ->free_inode() Al Viro
2019-04-16 17:53   ` [RFC PATCH 54/62] ext4: " Al Viro
2019-04-18 12:10     ` Jan Kara
2019-04-16 17:53   ` [RFC PATCH 55/62] fuse: switch to ->free_inode() Al Viro
2019-04-16 17:53   ` [RFC PATCH 56/62] jfs: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 57/62] overlayfs: make use of ->free_inode() Al Viro
2019-04-16 17:53   ` [RFC PATCH 58/62] hugetlb: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 59/62] shmem: " Al Viro
2019-04-16 17:53   ` [RFC PATCH 60/62] orangefs: " Al Viro
2019-04-22 21:14     ` Mike Marshall
2019-04-22 21:56       ` Linus Torvalds
2019-04-22 23:10         ` Al Viro
2019-04-22 23:17           ` Mike Marshall
2019-04-16 17:53   ` [RFC PATCH 61/62] sockfs: switch to ->free_inode() Al Viro
2019-04-16 17:53   ` [RFC PATCH 62/62] coallocate socket->wq with socket itself Al Viro
2019-04-16 18:01 ` [RFC][PATCHSET] sorting out RCU-delayed stuff in ->destroy_inode() Linus Torvalds
2019-04-30  3:09   ` Al Viro
     [not found]     ` <CAHk-=wiMvCR0iENUVorfU-3EMC7G8RNSeHSQrz9tndP1uSg2BQ@mail.gmail.com>
2019-04-30  4:00       ` Al Viro
2019-05-01  1:59         ` Al Viro
2019-04-30  4:18     ` Andreas Dilger
2019-04-30  4:26       ` Al Viro
2019-04-30  5:26         ` Andreas Dilger
2019-04-17 15:55 ` David Sterba

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).