[Unionfs] Locking issue with unionfs
Erez Zadok
ezk at cs.sunysb.edu
Sun Oct 21 22:54:37 EDT 2007
In message <200710191147.12337.herton at mandriva.com.br>, Herton Ronaldo Krzesinski writes:
> Hi,
>
> While using unionfs (2.1.3) we are having a problem. basically if you do something
> like this:
>
> - mkdir -p /live/distrib
> - install a distro into /live/distrib so you can do a chroot/play with it
> - mkdir -p /live/memory
> - mount -t tmpfs none /live/memory
> - mkdir -p /live/union
> - mount -o dirs=/live/memory=rw:/live/distrib=ro -t unionfs
> unionfs /live/union
> - chroot /live/union
> - mkdir /foo
> - mount -t unionfs -o remount,add=/foo=rw none /live/union
>
> Then the last command freezes, instead of giving a error. This is just an
> example for reproducing, not a real usage. The real usage is using something
> similar to do something like a pivot root inside a live cd.
>
> Looking at the stack trace of mount command, you have something like this:
> mount D dbdb8800 0 13892 13843
> d1563b50 00200082 d739b000 dbdb8800 00000000 006013d4 c040f320 c040e9e0
> c040e9e0 c040e9e0 d739b000 cd2d2580 cd2d26ac c13889e0 d739b000 dbdb8800
> 00000000 d1563baa d9b35000 d739b000 fffeffff d9337d68 cd2d2580 d1563b74
> Call Trace:
> [<c01f9015>] rwsem_down_failed_common+0x75/0x180
> [<c03157cd>] rwsem_down_read_failed+0x1d/0x28
> [<c0315853>] call_rwsem_down_read_failed+0x7/0xc
> [<dcf0f6df>] unionfs_lookup+0x1f/0x170 [unionfs]
> [<c018ad90>] do_lookup+0x110/0x190
> [<c018cfcc>] __link_path_walk+0x74c/0xdf0
> [<c018d6b6>] link_path_walk+0x46/0xd0
> [<c018d759>] path_walk+0x19/0x20
> [<c018d917>] do_path_lookup+0x87/0x230
> [<c018e627>] path_lookup+0x17/0x20
> [<dcf1262c>] do_remount_add_option+0x10c/0x270 [unionfs]
> [<dcf130dd>] unionfs_remount_fs+0x39d/0x8b0 [unionfs]
> [<c01853c1>] do_remount_sb+0xc1/0x130
> [<c019ab4d>] do_mount+0x23d/0x6d0
> [<c019b55f>] sys_mount+0x6f/0xb0
> [<c01041ba>] sysenter_past_esp+0x6b/0xa1
>
> Looking at above, we can see that unionfs is locked at unionfs_lookup,
> probably at "unionfs_read_lock(sb);". Then if you analyze the stack trace
> above looking at the other unionfs functions, you discover that in
> unionfs_remount_fs there is a "unionfs_write_lock(sb)", and because this the
> deadlock happens. I made a patch that at least seems to have worked here on a
> quick test as a workaround, I don't know yet if it has some side effect or if
> could be the proper fix for this locking issue, here it's the patch:
>
> --- linux-2.6.22.10-0.2mdv/fs/unionfs/super.c 2007-10-18
> 17:11:39.000000000 -0200
> +++ linux-2.6.22.10-0.2mdv.mod/fs/unionfs/super.c 2007-10-18
> 16:56:39.000000000 -0200
> @@ -587,10 +587,12 @@ static int unionfs_remount_fs(struct sup
> }
>
> if (!strcmp("add", optname)) {
> + unionfs_write_unlock(sb);
> err = do_remount_add_option(optarg, new_branches,
> tmp_data,
> tmp_lower_paths,
> &new_high_branch_id);
> + unionfs_write_lock(sb);
> if (err)
> goto out_release;
> new_branches++;
>
> I just unlock temporarily sb, probably not the right fix, as I didn't
> understand well the locking scheme yet.
>
> --
> []'s
> Herton
Herton, your fix is probably ok in the short term. I'm looking into a way
to solve this deadlock more cleanly. It's not easy b/c a read-write
semaphore in linux has no easy way to allow the same lock-owner who holds
the write lock, to also get a readlock.
Cheers,
Erez.
More information about the unionfs
mailing list