[3/4] fs: add fput_queue
diff mbox

Message ID 1442238355-8203-4-git-send-email-jeff.layton@primarydata.com
State New
Headers show

Commit Message

Jeff Layton Sept. 14, 2015, 1:45 p.m. UTC
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
---
 fs/file_table.c      | 18 ++++++++++++++++++
 include/linux/file.h |  1 +
 2 files changed, 19 insertions(+)

Comments

Al Viro Sept. 14, 2015, 2:15 p.m. UTC | #1
On Mon, Sep 14, 2015 at 09:45:54AM -0400, Jeff Layton wrote:
> +/**
> + * fput_queue - do an fput without using task_work
> + * @file: file of which to put the reference
> + *
> + * If we need to ensure that the final __fput is done on a file before
> + * returning to userland, then we can't queue it to task_work. For that we
                                                       ?????????
> + * borrow the infrastructure used by kthreads, and the task can then just
> + * called flush_delayed_fput to ensure that the final fput has completed.

Are you sure that it's not a typo?
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Sept. 14, 2015, 2:19 p.m. UTC | #2
On Mon, 14 Sep 2015 15:15:39 +0100
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> On Mon, Sep 14, 2015 at 09:45:54AM -0400, Jeff Layton wrote:
> > +/**
> > + * fput_queue - do an fput without using task_work
> > + * @file: file of which to put the reference
> > + *
> > + * If we need to ensure that the final __fput is done on a file before
> > + * returning to userland, then we can't queue it to task_work. For that we
>                                                        ?????????
> > + * borrow the infrastructure used by kthreads, and the task can then just
> > + * called flush_delayed_fput to ensure that the final fput has completed.
> 
> Are you sure that it's not a typo?

I don't think so, but it could be clearer. Something like this maybe?

     "then we can't queue it via task_work_add."
Al Viro Sept. 14, 2015, 4:39 p.m. UTC | #3
On Mon, Sep 14, 2015 at 10:19:18AM -0400, Jeff Layton wrote:
> > > + * borrow the infrastructure used by kthreads, and the task can then just
> > > + * called flush_delayed_fput to ensure that the final fput has completed.
> > 
> > Are you sure that it's not a typo?
> 
> I don't think so, but it could be clearer. Something like this maybe?
> 
>      "then we can't queue it via task_work_add."

Huh?

task_work_add() callbacks *will* run before we return to userland
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Sept. 14, 2015, 5:30 p.m. UTC | #4
On Mon, 14 Sep 2015 17:39:54 +0100
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> On Mon, Sep 14, 2015 at 10:19:18AM -0400, Jeff Layton wrote:
> > > > + * borrow the infrastructure used by kthreads, and the task can then just
> > > > + * called flush_delayed_fput to ensure that the final fput has completed.
> > > 
> > > Are you sure that it's not a typo?
> > 
> > I don't think so, but it could be clearer. Something like this maybe?
> > 
> >      "then we can't queue it via task_work_add."
> 
> Huh?
> 
> task_work_add() callbacks *will* run before we return to userland

Right, but only just before. We need it to run before we try to set the
lease in the context of a fcntl() call. How about this text instead
then? I'll fix up the patch if this sounds reasonable:

"When fput is called in the context of a userland process, it'll queue
the actual work (__fput()) to be done just before returning to userland. In
some cases however, we need to ensure that the __fput runs before that
point. There is no safe way to flush work that has been queued via
task_work_add however, so to do this we borrow the delayed_fput
infrastructure that kthreads use. The userland process can use
fput_queue() on one or more struct files and then call
flush_delayed_fput() to ensure that they are completely closed."

Patch
diff mbox

diff --git a/fs/file_table.c b/fs/file_table.c
index d63f4a399d39..1ad2e3fd2064 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -297,6 +297,24 @@  void fput(struct file *file)
 }
 EXPORT_SYMBOL(fput);
 
+/**
+ * fput_queue - do an fput without using task_work
+ * @file: file of which to put the reference
+ *
+ * If we need to ensure that the final __fput is done on a file before
+ * returning to userland, then we can't queue it to task_work. For that we
+ * borrow the infrastructure used by kthreads, and the task can then just
+ * called flush_delayed_fput to ensure that the final fput has completed.
+ */
+void fput_queue(struct file *file)
+{
+	if (atomic_long_dec_and_test(&file->f_count)) {
+		if (llist_add(&file->f_u.fu_llist, &delayed_fput_list))
+			schedule_delayed_work(&delayed_fput_work, 1);
+	}
+}
+EXPORT_SYMBOL(fput_queue);
+
 /*
  * synchronous analog of fput(); for kernel threads that might be needed
  * in some umount() (and thus can't use flush_delayed_fput() without
diff --git a/include/linux/file.h b/include/linux/file.h
index f87d30882a24..543b0e2faf2c 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -12,6 +12,7 @@ 
 struct file;
 
 extern void fput(struct file *);
+extern void fput_queue(struct file *);
 
 struct file_operations;
 struct vfsmount;