[PATCH RFC 1/7] fs: add filp_close_sync()

Christian Brauner <[email protected]>
Newsgroups gmane.linux.file-systems
Message-ID <[email protected]>
Currently close() already does a synchronous release of the last
reference since the task is about to return to userspace and the
deferral through task work buys nothing.

Turn that into a filp_close_sync() helper. We'll use that in one of
the next patches.

No functional changes.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 fs/file_table.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
 fs/internal.h   |  3 ++-
 fs/open.c       | 39 +--------------------------------------
 3 files changed, 49 insertions(+), 46 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index c68b8c0a4097..3c705917646b 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/filelock.h>
+#include <linux/dnotify.h>
 #include <linux/security.h>
 #include <linux/cred.h>
 #include <linux/eventpoll.h>
@@ -606,15 +607,53 @@ void __fput_sync(struct file *file)
 EXPORT_SYMBOL(__fput_sync);
 
 /*
- * Equivalent to __fput_sync(), but optimized for being called with the last
- * reference.
- *
- * See file_ref_put_close() for details.
+ * "id" is the POSIX thread ID. We use the
+ * files pointer for this..
  */
-void fput_close_sync(struct file *file)
+static int filp_flush(struct file *filp, fl_owner_t id)
 {
-	if (likely(file_ref_put_close(&file->f_ref)))
-		__fput(file);
+	int retval = 0;
+
+	if (CHECK_DATA_CORRUPTION(file_count(filp) == 0, filp,
+			"VFS: Close: file count is 0 (f_op=%ps)",
+			filp->f_op)) {
+		return 0;
+	}
+
+	if (filp->f_op->flush)
+		retval = filp->f_op->flush(filp, id);
+
+	if (likely(!(filp->f_mode & FMODE_PATH))) {
+		dnotify_flush(filp, id);
+		locks_remove_posix(filp, id);
+	}
+	return retval;
+}
+
+int filp_close(struct file *filp, fl_owner_t id)
+{
+	int retval;
+
+	retval = filp_flush(filp, id);
+	fput_close(filp);
+
+	return retval;
+}
+EXPORT_SYMBOL(filp_close);
+
+/*
+ * Like filp_close() but without deferring the release of the last
+ * reference, see file_ref_put_close() for details.
+ */
+int filp_close_sync(struct file *filp, fl_owner_t id)
+{
+	int retval;
+
+	retval = filp_flush(filp, id);
+	if (likely(file_ref_put_close(&filp->f_ref)))
+		__fput(filp);
+
+	return retval;
 }
 
 /*
diff --git a/fs/internal.h b/fs/internal.h
index 355d93f92208..7ba8cd26a698 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -127,7 +127,7 @@ static inline void put_file_access(struct file *file)
 	}
 }
 
-void fput_close_sync(struct file *);
+int filp_close_sync(struct file *filp, fl_owner_t id);
 void fput_close(struct file *);
 
 /*
@@ -190,6 +190,7 @@ struct open_flags {
 	int intent;
 	int lookup_flags;
 };
+
 extern struct file *do_file_open(int dfd, struct filename *pathname,
 		const struct open_flags *op);
 extern struct file *do_file_open_root(const struct path *,
diff --git a/fs/open.c b/fs/open.c
index 408925d7bd0b..d036736d5d43 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1453,41 +1453,6 @@ SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
 }
 #endif
 
-/*
- * "id" is the POSIX thread ID. We use the
- * files pointer for this..
- */
-static int filp_flush(struct file *filp, fl_owner_t id)
-{
-	int retval = 0;
-
-	if (CHECK_DATA_CORRUPTION(file_count(filp) == 0, filp,
-			"VFS: Close: file count is 0 (f_op=%ps)",
-			filp->f_op)) {
-		return 0;
-	}
-
-	if (filp->f_op->flush)
-		retval = filp->f_op->flush(filp, id);
-
-	if (likely(!(filp->f_mode & FMODE_PATH))) {
-		dnotify_flush(filp, id);
-		locks_remove_posix(filp, id);
-	}
-	return retval;
-}
-
-int filp_close(struct file *filp, fl_owner_t id)
-{
-	int retval;
-
-	retval = filp_flush(filp, id);
-	fput_close(filp);
-
-	return retval;
-}
-EXPORT_SYMBOL(filp_close);
-
 /*
  * Careful here! We test whether the file pointer is NULL before
  * releasing the fd. This ensures that one clone task can't release
@@ -1502,13 +1467,11 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
 	if (!file)
 		return -EBADF;
 
-	retval = filp_flush(file, current->files);
-
 	/*
 	 * We're returning to user space. Don't bother
 	 * with any delayed fput() cases.
 	 */
-	fput_close_sync(file);
+	retval = filp_close_sync(file, current->files);
 
 	if (likely(retval == 0))
 		return 0;

-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.