From: David S. <ds...@ja...> - 2004-10-07 18:14:00
|
Hi, I'm using the CVS version of FUSE (though a couple of weeks behind the current head), and am having an odd problem with the FLUSH command. As I understand it, for every OPEN, there is one or more FLUSHes, followed by a single RELEASE. What I am seeing is an OPEN followed by a RELEASE with no FLUSH at all. This does not happen often, but after a number of hours of constant hammering on the filesystem, there are a few examples. Any thoughts? Could this be correct behavior somehow? David |
From: Miklos S. <mi...@sz...> - 2004-10-08 08:07:58
|
> As I understand it, for every OPEN, there is one or more FLUSHes, > followed by a single RELEASE. What I am seeing is an OPEN followed by > a RELEASE with no FLUSH at all. This does not happen often, but after > a number of hours of constant hammering on the filesystem, there are a > few examples. Not in the kernel, I think. But the library will send a release if the open was interrupted (see do_open() in lib/fuse.c). But in this case it is guaranteed that no read or write was done on the file, since the kernel never finished the open. Is this a problem? Miklos |
From: David S. <ds...@ja...> - 2004-10-08 14:43:13
|
On Fri, Oct 08, 2004 at 10:07:41AM +0200, Miklos Szeredi wrote: > > > As I understand it, for every OPEN, there is one or more FLUSHes, > > followed by a single RELEASE. What I am seeing is an OPEN followed by > > a RELEASE with no FLUSH at all. This does not happen often, but after > > a number of hours of constant hammering on the filesystem, there are a > > few examples. > > Not in the kernel, I think. But the library will send a release if > the open was interrupted (see do_open() in lib/fuse.c). But in this > case it is guaranteed that no read or write was done on the file, > since the kernel never finished the open. > > Is this a problem? I think that is good. If I understand this properly, this would be after the userland program "agreed to" the open by returning successfully from its open function. Since the userland program thinks the file is open now, it is appropriate that it will get a release to inform it that the file is no longer open. However, I was not clear enough in my original email. I am seeing reads and writes on the open file, so the open had to have been successful. I have seen both open+read+release, and open+write+release, with no flushes at all. David |
From: Miklos S. <mi...@sz...> - 2004-10-08 15:03:14
|
> I think that is good. If I understand this properly, this would be > after the userland program "agreed to" the open by returning > successfully from its open function. Since the userland program > thinks the file is open now, it is appropriate that it will get a > release to inform it that the file is no longer open. > > However, I was not clear enough in my original email. I am seeing > reads and writes on the open file, so the open had to have been > successful. I have seen both open+read+release, and > open+write+release, with no flushes at all. Oh! That cannot happen. Since it does, there must be something strange going on. Could you try making a trace of what the kernel does, by inserting printk's into fuse_open(), fuse_release() and fuse_flush(), and printing out some idetification of the file (e.g. the file pointer) to see if there is a flush at all? Thanks, Miklos |
From: David S. <ds...@ja...> - 2004-10-08 19:14:41
|
On Fri, Oct 08, 2004 at 05:02:59PM +0200, Miklos Szeredi wrote: > > > I think that is good. If I understand this properly, this would be > > after the userland program "agreed to" the open by returning > > successfully from its open function. Since the userland program > > thinks the file is open now, it is appropriate that it will get a > > release to inform it that the file is no longer open. > > > > However, I was not clear enough in my original email. I am seeing > > reads and writes on the open file, so the open had to have been > > successful. I have seen both open+read+release, and > > open+write+release, with no flushes at all. > > Oh! That cannot happen. Since it does, there must be something > strange going on. Could you try making a trace of what the kernel > does, by inserting printk's into fuse_open(), fuse_release() and > fuse_flush(), and printing out some idetification of the file > (e.g. the file pointer) to see if there is a flush at all? Okay, I did this and the printk results show there is a flush. My test does an open for write which creates the file, several writes, then a close. Then open the same file for read, several reads, then a close. Here's the write part in the kernel: fuse: open on file "1097256901643.testFile" flags 101101 (d51bcba0) fuse: flush on file "1097256901643.testFile" count 1 (d51bcba0) fuse: release on file "1097256901643.testFile" flags 100001 (d51bcba0) And the read part in the kernel: fuse: open on file "1097256901643.testFile" flags 100000 (c8ca24a0) fuse: flush on file "1097256901643.testFile" count 1 (c8ca24a0) fuse: release on file "1097256901643.testFile" flags 100000 (c8ca24a0) Here's the write part in userspace: OPEN /0/1/1097256901643.testFile, flags 101101 (some WRITEs in here) FLUSH /0/1/1097256901643.testFile count 1 RELEASE /0/1/1097256901643.testFile, flags 100001 And the read part in userspace: OPEN /0/1/1097256901643.testFile, flags 100000 (some READs in here) RELEASE /0/1/1097256901643.testFile, flags 100000 There was no FLUSH on the read part in userspace. David |
From: Miklos S. <mi...@sz...> - 2004-10-08 20:12:13
|
> Okay, I did this and the printk results show there is a flush. My > test does an open for write which creates the file, several writes, > then a close. Then open the same file for read, several reads, then a > close. Good. Looking closer at fuse_flush() I see that it will not send the request if interrupted. This is stupid behavior, since close() is final, it cannot be repeated. So instead it could use the request reserved for release. This means that only one fuse_flush() can be done at a time on a file (but this makes sense anyway). So does the following patch fix this problem Miklos Index: kernel/file.c =================================================================== RCS file: /cvsroot/avf/fuse/kernel/file.c,v retrieving revision 1.44 diff -u -r1.44 file.c --- kernel/file.c 16 Aug 2004 13:29:11 -0000 1.44 +++ kernel/file.c 8 Oct 2004 20:01:24 -0000 @@ -158,17 +158,14 @@ struct inode *inode = file->f_dentry->d_inode; struct fuse_conn *fc = INO_FC(inode); struct fuse_file *ff = file->private_data; - struct fuse_req *req; + struct fuse_req *req = ff->release_req; struct fuse_flush_in inarg; int err; if (fc->no_flush) return 0; - req = fuse_get_request(fc); - if (!req) - return -EINTR; - + down(&inode->i_sem); memset(&inarg, 0, sizeof(inarg)); inarg.fh = ff->fh; req->in.h.opcode = FUSE_FLUSH; @@ -178,11 +175,11 @@ req->in.args[0].value = &inarg; request_send(fc, req); err = req->out.h.error; + up(&inode->i_sem); if (err == -ENOSYS) { fc->no_flush = 1; err = 0; } - fuse_put_request(fc, req); return err; } |
From: David S. <ds...@ja...> - 2004-10-09 00:12:52
|
On Fri, Oct 08, 2004 at 10:11:54PM +0200, Miklos Szeredi wrote: > > Okay, I did this and the printk results show there is a flush. My > > test does an open for write which creates the file, several writes, > > then a close. Then open the same file for read, several reads, then a > > close. > > Good. Looking closer at fuse_flush() I see that it will not send the > request if interrupted. This is stupid behavior, since close() is > final, it cannot be repeated. So instead it could use the request > reserved for release. This means that only one fuse_flush() can be > done at a time on a file (but this makes sense anyway). > > So does the following patch fix this problem It does indeed. Thank you very much! David |