From patchwork Tue Nov 25 07:23:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 5372881 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A0E099F319 for ; Tue, 25 Nov 2014 07:24:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CF119201BB for ; Tue, 25 Nov 2014 07:24:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E6DAE200E6 for ; Tue, 25 Nov 2014 07:24:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752180AbaKYHYu (ORCPT ); Tue, 25 Nov 2014 02:24:50 -0500 Received: from mail-pa0-f46.google.com ([209.85.220.46]:48886 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751944AbaKYHYu (ORCPT ); Tue, 25 Nov 2014 02:24:50 -0500 Received: by mail-pa0-f46.google.com with SMTP id lj1so6834pab.33 for ; Mon, 24 Nov 2014 23:24:49 -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=ins9wL8UEMBSXZUVUXl9oTlWnfk18eNOG/rpJeiLswM=; b=z9ssKHXCFtMT6iF7tbRdBcUocCytaH5fImgFKiV/QpqH0mhb+KtWj/2B2R72dON266 s2NZeuaH0k1CekIkQYSl96eSqsef8Wvk6GMd5WGurYm1tdg9LOP+LENSGOUvbVEU6897 cx5fRB0NRMSyuMMislkTKIN6YtQoFzPeS7SIQ2MC8cB4q5R9KQPyLB4QNynBKDJ3mCrf 5XgVAaGktgbPBE/7P1Ym+ljEcPMIRI68y2xT4t3U9ROk7Lngq9+IPRGT7vqwjJsc1jRR QKyCNu0h8S3uF2SuILYCCMTEY9QXG8hmJbOoUahxriMNHhFW5Vi/1bsex9LEOW+c31CI GI1A== X-Received: by 10.66.159.3 with SMTP id wy3mr39913868pab.98.1416900289610; Mon, 24 Nov 2014 23:24:49 -0800 (PST) Received: from localhost.localdomain.localdomain ([112.23.171.71]) by mx.google.com with ESMTPSA id dp3sm570842pdb.46.2014.11.24.23.24.48 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Nov 2014 23:24:49 -0800 (PST) From: Wang Shilong To: linux-btrfs@vger.kernel.org Subject: [PATCH] Btrfs: deal with all 'subvol=xxx' options once Date: Tue, 25 Nov 2014 15:23:14 +0800 Message-Id: <1416900194-17495-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 --- fs/btrfs/super.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 54bd91e..2b2fa4b 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; @@ -1161,6 +1161,24 @@ 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) { + kfree(new_args); + new_args = p; + } else { + break; + } + } + return new_args; +} + static struct dentry *mount_subvol(const char *subvol_name, int flags, const char *device_name, char *data) {