diff mbox series

[v2,02/14] fs: create simple_remove() helper

Message ID CAOQ4uxigP4rP=+h=_OXhetFd2ZWmYeLnv=zjUp21qV=sP5VtSQ@mail.gmail.com
State New
Headers show
Series None | expand

Commit Message

Amir Goldstein May 16, 2019, 3:08 p.m. UTC
Dear pseudo fs maintainer,

Today you received a patch from me titled
"fs: convert <your>fs to use simple_remove() helper"

The patch that you received depends on this patch from my series
and this patch is obviously needed for the context of your review.

Please review the use of the helper as a cleanup/refactoring
patch for your fs that should not change logic regardless of the wider
scope of my series.

For complete context and motivation, please see the rest of the series at:
https://lore.kernel.org/linux-fsdevel/20190516102641.6574-1-amir73il@gmail.com/

Thanks,
Amir.

---------- Forwarded message ---------
From: Amir Goldstein <amir73il@gmail.com>
Date: Thu, May 16, 2019 at 1:26 PM
Subject: [PATCH v2 02/14] fs: create simple_remove() helper
To: Jan Kara <jack@suse.cz>
Cc: Matthew Bobrowski <mbobrowski@mbobrowski.org>,
<linux-fsdevel@vger.kernel.org>


There is a common pattern among pseudo filesystems for removing a dentry
from code paths that are NOT coming from vfs_{unlink,rmdir}, using a
combination of simple_{unlink,rmdir} and d_delete().

Create an helper to perform this common operation.  This helper is going
to be used as a place holder for the new fsnotify_{unlink,rmdir} hooks.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/libfs.c         | 27 +++++++++++++++++++++++++++
 include/linux/fs.h |  1 +
 2 files changed, 28 insertions(+)

 extern int noop_fsync(struct file *, loff_t, loff_t, int);
--
2.17.1
diff mbox series

Patch

diff --git a/fs/libfs.c b/fs/libfs.c
index 4b59b1816efb..ca1132f1d5c6 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -353,6 +353,33 @@  int simple_rmdir(struct inode *dir, struct dentry *dentry)
 }
 EXPORT_SYMBOL(simple_rmdir);

+/*
+ * Unlike simple_unlink/rmdir, this helper is NOT called from vfs_unlink/rmdir.
+ * Caller must guaranty that d_parent and d_name are stable.
+ */
+int simple_remove(struct inode *dir, struct dentry *dentry)
+{
+       int ret;
+
+       /*
+        * 'simple_' operations get a dentry reference on create/mkdir and drop
+        * it on unlink/rmdir. So we have to get dentry reference here to
+        * protect d_delete() from accessing a freed dentry.
+        */
+       dget(dentry);
+       if (d_is_dir(dentry))
+               ret = simple_rmdir(dir, dentry);
+       else
+               ret = simple_unlink(dir, dentry);
+
+       if (!ret)
+               d_delete(dentry);
+       dput(dentry);
+
+       return ret;
+}
+EXPORT_SYMBOL(simple_remove);
+
 int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
                  struct inode *new_dir, struct dentry *new_dentry,
                  unsigned int flags)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f7fdfe93e25d..74ea5f0b3b9d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3245,6 +3245,7 @@  extern int simple_open(struct inode *inode,
struct file *file);
 extern int simple_link(struct dentry *, struct inode *, struct dentry *);
 extern int simple_unlink(struct inode *, struct dentry *);
 extern int simple_rmdir(struct inode *, struct dentry *);
+extern int simple_remove(struct inode *, struct dentry *);
 extern int simple_rename(struct inode *, struct dentry *,
                         struct inode *, struct dentry *, unsigned int);