Ticket #343 (assigned defect)
Permission Errors after file deletion
| Reported by: | chrisw@… | Owned by: | dbalmain |
|---|---|---|---|
| Priority: | major | Milestone: | |
| Component: | component1 | Version: | |
| Keywords: | Cc: |
Description
I run ferret in a cygwin environment (my e-mail client is sup).
Sometimes, when sup has modified the ferret store, I get the following error (in 0.11.4, I think): --- IOError at Mon Oct 29 16:27:51 -0500 2007 IO Error occured at <except.c>:117 in xpop_context Error occured in fs_store.c:70 - fs_exists
checking existance of /home/chrisw/.sup/ferret/_g9c.cfs: <Permission denied>
/usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:700:in `initialize' /usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:700:in `new' /usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:700:in `ensure_writer_open' /usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:429:in `delete' /usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:8:in `synchrolock' /usr/lib/ruby/1.8/monitor.rb:238:in `synchronize' /usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:8:in `synchrolock' /usr/lib/ruby/gems/1.8/gems/ferret-0.11.4/lib/ferret/index.rb:428:in `delete' <sup backtrace elided>
I think I have tracked the error down; however, I could be way off.
What follows is speculation, based on tracing executing. I do not know how ferret works.
most Linux and Unix systems, a file that is open can be deleted. When it is deleted, its directory entry is removed, effectively making is dissapear from the file system. When all open handles to that file are closed, its actual bits are marked as free.
On Windows, something slightly differen happens. When an open file is deleted, it enters the DELETE_PENDING state. During this time, no NEW handles can be opened, but it continues to exist in the file system.
During ferret's operations, sometimes it needs to delete (or rename, I'm not sure) one of its files. So, ferret deletes the file and then checks that it has been deleted (in fs_exists() ext/fs_store.c:70). To do the delete, unlink() is called. Cygwin maps this to a series of Windows kernel calls that 1) open the file, 2) set the delete-on-close flag, and 3) close the file.
(See unlink_nt() in http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/syscalls.cc?rev=1.469&content-type=text/x-cvsweb-markup&cvsroot=src)
If all handles to the file are closed, the file is deleted deleted. The file no longer exists, so the open() in fs_exists fails with ENOENT. This is to be expected.
If other handles are open, things happen a bit differently. When unlink() is called this time, the same three kernel calls are made: 1) open, 2) set delete-on-close flag, 3) close file. However, there are still an open handle for the file, so the file enters the DELETE_PENDING state. This causes the open() call in fs_exists to fail with EACCES, triggering the exception.
