fuse: allow parallel dio writes with FUSE_DIRECT_IO_ALLOW_MMAP
[linux-2.6-block.git] / fs / fuse / iomode.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * FUSE inode io modes.
4  *
5  * Copyright (c) 2024 CTERA Networks.
6  */
7
8 #include "fuse_i.h"
9
10 #include <linux/kernel.h>
11 #include <linux/sched.h>
12 #include <linux/file.h>
13 #include <linux/fs.h>
14
15 /*
16  * Return true if need to wait for new opens in caching mode.
17  */
18 static inline bool fuse_is_io_cache_wait(struct fuse_inode *fi)
19 {
20         return READ_ONCE(fi->iocachectr) < 0;
21 }
22
23 /*
24  * Start cached io mode.
25  *
26  * Blocks new parallel dio writes and waits for the in-progress parallel dio
27  * writes to complete.
28  */
29 int fuse_file_cached_io_start(struct inode *inode, struct fuse_file *ff)
30 {
31         struct fuse_inode *fi = get_fuse_inode(inode);
32
33         /* There are no io modes if server does not implement open */
34         if (!ff->release_args)
35                 return 0;
36
37         spin_lock(&fi->lock);
38         /*
39          * Setting the bit advises new direct-io writes to use an exclusive
40          * lock - without it the wait below might be forever.
41          */
42         while (fuse_is_io_cache_wait(fi)) {
43                 set_bit(FUSE_I_CACHE_IO_MODE, &fi->state);
44                 spin_unlock(&fi->lock);
45                 wait_event(fi->direct_io_waitq, !fuse_is_io_cache_wait(fi));
46                 spin_lock(&fi->lock);
47         }
48         WARN_ON(ff->iomode == IOM_UNCACHED);
49         if (ff->iomode == IOM_NONE) {
50                 ff->iomode = IOM_CACHED;
51                 if (fi->iocachectr == 0)
52                         set_bit(FUSE_I_CACHE_IO_MODE, &fi->state);
53                 fi->iocachectr++;
54         }
55         spin_unlock(&fi->lock);
56         return 0;
57 }
58
59 static void fuse_file_cached_io_end(struct inode *inode, struct fuse_file *ff)
60 {
61         struct fuse_inode *fi = get_fuse_inode(inode);
62
63         spin_lock(&fi->lock);
64         WARN_ON(fi->iocachectr <= 0);
65         WARN_ON(ff->iomode != IOM_CACHED);
66         ff->iomode = IOM_NONE;
67         fi->iocachectr--;
68         if (fi->iocachectr == 0)
69                 clear_bit(FUSE_I_CACHE_IO_MODE, &fi->state);
70         spin_unlock(&fi->lock);
71 }
72
73 /* Start strictly uncached io mode where cache access is not allowed */
74 int fuse_file_uncached_io_start(struct inode *inode, struct fuse_file *ff)
75 {
76         struct fuse_inode *fi = get_fuse_inode(inode);
77         int err = 0;
78
79         spin_lock(&fi->lock);
80         if (fi->iocachectr > 0) {
81                 err = -ETXTBSY;
82                 goto unlock;
83         }
84         WARN_ON(ff->iomode != IOM_NONE);
85         fi->iocachectr--;
86         ff->iomode = IOM_UNCACHED;
87 unlock:
88         spin_unlock(&fi->lock);
89         return err;
90 }
91
92 void fuse_file_uncached_io_end(struct inode *inode, struct fuse_file *ff)
93 {
94         struct fuse_inode *fi = get_fuse_inode(inode);
95
96         spin_lock(&fi->lock);
97         WARN_ON(fi->iocachectr >= 0);
98         WARN_ON(ff->iomode != IOM_UNCACHED);
99         ff->iomode = IOM_NONE;
100         fi->iocachectr++;
101         if (!fi->iocachectr)
102                 wake_up(&fi->direct_io_waitq);
103         spin_unlock(&fi->lock);
104 }
105
106 /* Request access to submit new io to inode via open file */
107 int fuse_file_io_open(struct file *file, struct inode *inode)
108 {
109         struct fuse_file *ff = file->private_data;
110         int err;
111
112         /*
113          * io modes are not relevant with DAX and with server that does not
114          * implement open.
115          */
116         if (FUSE_IS_DAX(inode) || !ff->release_args)
117                 return 0;
118
119         /*
120          * FOPEN_PARALLEL_DIRECT_WRITES requires FOPEN_DIRECT_IO.
121          */
122         if (!(ff->open_flags & FOPEN_DIRECT_IO))
123                 ff->open_flags &= ~FOPEN_PARALLEL_DIRECT_WRITES;
124
125         /*
126          * First caching file open enters caching inode io mode.
127          *
128          * Note that if user opens a file open with O_DIRECT, but server did
129          * not specify FOPEN_DIRECT_IO, a later fcntl() could remove O_DIRECT,
130          * so we put the inode in caching mode to prevent parallel dio.
131          */
132         if (ff->open_flags & FOPEN_DIRECT_IO)
133                 return 0;
134
135         err = fuse_file_cached_io_start(inode, ff);
136         if (err)
137                 goto fail;
138
139         return 0;
140
141 fail:
142         pr_debug("failed to open file in requested io mode (open_flags=0x%x, err=%i).\n",
143                  ff->open_flags, err);
144         /*
145          * The file open mode determines the inode io mode.
146          * Using incorrect open mode is a server mistake, which results in
147          * user visible failure of open() with EIO error.
148          */
149         return -EIO;
150 }
151
152 /* No more pending io and no new io possible to inode via open/mmapped file */
153 void fuse_file_io_release(struct fuse_file *ff, struct inode *inode)
154 {
155         /*
156          * Last parallel dio close allows caching inode io mode.
157          * Last caching file close exits caching inode io mode.
158          */
159         switch (ff->iomode) {
160         case IOM_NONE:
161                 /* Nothing to do */
162                 break;
163         case IOM_UNCACHED:
164                 fuse_file_uncached_io_end(inode, ff);
165                 break;
166         case IOM_CACHED:
167                 fuse_file_cached_io_end(inode, ff);
168                 break;
169         }
170 }