aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-09-09 16:10:39 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 17:03:48 -0400
commit7c352bdf048811b8128019ffc1e886161e09c11c (patch)
tree74c48298b67d37295433d9b2bb08d590a5f97a78
parent8254798199332966e2ab647380c990193af7e854 (diff)
[PATCH] FUSE: don't allow restarting of system calls
This patch removes ability to interrupt and restart operations while there hasn't been any side-effect. The reason: applications. There are some apps it seems that generate signals at a fast rate. This means, that if the operation cannot make enough progress between two signals, it will be restarted for ever. This bug actually manifested itself with 'krusader' trying to open a file for writing under sshfs. Thanks to Eduard Czimbalmos for the report. The problem can be solved just by making open() uninterruptible, because in this case it was the truncate operation that slowed down the progress. But it's better to solve this by simply not allowing interrupts at all (except SIGKILL), because applications don't expect file operations to be interruptible anyway. As an added bonus the code is simplified somewhat. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/fuse/dev.c73
-rw-r--r--fs/fuse/dir.c36
-rw-r--r--fs/fuse/file.c33
-rw-r--r--fs/fuse/fuse_i.h12
-rw-r--r--fs/fuse/inode.c2
5 files changed, 45 insertions, 111 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index e4ada021d087..d4c869c6d01b 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -103,20 +103,9 @@ static struct fuse_req *do_get_request(struct fuse_conn *fc)
103 return req; 103 return req;
104} 104}
105 105
106/* This can return NULL, but only in case it's interrupted by a SIGKILL */
106struct fuse_req *fuse_get_request(struct fuse_conn *fc) 107struct fuse_req *fuse_get_request(struct fuse_conn *fc)
107{ 108{
108 if (down_interruptible(&fc->outstanding_sem))
109 return NULL;
110 return do_get_request(fc);
111}
112
113/*
114 * Non-interruptible version of the above function is for operations
115 * which can't legally return -ERESTART{SYS,NOINTR}. This can still
116 * return NULL, but only in case the signal is SIGKILL.
117 */
118struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc)
119{
120 int intr; 109 int intr;
121 sigset_t oldset; 110 sigset_t oldset;
122 111
@@ -241,43 +230,20 @@ static void background_request(struct fuse_conn *fc, struct fuse_req *req)
241 get_file(req->file); 230 get_file(req->file);
242} 231}
243 232
244static int request_wait_answer_nonint(struct fuse_req *req)
245{
246 int err;
247 sigset_t oldset;
248 block_sigs(&oldset);
249 err = wait_event_interruptible(req->waitq, req->finished);
250 restore_sigs(&oldset);
251 return err;
252}
253
254/* Called with fuse_lock held. Releases, and then reacquires it. */ 233/* Called with fuse_lock held. Releases, and then reacquires it. */
255static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req, 234static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
256 int interruptible)
257{ 235{
258 int intr; 236 sigset_t oldset;
259 237
260 spin_unlock(&fuse_lock); 238 spin_unlock(&fuse_lock);
261 if (interruptible) 239 block_sigs(&oldset);
262 intr = wait_event_interruptible(req->waitq, req->finished); 240 wait_event_interruptible(req->waitq, req->finished);
263 else 241 restore_sigs(&oldset);
264 intr = request_wait_answer_nonint(req);
265 spin_lock(&fuse_lock); 242 spin_lock(&fuse_lock);
266 if (intr && interruptible && req->sent) { 243 if (req->finished)
267 /* If request is already in userspace, only allow KILL
268 signal to interrupt */
269 spin_unlock(&fuse_lock);
270 intr = request_wait_answer_nonint(req);
271 spin_lock(&fuse_lock);
272 }
273 if (!intr)
274 return; 244 return;
275 245
276 if (!interruptible || req->sent) 246 req->out.h.error = -EINTR;
277 req->out.h.error = -EINTR;
278 else
279 req->out.h.error = -ERESTARTNOINTR;
280
281 req->interrupted = 1; 247 req->interrupted = 1;
282 if (req->locked) { 248 if (req->locked) {
283 /* This is uninterruptible sleep, because data is 249 /* This is uninterruptible sleep, because data is
@@ -330,8 +296,10 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
330 wake_up(&fc->waitq); 296 wake_up(&fc->waitq);
331} 297}
332 298
333static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req, 299/*
334 int interruptible) 300 * This can only be interrupted by a SIGKILL
301 */
302void request_send(struct fuse_conn *fc, struct fuse_req *req)
335{ 303{
336 req->isreply = 1; 304 req->isreply = 1;
337 spin_lock(&fuse_lock); 305 spin_lock(&fuse_lock);
@@ -345,26 +313,11 @@ static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req,
345 after request_end() */ 313 after request_end() */
346 __fuse_get_request(req); 314 __fuse_get_request(req);
347 315
348 request_wait_answer(fc, req, interruptible); 316 request_wait_answer(fc, req);
349 } 317 }
350 spin_unlock(&fuse_lock); 318 spin_unlock(&fuse_lock);
351} 319}
352 320
353void request_send(struct fuse_conn *fc, struct fuse_req *req)
354{
355 request_send_wait(fc, req, 1);
356}
357
358/*
359 * Non-interruptible version of the above function is for operations
360 * which can't legally return -ERESTART{SYS,NOINTR}. This can still
361 * be interrupted but only with SIGKILL.
362 */
363void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req)
364{
365 request_send_wait(fc, req, 0);
366}
367
368static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 321static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
369{ 322{
370 spin_lock(&fuse_lock); 323 spin_lock(&fuse_lock);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 73792d65b6cf..e79e49b3eec7 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -46,12 +46,12 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
46 struct inode *inode = entry->d_inode; 46 struct inode *inode = entry->d_inode;
47 struct fuse_inode *fi = get_fuse_inode(inode); 47 struct fuse_inode *fi = get_fuse_inode(inode);
48 struct fuse_conn *fc = get_fuse_conn(inode); 48 struct fuse_conn *fc = get_fuse_conn(inode);
49 struct fuse_req *req = fuse_get_request_nonint(fc); 49 struct fuse_req *req = fuse_get_request(fc);
50 if (!req) 50 if (!req)
51 return 0; 51 return 0;
52 52
53 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg); 53 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
54 request_send_nonint(fc, req); 54 request_send(fc, req);
55 err = req->out.h.error; 55 err = req->out.h.error;
56 if (!err) { 56 if (!err) {
57 if (outarg.nodeid != get_node_id(inode)) { 57 if (outarg.nodeid != get_node_id(inode)) {
@@ -91,7 +91,7 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
91 91
92 req = fuse_get_request(fc); 92 req = fuse_get_request(fc);
93 if (!req) 93 if (!req)
94 return -ERESTARTNOINTR; 94 return -EINTR;
95 95
96 fuse_lookup_init(req, dir, entry, &outarg); 96 fuse_lookup_init(req, dir, entry, &outarg);
97 request_send(fc, req); 97 request_send(fc, req);
@@ -185,7 +185,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
185 struct fuse_conn *fc = get_fuse_conn(dir); 185 struct fuse_conn *fc = get_fuse_conn(dir);
186 struct fuse_req *req = fuse_get_request(fc); 186 struct fuse_req *req = fuse_get_request(fc);
187 if (!req) 187 if (!req)
188 return -ERESTARTNOINTR; 188 return -EINTR;
189 189
190 memset(&inarg, 0, sizeof(inarg)); 190 memset(&inarg, 0, sizeof(inarg));
191 inarg.mode = mode; 191 inarg.mode = mode;
@@ -211,7 +211,7 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
211 struct fuse_conn *fc = get_fuse_conn(dir); 211 struct fuse_conn *fc = get_fuse_conn(dir);
212 struct fuse_req *req = fuse_get_request(fc); 212 struct fuse_req *req = fuse_get_request(fc);
213 if (!req) 213 if (!req)
214 return -ERESTARTNOINTR; 214 return -EINTR;
215 215
216 memset(&inarg, 0, sizeof(inarg)); 216 memset(&inarg, 0, sizeof(inarg));
217 inarg.mode = mode; 217 inarg.mode = mode;
@@ -236,7 +236,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
236 236
237 req = fuse_get_request(fc); 237 req = fuse_get_request(fc);
238 if (!req) 238 if (!req)
239 return -ERESTARTNOINTR; 239 return -EINTR;
240 240
241 req->in.h.opcode = FUSE_SYMLINK; 241 req->in.h.opcode = FUSE_SYMLINK;
242 req->in.numargs = 2; 242 req->in.numargs = 2;
@@ -253,7 +253,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
253 struct fuse_conn *fc = get_fuse_conn(dir); 253 struct fuse_conn *fc = get_fuse_conn(dir);
254 struct fuse_req *req = fuse_get_request(fc); 254 struct fuse_req *req = fuse_get_request(fc);
255 if (!req) 255 if (!req)
256 return -ERESTARTNOINTR; 256 return -EINTR;
257 257
258 req->in.h.opcode = FUSE_UNLINK; 258 req->in.h.opcode = FUSE_UNLINK;
259 req->in.h.nodeid = get_node_id(dir); 259 req->in.h.nodeid = get_node_id(dir);
@@ -284,7 +284,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
284 struct fuse_conn *fc = get_fuse_conn(dir); 284 struct fuse_conn *fc = get_fuse_conn(dir);
285 struct fuse_req *req = fuse_get_request(fc); 285 struct fuse_req *req = fuse_get_request(fc);
286 if (!req) 286 if (!req)
287 return -ERESTARTNOINTR; 287 return -EINTR;
288 288
289 req->in.h.opcode = FUSE_RMDIR; 289 req->in.h.opcode = FUSE_RMDIR;
290 req->in.h.nodeid = get_node_id(dir); 290 req->in.h.nodeid = get_node_id(dir);
@@ -311,7 +311,7 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
311 struct fuse_conn *fc = get_fuse_conn(olddir); 311 struct fuse_conn *fc = get_fuse_conn(olddir);
312 struct fuse_req *req = fuse_get_request(fc); 312 struct fuse_req *req = fuse_get_request(fc);
313 if (!req) 313 if (!req)
314 return -ERESTARTNOINTR; 314 return -EINTR;
315 315
316 memset(&inarg, 0, sizeof(inarg)); 316 memset(&inarg, 0, sizeof(inarg));
317 inarg.newdir = get_node_id(newdir); 317 inarg.newdir = get_node_id(newdir);
@@ -356,7 +356,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
356 struct fuse_conn *fc = get_fuse_conn(inode); 356 struct fuse_conn *fc = get_fuse_conn(inode);
357 struct fuse_req *req = fuse_get_request(fc); 357 struct fuse_req *req = fuse_get_request(fc);
358 if (!req) 358 if (!req)
359 return -ERESTARTNOINTR; 359 return -EINTR;
360 360
361 memset(&inarg, 0, sizeof(inarg)); 361 memset(&inarg, 0, sizeof(inarg));
362 inarg.oldnodeid = get_node_id(inode); 362 inarg.oldnodeid = get_node_id(inode);
@@ -386,7 +386,7 @@ int fuse_do_getattr(struct inode *inode)
386 struct fuse_conn *fc = get_fuse_conn(inode); 386 struct fuse_conn *fc = get_fuse_conn(inode);
387 struct fuse_req *req = fuse_get_request(fc); 387 struct fuse_req *req = fuse_get_request(fc);
388 if (!req) 388 if (!req)
389 return -ERESTARTNOINTR; 389 return -EINTR;
390 390
391 req->in.h.opcode = FUSE_GETATTR; 391 req->in.h.opcode = FUSE_GETATTR;
392 req->in.h.nodeid = get_node_id(inode); 392 req->in.h.nodeid = get_node_id(inode);
@@ -533,7 +533,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
533 struct page *page; 533 struct page *page;
534 struct inode *inode = file->f_dentry->d_inode; 534 struct inode *inode = file->f_dentry->d_inode;
535 struct fuse_conn *fc = get_fuse_conn(inode); 535 struct fuse_conn *fc = get_fuse_conn(inode);
536 struct fuse_req *req = fuse_get_request_nonint(fc); 536 struct fuse_req *req = fuse_get_request(fc);
537 if (!req) 537 if (!req)
538 return -EINTR; 538 return -EINTR;
539 539
@@ -564,7 +564,7 @@ static char *read_link(struct dentry *dentry)
564 char *link; 564 char *link;
565 565
566 if (!req) 566 if (!req)
567 return ERR_PTR(-ERESTARTNOINTR); 567 return ERR_PTR(-EINTR);
568 568
569 link = (char *) __get_free_page(GFP_KERNEL); 569 link = (char *) __get_free_page(GFP_KERNEL);
570 if (!link) { 570 if (!link) {
@@ -677,7 +677,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
677 677
678 req = fuse_get_request(fc); 678 req = fuse_get_request(fc);
679 if (!req) 679 if (!req)
680 return -ERESTARTNOINTR; 680 return -EINTR;
681 681
682 memset(&inarg, 0, sizeof(inarg)); 682 memset(&inarg, 0, sizeof(inarg));
683 inarg.valid = iattr_to_fattr(attr, &inarg.attr); 683 inarg.valid = iattr_to_fattr(attr, &inarg.attr);
@@ -761,7 +761,7 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
761 761
762 req = fuse_get_request(fc); 762 req = fuse_get_request(fc);
763 if (!req) 763 if (!req)
764 return -ERESTARTNOINTR; 764 return -EINTR;
765 765
766 memset(&inarg, 0, sizeof(inarg)); 766 memset(&inarg, 0, sizeof(inarg));
767 inarg.size = size; 767 inarg.size = size;
@@ -801,7 +801,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
801 801
802 req = fuse_get_request(fc); 802 req = fuse_get_request(fc);
803 if (!req) 803 if (!req)
804 return -ERESTARTNOINTR; 804 return -EINTR;
805 805
806 memset(&inarg, 0, sizeof(inarg)); 806 memset(&inarg, 0, sizeof(inarg));
807 inarg.size = size; 807 inarg.size = size;
@@ -851,7 +851,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
851 851
852 req = fuse_get_request(fc); 852 req = fuse_get_request(fc);
853 if (!req) 853 if (!req)
854 return -ERESTARTNOINTR; 854 return -EINTR;
855 855
856 memset(&inarg, 0, sizeof(inarg)); 856 memset(&inarg, 0, sizeof(inarg));
857 inarg.size = size; 857 inarg.size = size;
@@ -897,7 +897,7 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
897 897
898 req = fuse_get_request(fc); 898 req = fuse_get_request(fc);
899 if (!req) 899 if (!req)
900 return -ERESTARTNOINTR; 900 return -EINTR;
901 901
902 req->in.h.opcode = FUSE_REMOVEXATTR; 902 req->in.h.opcode = FUSE_REMOVEXATTR;
903 req->in.h.nodeid = get_node_id(inode); 903 req->in.h.nodeid = get_node_id(inode);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e225f8c0b267..6454022b0536 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -22,9 +22,6 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
22 struct fuse_open_out outarg; 22 struct fuse_open_out outarg;
23 struct fuse_file *ff; 23 struct fuse_file *ff;
24 int err; 24 int err;
25 /* Restarting the syscall is not allowed if O_CREAT and O_EXCL
26 are both set, because creation will fail on the restart */
27 int excl = (file->f_flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL);
28 25
29 err = generic_file_open(inode, file); 26 err = generic_file_open(inode, file);
30 if (err) 27 if (err)
@@ -38,12 +35,9 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
38 return err; 35 return err;
39 } 36 }
40 37
41 if (excl) 38 req = fuse_get_request(fc);
42 req = fuse_get_request_nonint(fc);
43 else
44 req = fuse_get_request(fc);
45 if (!req) 39 if (!req)
46 return excl ? -EINTR : -ERESTARTSYS; 40 return -EINTR;
47 41
48 err = -ENOMEM; 42 err = -ENOMEM;
49 ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); 43 ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
@@ -67,10 +61,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
67 req->out.numargs = 1; 61 req->out.numargs = 1;
68 req->out.args[0].size = sizeof(outarg); 62 req->out.args[0].size = sizeof(outarg);
69 req->out.args[0].value = &outarg; 63 req->out.args[0].value = &outarg;
70 if (excl) 64 request_send(fc, req);
71 request_send_nonint(fc, req);
72 else
73 request_send(fc, req);
74 err = req->out.h.error; 65 err = req->out.h.error;
75 if (err) { 66 if (err) {
76 fuse_request_free(ff->release_req); 67 fuse_request_free(ff->release_req);
@@ -133,7 +124,7 @@ static int fuse_flush(struct file *file)
133 if (fc->no_flush) 124 if (fc->no_flush)
134 return 0; 125 return 0;
135 126
136 req = fuse_get_request_nonint(fc); 127 req = fuse_get_request(fc);
137 if (!req) 128 if (!req)
138 return -EINTR; 129 return -EINTR;
139 130
@@ -146,7 +137,7 @@ static int fuse_flush(struct file *file)
146 req->in.numargs = 1; 137 req->in.numargs = 1;
147 req->in.args[0].size = sizeof(inarg); 138 req->in.args[0].size = sizeof(inarg);
148 req->in.args[0].value = &inarg; 139 req->in.args[0].value = &inarg;
149 request_send_nonint(fc, req); 140 request_send(fc, req);
150 err = req->out.h.error; 141 err = req->out.h.error;
151 fuse_put_request(fc, req); 142 fuse_put_request(fc, req);
152 if (err == -ENOSYS) { 143 if (err == -ENOSYS) {
@@ -171,7 +162,7 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
171 162
172 req = fuse_get_request(fc); 163 req = fuse_get_request(fc);
173 if (!req) 164 if (!req)
174 return -ERESTARTSYS; 165 return -EINTR;
175 166
176 memset(&inarg, 0, sizeof(inarg)); 167 memset(&inarg, 0, sizeof(inarg));
177 inarg.fh = ff->fh; 168 inarg.fh = ff->fh;
@@ -224,7 +215,7 @@ size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
224 req->out.argvar = 1; 215 req->out.argvar = 1;
225 req->out.numargs = 1; 216 req->out.numargs = 1;
226 req->out.args[0].size = count; 217 req->out.args[0].size = count;
227 request_send_nonint(fc, req); 218 request_send(fc, req);
228 return req->out.args[0].size; 219 return req->out.args[0].size;
229} 220}
230 221
@@ -240,7 +231,7 @@ static int fuse_readpage(struct file *file, struct page *page)
240 struct inode *inode = page->mapping->host; 231 struct inode *inode = page->mapping->host;
241 struct fuse_conn *fc = get_fuse_conn(inode); 232 struct fuse_conn *fc = get_fuse_conn(inode);
242 loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT; 233 loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT;
243 struct fuse_req *req = fuse_get_request_nonint(fc); 234 struct fuse_req *req = fuse_get_request(fc);
244 int err = -EINTR; 235 int err = -EINTR;
245 if (!req) 236 if (!req)
246 goto out; 237 goto out;
@@ -314,7 +305,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
314 int err; 305 int err;
315 data.file = file; 306 data.file = file;
316 data.inode = inode; 307 data.inode = inode;
317 data.req = fuse_get_request_nonint(fc); 308 data.req = fuse_get_request(fc);
318 if (!data.req) 309 if (!data.req)
319 return -EINTR; 310 return -EINTR;
320 311
@@ -350,7 +341,7 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
350 req->out.numargs = 1; 341 req->out.numargs = 1;
351 req->out.args[0].size = sizeof(struct fuse_write_out); 342 req->out.args[0].size = sizeof(struct fuse_write_out);
352 req->out.args[0].value = &outarg; 343 req->out.args[0].value = &outarg;
353 request_send_nonint(fc, req); 344 request_send(fc, req);
354 return outarg.size; 345 return outarg.size;
355} 346}
356 347
@@ -370,7 +361,7 @@ static int fuse_commit_write(struct file *file, struct page *page,
370 struct inode *inode = page->mapping->host; 361 struct inode *inode = page->mapping->host;
371 struct fuse_conn *fc = get_fuse_conn(inode); 362 struct fuse_conn *fc = get_fuse_conn(inode);
372 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset; 363 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset;
373 struct fuse_req *req = fuse_get_request_nonint(fc); 364 struct fuse_req *req = fuse_get_request(fc);
374 if (!req) 365 if (!req)
375 return -EINTR; 366 return -EINTR;
376 367
@@ -444,7 +435,7 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
444 ssize_t res = 0; 435 ssize_t res = 0;
445 struct fuse_req *req = fuse_get_request(fc); 436 struct fuse_req *req = fuse_get_request(fc);
446 if (!req) 437 if (!req)
447 return -ERESTARTSYS; 438 return -EINTR;
448 439
449 while (count) { 440 while (count) {
450 size_t tmp; 441 size_t tmp;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index d7647289d8a1..24d761518d86 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -410,27 +410,17 @@ void fuse_reset_request(struct fuse_req *req);
410struct fuse_req *fuse_get_request(struct fuse_conn *fc); 410struct fuse_req *fuse_get_request(struct fuse_conn *fc);
411 411
412/** 412/**
413 * Reserve a preallocated request, only interruptible by SIGKILL
414 */
415struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc);
416
417/**
418 * Decrement reference count of a request. If count goes to zero put 413 * Decrement reference count of a request. If count goes to zero put
419 * on unused list (preallocated) or free reqest (not preallocated). 414 * on unused list (preallocated) or free reqest (not preallocated).
420 */ 415 */
421void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); 416void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
422 417
423/** 418/**
424 * Send a request (synchronous, interruptible) 419 * Send a request (synchronous)
425 */ 420 */
426void request_send(struct fuse_conn *fc, struct fuse_req *req); 421void request_send(struct fuse_conn *fc, struct fuse_req *req);
427 422
428/** 423/**
429 * Send a request (synchronous, non-interruptible except by SIGKILL)
430 */
431void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req);
432
433/**
434 * Send a request with no reply 424 * Send a request with no reply
435 */ 425 */
436void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); 426void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 52e954f4bb91..e69a546844d0 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -236,7 +236,7 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
236 236
237 req = fuse_get_request(fc); 237 req = fuse_get_request(fc);
238 if (!req) 238 if (!req)
239 return -ERESTARTSYS; 239 return -EINTR;
240 240
241 req->in.numargs = 0; 241 req->in.numargs = 0;
242 req->in.h.opcode = FUSE_STATFS; 242 req->in.h.opcode = FUSE_STATFS;