diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2005-09-09 16:10:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 17:03:48 -0400 |
commit | 7c352bdf048811b8128019ffc1e886161e09c11c (patch) | |
tree | 74c48298b67d37295433d9b2bb08d590a5f97a78 /fs/fuse/dir.c | |
parent | 8254798199332966e2ab647380c990193af7e854 (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>
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 36 |
1 files changed, 18 insertions, 18 deletions
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); |