dentry hardlink problem

Matija Nalis (mnalis@public.srce.hr)
3 Mar 1999 21:41:45 GMT


In process of fixing last (ha!) bugs in umsdosfs code, I've stumbled into
problem that I don't even have idea how to handle correctly.

In umsdos, hardlink are emulated. hardlink is normal file,
with 'HLINK' flag, that contains full path to original hardlink file.

so suppose I have:

/usr/bin/ls which is standars ls program.
When I do 'ln /usr/bin/ls /bin/dir', the next thing happens:

1) /usr/bin/ls is moved to /usr/bin/..LINK64 (automatically generated name)
2) /usr/bin/ls is made a text file marked with HLINK flag which contains
following text: "/usr/bin/..LINK64" (that is full path to real inode with
program data)
3) /bin/dir is likely made a text file marked with HLINK flag which
contains following text: "/usr/bin/..LINK64"

(for furher hardlinks [where i_nlink > 1], only step (3) is repated)

The way it is currently done is that in umsdos_lookup, if we try to lookup a
file which is marked as HLINK, we read its content, lookup that file, find
its inode, and do "d_add (dentry, found_inode)" (where dentry is real name
which was passed to lookup code, eg. /usr/bin/ls, and found_inode is inode
of /usr/bin/..LINK64)

It works nicely for lookups.

problem is when I want for example to change owner of a hardlinked file.
My notify_change gets called, with dentry pointing to realname /usr/bin/ls
(but with patched inode which points to /usr/bin/..LINK64 file).

Now, the way it currently works (which is broken) is to find EMD (extended
directory file where all non-FAT information is kept) of parent directory of
given file (so, for given /usr/bin/ls it finds EMD for /usr/bin, and updates
info there). No problem so far.

But, if hardlinks are not in the same directory, we have big problem,
because if for example we try to chown /bin/dir instead of /usr/bin/ls (and
since it is hardlink, result should be the same), we would actually update
EMD which corresponds to /bin directory (instead of correct /usr/bin) and
change permissions of some totaly different file!

So problem translates to that I am not able to find real directory in which
..LINK64 file is stored.

So far I had two ideas how to fix it, but...

1) kludge to notify_change, so if we try to update HLINK file, we drop
dentry (so we get rid of kludged inode - I can see tons of races here),
lookup it again but without patching inode, read where it points to (to
/usr/bin/..LINK64), find that file, and update info for it. Besides being
very kludgy, it does not work well, and would reqire even bigger kludge when
I get to the point of fixing code which MOVES (pseudo)hardlinks to different
directory.

2) somehow change umsdos_lookup method, so when it asks me to fill inode for
/usr/bin/ls, I modify that dentry and return it as /usr/bin/..LINK64 instead
(with correct inode). All other stuff then would work automagically (since
it would always operate on /usr/bin/..LINK64 file). But I cannot see an easy
way to do it, and am not convinced that it is The Right Way.

I would very much appreciate any input and ideas on this.
(and sorry for overly long post)

-- 
Opinions above are GNU-copylefted.

- 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/