Re: closefd: closes a file of any process

Tigran Aivazian (tigran@veritas.com)
Tue, 27 Jun 2000 18:08:19 +0100 (BST)


On Tue, 27 Jun 2000, Manfred Spraul wrote:

> Tigran Aivazian wrote:
> >
> >
> > Amazing that nobody noticed this before. Ok, next problem - how do you
> > synchronize this non-current do_close() with the possibility of the
> > process being between
> >
> > file = fget(fd);
> > ...
> > fput(file);
>
> Where is the problem?
>
> * fget atomically reads the pointer with the descriptor "fd" and
> increases the reference count within "file".
>
> * fput decreases that reference count, and if the count is 0, then it
> closes the file.
>
> * frip atomically replaces "fd" with NULL. close() then decreases the
> ref count, and only if the ref count becomes 0, then file is really
> closed.
>

your analysis is correct, however, the problem is that the file really was
not closed at the time of our do_close() because the other context held
the reference because of its fget(fd). So, we do_close() successfully and
the filesystem is still kept busy because no dput() was called on the
corresponding dentry. Hence the desire to delay closing until we are sure
that nobody holds an extra reference by being in the middle of a system
call.

Alexander, my previous email was slightly misleading - insteading of
saying "we call things twice" I should have said "we don't call them once
soon enough".

Alexander, about your previous reply:

>> I think if we are in __do_close(p->files, fd, 1) and the process 'p' is
>> inside, for example, sys_close(fd, 1) which called do_close(), it will
>
>Huh??? Since when did close(2) get the second argument???

it was a typo, of course I meant do_close(fd, 1). release=1 i.e.

>> have troubles. What troubles? Well, if the check for EBADF possibility
>> has been done then we will be releasing resources twice - certainly not
>> right. Do you agree with this?

>Not. ->file_lock protects you against it.

Ok, true.

>> Therefore, I mentioned a possibility of adding a rw semaphore to struct
>> file, which would be taken read in fget and write in do_close. I am not
>> 100% sure this will work. Do you have a better idea?

>Yes. E.g. recalling that files_struct may be shared between processes, so
>there is nothing special about your case.

Ok.

>Why do you want to do that? There are many other users of struct file and
>many of them can't be convinced to disappear that easily. If that's a
>part of your revoke() stuff - well, I think you are on a very wrong path.

Fortunately, it is not part of it at all - it was so in the very early
beginning but I gave up that direction quickly. The last direction I took
(before more urgent things came up that required my 100% attention for
now) was to have a special filesystem into which a file (more precisely,
inode) is migrated to. So, we don't close the descriptor but make it point
to a different inode. The real inode is released. Do you think this is the
wrong direction too?

Regards,
Tigran

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/