Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp10930015ybl; Fri, 27 Dec 2019 04:50:23 -0800 (PST) X-Google-Smtp-Source: APXvYqynphpygzriN3oB4RQCSgI5iFX1prPNnOm6Wstw9Y1C7dUpgRMH7lcfvOnMcQoBgT/OC8CG X-Received: by 2002:a05:6830:3048:: with SMTP id p8mr34099229otr.312.1577451023316; Fri, 27 Dec 2019 04:50:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1577451023; cv=none; d=google.com; s=arc-20160816; b=KqUTdYSmCzItkbsbyEF5dMnTX1wynegVwpLhhcWonhWCliNN49hO3IBvYwCtyKWhTx 9jtM1WgT60SGUvEeTYGqT/nMXoKwoju7GDtziasyLdT5vorHMi6eLRLI79HSFgnGh8eM m9FHDabBJywb5314nI9TWHNgfFMZ8IAbR59agQlP8O5F+OBsc85XMYV/zTMCDKq5IWF9 DFjm/n1hjZHz25dR8102bj5cBt16FbCCeFhcHJW4hhCUkKrHrcGnmFaHX+DWB+je7YJW Et/3I0N6fmHC5/wgkv/CeC2HZDGzP4fqUvxGPnnnm9kknRLGUXwMm8BB+UizsWrXWkTB 4Wxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=/NBSNtVPyPgrrharXgVV3+pnue+5O7wRFnCq1ZNCrNY=; b=aDBMzT7v+wXLuNFVe5NitqmAn0uE/EYiG2PrukI8v37ZRgy55ThsGLldhrqHdvzZUU l6qfLEe7UApzZeDcak6PDaJ7In7BKFokoUKw7cEsAgoM/Xx2AfxfQBz5CsAT38kuEIaZ w5NsOx4pfzqFCfnW0Csna7dA5RBJj650sMXBHDYgjaPIlt1fGDdgnyY4/P07Kbv3W1jT MN6AUYlE1W8tJvqqoQfo6yza8xjlk67k1vyKJimbKhIkMEtpr7KETW7METQ8+5WcX3Ag bPqvEba11kuAHHtgiyxqlU+h+DZrQ3iIIm7vUt42WP77aAvMMSj4nVg019kAUd1nTVOy BnmA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d63si15090291oif.178.2019.12.27.04.50.11; Fri, 27 Dec 2019 04:50:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727140AbfL0MsJ (ORCPT + 99 others); Fri, 27 Dec 2019 07:48:09 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:8632 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726562AbfL0MsJ (ORCPT ); Fri, 27 Dec 2019 07:48:09 -0500 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 243DD999849C7532FF57; Fri, 27 Dec 2019 20:48:06 +0800 (CST) Received: from [127.0.0.1] (10.173.220.179) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.439.0; Fri, 27 Dec 2019 20:48:00 +0800 Subject: Re: [QUESTION] question about the errno of rename the parent dir to a subdir of a specified directory To: Al Viro CC: "linux-fsdevel@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "miaoxie (A)" , zhangtianci References: <4c54c1f0-fe9a-6dea-1727-6898e8dd85ef@huawei.com> <20191225162729.GP4203@ZenIV.linux.org.uk> From: "zhangyi (F)" Message-ID: <62e4c112-afc2-eb33-acc1-21c84aa528fa@huawei.com> Date: Fri, 27 Dec 2019 20:47:59 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.3.0 MIME-Version: 1.0 In-Reply-To: <20191225162729.GP4203@ZenIV.linux.org.uk> Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.173.220.179] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Thanks for your detailed explanation, I will also check the freeBSD. Thanks, Yi. On 2019/12/26 0:27, Al Viro wrote: > On Wed, Dec 25, 2019 at 09:16:09PM +0800, zhangyi (F) wrote: >> Hi, >> >> If we rename the parent-dir to a sub-dir of a specified directory, the >> rename() syscall return -EINVAL because lock_rename() in lock_rename() >> checks the relations of the sorece and dest dirs. But if the 'parent' >> dir is a mountpoint, the rename() syscall return -EXDEV instead because >> it checks the parent dir's mountpoint of the sorece and dest dirs. >> >> For example: >> Case 1: rename() return -EINVAL >> # mkdir -p parent/dir >> # rename parent parent/dir/subdir parent >> rename: parent: rename to parent/dir/subdir failed: Invalid argument > > That was rename("parent", "parent/dir/subdir") being told to sod off and > not try to create loops. > >> Case 2: rename() return -EXDEV >> # mkdir parent >> # mount -t tmpfs test parent >> # mkdir parent/dir >> # rename parent parent/dir/subdir parent >> rename: parent: rename to parent/dir/subdir failed: Invalid cross-device link >> >> In case 2, although 'parent' directory is a mountpoint, it acted as a root >> dir of the "test tmpfs", so it should belongs to the same mounted fs of >> 'dir' directoty, so I think it shall return -EINVAL. >> >> Is it a bug or just designed as this ? > > rename() operates on directory entries. Pathnames can refer to files (including > directories) or they can refer to directory entries (links). rename() and other > directory-modifying syscalls operate on the latter. In the second test two > error conditions apply: in addition to attempted loop creation, we are asked to > move the link 'parent' from whatever it's in (your current directory) to 'subdir' > in the directory parent/dir, the latter being on a different filesystem. > > It's not "take the file old pathname refers to, move it to new place"; that's > particularly obvious when you consider > > echo foo >a # create a file > ln a b # now 'a' and 'b' both refer to it > mv a c # or rename a c a, if you really want to touch util-linux rename(1) > > Desired result is, of course, 'a' disappearing, 'b' left as is and 'c' now refering > to the same file. If you did mv b c as the last step, 'a' would be left as is, > 'b' would disappear and 'c' added, refering to the same file. But the only > difference between mv a c and mv b c is the first argument of rename(2) and > in both cases it resolves to the same file. In other words, rename(2) can't > operate on that level; to be of any use it has to interpret the pathnames > as refering to directory entries. > > That, BTW, is the source of "the last component must not be . or .." - they > do refer to directories just fine, but rename("dir1/.", "dir2/foo") is not just > 'make the directory refered to by "dir1/." show up as "dir2/foo"' - it's > 'rip the entry "." from the directory "dir1" and move it into directory "dir2" > under the name "foo"'. > > So your second testcase is a genuine cross-filesystem move; you want a link > to disappear from a directory on one filesystem and reappear in a directory > on another. It doesn't matter what's mounted on top of that - directory > entry refers to the mountpoint, not the thing mounted on it. > > And in cases when more than one error condition applies, portable userland > should be ready to cope with the operating system returning any of those. > Different Unices might return different applicable errors. In this particular > case I would expect EXDEV to take precedence on the majority of implementations, > but that's not guaranteed. Note, BTW, that there might be other errors > applicable here and it's a sufficiently dark corner to expect differences > (e.g. there might be a blanket ban on renaming mountpoints in general, > POSIX being quiet on that topic be damned). > > That actually might be a good way to get into given Unix VFS - figuring out > what happens in this implementation will tell you a lot about its pathname > resolution, related kernel data structures and locking involved. Might > send you away screaming, though - rename(2) is usually the worst part > as it is, and bringing the mountpoint crossing into the game is likely > to expose all kinds of interesting corner cases. > > . >