Messages in this thread | | | From | (Matija Nalis) | Subject | dentry hardlink problem | Date | 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/
| |