1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2024 CTERA Networks.
10 #include <linux/kernel.h>
11 #include <linux/sched.h>
12 #include <linux/file.h>
16 * Return true if need to wait for new opens in caching mode.
18 static inline bool fuse_is_io_cache_wait(struct fuse_inode
*fi
)
20 return READ_ONCE(fi
->iocachectr
) < 0 && !fuse_inode_backing(fi
);
24 * Called on cached file open() and on first mmap() of direct_io file.
25 * Takes cached_io inode mode reference to be dropped on file release.
27 * Blocks new parallel dio writes and waits for the in-progress parallel dio
30 int fuse_file_cached_io_open(struct inode
*inode
, struct fuse_file
*ff
)
32 struct fuse_inode
*fi
= get_fuse_inode(inode
);
34 /* There are no io modes if server does not implement open */
40 * Setting the bit advises new direct-io writes to use an exclusive
41 * lock - without it the wait below might be forever.
43 while (fuse_is_io_cache_wait(fi
)) {
44 set_bit(FUSE_I_CACHE_IO_MODE
, &fi
->state
);
45 spin_unlock(&fi
->lock
);
46 wait_event(fi
->direct_io_waitq
, !fuse_is_io_cache_wait(fi
));
51 * Check if inode entered passthrough io mode while waiting for parallel
52 * dio write completion.
54 if (fuse_inode_backing(fi
)) {
55 clear_bit(FUSE_I_CACHE_IO_MODE
, &fi
->state
);
56 spin_unlock(&fi
->lock
);
60 WARN_ON(ff
->iomode
== IOM_UNCACHED
);
61 if (ff
->iomode
== IOM_NONE
) {
62 ff
->iomode
= IOM_CACHED
;
63 if (fi
->iocachectr
== 0)
64 set_bit(FUSE_I_CACHE_IO_MODE
, &fi
->state
);
67 spin_unlock(&fi
->lock
);
71 static void fuse_file_cached_io_release(struct fuse_file
*ff
,
72 struct fuse_inode
*fi
)
75 WARN_ON(fi
->iocachectr
<= 0);
76 WARN_ON(ff
->iomode
!= IOM_CACHED
);
77 ff
->iomode
= IOM_NONE
;
79 if (fi
->iocachectr
== 0)
80 clear_bit(FUSE_I_CACHE_IO_MODE
, &fi
->state
);
81 spin_unlock(&fi
->lock
);
84 /* Start strictly uncached io mode where cache access is not allowed */
85 int fuse_inode_uncached_io_start(struct fuse_inode
*fi
, struct fuse_backing
*fb
)
87 struct fuse_backing
*oldfb
;
91 /* deny conflicting backing files on same fuse inode */
92 oldfb
= fuse_inode_backing(fi
);
93 if (fb
&& oldfb
&& oldfb
!= fb
) {
97 if (fi
->iocachectr
> 0) {
103 /* fuse inode holds a single refcount of backing file */
105 oldfb
= fuse_inode_backing_set(fi
, fb
);
106 WARN_ON_ONCE(oldfb
!= NULL
);
108 fuse_backing_put(fb
);
111 spin_unlock(&fi
->lock
);
115 /* Takes uncached_io inode mode reference to be dropped on file release */
116 static int fuse_file_uncached_io_open(struct inode
*inode
,
117 struct fuse_file
*ff
,
118 struct fuse_backing
*fb
)
120 struct fuse_inode
*fi
= get_fuse_inode(inode
);
123 err
= fuse_inode_uncached_io_start(fi
, fb
);
127 WARN_ON(ff
->iomode
!= IOM_NONE
);
128 ff
->iomode
= IOM_UNCACHED
;
132 void fuse_inode_uncached_io_end(struct fuse_inode
*fi
)
134 struct fuse_backing
*oldfb
= NULL
;
136 spin_lock(&fi
->lock
);
137 WARN_ON(fi
->iocachectr
>= 0);
139 if (!fi
->iocachectr
) {
140 wake_up(&fi
->direct_io_waitq
);
141 oldfb
= fuse_inode_backing_set(fi
, NULL
);
143 spin_unlock(&fi
->lock
);
145 fuse_backing_put(oldfb
);
148 /* Drop uncached_io reference from passthrough open */
149 static void fuse_file_uncached_io_release(struct fuse_file
*ff
,
150 struct fuse_inode
*fi
)
152 WARN_ON(ff
->iomode
!= IOM_UNCACHED
);
153 ff
->iomode
= IOM_NONE
;
154 fuse_inode_uncached_io_end(fi
);
158 * Open flags that are allowed in combination with FOPEN_PASSTHROUGH.
159 * A combination of FOPEN_PASSTHROUGH and FOPEN_DIRECT_IO means that read/write
160 * operations go directly to the server, but mmap is done on the backing file.
161 * FOPEN_PASSTHROUGH mode should not co-exist with any users of the fuse inode
162 * page cache, so FOPEN_KEEP_CACHE is a strange and undesired combination.
164 #define FOPEN_PASSTHROUGH_MASK \
165 (FOPEN_PASSTHROUGH | FOPEN_DIRECT_IO | FOPEN_PARALLEL_DIRECT_WRITES | \
168 static int fuse_file_passthrough_open(struct inode
*inode
, struct file
*file
)
170 struct fuse_file
*ff
= file
->private_data
;
171 struct fuse_conn
*fc
= get_fuse_conn(inode
);
172 struct fuse_backing
*fb
;
175 /* Check allowed conditions for file open in passthrough mode */
176 if (!IS_ENABLED(CONFIG_FUSE_PASSTHROUGH
) || !fc
->passthrough
||
177 (ff
->open_flags
& ~FOPEN_PASSTHROUGH_MASK
))
180 fb
= fuse_passthrough_open(file
, inode
,
181 ff
->args
->open_outarg
.backing_id
);
185 /* First passthrough file open denies caching inode io mode */
186 err
= fuse_file_uncached_io_open(inode
, ff
, fb
);
190 fuse_passthrough_release(ff
, fb
);
191 fuse_backing_put(fb
);
196 /* Request access to submit new io to inode via open file */
197 int fuse_file_io_open(struct file
*file
, struct inode
*inode
)
199 struct fuse_file
*ff
= file
->private_data
;
200 struct fuse_inode
*fi
= get_fuse_inode(inode
);
204 * io modes are not relevant with DAX and with server that does not
207 if (FUSE_IS_DAX(inode
) || !ff
->args
)
211 * Server is expected to use FOPEN_PASSTHROUGH for all opens of an inode
212 * which is already open for passthrough.
215 if (fuse_inode_backing(fi
) && !(ff
->open_flags
& FOPEN_PASSTHROUGH
))
219 * FOPEN_PARALLEL_DIRECT_WRITES requires FOPEN_DIRECT_IO.
221 if (!(ff
->open_flags
& FOPEN_DIRECT_IO
))
222 ff
->open_flags
&= ~FOPEN_PARALLEL_DIRECT_WRITES
;
225 * First passthrough file open denies caching inode io mode.
226 * First caching file open enters caching inode io mode.
228 * Note that if user opens a file open with O_DIRECT, but server did
229 * not specify FOPEN_DIRECT_IO, a later fcntl() could remove O_DIRECT,
230 * so we put the inode in caching mode to prevent parallel dio.
232 if ((ff
->open_flags
& FOPEN_DIRECT_IO
) &&
233 !(ff
->open_flags
& FOPEN_PASSTHROUGH
))
236 if (ff
->open_flags
& FOPEN_PASSTHROUGH
)
237 err
= fuse_file_passthrough_open(inode
, file
);
239 err
= fuse_file_cached_io_open(inode
, ff
);
246 pr_debug("failed to open file in requested io mode (open_flags=0x%x, err=%i).\n",
247 ff
->open_flags
, err
);
249 * The file open mode determines the inode io mode.
250 * Using incorrect open mode is a server mistake, which results in
251 * user visible failure of open() with EIO error.
256 /* No more pending io and no new io possible to inode via open/mmapped file */
257 void fuse_file_io_release(struct fuse_file
*ff
, struct inode
*inode
)
259 struct fuse_inode
*fi
= get_fuse_inode(inode
);
262 * Last passthrough file close allows caching inode io mode.
263 * Last caching file close exits caching inode io mode.
265 switch (ff
->iomode
) {
270 fuse_file_uncached_io_release(ff
, fi
);
273 fuse_file_cached_io_release(ff
, fi
);