@@ -21,12 +21,13 @@ static inline bool fuse_is_io_cache_wait(struct fuse_inode *fi)
21
21
}
22
22
23
23
/*
24
- * Start cached io mode.
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.
25
26
*
26
27
* Blocks new parallel dio writes and waits for the in-progress parallel dio
27
28
* writes to complete.
28
29
*/
29
- int fuse_file_cached_io_start (struct inode * inode , struct fuse_file * ff )
30
+ int fuse_file_cached_io_open (struct inode * inode , struct fuse_file * ff )
30
31
{
31
32
struct fuse_inode * fi = get_fuse_inode (inode );
32
33
@@ -67,10 +68,9 @@ int fuse_file_cached_io_start(struct inode *inode, struct fuse_file *ff)
67
68
return 0 ;
68
69
}
69
70
70
- static void fuse_file_cached_io_end (struct inode * inode , struct fuse_file * ff )
71
+ static void fuse_file_cached_io_release (struct fuse_file * ff ,
72
+ struct fuse_inode * fi )
71
73
{
72
- struct fuse_inode * fi = get_fuse_inode (inode );
73
-
74
74
spin_lock (& fi -> lock );
75
75
WARN_ON (fi -> iocachectr <= 0 );
76
76
WARN_ON (ff -> iomode != IOM_CACHED );
@@ -82,29 +82,26 @@ static void fuse_file_cached_io_end(struct inode *inode, struct fuse_file *ff)
82
82
}
83
83
84
84
/* Start strictly uncached io mode where cache access is not allowed */
85
- int fuse_file_uncached_io_start (struct inode * inode , struct fuse_file * ff , struct fuse_backing * fb )
85
+ int fuse_inode_uncached_io_start (struct fuse_inode * fi , struct fuse_backing * fb )
86
86
{
87
- struct fuse_inode * fi = get_fuse_inode (inode );
88
87
struct fuse_backing * oldfb ;
89
88
int err = 0 ;
90
89
91
90
spin_lock (& fi -> lock );
92
91
/* deny conflicting backing files on same fuse inode */
93
92
oldfb = fuse_inode_backing (fi );
94
- if (oldfb && oldfb != fb ) {
93
+ if (fb && oldfb && oldfb != fb ) {
95
94
err = - EBUSY ;
96
95
goto unlock ;
97
96
}
98
97
if (fi -> iocachectr > 0 ) {
99
98
err = - ETXTBSY ;
100
99
goto unlock ;
101
100
}
102
- WARN_ON (ff -> iomode != IOM_NONE );
103
101
fi -> iocachectr -- ;
104
- ff -> iomode = IOM_UNCACHED ;
105
102
106
103
/* fuse inode holds a single refcount of backing file */
107
- if (!oldfb ) {
104
+ if (fb && !oldfb ) {
108
105
oldfb = fuse_inode_backing_set (fi , fb );
109
106
WARN_ON_ONCE (oldfb != NULL );
110
107
} else {
@@ -115,15 +112,29 @@ int fuse_file_uncached_io_start(struct inode *inode, struct fuse_file *ff, struc
115
112
return err ;
116
113
}
117
114
118
- void fuse_file_uncached_io_end (struct inode * inode , struct fuse_file * ff )
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 )
119
119
{
120
120
struct fuse_inode * fi = get_fuse_inode (inode );
121
+ int err ;
122
+
123
+ err = fuse_inode_uncached_io_start (fi , fb );
124
+ if (err )
125
+ return err ;
126
+
127
+ WARN_ON (ff -> iomode != IOM_NONE );
128
+ ff -> iomode = IOM_UNCACHED ;
129
+ return 0 ;
130
+ }
131
+
132
+ void fuse_inode_uncached_io_end (struct fuse_inode * fi )
133
+ {
121
134
struct fuse_backing * oldfb = NULL ;
122
135
123
136
spin_lock (& fi -> lock );
124
137
WARN_ON (fi -> iocachectr >= 0 );
125
- WARN_ON (ff -> iomode != IOM_UNCACHED );
126
- ff -> iomode = IOM_NONE ;
127
138
fi -> iocachectr ++ ;
128
139
if (!fi -> iocachectr ) {
129
140
wake_up (& fi -> direct_io_waitq );
@@ -134,6 +145,15 @@ void fuse_file_uncached_io_end(struct inode *inode, struct fuse_file *ff)
134
145
fuse_backing_put (oldfb );
135
146
}
136
147
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 )
151
+ {
152
+ WARN_ON (ff -> iomode != IOM_UNCACHED );
153
+ ff -> iomode = IOM_NONE ;
154
+ fuse_inode_uncached_io_end (fi );
155
+ }
156
+
137
157
/*
138
158
* Open flags that are allowed in combination with FOPEN_PASSTHROUGH.
139
159
* A combination of FOPEN_PASSTHROUGH and FOPEN_DIRECT_IO means that read/write
@@ -163,7 +183,7 @@ static int fuse_file_passthrough_open(struct inode *inode, struct file *file)
163
183
return PTR_ERR (fb );
164
184
165
185
/* First passthrough file open denies caching inode io mode */
166
- err = fuse_file_uncached_io_start (inode , ff , fb );
186
+ err = fuse_file_uncached_io_open (inode , ff , fb );
167
187
if (!err )
168
188
return 0 ;
169
189
@@ -216,7 +236,7 @@ int fuse_file_io_open(struct file *file, struct inode *inode)
216
236
if (ff -> open_flags & FOPEN_PASSTHROUGH )
217
237
err = fuse_file_passthrough_open (inode , file );
218
238
else
219
- err = fuse_file_cached_io_start (inode , ff );
239
+ err = fuse_file_cached_io_open (inode , ff );
220
240
if (err )
221
241
goto fail ;
222
242
@@ -236,19 +256,21 @@ int fuse_file_io_open(struct file *file, struct inode *inode)
236
256
/* No more pending io and no new io possible to inode via open/mmapped file */
237
257
void fuse_file_io_release (struct fuse_file * ff , struct inode * inode )
238
258
{
259
+ struct fuse_inode * fi = get_fuse_inode (inode );
260
+
239
261
/*
240
- * Last parallel dio close allows caching inode io mode.
262
+ * Last passthrough file close allows caching inode io mode.
241
263
* Last caching file close exits caching inode io mode.
242
264
*/
243
265
switch (ff -> iomode ) {
244
266
case IOM_NONE :
245
267
/* Nothing to do */
246
268
break ;
247
269
case IOM_UNCACHED :
248
- fuse_file_uncached_io_end ( inode , ff );
270
+ fuse_file_uncached_io_release ( ff , fi );
249
271
break ;
250
272
case IOM_CACHED :
251
- fuse_file_cached_io_end ( inode , ff );
273
+ fuse_file_cached_io_release ( ff , fi );
252
274
break ;
253
275
}
254
276
}
0 commit comments