[Tux3] Deferred namespace operations, change return type of fs create method
Daniel Phillips
phillips at phunq.net
Mon Dec 8 04:49:32 PST 2008
This updated patch implements an instantiate variant that takes care of
the orphan dirent problem (unlinked while open) by implementing a
variant of d_instantiate that unhashes the orphan and returns a clone of
the open dirent in the rare case that somebody creates a entry of the
same name before the orphan closes:
static inline void d_attach_locked(struct dentry *dentry, struct inode *inode)
{
list_add(&dentry->d_alias, &inode->i_dentry);
dentry->d_inode = inode;
dentry->d_flags &= ~DCACHE_HIDDEN;
fsnotify_d_instantiate(dentry, inode);
}
struct dentry *d_expose(struct dentry *dentry, struct inode *inode)
{
BUG_ON(!d_negative(dentry) || !inode);
if (dentry->d_inode) {
struct dentry *orphan = dentry;
dentry = d_alloc(orphan->d_parent, &orphan->d_name);
dentry->d_flags = orphan->d_flags;
orphan->d_flags = 0;
spin_lock(&dcache_lock);
__d_drop(orphan);
_d_rehash(dentry);
d_attach_locked(dentry, inode);
spin_unlock(&dcache_lock);
dput(orphan);
} else {
spin_lock(&dcache_lock);
d_attach_locked(dentry, inode);
spin_unlock(&dcache_lock);
}
security_d_instantiate(dentry, inode);
return dentry;
}
The strategy seems to work pretty well, but the patch is 800 lines
already, and I only implemented the idea for ->create, there are still
all the mknods etc to do. And it requires changes to every filesystem
to implement the idea that any entry-creating function can return a
different inode than it was passed. This makes ->create more like
->lookup, which was changed to support disconnected dentries from NFS,
and it might be a good change, but it's still a pretty big change.
So I think your idea of detecting the orphan case and cloning a new,
negative dentry for it is more practical. I will try it.
This patch does not yet include deferred inode creation (but includes
deferred inode deletion, which is similar) and I have not looked at
rename yet.
I think a similar technique to what you proposed will work for rename:
clone the source dentry of the move as a negative dentry. Then the
d_move will expose the negative dentry. Arguably, this should be the
normal behaviour of d_move. But since d_move does not now try to leave
a negative dentry behind, that makes things a little easier for us, as
we do not have to deal with d_move sometimes leaving a negative dentry
and sometimes not, depending on whether the source dentry was held
open.
Regards,
Daniel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: defer.patch
Type: text/x-diff
Size: 26763 bytes
Desc: not available
URL: <http://phunq.net/pipermail/tux3/attachments/20081208/5fe30474/attachment-0001.patch>
-------------- next part --------------
_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3
More information about the Tux3
mailing list