From: viro@parcelfarce.linux.theplanet.co.uk
To: Nir Tzachar <tzachar@cs.bgu.ac.il>
Cc: linux-fsdevel@vger.kernel.org
Subject: Re: inode->i_op->rename semantics .
Date: Fri, 16 May 2003 02:09:29 +0100 [thread overview]
Message-ID: <20030516010929.GF10374@parcelfarce.linux.theplanet.co.uk> (raw)
In-Reply-To: <Pine.LNX.4.44.0305151036340.1541-100000@merlin>
On Thu, May 15, 2003 at 10:46:42AM +0300, Nir Tzachar wrote:
> first, thanks for your help ;)
>
> now, i still haver some problems:
>
> > Leave association between dentries and inodes alone; VFS will call
> > d_move() afterwards and it will do the right thing.
> im not messing with dentry<->inode associations .
> anyway, i tried to read the d_move() code, but some explanations will be
> appreciated.
>
> > All you need to do in ->rename() is
> > a) modify on-disk structures
> im doing this.
>
> > b) update ->i_nlink for inodes that need it.
> which inodes need it? wont the vfs update ->i_nlink for them?
No. ->i_nlink is the number of (on-disk) directory entries that point to
your (on-disk) inodes. VFS has no business touching it - it belongs to
filesystem data structures and is responsibility of filesystem code.
In other words, ->i_nlink changes should reflect the changes of directory
tree:
if target exists, we need to decrement its ->i_nlink since target
directory entry is not pointing to it anymore.
if we are moving a directory, old parent should have ->i_nlink
decremented and new one - incremented, since '..' in the child now points
to new parent.
if target was an empty directory, we should also decrement ->i_nlink
on target and target's parent since '.' and '..' in target are goners now.
> if i need to update ->i_nlink, should i also iput/iget them?? or will the
> vfs do this also?? (im asking, because i didnt see this kind of code
> anywhere in the vfs code. )
Updates of ->i_nlink have nothing to do with iput/iget.
All right, let's take a look at the way it works. Suppose we
rename foo/a to bar/a, both exist and are regular files.
We have two dentries (for foo/a and bar/a resp.) and two inodes.
->rename() will update data structures on disk and decrement ->i_nlink
for target. Then d_move() is called. Note that at this point dentries
still reflect the *old* state - they had not been moved/renamed/etc. yet.
d_move() does it. It will
* unhash dentry of bar/a
* exchange the names and parents between dentries of foo/a and bar/a
Now we have the dentry of target unhashed (still with the same inode) and
dentry of source successfully renamed.
Now we drop our references to both dentries. Since target had been unhashed,
it will be freed as soon as the last reference is dropped. Freeing it will
drop the reference to its inode (i.e. inode that used to be bar/a).
_If_ there was no other links to that inode, iput() will see that it's time
to delete it and call filesystem ->delete_inode().
Note that we can't do anything about that sequence of operations.
Indeed, if somebody had bar/a opened, we have to keep it alive until it's
finally closed. It is detached from bar, no lookups will find it, but we
can't free inode yet. IOW, ->rename() itself shouldn't free any inodes -
it's left to VFS code. Normally it happens when rename(2) does dput()
on dentries it had dealt with, but it can happen later if somebody is
also holding them.
It might be easier if you had shown your code, actually. Are you
sure that you do not leak references to dentries somewhere? That would
explain the things - inode removal is triggered by releasing the last
reference to dentry and if that never happens...
next prev parent reply other threads:[~2003-05-16 0:56 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-13 9:29 inode->i_op->rename semantics Nir Tzachar
2003-05-13 10:06 ` viro
2003-05-13 15:23 ` Nir Tzachar
2003-05-13 15:48 ` Nikita Danilov
2003-05-13 19:28 ` Charles Manning
2003-05-14 5:54 ` Nir Tzachar
2003-05-14 15:33 ` viro
2003-05-15 7:46 ` Nir Tzachar
2003-05-15 22:20 ` Charles Manning
2003-05-16 1:09 ` viro [this message]
2003-05-16 7:39 ` Nir Tzachar
2003-05-25 17:54 ` David Chow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030516010929.GF10374@parcelfarce.linux.theplanet.co.uk \
--to=viro@parcelfarce.linux.theplanet.co.uk \
--cc=linux-fsdevel@vger.kernel.org \
--cc=tzachar@cs.bgu.ac.il \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox