All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch 2/2] grub-0.97: btrfs multidevice configuration support
@ 2009-09-24 22:06 Edward Shishkin
  2009-11-02 22:16 ` Johannes Hirte
  0 siblings, 1 reply; 5+ messages in thread
From: Edward Shishkin @ 2009-09-24 22:06 UTC (permalink / raw)
  To: The development of BTRFS

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: grub-btrfs-multidev.patch --]
[-- Type: text/plain, Size: 32964 bytes --]

Signed-off-by: Edward Shishkin <edward@redhat.com>

---
 grub/Makefile.am    |    2 
 stage2/btrfs.h      |   55 ++--
 stage2/builtins.c   |   10 
 stage2/disk_io.c    |    2 
 stage2/filesys.h    |    4 
 stage2/fsys_btrfs.c |  693 +++++++++++++++++++++++++++++++++++++++++-----------
 6 files changed, 595 insertions(+), 171 deletions(-)

--- grub-0.97.orig/stage2/btrfs.h
+++ grub-0.97/stage2/btrfs.h
@@ -124,6 +124,7 @@ static int btrfs_csum_sizes[] = { 4, 0 }
 #define BTRFS_DEFAULT_NUM_DEVICES     1
 #define BTRFS_DEFAULT_NODE_SIZE       4096
 #define BTRFS_DEFAULT_LEAF_SIZE       4096
+#define BTRFS_NUM_CACHED_DEVICES      128
 
 #define WARN_ON(c)
 #define cassert(cond) ({ switch (-1) { case (cond): case 0: break; } })
@@ -315,13 +316,22 @@ struct btrfs_node {
 	struct btrfs_key_ptr ptrs[];
 } __attribute__ ((__packed__));
 
+struct btrfs_device {
+	/* the internal btrfs device id */
+	u64 devid;
+	/* the internal grub device representation */
+	unsigned long drive;
+	unsigned long part;
+	unsigned long length;
+};
+
 struct extent_buffer {
 	/* metadata */
+	struct btrfs_device dev;
 	u64 start;
 	u64 dev_bytenr;
 	u32 len;
-	int refs;
-	int flags;
+	/* data */
 	char *data;
 };
 
@@ -555,12 +565,8 @@ struct btrfs_block_group_item {
 struct btrfs_root {
 	struct extent_buffer   node;
 	char                   data[4096];
-	struct extent_buffer   *commit_root;
 	struct btrfs_root_item root_item;
-	struct btrfs_key       root_key;
-	struct btrfs_fs_info   *fs_info;
 	u64 objectid;
-	u64 last_trans;
 
 	/* data allocations are done in sectorsize units */
 	u32 sectorsize;
@@ -573,42 +579,31 @@ struct btrfs_root {
 
 	/* leaf allocations are done in leafsize units */
 	u32 stripesize;
+};
 
-	int ref_cows;
-	int track_dirty;
-
-
-	u32 type;
-	u64 highest_inode;
-	u64 last_inode_alloc;
+struct btrfs_file_info {
+	struct btrfs_key key;
 };
 
 struct btrfs_root;
 struct btrfs_fs_devices;
 struct btrfs_fs_info {
 	u8 fsid[BTRFS_FSID_SIZE];
-	u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
 	struct btrfs_root fs_root;
 	struct btrfs_root tree_root;
 	struct btrfs_root chunk_root;
 
-	struct btrfs_key  file_info; /* currently opened file */
+	struct btrfs_file_info file_info; /* currently opened file */
 	struct btrfs_path paths [LAST_LOOKUP_POOL];
 
-	u64 generation;
-	u64 last_trans_committed;
+	char mbr[SECTOR_SIZE];
 
-	u64 system_alloc_profile;
-	u64 alloc_start;
+	int sb_mirror;
+	u64 sb_transid;
+	struct btrfs_device sb_dev;
+   	struct btrfs_super_block sb_copy;
 
-	struct btrfs_super_block super_temp;
-   	struct btrfs_super_block super_copy;
-
-	u64 super_bytenr;
-	u64 total_pinned;
-
-	int system_allocs;
-	int readonly;
+	struct btrfs_device devices[BTRFS_NUM_CACHED_DEVICES + 1];
 };
 
 /*
@@ -1129,6 +1124,11 @@ static inline void btrfs_set_key_type(st
 	key->type = val;
 }
 
+static inline u64 btrfs_super_devid(struct btrfs_super_block *disk_super)
+{
+	return le64_to_cpu(disk_super->dev_item.devid);
+}
+
 /* struct btrfs_header */
 BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64);
 BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,
@@ -1317,6 +1317,7 @@ struct btrfs_fs_devices {
 };
 
 struct btrfs_bio_stripe {
+	struct btrfs_device dev;
 	u64 physical;
 };
 
--- grub-0.97.orig/stage2/fsys_btrfs.c
+++ grub-0.97/stage2/fsys_btrfs.c
@@ -31,15 +31,21 @@
 #define BTRFS_FS_INFO							\
 	((struct btrfs_fs_info *)((unsigned long)FSYS_BUF +		\
 				  LOOKUP_CACHE_SIZE))
-#define BTRFS_CACHE_SIZE        (sizeof(struct btrfs_fs_info) +	\
-				 LOOKUP_CACHE_SIZE)
-#define BTRFS_FILE_INFO         (&BTRFS_FS_INFO->file_info)
-#define BTRFS_TREE_ROOT         (&BTRFS_FS_INFO->tree_root)
-#define BTRFS_CHUNK_ROOT        (&BTRFS_FS_INFO->chunk_root)
-#define BTRFS_FS_ROOT           (&BTRFS_FS_INFO->fs_root)
-#define BTRFS_SUPER             (&BTRFS_FS_INFO->super_copy)
-#define LOOKUP_CACHE_BUF(id)	((char *)((unsigned long)FSYS_BUF +	\
-					  id * LOOKUP_CACHE_BUF_SIZE))
+#define BTRFS_CACHE_SIZE         (sizeof(struct btrfs_fs_info) +	\
+				  LOOKUP_CACHE_SIZE)
+#define BTRFS_TREE_ROOT          (&BTRFS_FS_INFO->tree_root)
+#define BTRFS_CHUNK_ROOT         (&BTRFS_FS_INFO->chunk_root)
+#define BTRFS_FS_ROOT            (&BTRFS_FS_INFO->fs_root)
+#define BTRFS_SUPER              (&BTRFS_FS_INFO->sb_copy)
+#define BTRFS_DEVICES            (&BTRFS_FS_INFO->devices[0])
+#define BTRFS_FILE_INFO          (&BTRFS_FS_INFO->file_info)
+#define BTRFS_FILE_INFO_KEY      (&BTRFS_FILE_INFO->key)
+
+#define BTRFS_VOLATILE_DEV_CACHE				        \
+	(&BTRFS_FS_INFO->devices[BTRFS_NUM_CACHED_DEVICES])
+
+#define LOOKUP_CACHE_BUF(id) ((char *)((unsigned long)FSYS_BUF +	\
+				       id * LOOKUP_CACHE_BUF_SIZE))
 
 #define noop   do {; } while (0)
 
@@ -76,13 +82,19 @@ static inline struct btrfs_path *btrfs_g
 	return &BTRFS_FS_INFO->paths[lpid];
 }
 
-static inline void btrfs_update_file_info(struct btrfs_path *path)
+static inline void btrfs_set_path_key(struct btrfs_path *path,
+				      struct btrfs_key *key)
 {
 	btrfs_item_key_to_cpu(&path->nodes[0],
-			      BTRFS_FILE_INFO,
+			      key,
 			      path->slots[0]);
 }
 
+static inline void btrfs_update_file_info(struct btrfs_path *path)
+{
+	btrfs_set_path_key(path, BTRFS_FILE_INFO_KEY);
+}
+
 static inline void btrfs_set_root_dir_key(struct btrfs_key *key)
 {
 	key->objectid = BTRFS_FIRST_FREE_OBJECTID;
@@ -120,14 +132,13 @@ static inline void init_btrfs_path(looku
 static inline void init_btrfs_info(void)
 {
 	int i;
-	struct btrfs_fs_info *fs = BTRFS_FS_INFO;
 
-	memset(fs, 0, sizeof (*fs));
+	memset(BTRFS_FS_INFO, 0, sizeof(struct btrfs_fs_info));
 	for(i = 0; i < LAST_LOOKUP_POOL; i++)
 		init_btrfs_path(i);
-	init_btrfs_root(&fs->tree_root);
-	init_btrfs_root(&fs->chunk_root);
-	init_btrfs_root(&fs->fs_root);
+	init_btrfs_root(BTRFS_TREE_ROOT);
+	init_btrfs_root(BTRFS_CHUNK_ROOT);
+	init_btrfs_root(BTRFS_FS_ROOT);
 }
 
 static void setup_root(struct btrfs_root *root,
@@ -137,7 +148,6 @@ static void setup_root(struct btrfs_root
 		       u32 stripesize,
 		       u64 objectid)
 {
-	root->fs_info = BTRFS_FS_INFO;
 	root->nodesize = nodesize;
 	root->leafsize = leafsize;
 	root->sectorsize = sectorsize;
@@ -152,7 +162,6 @@ static void setup_root(struct btrfs_root
 static int btrfs_find_last_root(struct btrfs_root *tree_root,
 				u64 objectid,
 				struct btrfs_root_item *item,
-				struct btrfs_key *key,
 				lookup_pool_id lpid)
 {
 	int ret;
@@ -175,10 +184,10 @@ static int btrfs_find_last_root(struct b
 	btrfs_item_key_to_cpu(&path->nodes[0], &found_key, slot);
 	if (found_key.objectid != objectid)
 		return 1;
+
 	read_extent_buffer(&path->nodes[0], item,
 			   btrfs_item_ptr_offset(&path->nodes[0], slot),
 			   sizeof(*item));
-	memcpy(key, &found_key, sizeof(found_key));
 	return 0;
 }
 
@@ -210,14 +219,13 @@ static int find_setup_root(struct btrfs_
 		 */
 		ret = btrfs_find_last_root(tree_root, objectid,
 					   &dest_root->root_item,
-					   &dest_root->root_key,
 					   lpid);
 		if (ret)
 			return ret;
 		bytenr = btrfs_root_bytenr(&dest_root->root_item);
 		blocksize = btrfs_level_size(dest_root,
 				       btrfs_root_level(&dest_root->root_item));
-		generation = btrfs_root_generation(&tree_root->root_item);
+		generation = btrfs_root_generation(&dest_root->root_item);
 	}
 	ret = read_tree_block(dest_root,
 			      &eb,
@@ -243,12 +251,34 @@ static inline int btrfs_strncmp(const ch
 	return __res;
 }
 
-static int btrfs_check_super_block(struct btrfs_super_block *sb)
-{
-	if (sb->num_devices != BTRFS_DEFAULT_NUM_DEVICES) {
-		btrfs_msg("Btrfs multi-device configuration unsupported\n");
-		goto error;
+/*
+ * the same as devread, but accepts
+ * device number, start and length.
+ */
+static int btrfs_devread(unsigned long drive, unsigned long part,
+			 unsigned long dev_len, int sector,
+			 int byte_offset, int byte_len, char *buf)
+{
+	if (sector < 0
+	    || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
+		>= dev_len)) {
+		errnum = ERR_OUTSIDE_PART;
+		return 0;
 	}
+	sector += byte_offset >> SECTOR_BITS;
+	byte_offset &= SECTOR_SIZE - 1;
+#if !defined(STAGE1_5)
+	if (disk_read_hook && debug)
+		printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
+#endif /* !STAGE1_5 */
+	return rawread(drive, part + sector, byte_offset,
+		       byte_len, buf);
+}
+
+static int btrfs_check_super(void)
+{
+	struct btrfs_super_block *sb = BTRFS_SUPER;
+
 	if (sb->nodesize != BTRFS_DEFAULT_NODE_SIZE) {
 		btrfs_msg("Btrfs node size (%d) != %d unsupported\n",
 			  sb->nodesize, BTRFS_DEFAULT_NODE_SIZE);
@@ -259,103 +289,412 @@ static int btrfs_check_super_block(struc
 			  sb->leafsize, BTRFS_DEFAULT_LEAF_SIZE);
 		goto error;
 	}
-	return 1;
- error:
-	errnum = ERR_FSYS_MOUNT;
 	return 0;
+ error:
+	return 1;
 }
 
-int btrfs_mount(void)
+/* lift the super block */
+static int btrfs_uptodate_super_copy(struct btrfs_fs_info *fs)
 {
-	int i;
-	int ret;
-	u64 transid = 0;
-	u64 bytenr;
-
-	struct btrfs_fs_info *fs = BTRFS_FS_INFO;
-	struct btrfs_super_block *sb_tmp; /* current */
-	struct btrfs_super_block *sb;     /* latest */
-
-	struct btrfs_root *tree_root = &fs->tree_root;
-	struct btrfs_root *chunk_root = &fs->chunk_root;
-	struct btrfs_root *fs_root = &fs->fs_root;
-
-	check_btrfs_cache_size();
-	init_btrfs_info();
+	errnum = ERR_NONE;
+	btrfs_devread(BTRFS_FS_INFO->sb_dev.drive,
+		      BTRFS_FS_INFO->sb_dev.part,
+		      BTRFS_FS_INFO->sb_dev.length,
+		      btrfs_sb_offset(BTRFS_FS_INFO->sb_mirror) >> SECTOR_BITS,
+		      0,
+		      sizeof(struct btrfs_super_block),
+		      (char *)BTRFS_SUPER);
+	return btrfs_check_super();
+}
 
-	sb_tmp = &fs->super_temp;
-	sb = &fs->super_copy;
+/*
+ * Looking for a btrfs super block by magic, @fsid and @devid
+ * (the last two ones are optional). Update latest transid (if
+ * any). Return 0, if such super block was found. Otherwise,
+ * return 1.
+ *
+ * NOTE:
+ * After calling this function the sb_copy of global btrfs_fs_info
+ * can contain garbage, so the caller is responsible for this to be
+ * uptodate (see the function btrfs_uptodate_super_copy()).
+ */
+static int btrfs_find_super(struct btrfs_device *dev, char *fsid, u64 *devid)
+{
+	int i, ret;
+	int found = 0;
 
-	/* pick up the latest version of superblock */
 	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
-		bytenr = btrfs_sb_offset(i);
-		ret = devread(bytenr >> SECTOR_BITS,
-			      0,
-			      sizeof(*sb_tmp),
-			      (char *)sb_tmp);
-		if (!ret)
-		        continue;
-
-		if (btrfs_super_bytenr(sb_tmp) != bytenr ||
-		    btrfs_strncmp((char *)(&sb_tmp->magic),
+		ret = btrfs_devread(dev->drive,
+				    dev->part,
+				    dev->length,
+				    btrfs_sb_offset(i) >> SECTOR_BITS,
+				    0,
+				    sizeof(struct btrfs_super_block),
+				    (char *)BTRFS_SUPER);
+		if (!ret) {
+			if (errnum == ERR_OUTSIDE_PART) {
+				errnum = ERR_NONE;
+				break;
+			} else {
+				errnum = ERR_NONE;
+				continue;
+			}
+		}
+		if (btrfs_super_bytenr(BTRFS_SUPER) != btrfs_sb_offset(i) ||
+		    btrfs_strncmp((char *)(&BTRFS_SUPER->magic),
 				  BTRFS_MAGIC,
-				  sizeof(sb_tmp->magic)))
+				  sizeof(BTRFS_SUPER->magic)))
 			continue;
-		if (btrfs_super_generation(sb_tmp) > transid) {
-			memcpy(sb, sb_tmp, sizeof(*sb_tmp));
-			transid = btrfs_super_generation(sb);
+		if (fsid &&
+		    btrfs_strncmp(fsid,
+				  (char *)BTRFS_SUPER->fsid,
+				  BTRFS_FSID_SIZE))
+			return 1;
+		if (devid &&
+		    *devid != btrfs_super_devid(BTRFS_SUPER))
+			return 1;
+		found = 1;
+		dev->devid = btrfs_super_devid(BTRFS_SUPER);
+
+		if (btrfs_super_generation(BTRFS_SUPER) >
+		    BTRFS_FS_INFO->sb_transid) {
+			BTRFS_FS_INFO->sb_transid =
+				btrfs_super_generation(BTRFS_SUPER);
+			BTRFS_FS_INFO->sb_mirror = i;
+			BTRFS_FS_INFO->sb_dev.devid =
+				btrfs_super_devid(BTRFS_SUPER);
+			BTRFS_FS_INFO->sb_dev.drive = dev->drive;
+			BTRFS_FS_INFO->sb_dev.part = dev->part;
+			BTRFS_FS_INFO->sb_dev.length = dev->length;
+		}
+	}
+	return !found;
+}
+
+/*
+ * "Discern" a btrfs device by fsid and
+ * optionaly by devid (if lookup is set).
+ * Populate persistent device cache (if
+ * there are free slots).
+ */
+static int btrfs_discerner(struct btrfs_device **dev, int lookup)
+{
+	if (btrfs_find_super(*dev,
+			     (char *)BTRFS_FS_INFO->fsid,
+			     (lookup ? &(*dev)->devid : 0)))
+		/* not found */
+		return 0;
+	if (*dev < BTRFS_VOLATILE_DEV_CACHE) {
+		/* populate persistent device cache */
+		memcpy(*dev + 1, *dev, sizeof(struct btrfs_device));
+		(*dev)++;
+	}
+	return 1;
+}
+
+/*
+ * Scan available grub devices and call discerner
+ * for them. Return a number of discerned devices
+ * The scanner was stolen from print_completions().
+ *
+ * Preconditions:
+ * The global structure btrfs_fs_info contains
+ * the latest valid version of btrfs superblock
+ * (the field @sb_copy)
+ */
+static u64 scan_grub_devices(struct btrfs_device *dev,
+			     int (*discerner)(struct btrfs_device **, int),
+			     int lookup)
+{
+	int i, j;
+	u64 count = 0;
+	struct geometry geom;
+
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < 8; j++) {
+			unsigned long part = 0xFFFFFF;
+			int type, entry, gpt_count, gpt_size;
+			unsigned long offset, ext_offset, gpt_offset;
+
+			dev->drive = (i * 0x80) + j;
+			if (get_diskinfo(dev->drive, &geom))
+				continue;
+			while (1) {
+				int ret;
+				buf_drive = -1;
+				errnum = ERR_NONE;
+				ret = next_partition(dev->drive, 0xFFFFFF,
+						     &part, &type, &dev->part,
+						     &dev->length, &offset,
+						     &entry, &ext_offset,
+						     &gpt_offset, &gpt_count,
+						     &gpt_size,
+						     BTRFS_FS_INFO->mbr);
+				if (!ret)
+					break;
+				if (discerner(&dev, lookup)) {
+					count++;
+					if (lookup)
+						goto exit;
+				}
+			}
+		}
+	errnum = ERR_NONE;
+	if (cdrom_drive != GRUB_INVALID_DRIVE &&
+	    !get_diskinfo(cdrom_drive, &geom)) {
+		dev->drive = cdrom_drive;
+		dev->part = 0;
+		dev->length = geom.total_sectors;
+		if (discerner(&dev, lookup)) {
+			count++;
+			if (lookup)
+				goto exit;
+		}
+	}
+#ifdef SUPPORT_NETBOOT
+	errnum = ERR_NONE;
+	if (network_ready &&
+	    !get_diskinfo(NETWORK_DRIVE, &geom)) {
+		dev->drive = NETWORK_DRIVE;
+		dev->part = 0;
+		dev->length = geom.total_sectors;
+		if (discerner(&dev, lookup)) {
+			count++;
+			if (lookup)
+				goto exit;
+		}
+	}
+#endif /* SUPPORT_NETBOOT */
+ exit:
+	return count;
+}
+
+#if 0
+static int btrfs_next_item(struct btrfs_root *root,
+			   struct btrfs_path *path);
+
+/*
+ * Scan the chunk tree for dev items
+ * and call a seeker for all of them.
+ * Preconditions: chunk root is installed
+ * to the global btrfs_fs_info.
+ */
+static int scan_dev_tree(struct btrfs_device* (*seeker)(u64))
+{
+	int ret;
+	u64 num_devices = 0;
+	struct btrfs_key key;
+	struct btrfs_key found_key;
+	struct btrfs_path *path;
+	struct btrfs_root *root;
+
+	root = BTRFS_CHUNK_ROOT;
+	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
+	key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
+	key.type = 0;
+	key.offset = 0;
+
+	ret = aux_tree_lookup(root, &key, path);
+	if (ret == -1)
+		goto corrupted;
+	while (1) {
+		struct btrfs_device *result;
+		struct btrfs_dev_item *dev_item;
+
+		btrfs_item_key_to_cpu(&path->nodes[0],
+				      &found_key,
+				      path->slots[0]);
+		if (found_key.objectid != BTRFS_DEV_ITEMS_OBJECTID)
+			break;
+		dev_item = btrfs_item_ptr(&path->nodes[0],
+					  path->slots[0],
+					  struct btrfs_dev_item);
+		result = seeker(btrfs_device_id(&path->nodes[0], dev_item));
+		if (result == NULL) {
+			btrfs_msg("Btrfs device %llu is not available\n",
+				  btrfs_device_id(&path->nodes[0], dev_item));
+			goto missed_dev;
 		}
+		num_devices++;
+		ret = btrfs_next_item(root, path);
+		if (ret)
+			break;
 	}
-	/* there might be errors when reading super mirrors */
-	if (errnum == ERR_OUTSIDE_PART)
-		errnum = ERR_NONE;
-	if (transid <= 0) {
-		btrfs_msg("No valid Btrfs superblock found\n");
+	if (num_devices == btrfs_super_num_devices(BTRFS_SUPER))
+		return 0;
+ corrupted:
+	errnum = ERR_FSYS_CORRUPT;
+	return 1;
+ missed_dev:
+	errnum = ERR_FSYS_MOUNT;
+	return 1;
+}
+#endif /* 0 */
+
+/*
+ * Find a grub btrfs device by devid.
+ * Preconditions: global btrfs_fs_info
+ * contains a copy of btrfs super block.
+ *
+ * Return pointer to the cached device on success.
+ * Otherwise return NULL.
+ */
+static struct btrfs_device *btrfs_lookup_device(u64 devid)
+{
+	int i, result;
+	struct btrfs_device *cdev;
+
+	for (i = 0; i < BTRFS_NUM_CACHED_DEVICES; i++) {
+		cdev = &BTRFS_DEVICES[i];
+		if (cdev->devid == devid)
+			goto found_in_cache;
+		if (cdev->devid == 0)
+			goto not_found_in_cache;
+	}
+ not_found_in_cache:
+	cdev = BTRFS_VOLATILE_DEV_CACHE;
+	cdev->devid = devid;
+	result = scan_grub_devices(cdev,
+				   btrfs_discerner,
+				   1);
+	if (result == 0)
+		/*
+		 * At mount time we have figured out that
+		 * number of available devices is not less
+		 * then number of devices recorded in the
+		 * super block. Hence we treat this case as
+		 * file system corruption.
+		 */
+		goto corrupt;
+	result = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
+	if (result)
+		goto corrupt;
+ found_in_cache:
+	return cdev;
+ corrupt:
+	errnum = ERR_FSYS_CORRUPT;
+	return NULL;
+}
+
+static int btrfs_find_device(struct btrfs_device *dev)
+{
+	struct btrfs_device *cdev;
+
+	if (btrfs_super_num_devices(BTRFS_SUPER) == 1) {
+		dev->drive = current_drive;
+		dev->part = part_start;
+		dev->length = part_length;
 		return 0;
 	}
-	if (!btrfs_check_super_block(sb))
+	cdev = btrfs_lookup_device(dev->devid);
+	if (cdev == NULL)
+		return 1;
+	dev->drive  = cdev->drive;
+	dev->part   = cdev->part;
+	dev->length = cdev->length;
+	return 0;
+}
+
+static inline void init_btrfs_volatile_dev_cache(void)
+{
+	BTRFS_VOLATILE_DEV_CACHE->devid = 0;
+	BTRFS_VOLATILE_DEV_CACHE->drive = current_drive;
+	BTRFS_VOLATILE_DEV_CACHE->part = part_start;
+	BTRFS_VOLATILE_DEV_CACHE->length = part_length;
+}
+
+/*
+ * check availability of btrfs devices
+ * and populate the persistent device cache
+ */
+static int btrfs_check_devices(void)
+{
+	u64 num_dev;
+
+	if (btrfs_super_num_devices(BTRFS_SUPER) == 1)
 		return 0;
+	num_dev = scan_grub_devices(BTRFS_DEVICES,
+				    btrfs_discerner, 0);
+	if (btrfs_uptodate_super_copy(BTRFS_FS_INFO))
+		return 1;
+	if (num_dev < btrfs_super_num_devices(BTRFS_SUPER)) {
+		btrfs_msg("Some (%llu) Btrfs devices is not available\n",
+			  btrfs_super_num_devices(BTRFS_SUPER) - num_dev);
+	        return 1;
+	}
+	return 0;
+}
+
+int btrfs_mount(void)
+{
+	int ret;
+
+	check_btrfs_cache_size();
+	init_btrfs_info();
+	init_btrfs_volatile_dev_cache();
+
+	ret = btrfs_find_super(BTRFS_VOLATILE_DEV_CACHE, NULL, NULL);
+	if (ret) {
+		btrfs_msg("Drive %lu, partition %lu: no Btrfs metadata\n",
+			  current_drive, part_start);
+		goto error;
+	}
+	ret = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
+	if (ret)
+		goto error;
+	BTRFS_FS_INFO->sb_transid =
+		btrfs_super_generation(BTRFS_SUPER);
+	memcpy(BTRFS_FS_INFO->fsid,
+	       BTRFS_SUPER->fsid,
+	       BTRFS_FSID_SIZE);
+	ret = btrfs_check_devices();
+	if (ret)
+		goto error;
 	/* setup chunk root */
 	ret = find_setup_root(NULL,
-			      btrfs_super_nodesize(sb),
-			      btrfs_super_leafsize(sb),
-			      btrfs_super_sectorsize(sb),
-			      btrfs_super_stripesize(sb),
+			      btrfs_super_nodesize(BTRFS_SUPER),
+			      btrfs_super_leafsize(BTRFS_SUPER),
+			      btrfs_super_sectorsize(BTRFS_SUPER),
+			      btrfs_super_stripesize(BTRFS_SUPER),
 			      BTRFS_CHUNK_TREE_OBJECTID,
-			      chunk_root,
-			      btrfs_super_chunk_root(sb),
-			      btrfs_chunk_root_level_size(sb),
-			      btrfs_super_chunk_root_generation(sb),
+			      BTRFS_CHUNK_ROOT,
+			      btrfs_super_chunk_root(BTRFS_SUPER),
+			      btrfs_chunk_root_level_size(BTRFS_SUPER),
+			      btrfs_super_chunk_root_generation(BTRFS_SUPER),
 			      FIRST_EXTERNAL_LOOKUP_POOL);
 	if (ret)
 		return 0;
 	/* setup tree root */
 	ret = find_setup_root(NULL,
-			      btrfs_super_nodesize(sb),
-			      btrfs_super_leafsize(sb),
-			      btrfs_super_sectorsize(sb),
-			      btrfs_super_stripesize(sb),
+			      btrfs_super_nodesize(BTRFS_SUPER),
+			      btrfs_super_leafsize(BTRFS_SUPER),
+			      btrfs_super_sectorsize(BTRFS_SUPER),
+			      btrfs_super_stripesize(BTRFS_SUPER),
 			      BTRFS_ROOT_TREE_OBJECTID,
-			      tree_root,
-			      btrfs_super_root(sb),
-			      btrfs_root_level_size(sb),
-			      btrfs_super_generation(sb),
+			      BTRFS_TREE_ROOT,
+			      btrfs_super_root(BTRFS_SUPER),
+			      btrfs_root_level_size(BTRFS_SUPER),
+			      btrfs_super_generation(BTRFS_SUPER),
 			      FIRST_EXTERNAL_LOOKUP_POOL);
 	if (ret)
 		return 0;
 	/* setup fs_root */
-	ret = find_setup_root(tree_root,
-			      btrfs_super_nodesize(sb),
-			      btrfs_super_leafsize(sb),
-			      btrfs_super_sectorsize(sb),
-			      btrfs_super_stripesize(sb),
+	ret = find_setup_root(BTRFS_TREE_ROOT,
+			      btrfs_super_nodesize(BTRFS_SUPER),
+			      btrfs_super_leafsize(BTRFS_SUPER),
+			      btrfs_super_sectorsize(BTRFS_SUPER),
+			      btrfs_super_stripesize(BTRFS_SUPER),
 			      BTRFS_FS_TREE_OBJECTID,
-			      fs_root,
+			      BTRFS_FS_ROOT,
 			      0,
 			      0,
 			      0,
 			      FIRST_EXTERNAL_LOOKUP_POOL);
 	return !ret;
+ error:
+	errnum = ERR_FSYS_MOUNT;
+	return 0;
 }
 
 /*
@@ -371,7 +710,7 @@ int check_read_chunk(struct btrfs_key *k
 			    struct map_lookup *map,
 			    u64 logical)
 {
-	int i;
+	int i, ret;
 	u64 chunk_start;
 	u64 chunk_size;
 	int num_stripes;
@@ -397,20 +736,26 @@ int check_read_chunk(struct btrfs_key *k
 	for (i = 0; i < num_stripes; i++) {
 		map->stripes[i].physical =
 			btrfs_stripe_offset_nr(leaf, chunk, i);
+		map->stripes[i].dev.devid =
+			btrfs_stripe_devid_nr(leaf, chunk, i);
+		ret = btrfs_find_device(&map->stripes[i].dev);
+		if (ret)
+			return 0;
 	}
 	return 1;
 }
 
 static void init_extent_buffer(struct extent_buffer *eb,
+			       struct btrfs_device *dev,
 			       u64 logical,
 			       u32 blocksize,
 			       u64 physical,
 			       lookup_pool_id lpid)
 {
+	if (dev)
+		memcpy(&eb->dev, dev, sizeof(*dev));
 	eb->start = logical;
 	eb->len = blocksize;
-	eb->refs = 2;
-	eb->flags = 0;
 	eb->dev_bytenr = physical;
 	eb->data = grab_lookup_cache(lpid);
 }
@@ -516,8 +861,9 @@ static int chunk_tree_lookup(struct map_
  * Look for an appropriate map-extent and
  * perform a translation. Return 1 on errors.
  */
-int __btrfs_map_block(u64 logical, u64 *length, struct btrfs_multi_bio *multi,
-		      int mirror_num)
+static int btrfs_map_block(u64 logical, u64 *length,
+			   struct btrfs_multi_bio *multi,
+			   int mirror_num)
 {
 	struct map_lookup map;
 	u64 offset;
@@ -592,29 +938,57 @@ int __btrfs_map_block(u64 logical, u64 *
 		multi->stripes[i].physical =
 			map.stripes[stripe_index].physical + stripe_offset +
 			stripe_nr * map.stripe_len;
+		memcpy(&multi->stripes[i].dev,
+		       &map.stripes[stripe_index].dev,
+		       sizeof(struct btrfs_device));
 		stripe_index++;
 	}
 	return 0;
 }
 
-static u64 btrfs_map_block(u64 logical)
+static u64 read_data_extent(u64 logical_start, u64 to_read, char *pos)
 {
 	int ret;
 	u64 length;
 	struct btrfs_multi_bio multi;
 
-	ret = __btrfs_map_block(logical, &length, &multi, 0);
-	if (ret) {
-		errnum = ERR_FSYS_CORRUPT;
-		return 0;
+	while (to_read) {
+		ret = btrfs_map_block(logical_start, &length, &multi, 0);
+		if (ret) {
+			errnum = ERR_FSYS_CORRUPT;
+			return ret;
+		}
+		if (length > to_read)
+			length = to_read;
+		disk_read_func = disk_read_hook;
+		ret = btrfs_devread(multi.stripes[0].dev.drive,
+				    multi.stripes[0].dev.part,
+				    multi.stripes[0].dev.length,
+				    multi.stripes[0].physical >> SECTOR_BITS,
+				    logical_start & ((u64)SECTOR_SIZE - 1),
+				    length,
+				    pos);
+		disk_read_func = NULL;
+		if (!ret)
+			return 1;
+		btrfs_msg("BTRFS data extent: read %llu bytes\n", length);
+		to_read -= length;
+		pos += length;
+		logical_start += length;
 	}
-	return multi.stripes[0].physical;
+	return 0;
 }
 
 static int read_extent_from_disk(struct extent_buffer *eb)
 {
 	WARN_ON(eb->dev_bytenr % SECTOR_BITS);
-	return devread(eb->dev_bytenr >> SECTOR_BITS, 0, eb->len, eb->data);
+	return btrfs_devread(eb->dev.drive,
+			     eb->dev.part,
+			     eb->dev.length,
+			     eb->dev_bytenr >> SECTOR_BITS,
+			     0,
+			     eb->len,
+			     eb->data);
 }
 
 static int verify_parent_transid(struct extent_buffer *eb, u64 parent_transid)
@@ -660,13 +1034,14 @@ int read_tree_block(struct btrfs_root *r
 	dev_nr = 0;
 	length = blocksize;
 	while (1) {
-		ret = __btrfs_map_block(bytenr,
-					&length, &multi, mirror_num);
+		ret = btrfs_map_block(bytenr,
+				      &length, &multi, mirror_num);
 		if (ret) {
 			errnum = ERR_FSYS_CORRUPT;
 			return 0;
 		}
 		init_extent_buffer(eb,
+				   &multi.stripes[0].dev,
 				   bytenr,
 				   blocksize,
 				   multi.stripes[0].physical,
@@ -814,6 +1189,7 @@ int aux_tree_lookup(struct btrfs_root *r
 	int level;
 	struct extent_buffer node;
 	init_extent_buffer(&node,
+			   NULL,
 			   0,
 			   0,
 			   0,
@@ -939,13 +1315,18 @@ static int btrfs_next_item(struct btrfs_
  * search for read operation
  */
 static int path_is_valid(struct btrfs_path *path,
-			 struct btrfs_key *key)
+			 struct btrfs_key *key, u64 offset)
 {
 	btrfs_item_key_to_cpu(&path->nodes[0],
 			      key,
 			      path->slots[0]);
-	return (key->objectid == BTRFS_FILE_INFO->objectid) &&
-		(btrfs_key_type(key) == BTRFS_EXTENT_DATA_KEY);
+	if (BTRFS_FILE_INFO_KEY->objectid != key->objectid)
+		return 0;
+	if (btrfs_key_type(key) == BTRFS_INODE_ITEM_KEY)
+		return 1;
+	if (btrfs_key_type(key) != BTRFS_EXTENT_DATA_KEY)
+		return 0;
+	return BTRFS_FILE_INFO_KEY->offset <= offset;
 }
 
 /* ->read_func() */
@@ -954,31 +1335,35 @@ int btrfs_read(char *buf, int len)
 	int ret;
 	struct btrfs_root *fs_root;
 	struct btrfs_path *path;
-	struct btrfs_key *info_key;
 	struct btrfs_key  path_key;
-	u64 off;
+	u64 ioff;
 	u64 bytes;
-	unsigned int to_read;
+	int to_read;
 	char *pos = buf;
 
 	fs_root = BTRFS_FS_ROOT;
-	info_key = BTRFS_FILE_INFO;
 	path = btrfs_grab_path(FIRST_EXTERNAL_LOOKUP_POOL);
 
-	if (!path_is_valid(path, &path_key)) {
-		btrfs_set_key_type(info_key, BTRFS_EXTENT_DATA_KEY);
-		info_key->offset = filepos;
-		ret = aux_tree_lookup(fs_root, info_key, path);
+	if (!path_is_valid(path, &path_key, filepos)) {
+		ret = aux_tree_lookup(fs_root, BTRFS_FILE_INFO_KEY, path);
 		if (ret < 0)
 			errnum = ERR_FSYS_CORRUPT;
 	}
 	while (!errnum) {
 		struct btrfs_item *item;
 		struct btrfs_file_extent_item *fi;
-		unsigned int from;
+		u64 from;
 
-		if (!path_is_valid(path, &path_key))
+		btrfs_item_key_to_cpu(&path->nodes[0],
+				      &path_key,
+				      path->slots[0]);
+		if (BTRFS_FILE_INFO_KEY->objectid != path_key.objectid)
 			break;
+		if (btrfs_key_type(&path_key) != BTRFS_EXTENT_DATA_KEY)
+			goto next;
+		/*
+		 * current position is extent item
+		 */
 		item = btrfs_item_nr(&path->nodes[0], path->slots[0]);
 		fi = btrfs_item_ptr(&path->nodes[0],
 				    path->slots[0],
@@ -988,44 +1373,54 @@ int btrfs_read(char *buf, int len)
 		       errnum = ERR_BAD_FILETYPE;
 		       goto exit;
 		}
-		off = filepos - path_key.offset;
+		ioff = filepos - path_key.offset;
 
 		switch (btrfs_file_extent_type(&path->nodes[0], fi)) {
 		case BTRFS_FILE_EXTENT_INLINE:
 			bytes = btrfs_file_extent_inline_item_len(&path->
 								  nodes[0],
 								  item);
-			to_read = bytes - off;
+			if (path_key.offset + bytes < filepos)
+				goto next;
+			to_read = bytes - ioff;
 			if (to_read > len)
 				to_read = len;
-			from = off + btrfs_file_extent_inline_start(fi);
+			from = ioff + btrfs_file_extent_inline_start(fi);
 			if (disk_read_hook != NULL) {
 				disk_read_func = disk_read_hook;
-				ret = devread(path->nodes[0].dev_bytenr >>
-					      SECTOR_BITS, from, to_read, pos);
+				ret = btrfs_devread(path->nodes[0].dev.drive,
+						    path->nodes[0].dev.part,
+						    path->nodes[0].dev.length,
+						    path->nodes[0].dev_bytenr >>
+						    SECTOR_BITS,
+						    from,
+						    to_read,
+						    pos);
 				disk_read_func = NULL;
-			} else {
+				if (ret)
+					goto exit;
+			} else
 				memcpy(pos,
 				       path->nodes[0].data + from,
 				       to_read);
-			}
+			btrfs_msg("BTRFS inline extent: read %d bytes pos %d\n",
+				  to_read, filepos);
 			break;
 		case BTRFS_FILE_EXTENT_REG:
 			bytes = btrfs_file_extent_num_bytes(&path->nodes[0],
 							    fi);
-			to_read = bytes - off;
+			if (path_key.offset + bytes < filepos)
+				goto next;
+			to_read = bytes - ioff;
 			if (to_read > len)
 				to_read = len;
-			from = off +
+			from = ioff +
 				btrfs_file_extent_disk_bytenr(&path->nodes[0],
-							      fi);
-			disk_read_func = disk_read_hook;
-			ret = devread(btrfs_map_block(from) >> SECTOR_BITS,
-				      from & ((u64)SECTOR_SIZE - 1),
-				      to_read,
-				      pos);
-			disk_read_func = NULL;
-			if (!ret)
+							      fi) +
+				btrfs_file_extent_offset(&path->nodes[0],
+							 fi);
+			ret = read_data_extent(from, to_read, pos);
+			if (ret)
 				goto exit;
 			break;
 		case BTRFS_FILE_EXTENT_PREALLOC:
@@ -1042,12 +1437,14 @@ int btrfs_read(char *buf, int len)
 		if (len == 0)
 			break;
 		/* not everything was read */
+	next:
 		ret = btrfs_next_item(fs_root, path);
-		if (ret) {
-			/* something should be found */
+		if (ret < 0) {
 			errnum = ERR_FSYS_CORRUPT;
 			break;
 		}
+		btrfs_update_file_info(path);
+		continue;
 	}
  exit:
 	return errnum ? 0 : pos - buf;
@@ -1082,14 +1479,14 @@ static int btrfs_follow_link(struct btrf
 	filepos = 0;
 	/* extract symlink content */
 	while (1) {
-		u64 oid = BTRFS_FILE_INFO->objectid;
+		u64 oid = BTRFS_FILE_INFO_KEY->objectid;
 		ret = btrfs_next_item(root, path);
 		if (ret)
 			break;
 		btrfs_update_file_info(path);
-		if (oid != BTRFS_FILE_INFO->objectid)
+		if (oid != BTRFS_FILE_INFO_KEY->objectid)
 			break;
-		if (btrfs_key_type(BTRFS_FILE_INFO) ==
+		if (btrfs_key_type(BTRFS_FILE_INFO_KEY) ==
 		    BTRFS_EXTENT_DATA_KEY)
 			goto found;
 	}
@@ -1114,7 +1511,7 @@ static int update_fs_root(struct btrfs_r
 
 	if (location->offset != (u64)-1)
 		return 0;
-	tree_root = &fs_root->fs_info->tree_root;
+	tree_root = &BTRFS_FS_INFO->tree_root;
 	ret = find_setup_root(tree_root,
 			      tree_root->nodesize,
 			      tree_root->leafsize,
@@ -1388,6 +1785,22 @@ int btrfs_dir(char *dirname)
 	}
 }
 
+int btrfs_embed(int *start_sector, int needed_sectors)
+{
+	int ret;
+	init_btrfs_info();
+	init_btrfs_volatile_dev_cache();
+
+	ret = btrfs_find_super(BTRFS_VOLATILE_DEV_CACHE, NULL, NULL);
+	if (ret)
+		return 0;
+	ret = btrfs_uptodate_super_copy(BTRFS_FS_INFO);
+	if (ret)
+		return 0;
+	*start_sector = 1; /* reserve first sector for stage1 */
+	return needed_sectors <=
+		((BTRFS_SUPER_INFO_OFFSET >> SECTOR_BITS) - 1);
+}
 #endif /* FSYS_BTRFS */
 
 /*
--- grub-0.97.orig/stage2/filesys.h
+++ grub-0.97/stage2/filesys.h
@@ -137,8 +137,8 @@ int iso9660_dir (char *dirname);
 #ifndef NUM_FSYS
 #define NUM_FSYS	\
   (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
-   + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM	\
-   + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
+   + FSYS_REISERFS_NUM + FSYS_BTRFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM \
+   + FSYS_XFS_NUM + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
 #endif
 
 /* defines for the block filesystem info area */
--- grub-0.97.orig/grub/Makefile.am
+++ grub-0.97/grub/Makefile.am
@@ -8,7 +8,7 @@ endif
 
 AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
 	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
+	-DFSYS_BTRFS=1 -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
 	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
 	$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
 	-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
--- grub-0.97.orig/stage2/disk_io.c
+++ grub-0.97/stage2/disk_io.c
@@ -65,7 +65,7 @@ struct fsys_entry fsys_table[NUM_FSYS + 
   {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed},
 # endif
 # ifdef FSYS_BTRFS
-  {"btrfs", btrfs_mount, btrfs_read, btrfs_dir, 0, 0},
+  {"btrfs", btrfs_mount, btrfs_read, btrfs_dir, 0, btrfs_embed},
 # endif
 # ifdef FSYS_VSTAFS
   {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0},
--- grub-0.97.orig/stage2/builtins.c
+++ grub-0.97/stage2/builtins.c
@@ -2423,6 +2423,16 @@ install_func (char *arg, int flags)
 	  else
 #endif /* GRUB_UTIL */
 	    {
+	      /*
+	       * FIXME: Ugly hack.
+	       * Do not write to btrfs partition
+	       * without a help of the file system!
+	       */
+	      if (!strcmp(fsys_table[fsys_type].name, "btrfs"))
+		{
+		  errnum = ERR_BAD_ARGUMENT;
+		  goto fail;
+		}
 	      if (! devwrite (*saved_sector - part_start, 1, stage2_buffer))
 		goto fail;
 	    }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch 2/2] grub-0.97: btrfs multidevice configuration support
  2009-09-24 22:06 [patch 2/2] grub-0.97: btrfs multidevice configuration support Edward Shishkin
@ 2009-11-02 22:16 ` Johannes Hirte
  2009-11-03  0:59   ` Edward Shishkin
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Hirte @ 2009-11-02 22:16 UTC (permalink / raw)
  To: Edward Shishkin; +Cc: The development of BTRFS

Am Freitag 25 September 2009 00:06:40 schrieb Edward Shishkin:
> 

Hi Edward,

I was pointed to a problem with this patch.

+static u64 scan_grub_devices(struct btrfs_device *dev,
+                            int (*discerner)(struct btrfs_device **, int),
+                            int lookup)
+{
...
+#ifdef SUPPORT_NETBOOT
+       errnum = ERR_NONE;
+       if (network_ready &&
+           !get_diskinfo(NETWORK_DRIVE, &geom)) {
+               dev->drive = NETWORK_DRIVE;
+               dev->part = 0;
+               dev->length = geom.total_sectors;
+               if (discerner(&dev, lookup)) {
+                       count++;
+                       if (lookup)
+                               goto exit;
+               }
+       }
+#endif /* SUPPORT_NETBOOT */
+ exit:
+       return count;
+}

This won't compile since network_ready is undeclared. Why is the btrfs code 
dealing with network devices at all?

regards
  Johannes

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch 2/2] grub-0.97: btrfs multidevice configuration support
  2009-11-02 22:16 ` Johannes Hirte
@ 2009-11-03  0:59   ` Edward Shishkin
  2009-12-10 23:21     ` Johannes Hirte
  0 siblings, 1 reply; 5+ messages in thread
From: Edward Shishkin @ 2009-11-03  0:59 UTC (permalink / raw)
  To: Johannes Hirte; +Cc: The development of BTRFS

[-- Attachment #1: Type: text/plain, Size: 1129 bytes --]

Johannes Hirte wrote:
> Am Freitag 25 September 2009 00:06:40 schrieb Edward Shishkin:
>   
>
> Hi Edward,
>
> I was pointed to a problem with this patch.
>
> +static u64 scan_grub_devices(struct btrfs_device *dev,
> +                            int (*discerner)(struct btrfs_device **, int),
> +                            int lookup)
> +{
> ...
> +#ifdef SUPPORT_NETBOOT
> +       errnum = ERR_NONE;
> +       if (network_ready &&
> +           !get_diskinfo(NETWORK_DRIVE, &geom)) {
> +               dev->drive = NETWORK_DRIVE;
> +               dev->part = 0;
> +               dev->length = geom.total_sectors;
> +               if (discerner(&dev, lookup)) {
> +                       count++;
> +                       if (lookup)
> +                               goto exit;
> +               }
> +       }
> +#endif /* SUPPORT_NETBOOT */
> + exit:
> +       return count;
> +}
>
> This won't compile since network_ready is undeclared.

Yup, indeed..

>  Why is the btrfs code 
> dealing with network devices at all?
>   

Why not? :)
Well, would you please disable it for now with the attached patch?
 
Thanks,
Edward.

[-- Attachment #2: grub-btrfs-multidev-fixup.patch --]
[-- Type: text/plain, Size: 615 bytes --]

Disable booting from network devices.

Signed-off-by: Edward Shishkin <edward@redhat.com>
---
 stage2/fsys_btrfs.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- grub-0.97.orig/stage2/fsys_btrfs.c
+++ grub-0.97/stage2/fsys_btrfs.c
@@ -452,7 +452,7 @@ static u64 scan_grub_devices(struct btrf
 				goto exit;
 		}
 	}
-#ifdef SUPPORT_NETBOOT
+#if 0
 	errnum = ERR_NONE;
 	if (network_ready &&
 	    !get_diskinfo(NETWORK_DRIVE, &geom)) {
@@ -465,7 +465,7 @@ static u64 scan_grub_devices(struct btrf
 				goto exit;
 		}
 	}
-#endif /* SUPPORT_NETBOOT */
+#endif /* 0 */
  exit:
 	return count;
 }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch 2/2] grub-0.97: btrfs multidevice configuration support
  2009-11-03  0:59   ` Edward Shishkin
@ 2009-12-10 23:21     ` Johannes Hirte
  2009-12-11 11:26       ` Edward Shishkin
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Hirte @ 2009-12-10 23:21 UTC (permalink / raw)
  To: Edward Shishkin; +Cc: The development of BTRFS

Am Dienstag 03 November 2009 01:59:39 schrieb Edward Shishkin:
> Johannes Hirte wrote:
> >  Why is the btrfs code
> > dealing with network devices at all?
> 
> Why not? :)

I don't see the possiblity to get a btrfs filesystem this way. So as far as I 
understand this, it's complete useless. The CD support doesn't look very 
usefull too to me. It's possible to put a btrfs filesystem on a CD or DVD. But 
that seems rather theoretical.

regards,
  Johannes


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [patch 2/2] grub-0.97: btrfs multidevice configuration support
  2009-12-10 23:21     ` Johannes Hirte
@ 2009-12-11 11:26       ` Edward Shishkin
  0 siblings, 0 replies; 5+ messages in thread
From: Edward Shishkin @ 2009-12-11 11:26 UTC (permalink / raw)
  To: Johannes Hirte; +Cc: The development of BTRFS

Johannes Hirte wrote:
> Am Dienstag 03 November 2009 01:59:39 schrieb Edward Shishkin:
>   
>> Johannes Hirte wrote:
>>     
>>>  Why is the btrfs code
>>> dealing with network devices at all?
>>>       
>> Why not? :)
>>     
>
> I don't see the possiblity to get a btrfs filesystem this way. So as far as I 
> understand this, it's complete useless. The CD support doesn't look very 
> usefull too to me. It's possible to put a btrfs filesystem on a CD or DVD. But 
> that seems rather theoretical.
>   

Ok, let's keep this theoretical possibility,
I don't see wrong things here..

Thanks,
Edward.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-12-11 11:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-24 22:06 [patch 2/2] grub-0.97: btrfs multidevice configuration support Edward Shishkin
2009-11-02 22:16 ` Johannes Hirte
2009-11-03  0:59   ` Edward Shishkin
2009-12-10 23:21     ` Johannes Hirte
2009-12-11 11:26       ` Edward Shishkin

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.