Unionfs persistent inode number feature is a very good idea and very
important, especially very effective in these cases.
- link(2) on nfs branch.
  someone posted this problem recently, about "pwd.lock".
- rmdir(2) failure.
- shrink dcache.
  it happens anytime.

But it is a little buggy.
I have tried addressing it, and will post my patches.

First problem, the validation of the specifiend file doesn't
work. Currently users will not meet this problem if the multiple files
are specified.

$ > /dev/shm/fwd
$ unionimap -c /dev/shm/fwd
$ > /dev/shm/rev.b0
$ unionimap -a /dev/shm/fwd /dev/shm/rev.b0 /n/lower/b0
# mount -t unionfs -o dirs=/n/lower/b0,imap=/dev/shm/fwd:/dev/shm/rev.b0 none 
/mnt/unionfs
Could not match the reversemap uuid with an entry in the forwardmap table
Before cleanup_imap_data
After cleanup_imap_data
unionfs_read_super: error while parsing options (err = -22)

mount: wrong fs type, bad option, bad superblock on none,
       missing codepage or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

----------------------------------------------------------------------

Additionally, file size check in get_uin() is wrong and returns -EIO(-5).
But unionfs_readdir() receives it as unsigned and test it if minus. Finally,
-5 is used as inode number 4294967291.
It might be a rare case since this bug depends on the file size and
the hidden inode number. But it can cause kernel panic.
In this exsample, 'dir/a' has a largest inode number on the branch 'ro'.

unionfs on /dev/shm/u type unionfs 
(rw,dirs=rw=rw:ro=ro,imap=/dev/shm/fwd:/dev/shm/rev.rw:/dev/shm/rev.ro)
$ cd /dev/shm/u
$ find ../ro -ls | sort -n | tail -1
    31    0 -rw-r--r--   1 jro      jro             0 Jan 18 16:31 ../ro/dir/a
$ find . -name a -ls
4294967291    0 -rw-r--r--   1 jro      jro             0 Jan 18 16:31 ./u/dir/a

----------------------------------------------------------------------

And the inode number is not stored in the file when it is
copied-up. When the system shrinks dcache, the unionfs inode number will
be changed. (In this example, the inode numbers are not largest.)

unionfs on /dev/shm/u type unionfs 
(rw,dirs=rw=rw:ro=ro,imap=/dev/shm/fwd:/dev/shm/rev.rw:/dev/shm/rev.ro)
$ cd /dev/shm/u
$ find .. -name dir -o -name a -o -name dir2 -o -name b
../u/dir
../u/dir/a
../u/dir2
../u/dir2/b
../ro/dir
../ro/dir/a
../ro/dir2
../ro/dir2/b
$ ls -lid dir dir2 dir/a dir2/b
34 drwxr-xr-x  2 jro jro 1024 Jan 18 16:55 dir
35 -rw-r--r--  1 jro jro    0 Jan 18 16:55 dir/a
16 drwxr-xr-x  2 jro jro 1024 Jan 18 16:55 dir2
36 -rw-r--r--  1 jro jro    0 Jan 18 16:55 dir2/b
$ chmod a+x dir/a dir2/b
$ ls -lid dir dir2 dir/a dir2/b
34 drwxr-xr-x  2 jro jro 1024 Jan 18 16:55 dir
35 -rwxr-xr-x  1 jro jro    0 Jan 18 16:55 dir/a
16 drwxr-xr-x  2 jro jro 1024 Jan 18 16:55 dir2
36 -rwxr-xr-x  1 jro jro    0 Jan 18 16:55 dir2/b

copyup worked correctly and the inode numbers are not changed
correctly. Causing a large number of stat(2), dcache will be
shrinked. After shrinking, the unionfs inode numbers are changed.
$ find /usr -ls
$ ls -lid dir dir2 dir/a dir2/b
        37 drwxr-xr-x  2 jro jro 1024 Jan 18 16:55 dir
        39 -rwxr-xr-x  1 jro jro    0 Jan 18 16:55 dir/a
        38 drwxr-xr-x  2 jro jro 1024 Jan 18 16:55 dir2
4294967291 -rwxr-xr-x  1 jro jro    0 Jan 18 16:55 dir2/b


Junjiro Okajima
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs

Reply via email to