All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Avishay Traeger <avishay@gmail.com>,
	Jeff Garzik <jeff@garzik.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Al Viro <viro@ZenIV.linux.org.uk>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	open-osd <osd-dev@open-osd.org>
Cc: linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH 7/9] exofs: mkexofs
Date: Tue, 16 Dec 2008 17:33:48 +0200	[thread overview]
Message-ID: <4947CA5C.50104@panasas.com> (raw)
In-Reply-To: <4947BFAA.4030208@panasas.com>


We need a mechanism to prepare the file system (mkfs).
I chose to implement that by means of a couple of
mount-options. Because there is no user-mode API for committing
OSD commands. And also, all this stuff is highly internal to
the file system itself.

- Added two mount options mkfs=0/1,format=capacity_in_meg, so mkfs/format
  can be executed by kernel code just before mount. An mkexofs utility
  can now be implemented by means of a script that mounts and unmount the
  file system with proper options.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
 fs/exofs/Kbuild    |    2 +-
 fs/exofs/exofs.h   |    3 +
 fs/exofs/mkexofs.c |  605 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/exofs/super.c   |   18 ++
 4 files changed, 627 insertions(+), 1 deletions(-)
 create mode 100644 fs/exofs/mkexofs.c

diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
index e293cb9..639c181 100644
--- a/fs/exofs/Kbuild
+++ b/fs/exofs/Kbuild
@@ -26,5 +26,5 @@ KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
 
 endif
 
-exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o super.o
+exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o super.o mkexofs.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 75c608d..f53d18b 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -204,6 +204,9 @@ int extract_list_from_req(struct osd_request *req,
 
 void free_osd_req(struct osd_request *req);
 
+/* mkexofs.c             */
+int exofs_mkfs(struct osd_dev *dev, uint64_t p_id, uint64_t format_size);
+
 /* inode.c               */
 void exofs_truncate(struct inode *inode);
 extern struct inode *exofs_iget(struct super_block *, unsigned long);
diff --git a/fs/exofs/mkexofs.c b/fs/exofs/mkexofs.c
new file mode 100644
index 0000000..79df3e3
--- /dev/null
+++ b/fs/exofs/mkexofs.c
@@ -0,0 +1,605 @@
+/*
+ * mkexofs.c - make an exofs file system.
+ *
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ *
+ * Copyrights from mke2fs.c:
+ *     Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ *     2003, 2004, 2005 by Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "exofs.h"
+#include <linux/random.h>
+
+/* #define __MKEXOFS_DEBUG_CHECKS 1 */
+
+static int kick_it(struct osd_request *req, int timeout, uint8_t *cred_a,
+		   const char *op)
+{
+	return exofs_sync_op(req, timeout, cred_a);
+}
+
+/* Format the LUN to the specified size */
+static int format(uint64_t lun_capacity, struct osd_dev *dev, int timeout)
+{
+	struct osd_request *req = prepare_osd_format_lun(dev, lun_capacity);
+	uint8_t cred_a[OSD_CAP_LEN];
+	int ret;
+
+	make_credential(cred_a, 0, 0);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "format");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int create_partition(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	bool try_remove = false;
+	int ret;
+
+	make_credential(cred_a, p_id, 0);
+
+create_part:
+	req = prepare_osd_create_partition(dev, p_id);
+	if (!req)
+		return -ENOMEM;
+	ret = kick_it(req, timeout, cred_a, "create partition");
+	free_osd_req(req);
+
+	if (ret && !try_remove) {
+		try_remove = true;
+		req = prepare_osd_remove_partition(dev, p_id);
+		if (!req)
+			return -ENOMEM;
+		ret = kick_it(req, timeout, cred_a, "remove partition");
+		free_osd_req(req);
+		if (!ret) /* Try again now */
+			goto create_part;
+	}
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int list(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	unsigned char *buf = NULL;
+	int ret;
+	uint64_t total_matches;
+	uint64_t total_ret;
+	uint64_t *id_list;
+	int is_part, is_utd;
+	uint64_t cont;
+	uint32_t more;
+	int i;
+
+	buf = kzalloc(1024, GFP_KERNEL);
+	if (!buf) {
+		EXOFS_ERR("ERROR: Failed to allocate memory.\n");
+		return -ENOMEM;
+	}
+
+	make_credential(cred_a, p_id, 0);
+
+	req = prepare_osd_list(dev, p_id, 0, 1024, 0, 0, buf);
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "list");
+	if (ret != 0)
+		goto out;
+
+	ret = extract_list_from_req(req, &total_matches, &total_ret, &id_list,
+				    &is_part, &is_utd, &cont, &more);
+
+	EXOFS_DBGMSG("created %llu objects:\n", _LLU(total_ret));
+	for (i = 0 ; i < total_ret ; i++)
+		EXOFS_DBGMSG("%llu\n", _LLU(id_list[i]));
+
+out:
+	free_osd_req(req);
+	kfree(buf);
+
+	return ret;
+}
+#endif
+
+static int create(struct osd_dev *dev, uint64_t p_id, uint64_t o_id,
+		  int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	int ret;
+
+	make_credential(cred_a, p_id, o_id);
+	req = prepare_osd_create(dev, p_id, o_id);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "create");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int write_super(struct osd_dev *dev, uint64_t p_id, int timeout,
+		       int newfile)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fscb data;
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_SUPER_ID);
+
+	data.s_nextid = 4;
+	data.s_magic = EXOFS_SUPER_MAGIC;
+	data.s_newfs = 1;
+	if (newfile)
+		data.s_numfiles = 1;
+	else
+		data.s_numfiles = 0;
+
+	req = prepare_osd_write(dev, p_id, EXOFS_SUPER_ID,
+				sizeof(struct exofs_fscb), 0, 0,
+				(unsigned char *)(&data));
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write super");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int read_super(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fscb data;
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_SUPER_ID);
+
+	req = prepare_osd_read(dev, p_id, EXOFS_SUPER_ID,
+				sizeof(struct exofs_fscb), 0, 0,
+				(unsigned char *)(&data));
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "read super");
+	if (ret)
+		goto out;
+
+	EXOFS_DBGMSG("nextid:\t%u\n", data.s_nextid);
+	EXOFS_DBGMSG("magic:\t%u\n", data.s_magic);
+	EXOFS_DBGMSG("numfiles:\t%u\n", data.s_numfiles);
+out:
+	free_osd_req(req);
+
+	return ret;
+}
+#endif
+
+static int write_bitmap(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	uint64_t off = 0;
+	unsigned int id = 3;
+	int ret;
+
+	/* XXX: For now just use counter - later make bitmap */
+	make_credential(cred_a, p_id, EXOFS_BM_ID);
+
+	req = prepare_osd_write(dev, p_id, EXOFS_BM_ID, sizeof(unsigned int),
+				off, 0, (unsigned char *)&id);
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write bitmap");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int write_testfile(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	uint64_t off = 0;
+	unsigned char buf[64];
+	int ret;
+
+	strcpy((char *)buf, "This file is a test, it is only a test.");
+	make_credential(cred_a, p_id, EXOFS_TEST_ID);
+
+	req = prepare_osd_write(dev, p_id, EXOFS_TEST_ID, 64, off, 0, buf);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write bitmap");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int read_testfile(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	unsigned char data[64];
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_TEST_ID);
+
+	req = prepare_osd_read(dev, p_id, EXOFS_TEST_ID, 64, 0, 0, data);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "read test file");
+	if (ret)
+		goto out;
+
+	EXOFS_DBGMSG("test file: %s\n", data);
+
+out:
+	free_osd_req(req);
+
+	return ret;
+}
+#endif
+
+static int write_rootdir(struct osd_dev *dev, uint64_t p_id, int timeout,
+			 int newfile)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_dir_entry *dir;
+	uint64_t off = 0;
+	unsigned char *buf = NULL;
+	int filetype = EXOFS_FT_DIR << 8;
+	int filetype2 = EXOFS_FT_REG_FILE << 8;
+	int rec_len;
+	int done;
+	int ret;
+
+	buf = kzalloc(EXOFS_BLKSIZE, GFP_KERNEL);
+	if (!buf) {
+		EXOFS_ERR("ERROR: Failed to allocate memory.\n");
+		return -ENOMEM;
+	}
+	dir = (struct exofs_dir_entry *)buf;
+
+	/* create entry for '.' */
+	dir->name[0] = '.';
+	dir->name_len = 1 | filetype;
+	dir->inode = EXOFS_ROOT_ID - EXOFS_OBJ_OFF;
+	dir->rec_len = EXOFS_DIR_REC_LEN(1);
+	rec_len = EXOFS_BLKSIZE - EXOFS_DIR_REC_LEN(1);
+
+	/* create entry for '..' */
+	dir = (struct exofs_dir_entry *) (buf + dir->rec_len);
+	dir->name[0] = '.';
+	dir->name[1] = '.';
+	dir->name_len = 2 | filetype;
+	dir->inode = EXOFS_ROOT_ID - EXOFS_OBJ_OFF;
+	if (newfile) {
+		rec_len -= EXOFS_DIR_REC_LEN(2);
+		dir->rec_len = EXOFS_DIR_REC_LEN(2);
+	} else
+		dir->rec_len = rec_len;
+	done = EXOFS_DIR_REC_LEN(1) + dir->rec_len;
+
+	/* create entry for 'test', if specified */
+	if (newfile) {
+		dir = (struct exofs_dir_entry *) (buf + done);
+		dir->inode = EXOFS_TEST_ID - EXOFS_OBJ_OFF;
+		dir->name_len = 4 | filetype2;
+		dir->name[0] = 't';
+		dir->name[1] = 'e';
+		dir->name[2] = 's';
+		dir->name[3] = 't';
+		dir->rec_len = rec_len;
+	}
+
+	make_credential(cred_a, p_id, EXOFS_ROOT_ID);
+
+	req = prepare_osd_write(dev, p_id, EXOFS_ROOT_ID, EXOFS_BLKSIZE, off,
+				0, buf);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write rootdir");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int set_inode(struct osd_dev *dev, uint64_t p_id, int timeout,
+		     uint64_t o_id, uint16_t mode)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fcb in = {0};
+	struct exofs_fcb *inode = &in;
+	uint32_t i_generation;
+	int ret;
+
+	inode->i_mode = cpu_to_be16(mode);
+	inode->i_uid = inode->i_gid = 0;
+	inode->i_links_count = cpu_to_be16(2);
+	inode->i_ctime = inode->i_atime = inode->i_mtime =
+					cpu_to_be32(CURRENT_TIME.tv_sec);
+	inode->i_size = cpu_to_be64(EXOFS_BLKSIZE);
+	if (o_id != EXOFS_ROOT_ID)
+		inode->i_size = cpu_to_be64(64);
+
+	get_random_bytes(&i_generation, sizeof(i_generation));
+	inode->i_generation = cpu_to_be32(i_generation);
+
+	make_credential(cred_a, p_id, o_id);
+
+	req = prepare_osd_set_attr(dev, p_id, o_id);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	prepare_set_attr_list_add_entry(req,
+			OSD_PAGE_NUM_IBM_UOBJ_FS_DATA,
+			OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE,
+			EXOFS_INO_ATTR_SIZE,
+			(unsigned char *)inode);
+
+	ret = kick_it(req, timeout, cred_a, "set inode");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int get_root_attr(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fcb in = {0};
+	struct exofs_fcb *inode = &in;
+	uint32_t page = OSD_PAGE_NUM_IBM_UOBJ_FS_DATA;
+	uint32_t attr = OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE;
+	uint16_t expected = EXOFS_INO_ATTR_SIZE;
+	uint8_t *buf;
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_ROOT_ID);
+
+	req = prepare_osd_get_attr(dev, p_id, EXOFS_ROOT_ID);
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	prepare_get_attr_list_add_entry(req,
+			OSD_PAGE_NUM_IBM_UOBJ_FS_DATA,
+			OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE,
+			EXOFS_INO_ATTR_SIZE);
+
+	ret = kick_it(req, timeout, cred_a, "get root inode");
+	if (ret)
+		goto out;
+
+	ret = extract_next_attr_from_req(req, &page, &attr, &expected, &buf);
+	if (ret) {
+		EXOFS_ERR("ERROR: extract attr from req failed\n");
+		goto out;
+	}
+
+	memcpy(inode, buf, sizeof(struct exofs_fcb));
+
+	EXOFS_DBGMSG("mode: %u\n", be16_to_cpu(inode->i_mode));
+	EXOFS_DBGMSG("uid: %u\n", be32_to_cpu(inode->i_uid));
+	EXOFS_DBGMSG("gid: %u\n", be32_to_cpu(inode->i_gid));
+	EXOFS_DBGMSG("links: %u\n", be16_to_cpu(inode->i_links_count));
+	EXOFS_DBGMSG("ctime: %u\n", be32_to_cpu(inode->i_ctime));
+	EXOFS_DBGMSG("atime: %u\n", be32_to_cpu(inode->i_atime));
+	EXOFS_DBGMSG("mtime: %u\n", be32_to_cpu(inode->i_mtime));
+	EXOFS_DBGMSG("gen: %u\n", be32_to_cpu(inode->i_generation));
+	EXOFS_DBGMSG("size: %llu\n", _LLU(be64_to_cpu(inode->i_size)));
+
+out:
+	free_osd_req(req);
+
+	return ret;
+}
+#endif
+
+/*
+ * This function creates an exofs file system on the specified OSD partition.
+ */
+int exofs_mkfs(struct osd_dev *dev, uint64_t p_id, uint64_t format_size_meg)
+{
+	int err;
+	const int to_format = (4 * 60 * HZ);
+	const int to_gen = (60 * HZ);
+	bool newfile = false;
+
+	/* Get a handle */
+	EXOFS_DBGMSG("setting up exofs on partition %llu:\n", _LLU(p_id));
+
+	/* Format LUN if requested */
+	if (format_size_meg > 0) {
+		EXOFS_DBGMSG("formatting %llu Mgb...\n", _LLU(format_size_meg));
+		err = format(format_size_meg * 1024 * 1024, dev, to_format);
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+
+	/* Create partition */
+	EXOFS_DBGMSG("creating partition...\n");
+	err = create_partition(dev, p_id, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Create object with known ID for superblock info */
+	EXOFS_DBGMSG("creating superblock...\n");
+	err = create(dev, p_id, EXOFS_SUPER_ID, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Create root directory object */
+	EXOFS_DBGMSG("creating root directory...\n");
+	err = create(dev, p_id, EXOFS_ROOT_ID, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Create bitmap object */
+	EXOFS_DBGMSG("creating free ID bitmap...\n");
+	err = create(dev, p_id, EXOFS_BM_ID, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+	/* Create a test file, if specified by options */
+	if (newfile) {
+		EXOFS_DBGMSG("creating test file...\n");
+		err = create(dev, p_id, EXOFS_TEST_ID, to_gen);
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+#endif
+
+	/* Write superblock */
+	EXOFS_DBGMSG("writing superblock...\n");
+	err = write_super(dev, p_id, to_gen, newfile);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Write root directory */
+	EXOFS_DBGMSG("writing root directory...\n");
+	err = write_rootdir(dev, p_id, to_gen, newfile);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Set root partition inode attribute */
+	EXOFS_DBGMSG("writing root inode...\n");
+	err = set_inode(dev, p_id, to_gen, EXOFS_ROOT_ID,
+			0040000 | (0777 & ~022));
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+	/* Set test file inode attribute */
+	if (newfile) {
+		EXOFS_DBGMSG("writing test inode...\n");
+		err = set_inode(dev, p_id, to_gen, EXOFS_TEST_ID,
+				0100000 | (0777 & ~022));
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+#endif
+	/* Write bitmap */
+	EXOFS_DBGMSG("writing free ID bitmap...\n");
+	err = write_bitmap(dev, p_id, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+	/* Write test file */
+	if (newfile) {
+		EXOFS_DBGMSG("writing test file...\n");
+		err = write_testfile(dev, p_id, to_gen);
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+
+	/* some debug info */
+	{
+		EXOFS_DBGMSG("listing:\n");
+		list(dev, p_id, to_gen);
+		EXOFS_DBGMSG("contents of superblock:\n");
+		read_super(dev, p_id, to_gen);
+		EXOFS_DBGMSG("contents of root inode:\n");
+		get_root_attr(dev, p_id, to_gen);
+		if (newfile) {
+			EXOFS_DBGMSG("contents of test file:\n");
+			read_testfile(dev, p_id, to_gen);
+		}
+	}
+#endif
+	EXOFS_DBGMSG("\nsetup complete: enjoy your shiny new exofs!\n");
+
+out:
+	return err;
+}
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 8ecf700..459b935 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -55,6 +55,8 @@ enum { Opt_lun, Opt_tid, Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
 static match_table_t tokens = {
 	{Opt_pid, "pid=%u"},
 	{Opt_to, "to=%u"},
+	{Opt_mkfs, "mkfs=%u"},
+	{Opt_format, "format=%u"},
 	{Opt_err, NULL}
 };
 
@@ -100,6 +102,16 @@ static int parse_options(char *options, struct exofs_mountopt *opts)
 			}
 			opts->timeout = option * HZ;
 			break;
+		case Opt_mkfs:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			opts->mkfs = option != 0;
+			break;
+		case Opt_format:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			opts->format = option;
+			break;
 		}
 	}
 
@@ -277,6 +289,12 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_bdev = NULL;
 	sb->s_dev = 0;
 
+	/* see if we need to make the file system on the obsd */
+	if (opts->mkfs) {
+		EXOFS_DBGMSG("exofs_mkfs %p\n", sbi->s_dev);
+		exofs_mkfs(sbi->s_dev, sbi->s_pid, opts->format);
+	}
+
 	/* read data from on-disk superblock object */
 	make_credential(sbi->s_cred, sbi->s_pid, EXOFS_SUPER_ID);
 
-- 
1.6.0.1



WARNING: multiple messages have this Message-ID (diff)
From: Boaz Harrosh <bharrosh@panasas.com>
To: Avishay Traeger <avishay@gmail.com>,
	Jeff Garzik <jeff@garzik.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Al Viro <viro@ZenIV.linux.org.uk>,
	linux-fsdevel <linux-fsdevel@vger.ker
Cc: linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH 7/9] exofs: mkexofs
Date: Tue, 16 Dec 2008 17:33:48 +0200	[thread overview]
Message-ID: <4947CA5C.50104@panasas.com> (raw)
In-Reply-To: <4947BFAA.4030208@panasas.com>


We need a mechanism to prepare the file system (mkfs).
I chose to implement that by means of a couple of
mount-options. Because there is no user-mode API for committing
OSD commands. And also, all this stuff is highly internal to
the file system itself.

- Added two mount options mkfs=0/1,format=capacity_in_meg, so mkfs/format
  can be executed by kernel code just before mount. An mkexofs utility
  can now be implemented by means of a script that mounts and unmount the
  file system with proper options.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
 fs/exofs/Kbuild    |    2 +-
 fs/exofs/exofs.h   |    3 +
 fs/exofs/mkexofs.c |  605 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/exofs/super.c   |   18 ++
 4 files changed, 627 insertions(+), 1 deletions(-)
 create mode 100644 fs/exofs/mkexofs.c

diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
index e293cb9..639c181 100644
--- a/fs/exofs/Kbuild
+++ b/fs/exofs/Kbuild
@@ -26,5 +26,5 @@ KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
 
 endif
 
-exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o super.o
+exofs-objs := osd.o inode.o file.o symlink.o namei.o dir.o super.o mkexofs.o
 obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 75c608d..f53d18b 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -204,6 +204,9 @@ int extract_list_from_req(struct osd_request *req,
 
 void free_osd_req(struct osd_request *req);
 
+/* mkexofs.c             */
+int exofs_mkfs(struct osd_dev *dev, uint64_t p_id, uint64_t format_size);
+
 /* inode.c               */
 void exofs_truncate(struct inode *inode);
 extern struct inode *exofs_iget(struct super_block *, unsigned long);
diff --git a/fs/exofs/mkexofs.c b/fs/exofs/mkexofs.c
new file mode 100644
index 0000000..79df3e3
--- /dev/null
+++ b/fs/exofs/mkexofs.c
@@ -0,0 +1,605 @@
+/*
+ * mkexofs.c - make an exofs file system.
+ *
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ *
+ * Copyrights from mke2fs.c:
+ *     Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ *     2003, 2004, 2005 by Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "exofs.h"
+#include <linux/random.h>
+
+/* #define __MKEXOFS_DEBUG_CHECKS 1 */
+
+static int kick_it(struct osd_request *req, int timeout, uint8_t *cred_a,
+		   const char *op)
+{
+	return exofs_sync_op(req, timeout, cred_a);
+}
+
+/* Format the LUN to the specified size */
+static int format(uint64_t lun_capacity, struct osd_dev *dev, int timeout)
+{
+	struct osd_request *req = prepare_osd_format_lun(dev, lun_capacity);
+	uint8_t cred_a[OSD_CAP_LEN];
+	int ret;
+
+	make_credential(cred_a, 0, 0);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "format");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int create_partition(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	bool try_remove = false;
+	int ret;
+
+	make_credential(cred_a, p_id, 0);
+
+create_part:
+	req = prepare_osd_create_partition(dev, p_id);
+	if (!req)
+		return -ENOMEM;
+	ret = kick_it(req, timeout, cred_a, "create partition");
+	free_osd_req(req);
+
+	if (ret && !try_remove) {
+		try_remove = true;
+		req = prepare_osd_remove_partition(dev, p_id);
+		if (!req)
+			return -ENOMEM;
+		ret = kick_it(req, timeout, cred_a, "remove partition");
+		free_osd_req(req);
+		if (!ret) /* Try again now */
+			goto create_part;
+	}
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int list(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	unsigned char *buf = NULL;
+	int ret;
+	uint64_t total_matches;
+	uint64_t total_ret;
+	uint64_t *id_list;
+	int is_part, is_utd;
+	uint64_t cont;
+	uint32_t more;
+	int i;
+
+	buf = kzalloc(1024, GFP_KERNEL);
+	if (!buf) {
+		EXOFS_ERR("ERROR: Failed to allocate memory.\n");
+		return -ENOMEM;
+	}
+
+	make_credential(cred_a, p_id, 0);
+
+	req = prepare_osd_list(dev, p_id, 0, 1024, 0, 0, buf);
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "list");
+	if (ret != 0)
+		goto out;
+
+	ret = extract_list_from_req(req, &total_matches, &total_ret, &id_list,
+				    &is_part, &is_utd, &cont, &more);
+
+	EXOFS_DBGMSG("created %llu objects:\n", _LLU(total_ret));
+	for (i = 0 ; i < total_ret ; i++)
+		EXOFS_DBGMSG("%llu\n", _LLU(id_list[i]));
+
+out:
+	free_osd_req(req);
+	kfree(buf);
+
+	return ret;
+}
+#endif
+
+static int create(struct osd_dev *dev, uint64_t p_id, uint64_t o_id,
+		  int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	int ret;
+
+	make_credential(cred_a, p_id, o_id);
+	req = prepare_osd_create(dev, p_id, o_id);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "create");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int write_super(struct osd_dev *dev, uint64_t p_id, int timeout,
+		       int newfile)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fscb data;
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_SUPER_ID);
+
+	data.s_nextid = 4;
+	data.s_magic = EXOFS_SUPER_MAGIC;
+	data.s_newfs = 1;
+	if (newfile)
+		data.s_numfiles = 1;
+	else
+		data.s_numfiles = 0;
+
+	req = prepare_osd_write(dev, p_id, EXOFS_SUPER_ID,
+				sizeof(struct exofs_fscb), 0, 0,
+				(unsigned char *)(&data));
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write super");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int read_super(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fscb data;
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_SUPER_ID);
+
+	req = prepare_osd_read(dev, p_id, EXOFS_SUPER_ID,
+				sizeof(struct exofs_fscb), 0, 0,
+				(unsigned char *)(&data));
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "read super");
+	if (ret)
+		goto out;
+
+	EXOFS_DBGMSG("nextid:\t%u\n", data.s_nextid);
+	EXOFS_DBGMSG("magic:\t%u\n", data.s_magic);
+	EXOFS_DBGMSG("numfiles:\t%u\n", data.s_numfiles);
+out:
+	free_osd_req(req);
+
+	return ret;
+}
+#endif
+
+static int write_bitmap(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	uint64_t off = 0;
+	unsigned int id = 3;
+	int ret;
+
+	/* XXX: For now just use counter - later make bitmap */
+	make_credential(cred_a, p_id, EXOFS_BM_ID);
+
+	req = prepare_osd_write(dev, p_id, EXOFS_BM_ID, sizeof(unsigned int),
+				off, 0, (unsigned char *)&id);
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write bitmap");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int write_testfile(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	uint64_t off = 0;
+	unsigned char buf[64];
+	int ret;
+
+	strcpy((char *)buf, "This file is a test, it is only a test.");
+	make_credential(cred_a, p_id, EXOFS_TEST_ID);
+
+	req = prepare_osd_write(dev, p_id, EXOFS_TEST_ID, 64, off, 0, buf);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write bitmap");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int read_testfile(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	unsigned char data[64];
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_TEST_ID);
+
+	req = prepare_osd_read(dev, p_id, EXOFS_TEST_ID, 64, 0, 0, data);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "read test file");
+	if (ret)
+		goto out;
+
+	EXOFS_DBGMSG("test file: %s\n", data);
+
+out:
+	free_osd_req(req);
+
+	return ret;
+}
+#endif
+
+static int write_rootdir(struct osd_dev *dev, uint64_t p_id, int timeout,
+			 int newfile)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_dir_entry *dir;
+	uint64_t off = 0;
+	unsigned char *buf = NULL;
+	int filetype = EXOFS_FT_DIR << 8;
+	int filetype2 = EXOFS_FT_REG_FILE << 8;
+	int rec_len;
+	int done;
+	int ret;
+
+	buf = kzalloc(EXOFS_BLKSIZE, GFP_KERNEL);
+	if (!buf) {
+		EXOFS_ERR("ERROR: Failed to allocate memory.\n");
+		return -ENOMEM;
+	}
+	dir = (struct exofs_dir_entry *)buf;
+
+	/* create entry for '.' */
+	dir->name[0] = '.';
+	dir->name_len = 1 | filetype;
+	dir->inode = EXOFS_ROOT_ID - EXOFS_OBJ_OFF;
+	dir->rec_len = EXOFS_DIR_REC_LEN(1);
+	rec_len = EXOFS_BLKSIZE - EXOFS_DIR_REC_LEN(1);
+
+	/* create entry for '..' */
+	dir = (struct exofs_dir_entry *) (buf + dir->rec_len);
+	dir->name[0] = '.';
+	dir->name[1] = '.';
+	dir->name_len = 2 | filetype;
+	dir->inode = EXOFS_ROOT_ID - EXOFS_OBJ_OFF;
+	if (newfile) {
+		rec_len -= EXOFS_DIR_REC_LEN(2);
+		dir->rec_len = EXOFS_DIR_REC_LEN(2);
+	} else
+		dir->rec_len = rec_len;
+	done = EXOFS_DIR_REC_LEN(1) + dir->rec_len;
+
+	/* create entry for 'test', if specified */
+	if (newfile) {
+		dir = (struct exofs_dir_entry *) (buf + done);
+		dir->inode = EXOFS_TEST_ID - EXOFS_OBJ_OFF;
+		dir->name_len = 4 | filetype2;
+		dir->name[0] = 't';
+		dir->name[1] = 'e';
+		dir->name[2] = 's';
+		dir->name[3] = 't';
+		dir->rec_len = rec_len;
+	}
+
+	make_credential(cred_a, p_id, EXOFS_ROOT_ID);
+
+	req = prepare_osd_write(dev, p_id, EXOFS_ROOT_ID, EXOFS_BLKSIZE, off,
+				0, buf);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	ret = kick_it(req, timeout, cred_a, "write rootdir");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+static int set_inode(struct osd_dev *dev, uint64_t p_id, int timeout,
+		     uint64_t o_id, uint16_t mode)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fcb in = {0};
+	struct exofs_fcb *inode = &in;
+	uint32_t i_generation;
+	int ret;
+
+	inode->i_mode = cpu_to_be16(mode);
+	inode->i_uid = inode->i_gid = 0;
+	inode->i_links_count = cpu_to_be16(2);
+	inode->i_ctime = inode->i_atime = inode->i_mtime =
+					cpu_to_be32(CURRENT_TIME.tv_sec);
+	inode->i_size = cpu_to_be64(EXOFS_BLKSIZE);
+	if (o_id != EXOFS_ROOT_ID)
+		inode->i_size = cpu_to_be64(64);
+
+	get_random_bytes(&i_generation, sizeof(i_generation));
+	inode->i_generation = cpu_to_be32(i_generation);
+
+	make_credential(cred_a, p_id, o_id);
+
+	req = prepare_osd_set_attr(dev, p_id, o_id);
+
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	prepare_set_attr_list_add_entry(req,
+			OSD_PAGE_NUM_IBM_UOBJ_FS_DATA,
+			OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE,
+			EXOFS_INO_ATTR_SIZE,
+			(unsigned char *)inode);
+
+	ret = kick_it(req, timeout, cred_a, "set inode");
+
+	free_osd_req(req);
+
+	return ret;
+}
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+static int get_root_attr(struct osd_dev *dev, uint64_t p_id, int timeout)
+{
+	struct osd_request *req;
+	uint8_t cred_a[OSD_CAP_LEN];
+	struct exofs_fcb in = {0};
+	struct exofs_fcb *inode = &in;
+	uint32_t page = OSD_PAGE_NUM_IBM_UOBJ_FS_DATA;
+	uint32_t attr = OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE;
+	uint16_t expected = EXOFS_INO_ATTR_SIZE;
+	uint8_t *buf;
+	int ret;
+
+	make_credential(cred_a, p_id, EXOFS_ROOT_ID);
+
+	req = prepare_osd_get_attr(dev, p_id, EXOFS_ROOT_ID);
+	if (req == NULL) {
+		EXOFS_ERR("ERROR: Failed to allocate request.\n");
+		return -ENOMEM;
+	}
+
+	prepare_get_attr_list_add_entry(req,
+			OSD_PAGE_NUM_IBM_UOBJ_FS_DATA,
+			OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE,
+			EXOFS_INO_ATTR_SIZE);
+
+	ret = kick_it(req, timeout, cred_a, "get root inode");
+	if (ret)
+		goto out;
+
+	ret = extract_next_attr_from_req(req, &page, &attr, &expected, &buf);
+	if (ret) {
+		EXOFS_ERR("ERROR: extract attr from req failed\n");
+		goto out;
+	}
+
+	memcpy(inode, buf, sizeof(struct exofs_fcb));
+
+	EXOFS_DBGMSG("mode: %u\n", be16_to_cpu(inode->i_mode));
+	EXOFS_DBGMSG("uid: %u\n", be32_to_cpu(inode->i_uid));
+	EXOFS_DBGMSG("gid: %u\n", be32_to_cpu(inode->i_gid));
+	EXOFS_DBGMSG("links: %u\n", be16_to_cpu(inode->i_links_count));
+	EXOFS_DBGMSG("ctime: %u\n", be32_to_cpu(inode->i_ctime));
+	EXOFS_DBGMSG("atime: %u\n", be32_to_cpu(inode->i_atime));
+	EXOFS_DBGMSG("mtime: %u\n", be32_to_cpu(inode->i_mtime));
+	EXOFS_DBGMSG("gen: %u\n", be32_to_cpu(inode->i_generation));
+	EXOFS_DBGMSG("size: %llu\n", _LLU(be64_to_cpu(inode->i_size)));
+
+out:
+	free_osd_req(req);
+
+	return ret;
+}
+#endif
+
+/*
+ * This function creates an exofs file system on the specified OSD partition.
+ */
+int exofs_mkfs(struct osd_dev *dev, uint64_t p_id, uint64_t format_size_meg)
+{
+	int err;
+	const int to_format = (4 * 60 * HZ);
+	const int to_gen = (60 * HZ);
+	bool newfile = false;
+
+	/* Get a handle */
+	EXOFS_DBGMSG("setting up exofs on partition %llu:\n", _LLU(p_id));
+
+	/* Format LUN if requested */
+	if (format_size_meg > 0) {
+		EXOFS_DBGMSG("formatting %llu Mgb...\n", _LLU(format_size_meg));
+		err = format(format_size_meg * 1024 * 1024, dev, to_format);
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+
+	/* Create partition */
+	EXOFS_DBGMSG("creating partition...\n");
+	err = create_partition(dev, p_id, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Create object with known ID for superblock info */
+	EXOFS_DBGMSG("creating superblock...\n");
+	err = create(dev, p_id, EXOFS_SUPER_ID, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Create root directory object */
+	EXOFS_DBGMSG("creating root directory...\n");
+	err = create(dev, p_id, EXOFS_ROOT_ID, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Create bitmap object */
+	EXOFS_DBGMSG("creating free ID bitmap...\n");
+	err = create(dev, p_id, EXOFS_BM_ID, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+	/* Create a test file, if specified by options */
+	if (newfile) {
+		EXOFS_DBGMSG("creating test file...\n");
+		err = create(dev, p_id, EXOFS_TEST_ID, to_gen);
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+#endif
+
+	/* Write superblock */
+	EXOFS_DBGMSG("writing superblock...\n");
+	err = write_super(dev, p_id, to_gen, newfile);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Write root directory */
+	EXOFS_DBGMSG("writing root directory...\n");
+	err = write_rootdir(dev, p_id, to_gen, newfile);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+	/* Set root partition inode attribute */
+	EXOFS_DBGMSG("writing root inode...\n");
+	err = set_inode(dev, p_id, to_gen, EXOFS_ROOT_ID,
+			0040000 | (0777 & ~022));
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+	/* Set test file inode attribute */
+	if (newfile) {
+		EXOFS_DBGMSG("writing test inode...\n");
+		err = set_inode(dev, p_id, to_gen, EXOFS_TEST_ID,
+				0100000 | (0777 & ~022));
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+#endif
+	/* Write bitmap */
+	EXOFS_DBGMSG("writing free ID bitmap...\n");
+	err = write_bitmap(dev, p_id, to_gen);
+	if (err)
+		goto out;
+	EXOFS_DBGMSG(" OK\n");
+
+#ifdef __MKEXOFS_DEBUG_CHECKS
+	/* Write test file */
+	if (newfile) {
+		EXOFS_DBGMSG("writing test file...\n");
+		err = write_testfile(dev, p_id, to_gen);
+		if (err)
+			goto out;
+		EXOFS_DBGMSG(" OK\n");
+	}
+
+	/* some debug info */
+	{
+		EXOFS_DBGMSG("listing:\n");
+		list(dev, p_id, to_gen);
+		EXOFS_DBGMSG("contents of superblock:\n");
+		read_super(dev, p_id, to_gen);
+		EXOFS_DBGMSG("contents of root inode:\n");
+		get_root_attr(dev, p_id, to_gen);
+		if (newfile) {
+			EXOFS_DBGMSG("contents of test file:\n");
+			read_testfile(dev, p_id, to_gen);
+		}
+	}
+#endif
+	EXOFS_DBGMSG("\nsetup complete: enjoy your shiny new exofs!\n");
+
+out:
+	return err;
+}
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 8ecf700..459b935 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -55,6 +55,8 @@ enum { Opt_lun, Opt_tid, Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
 static match_table_t tokens = {
 	{Opt_pid, "pid=%u"},
 	{Opt_to, "to=%u"},
+	{Opt_mkfs, "mkfs=%u"},
+	{Opt_format, "format=%u"},
 	{Opt_err, NULL}
 };
 
@@ -100,6 +102,16 @@ static int parse_options(char *options, struct exofs_mountopt *opts)
 			}
 			opts->timeout = option * HZ;
 			break;
+		case Opt_mkfs:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			opts->mkfs = option != 0;
+			break;
+		case Opt_format:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			opts->format = option;
+			break;
 		}
 	}
 
@@ -277,6 +289,12 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_bdev = NULL;
 	sb->s_dev = 0;
 
+	/* see if we need to make the file system on the obsd */
+	if (opts->mkfs) {
+		EXOFS_DBGMSG("exofs_mkfs %p\n", sbi->s_dev);
+		exofs_mkfs(sbi->s_dev, sbi->s_pid, opts->format);
+	}
+
 	/* read data from on-disk superblock object */
 	make_credential(sbi->s_cred, sbi->s_pid, EXOFS_SUPER_ID);
 
-- 
1.6.0.1



  parent reply	other threads:[~2008-12-16 15:34 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-16 14:48 [PATCHSET 0/9] exofs (was osdfs) Boaz Harrosh
2008-12-16 14:48 ` Boaz Harrosh
2008-12-16 14:52 ` [PATCH 1/9] exofs: osd Swiss army knife Boaz Harrosh
2008-12-16 14:52   ` Boaz Harrosh
2008-12-29 20:29   ` Andrew Morton
2008-12-31 15:33     ` Boaz Harrosh
2008-12-31 19:26       ` Andrew Morton
2009-01-01 14:44         ` Boaz Harrosh
2009-01-02 16:52     ` Pavel Machek
2009-01-04  8:43       ` Boaz Harrosh
2009-01-04 20:03         ` Pavel Machek
2009-01-05  9:01           ` Boaz Harrosh
2009-01-05  9:36             ` Pavel Machek
2008-12-16 15:15 ` Boaz Harrosh
2009-01-07 15:47   ` [osd-dev] " Benny Halevy
2009-01-13 13:55     ` Alan Cox
2009-01-13 14:43       ` Boaz Harrosh
2009-01-13 14:52         ` Boaz Harrosh
2009-01-13 15:09       ` Jamie Lokier
2009-01-13 15:17         ` Jeff Garzik
2009-01-13 15:28           ` Benny Halevy
2008-12-16 15:15 ` Boaz Harrosh
2008-12-16 15:17 ` [PATCH 2/9] exofs: file and file_inode operations Boaz Harrosh
2008-12-16 15:17   ` Boaz Harrosh
2008-12-29 20:34   ` Andrew Morton
2008-12-31 15:36     ` Boaz Harrosh
2008-12-16 15:21 ` [PATCH 3/9] exofs: symlink_inode and fast_symlink_inode operations Boaz Harrosh
2008-12-16 15:21   ` Boaz Harrosh
2008-12-29 20:35   ` Andrew Morton
2008-12-16 15:22 ` [PATCH 4/9] exofs: address_space_operations Boaz Harrosh
2008-12-16 15:22   ` Boaz Harrosh
2008-12-29 20:45   ` Andrew Morton
2008-12-31 15:35     ` Boaz Harrosh
2008-12-16 15:28 ` [PATCH 5/9] exofs: dir_inode and directory operations Boaz Harrosh
2008-12-16 15:28   ` Boaz Harrosh
2008-12-29 20:47   ` Andrew Morton
2008-12-31 15:33     ` Boaz Harrosh
2008-12-16 15:31 ` [PATCH 6/9] exofs: super_operations and file_system_type Boaz Harrosh
2008-12-16 15:31   ` Boaz Harrosh
2008-12-17 22:23   ` Marcin Slusarz
2008-12-18  8:41     ` Boaz Harrosh
2008-12-29 20:50   ` Andrew Morton
2008-12-16 15:33 ` Boaz Harrosh [this message]
2008-12-16 15:33   ` [PATCH 7/9] exofs: mkexofs Boaz Harrosh
2008-12-29 20:14   ` Andrew Morton
2008-12-31 15:19     ` Boaz Harrosh
2008-12-31 15:57       ` James Bottomley
2009-01-01  9:22         ` [osd-dev] " Benny Halevy
2009-01-01  9:54           ` Jeff Garzik
2009-01-01 14:23             ` Benny Halevy
2009-01-01 14:28               ` Matthew Wilcox
2009-01-01 18:12               ` Jörn Engel
2009-01-01 18:12                 ` Jörn Engel
2009-01-01 23:26           ` J. Bruce Fields
2009-01-02  7:14             ` Benny Halevy
2009-01-04 15:20         ` Boaz Harrosh
2009-01-04 15:38           ` Christoph Hellwig
2009-01-12 18:12           ` James Bottomley
2009-01-12 19:23             ` Jeff Garzik
2009-01-12 19:56               ` James Bottomley
2009-01-12 19:56               ` James Bottomley
2009-01-12 20:22                 ` Jeff Garzik
2009-01-12 23:25                   ` James Bottomley
2009-01-13 13:03                     ` [osd-dev] " Benny Halevy
2009-01-13 13:24                       ` Jeff Garzik
2009-01-13 13:32                         ` Benny Halevy
2009-01-13 13:44                     ` Jeff Garzik
2009-01-13 14:03                       ` Alan Cox
2009-01-13 14:17                         ` Jeff Garzik
2009-01-13 16:14                           ` Alan Cox
2009-01-13 17:21                             ` Boaz Harrosh
2009-01-21 18:13                               ` Jeff Garzik
2009-01-21 18:44                                 ` Boaz Harrosh
2009-01-12 22:48             ` Jamie Lokier
2009-01-06  8:40         ` Andreas Dilger
2008-12-31 19:25       ` Andrew Morton
2009-01-01 13:33         ` Boaz Harrosh
2009-01-02 22:46           ` James Bottomley
2009-01-04  8:59             ` Boaz Harrosh
2008-12-16 15:36 ` [PATCH 8/9] exofs: Documentation Boaz Harrosh
2008-12-16 15:36   ` Boaz Harrosh
2008-12-18  7:47   ` Pavel Machek
2008-12-18  8:32     ` Boaz Harrosh
2008-12-16 15:38 ` [PATCH 9/9] fs: Add exofs to Kernel build Boaz Harrosh
2008-12-16 15:38   ` Boaz Harrosh

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=4947CA5C.50104@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=akpm@linux-foundation.org \
    --cc=avishay@gmail.com \
    --cc=jeff@garzik.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=osd-dev@open-osd.org \
    --cc=viro@ZenIV.linux.org.uk \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.