Hello, On Sat 10-12-11 14:03:36, Gábor S. wrote: > > -----Original Message----- > > From: Jan Kara [mailto:jack@xxxxxxx] > > Sent: Wednesday, December 07, 2011 7:07 PM > > > > Hi, > > > > On Sun 04-12-11 20:43:31, Gábor S. wrote: > > > since it did not make through to the linux-fsdevel list for some > > unknown > > > reason, I'm trying your address - according to the Maintainers file, > > you are > > > maintaining the UDF driver for Linux... > > Yes, you chose the right address :) > > > > > I recently wanted to archive a bunch of data from my (well, Linux) > > box > > > faithfully, that is keeping not only the hard links but also the > > symbolic > > > links present. I wanted to directly represent the files on a DVD, so > > I opted > > > for creating a disc (image actually) in UDF format instead of > > creating a tgz > > > archive or similar and burn that to a DVD. The next step was to find > > an > > > application to build the UDF image with symbolic links. A short > > googling led > > > me to mkisofs (from cdrtools 3.01) and I created an image containing > > both > > > ISO9660 and UDF file systems with that. > > > > > > Then I mounted the image (because I had the premonition that symbolic > > links > > > in UDF are less commonly used) - and got pretty surprised since the > > symbolic > > > links with absolute target path were not working as I expected. For > > the > > > rest, let us assume that the image contains a file called mounttab > > which was > > > linking to /etc/mounttab on the source from which the image was > > created. > > > > > > - On Linux (kernel 3.0.4): the slash (/) at the beginning is omitted. > > So > > > mounttab actually points to etc/mounttab which is not absolute. > > > - On FreeBSD (GhostBSD 2.5 BETA 3): the names of the path components > > are > > > simply pasted together without any directory separator (/). So > > mounttab > > > actually points to /etcmounttab which is obviously erroneous. > > > > > > What I experienced made me also suspicious that mkisofs might be at > > fault. > > > So I set up another Unix-like OS and mounted the image... > > > > > > - On Oracle Solaris (Oracle Solaris 11 Express 2010.11, LiveCD): all > > the > > > symbolic links including the ones with absolute target path work as > > > expected. > > > > > > To investigate what is going on I had a look into the UDF > > specification > > > (ECMA 167) and the source code of the UDF writer of mkisofs and the > > UDF file > > > system drivers of the above mentioned operating systems. The result > > is... > > > > > > - According to the UDF specification: the target of the symbolic > > links is > > > broken into path components (/, etc, mounttab in the example) and > > that > > > target is basically represented as a sequence of those, where the > > root > > > directory is represented in a special manner, as so called component > > type 1 > > > or 2. (While standard path components such as etc and mounttab have a > > type > > > of 5.) > > > - mkisofs represents the root directory of the absolute target path > > as > > > component type 2. > > OK. While the meaning of component type 1 is clear to me in the > > standard > > (i.e. if length of the component is 0, component points to the root of > > UDF > > filesystem, if the length is > 0, the component points to a place as > > agreed > > between the creator and consumer of the disk), I have trouble parsing > > the > > meaning of component type 2. In particular the wording is: > > "The component specifies the root directory of the directory hierarchy > > of > > which the predecessor of the first component in the pathname is a > > member." > > > > Some light to this sheds 2/8.7 which says among other things "The > > predecessor of the initial component shall be the directory in which > > the > > pathname is described." - i.e. if the symlink exists in foo/bar/ on the > > filesystem then "the predecessor of the first component in the > > pathname" > > simply refers to foo/bar/ if I understand it right. > > > > In this light, type 2 > > is really meant to point to the root of the filesystem and 2/8.7.1 > > seems to confirm this by stating that a resolved pathname should begin > > with a component of type 2. > > > > So in this light, type 1 might be intented to point to the root of the > > whole filesystem hierarchy while type 2 points just to the root of the > > current filesystem. > Well, not all resolved pathnames can begin with the root of the current > filesystem. > Because there can be an alias (symbolic link) which refers to the root of > all filesystems. > So I think type 2 must represent the root of all filesystems. > Nevertheless this is how mkisofs, Solaris, FreeBSD and as Jörg Schilly > (author of mkisofs, I have shortly discussed the situation with him as well, > now he's in the Cc) pointed out also MacOS treat type 2. OK, it's certainly easy to make type 2 point to / and it's certainly more useful than just ignoring it. The patch for this is attached and I'll merge it with Linus in the next merge window. > > That being said it is kind of hard to implement > > symlink pointing to the root of the current filesystem - such thing > > cannot > > be easily expressed in terms of ., .., or /. It is even harder > > considering > > that root of the filesystem need to even be reachable in the current > > name > > space (because of bind mounts and such stuff). Also readlink(2) > > implementation is problematic since root of the current filesystem is > > not > > expressible by a simple path. > > > > > I'll try to ask for some suggestions in the linux-fsdevel list. > I don't think there are many users interested in having symbolic links > relative to the root of the UDF volume. Well, actually for removable media it makes more sense than having links starting with /. You never know where your filesystem is going to be mounted or on which system so such links are often going to point to some non-existent place. For backups it does not matter but if you actually need to use those symlinks it makes a lot of sense. But relative symlinks are probably more portable solution in that case... > I would rather like to have symbolic links relative to the global root. And > that to be compatible with other OS' appears to me a good idea. Yes, I agree with this, especially the 'compatibility' part, because that's what UDF is mostly about... > Nonetheless, the link to the source code of OpenSolaris I included in my > original mail to you might give you some idea how to implement a > volume-relative absolute symbolic link. Yup, I've checked OpenSolaris code and it's nice and easy but doesn't work on Linux. The problem is that on Linux, a filesystem can have arbitrarily many mount points (you can mount one filesystem in several places, you can even mount only some part of a filesystem tree in some places) - that makes things more complicated but still workable (we always know through which mountpoint did we come). But what makes the implementation rather hard is that root of the filesystem need not be even reachable in the filesystem tree because it is overlayed but some other mounts... Honza -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR
>From c54a637592e92a749a838132fa83ffc145a2dc8b Mon Sep 17 00:00:00 2001 From: Jan Kara <jack@xxxxxxx> Date: Mon, 12 Dec 2011 15:13:50 +0100 Subject: [PATCH] udf: Treat symlink component of type 2 as / MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, we ignore symlink component of type 2. But mkisofs and other OS' seem to treat it as / so do the same for compatibility. Reported-by: "Gábor S." <otnaccess@xxxxxxxxxxx> Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/udf/symlink.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index b1d4488..d7c6dbe 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -41,10 +41,16 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from, pc = (struct pathComponent *)(from + elen); switch (pc->componentType) { case 1: - if (pc->lengthComponentIdent == 0) { - p = to; - *p++ = '/'; - } + /* + * Symlink points to some place which should be agreed + * upon between originator and receiver of the media. Ignore. + */ + if (pc->lengthComponentIdent > 0) + break; + /* Fall through */ + case 2: + p = to; + *p++ = '/'; break; case 3: memcpy(p, "../", 3); -- 1.7.1