From patchwork Thu Aug 9 20:32:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 1302861 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id EF1EB3FC23 for ; Thu, 9 Aug 2012 20:32:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759652Ab2HIUcH (ORCPT ); Thu, 9 Aug 2012 16:32:07 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:34862 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759625Ab2HIUcG (ORCPT ); Thu, 9 Aug 2012 16:32:06 -0400 Received: by pbbrr13 with SMTP id rr13so1444563pbb.19 for ; Thu, 09 Aug 2012 13:32:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding:x-gm-message-state; bh=oAfGxJRWoPLWg28tY/DKfwZexi/10OUmG3KViCrCQuE=; b=mZAh2KMOBAmuvj/NBkBf7gY2pdKGsWWbta4GTqkI3fspgGig19Fh5JAVduezV/Ml49 2GHweprBCk4m1lszgMMo+M2c1z/n9AcekWgPsLOpPyut1AhxAC5lMtaA2H4BMkjJI2eM ikmIUcuiSJ3OxyPwH6f8oFdVmqYVmftgeNq1v+jvshMyGKXguQAWwVjOBJiY4zT1vIf9 ZgA0gYCGz5L/m81dFtUXp2H3lUtL7HWshAFK4he7GAhfd3t/Gq4i0qFGZm8pVSYX/gzT 2+XGsosg9LZBIb5mZukJIpVHr2+KBbqEWiicObW0JEvBOesGTYNKvQ5AyIBiK3MbzIHY nbcQ== Received: by 10.68.129.73 with SMTP id nu9mr6938178pbb.59.1344544326110; Thu, 09 Aug 2012 13:32:06 -0700 (PDT) Received: from [192.168.107.150] ([38.122.20.226]) by mx.google.com with ESMTPS id qc5sm1774984pbb.6.2012.08.09.13.32.05 (version=SSLv3 cipher=OTHER); Thu, 09 Aug 2012 13:32:05 -0700 (PDT) Message-ID: <50241E44.2010308@inktank.com> Date: Thu, 09 Aug 2012 13:32:04 -0700 From: Alex Elder User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120714 Thunderbird/14.0 MIME-Version: 1.0 To: ceph-devel@vger.kernel.org Subject: [PATCH] ceph: let path portion of mount "device" be optional X-Gm-Message-State: ALoCoQkxa6dzyc+ik5MK1d9P55Aj63fhGn5lGg3VsNEVOZ+v6pfpILe1T5ke9DsP7IdL8x3qCpNu Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org A recent change to /sbin/mountall causes any trailing '/' character in the "device" (or fs_spec) field in /etc/fstab to be stripped. As a result, an entry for a ceph mount that intends to mount the root of the name space ends up with now path portion, and the ceph mount option processing code rejects this. That is, an entry in /etc/fstab like: cephserver:port:/ /mnt ceph defaults 0 0 provides to the ceph code just "cephserver:port:" as the "device," and that gets rejected. Although this is a bug in /sbin/mountall, we can have the ceph mount code support an empty/nonexistent path, interpreting it to mean the root of the name space. RFC 5952 offers recommendations for how to express IPv6 addresses, and recommends the usage found in RFC 3986 (which specifies the format for URI's) for representing both IPv4 and IPv6 addresses that include port numbers. (See in particular the definition of "authority" found in the Appendix of RFC 3986.) According to those standards, no host specification will ever contain a '/' character. As a result, it is sufficient to scan a provided "device" from an /etc/fstab entry for the first '/' character, and if it's found, treat that as the beginning of the path. If no '/' character is present, we can treat the entire string as the monitor host specification(s), and assume the path to be the root of the name space. We'll still require a ':' to separate the host portion from the (possibly empty) path portion. This means that we can more formally define how ceph will interpret the "device" it's provided when processing a mount request: "device" will look like: [,...]:[] where is [:] is optional, but if present must begin with '/' This addresses http://tracker.newdream.net/issues/2919 Signed-off-by: Alex Elder --- fs/ceph/super.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: b/fs/ceph/super.c =================================================================== --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -307,7 +307,10 @@ static int parse_mount_options(struct ce { struct ceph_mount_options *fsopt; const char *dev_name_end; - int err = -ENOMEM; + int err; + + if (!dev_name || !*dev_name) + return -EINVAL; fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL); if (!fsopt) @@ -328,21 +331,33 @@ static int parse_mount_options(struct ce fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; fsopt->congestion_kb = default_congestion_kb(); - /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ + /* + * Distinguish the server list from the path in "dev_name". + * Internally we do not include the leading '/' in the path. + * + * "dev_name" will look like: + * [,...]:[] + * where + * is [:] + * is optional, but if present must begin with '/' + */ + dev_name_end = strchr(dev_name, '/'); + if (dev_name_end) { + /* skip over leading '/' for path */ + *path = dev_name_end + 1; + } else { + /* path is empty */ + dev_name_end = dev_name + strlen(dev_name); + *path = dev_name_end; + } err = -EINVAL; - if (!dev_name) - goto out; - *path = strstr(dev_name, ":/"); - if (*path == NULL) { - pr_err("device name is missing path (no :/ in %s)\n", + dev_name_end--; /* back up to ':' separator */ + if (*dev_name_end != ':') { + pr_err("device name is missing path (no : separator in %s)\n", dev_name); goto out; } - dev_name_end = *path; dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name); - - /* path on server */ - *path += 2; dout("server path '%s'\n", *path); *popt = ceph_parse_options(options, dev_name, dev_name_end,