[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