linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@infradead.org>
To: Chris Mason <chris.mason@oracle.com>
Cc: Mike Snitzer <snitzer@gmail.com>,
	linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [ANNOUNCE] Btrfs: a copy on write, snapshotting FS
Date: Wed, 13 Jun 2007 04:08:30 +0100	[thread overview]
Message-ID: <20070613030829.GA15724@infradead.org> (raw)
In-Reply-To: <20070612201439.GI28279@think.oraclecorp.com>

On Tue, Jun 12, 2007 at 04:14:39PM -0400, Chris Mason wrote:
> > Aside from folding snapshot history into the origin's namespace... It
> > could be possible to have a mount.btrfs that allows subvolumes and/or
> > snapshot volumes to be mounted as unique roots?  I'd imagine a bind
> > mount _could_ provide this too?  Anyway, I'm just interested in
> > understanding the vision for managing the potentially complex nature
> > of a Btrfs namespace.
> 
> One option is to put the real btrfs root into some directory in
> (/sys/fs/btrfs/$device?) and then use tools in userland to mount -o bind
> outside of that.  I wanted to wait to get fancy until I had a better
> idea of how people would use the feature.

We already support mounting into subdirectories of a filesystem for
nfs connection sharing.  The patch below makes use of this to allow
mounting any subdirectory of a btrfs filesystem by specifying it in
the form of /dev/somedevice:directory and when no subdirectory
is specified uses 'default'.  To make this more useful btrfs directories
should grow some way to be marked head of a subvolume, and we'd need
a more useful way to actually create subvolumes and snapshots without
fugly ioctls.

Btw, do create a subvolume with my patch you need to escape back to
the global root which is done by specifing /dev/somedevice:. as the
device on the mount command line.


Index: btrfs-0.2/super.c
===================================================================
--- btrfs-0.2.orig/super.c	2007-06-13 03:44:38.000000000 +0200
+++ btrfs-0.2/super.c	2007-06-13 03:48:35.000000000 +0200
@@ -17,6 +17,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
@@ -26,6 +27,7 @@
 #include <linux/string.h>
 #include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
+#include <linux/mount.h>
 #include <linux/mpage.h>
 #include <linux/swap.h>
 #include <linux/writeback.h>
@@ -135,11 +137,114 @@ static void btrfs_write_super(struct sup
 	sb->s_dirt = 0;
 }
 
+/*
+ * This is almost a copy of get_sb_bdev in fs/super.c.
+ * We need the local copy to allow direct mounting of
+ * subvolumes, but this could be easily integrated back
+ * into the generic version.  --hch
+ */
+
+/* start copy & paste */
+static int set_bdev_super(struct super_block *s, void *data)
+{
+	s->s_bdev = data;
+	s->s_dev = s->s_bdev->bd_dev;
+	return 0;
+}
+
+static int test_bdev_super(struct super_block *s, void *data)
+{
+	return (void *)s->s_bdev == data;
+}
+
+int btrfs_get_sb_bdev(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data,
+	int (*fill_super)(struct super_block *, void *, int),
+	struct vfsmount *mnt, const char *subvol)
+{
+	struct block_device *bdev = NULL;
+	struct super_block *s;
+	struct dentry *root;
+	int error = 0;
+
+	bdev = open_bdev_excl(dev_name, flags, fs_type);
+	if (IS_ERR(bdev))
+		return PTR_ERR(bdev);
+
+	/*
+	 * once the super is inserted into the list by sget, s_umount
+	 * will protect the lockfs code from trying to start a snapshot
+	 * while we are mounting
+	 */
+	down(&bdev->bd_mount_sem);
+	s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
+	up(&bdev->bd_mount_sem);
+	if (IS_ERR(s))
+		goto error_s;
+
+	if (s->s_root) {
+		if ((flags ^ s->s_flags) & MS_RDONLY) {
+			up_write(&s->s_umount);
+			deactivate_super(s);
+			error = -EBUSY;
+			goto error_bdev;
+		}
+
+		close_bdev_excl(bdev);
+		bdev = NULL;
+	} else {
+		char b[BDEVNAME_SIZE];
+
+		s->s_flags = flags;
+		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+		sb_set_blocksize(s, block_size(bdev));
+		error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
+		if (error) {
+			up_write(&s->s_umount);
+			deactivate_super(s);
+			goto error;
+		}
+
+		s->s_flags |= MS_ACTIVE;
+	}
+
+	if (subvol) {
+		root = lookup_one_len(subvol, s->s_root, strlen(subvol));
+		if (!root) {
+			error = -ENXIO;
+			goto error_bdev;
+		}
+	} else {
+		root = dget(s->s_root);
+	}
+
+	mnt->mnt_sb = s;
+	mnt->mnt_root = root;
+	return 0;
+
+error_s:
+	error = PTR_ERR(s);
+error_bdev:
+	if (bdev)
+		close_bdev_excl(bdev);
+error:
+	return error;
+}
+/* end copy & paste */
+
 static int btrfs_get_sb(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+	int flags, const char *identifier, void *data, struct vfsmount *mnt)
 {
-	return get_sb_bdev(fs_type, flags, dev_name, data,
-			   btrfs_fill_super, mnt);
+	char *_identifier = kstrdup(identifier, GFP_KERNEL);
+	const char *dev_name;
+
+	dev_name = strsep(&_identifier, ":");
+	if (!dev_name)
+		return -ENOMEM;
+
+	return btrfs_get_sb_bdev(fs_type, flags, dev_name, data,
+			   btrfs_fill_super, mnt,
+			   _identifier ? _identifier : "default");
 }
 
 static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)

  reply	other threads:[~2007-06-13  3:08 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-12 16:10 [ANNOUNCE] Btrfs: a copy on write, snapshotting FS Chris Mason
2007-06-12 19:53 ` Mike Snitzer
2007-06-12 20:14   ` Chris Mason
2007-06-13  3:08     ` Christoph Hellwig [this message]
2007-06-13 10:17       ` Chris Mason
2007-06-13  3:46 ` John Stoffel
2007-06-13 10:35   ` Chris Mason
2007-06-13 14:00     ` John Stoffel
2007-06-13 14:54       ` Chris Mason
2007-06-13 16:12         ` John Stoffel
2007-06-13 16:34           ` Chris Mason
2007-06-13 16:25         ` Grzegorz Kulewski
2007-06-14 18:20   ` Chuck Lever
2007-06-14 18:48     ` Chris Mason
2007-06-15 17:17       ` Chuck Lever
2007-06-14 18:29 ` Florian D.
2007-06-14 19:13   ` Chris Mason
2007-06-15 19:08     ` Florian D.
2007-06-15 19:11       ` Chris Mason
2007-06-15 20:46         ` Florian D.
2007-06-15 20:51           ` Chris Mason
2007-06-15 22:03             ` Florian D.
2007-06-16  0:54               ` Chris Mason
2007-06-16  9:31                 ` Florian D.
2007-06-18 14:29                   ` Chris Mason
2007-06-18 14:41 ` Chris Mason
2007-06-18 17:37 ` Vladislav Bolkhovitin
2007-06-18 20:08   ` John Stoffel
2007-06-19  9:11   ` Pádraig Brady
2007-06-19 10:01     ` Vladislav Bolkhovitin
2007-06-19 18:20       ` david
2007-06-20  8:41         ` Vladislav Bolkhovitin
2007-06-19 12:04     ` Chris Mason
2007-06-19 14:00       ` Vladislav Bolkhovitin
2007-06-19 18:24       ` david
2007-06-19 18:28       ` Philipp Matthias Hahn
2007-06-20  8:44         ` Vladislav Bolkhovitin
2007-06-20  9:18           ` Ph. Marek
  -- strict thread matches above, loose matches on Subject: below --
2007-06-13  5:45 Albert Cahalan
2007-06-13 12:00 ` Chris Mason
2007-06-13 16:14   ` Albert Cahalan
2007-06-13 16:57     ` Chris Mason
2007-06-14  6:59       ` Albert Cahalan
2007-06-14 12:30         ` Chris Mason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070613030829.GA15724@infradead.org \
    --to=hch@infradead.org \
    --cc=chris.mason@oracle.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=snitzer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).