From patchwork Tue Nov 25 08:20:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 5374411 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id EACE6C11AC for ; Tue, 25 Nov 2014 08:21:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 235672014A for ; Tue, 25 Nov 2014 08:21:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5178820145 for ; Tue, 25 Nov 2014 08:21:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751136AbaKYIVq (ORCPT ); Tue, 25 Nov 2014 03:21:46 -0500 Received: from mail-pd0-f171.google.com ([209.85.192.171]:40939 "EHLO mail-pd0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750974AbaKYIVq (ORCPT ); Tue, 25 Nov 2014 03:21:46 -0500 Received: by mail-pd0-f171.google.com with SMTP id y13so113486pdi.16 for ; Tue, 25 Nov 2014 00:21:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id; bh=hT3s64/ttJGN/dnYcg5o+qE8WMPPUNVYisGgm7N51Wk=; b=NJk15GhLhqOptpz3Jwi/E7KQ0vexE8XsZ1uNDFoP1gFmhoy8HbHHxWndbKcgUZz5sk v3khAJLn199Loc0qnDisbUvJZH31lMSsO96qhggUS812k6SEIzR9zbNyPeJQEefCRjL5 B+3epUoZNR5OAVIX3FHM3Kpep8AQWd0+mFxGfetDsxGb5gzjqVjKLXngw653nmhxjH30 STmJxw9KcXJhoOZl0xTXlrdic9gkroowSYGBRFHw3uMEwMVcwM1+6BFZ43JntqveEE1J WGZ8WbVTjfNIB4enEMA59PRcxcaypP0Hb0mNOo/gjZgKT+gWtCQ6ygZJtQYnLlqD64gr jX9A== X-Received: by 10.70.131.44 with SMTP id oj12mr17407770pdb.112.1416903705870; Tue, 25 Nov 2014 00:21:45 -0800 (PST) Received: from localhost.localdomain.localdomain ([112.23.171.71]) by mx.google.com with ESMTPSA id yc4sm748964pab.27.2014.11.25.00.21.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 25 Nov 2014 00:21:45 -0800 (PST) From: Wang Shilong To: linux-btrfs@vger.kernel.org Subject: [PATCH v2] Btrfs: deal with all 'subvol=xxx' options once Date: Tue, 25 Nov 2014 16:20:11 +0800 Message-Id: <1416903611-29812-1-git-send-email-wangshilong1991@gmail.com> X-Mailer: git-send-email 1.7.12.4 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Steps to reproduce: # mkfs.btrfs -f /dev/sdb # mount -t btrfs /dev/sdb /mnt # btrfs sub create /mnt/dir # mount -t btrfs /dev/sdb /mnt -o subvol=dir,subvol=dir It fails with: mount: mount(2) failed: No such file or directory Btrfs deal with subvolume mounting in a recursive way, to avoid looping, it will stripe out 'subvol=xxxx' string, then next loop will stop.Problem here is it only deal one string once, if users specify mount option multiple times. It will loop several times which is not good, and above reproducing steps will also return confusing results. Fix this problem by striping out all 'subvol=xxx' options, only last is valid. Signed-off-by: Wang Shilong --- v1->v2: error handling and comment update --- fs/btrfs/super.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 54bd91e..42f3176 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1115,7 +1115,7 @@ static inline int is_subvolume_inode(struct inode *inode) * subvolid=0 to make sure we get the actual tree root for path walking to the * subvol we want. */ -static char *setup_root_args(char *args) +static char *__setup_root_args(char *args) { unsigned len = strlen(args) + 2 + 1; char *src, *dst, *buf; @@ -1129,13 +1129,12 @@ static char *setup_root_args(char *args) */ src = strstr(args, "subvol="); - /* This shouldn't happen, but just in case.. */ if (!src) return NULL; buf = dst = kmalloc(len, GFP_NOFS); if (!buf) - return NULL; + return ERR_PTR(-ENOMEM); /* * If the subvol= arg is not at the start of the string, @@ -1161,6 +1160,27 @@ static char *setup_root_args(char *args) return buf; } +static char *setup_root_args(char *args) +{ + char *p, *new_args; + + p = new_args = __setup_root_args(args); + /* in case users specify subvol=xxx option multiple times */ + while (p) { + p = __setup_root_args(new_args); + if (!p) + break; + if (!IS_ERR(p)) { + kfree(new_args); + new_args = p; + } else { + kfree(new_args); + return NULL; + } + } + return new_args; +} + static struct dentry *mount_subvol(const char *subvol_name, int flags, const char *device_name, char *data) {