NetBSD Problem Report #41678

From www@NetBSD.org  Tue Jul  7 10:47:57 2009
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id 39DAE63B976
	for <gnats-bugs@gnats.netbsd.org>; Tue,  7 Jul 2009 10:47:57 +0000 (UTC)
Message-Id: <20090707104756.BDD1763B913@www.NetBSD.org>
Date: Tue,  7 Jul 2009 10:47:56 +0000 (UTC)
From: msporleder@gmail.com
Reply-To: msporleder@gmail.com
To: gnats-bugs@NetBSD.org
Subject: unionfs doesn't copy a file from the lower layer to the upper layer on rename(), it just fails
X-Send-Pr-Version: www-1.0

>Number:         41678
>Category:       kern
>Synopsis:       unionfs doesn't copy a file from the lower layer to the upper layer on rename(), it just fails
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 07 10:50:01 +0000 2009
>Last-Modified:  Sun Aug 16 05:50:02 +0000 2009
>Originator:     Matthew Sporleder
>Release:        5
>Organization:
>Environment:
NetBSD fester 5.0 NetBSD 5.0 (GENERIC) #0: Sun Apr 26 18:50:08 UTC 2009  builds@b6.netbsd.org:/home/builds/ab/netbsd-5-0-RELEASE/i386/200904260229Z-obj/home/builds/ab/netbsd-5-0-RELEASE/src/sys/arch/i386/compile/GENERIC i386
>Description:
unionfs doesn't support rename on a file originating in the lower layer
>How-To-Repeat:
/* ren.c */
#include <stdio.h>

int main (int argc, char *argv[])
{
       int ret;
       ret = rename(argv[1], argv[2]);
       ret == 0 ? : perror( "rename failed" );
       return(ret);
}

gcc -o /var/tmp/ren ren.c

mkdir /var/upper
mkdir /var/lower
touch /var/upper/willpass
touch /var/lower/willfail
mount -t union /var/upper /var/lower

(results so far)
<above>:/var/upper       832508     758010      51823  93% /var/lower
fester# ls -l /var/lower
total 0
-rw-r--r--  1 root  wheel  0 Jul  6 22:21 willfail
-rw-r--r--  1 root  wheel  0 Jul  6 22:21 willpass

... (back to the action)
/var/tmp/ren willpass pass
/var/tmp/ren willfail fail
rename failed: Cross-device link

(final results)
fester# ls -l /var/lower
total 0
-rw-r--r--  1 root  wheel  0 Jul  6 22:21 pass
-rw-r--r--  1 root  wheel  0 Jul  6 22:21 willfail

I guess when a rename is passed to the lower layer it should be turned
into a copy at the upper layer and then a rename.

Sorry this isn't in atf,
Matt
>Fix:

>Audit-Trail:
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/41678: unionfs doesn't copy a file from the lower layer to the upper layer on rename(), it just fails 
Date: Wed, 12 Aug 2009 17:41:44 +0700

     Date:        Tue,  7 Jul 2009 10:50:01 +0000 (UTC)
     From:        msporleder@gmail.com
     Message-ID:  <20090707105001.9478E63B976@www.NetBSD.org>

   | I guess when a rename is passed to the lower layer it should be turned
   | into a copy at the upper layer and then a rename.

 It can't really, that would have he effect of changing the inum
 (and more) which a successful rename(2) isn't supposed to do.

 Just leaving it returning EXDEV seems to be vaguely reasonable to
 me - normally a rename that affects only the final component of a
 pathname wouldn't ever hit that, but in general applications doing
 rename() need to be aware of the possibility and do their own copy
 and unlink if that's suitable for their purposes.

 Otherwise, a fix is going to need the combination of a whiteout to
 hide the lower (old) name (easy enough) and probably a new magic kind
 of symlink type object, invisible even to lstat(), with the semantics that
 it's target name is searched in the lower directory (only).  What
 that object would mean when seen in the upper filesys when it isn't
 union mounted I have no idea at all.

 I guess a third possibility would be to simply let the rename operate
 wholly on the lower layer (actually changing the lower filesys), but
 I think that breaks the purpose of unionfs, and is not without problems
 of its own.

 kre

From: David Holland <dholland-bugs@netbsd.org>
To: Robert Elz <kre@munnari.OZ.AU>
Cc: gnats-bugs@netbsd.org
Subject: Re: kern/41678: unionfs doesn't copy a file from the lower layer
	to the upper layer on rename(), it just fails
Date: Sun, 16 Aug 2009 05:45:22 +0000

 On Wed, Aug 12, 2009 at 10:45:02AM +0000, Robert Elz wrote:
  >    | I guess when a rename is passed to the lower layer it should be turned
  >    | into a copy at the upper layer and then a rename.
  >  
  >  It can't really, that would have he effect of changing the inum
  >  (and more) which a successful rename(2) isn't supposed to do.

 I dunno, unionfs inherently breaks that assumption (that the inode
 number of a given file doesn't change) in lots of other places.

 The alternatives look markedly worse, anyway. :-|

 I think what's fundamentally needed for unionfs is for someone to sit
 down and work out (formally, if necessary) exactly what the semantics
 are supposed to be.

 My guess is that any such attempt will fail. I think the reason it has
 so many problems is that all the things it's trying to do at once are
 mutually inconsistent.

 -- 
 David A. Holland
 dholland@netbsd.org

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.