[Ocfs2-tools-devel] [PATCH 2/6] ocfs2-tools: Remove open-coded slot map access.

Joel Becker joel.becker at oracle.com
Thu Dec 6 21:18:07 PST 2007


Anywhere the tools need to access the slot map, they open-code access.
Introduce a set of functions in libocfs2 to manage the slot map.  The
best is the load/store functions, which provide an in-memory structure
to isolate users from the specifics of the format.

We clean up the open-coded places as well.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 debugfs.ocfs2/commands.c     |   13 ++---
 debugfs.ocfs2/dump.c         |   11 +--
 debugfs.ocfs2/include/dump.h |    2 +-
 libocfs2/checkhb.c           |   53 +++-------------
 libocfs2/include/ocfs2.h     |   26 +++++++-
 libocfs2/slot_map.c          |  144 ++++++++++++++++++++++++++++++++++++++++-
 mkfs.ocfs2/mkfs.c            |   23 +++----
 mounted.ocfs2/mounted.c      |   43 +++++++------
 8 files changed, 215 insertions(+), 100 deletions(-)

diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index 5bad208..25cfe7d 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -1201,27 +1201,24 @@ static void do_slotmap (char **args)
 {
 	FILE *out;
 	errcode_t ret;
-	char *buf = NULL;
-	uint32_t len;
+        struct ocfs2_slot_map *sm = NULL;
 
 	if (check_device_open())
 		return ;
 
-	len = gbls.fs->fs_blocksize;
-	/* read in the first block of the slot_map file */
-	ret = read_whole_file(gbls.fs, gbls.slotmap_blkno, &buf, &len);
+	ret = ocfs2_read_slot_map(gbls.fs, &sm);
 	if (ret) {
 		com_err(args[0], ret, "while reading slotmap system file");
 		goto bail;
 	}
 
 	out = open_pager(gbls.interactive);
-	dump_slots (out, buf, len);
+	dump_slots (out, sm, OCFS2_RAW_SB(gbls.fs->fs_super)->s_max_slots);
 	close_pager (out);
 
 bail:
-	if (buf)
-		ocfs2_free(&buf);
+	if (sm)
+		ocfs2_free(&sm);
 
 	return ;
 }
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
index 49547f6..2f0b780 100644
--- a/debugfs.ocfs2/dump.c
+++ b/debugfs.ocfs2/dump.c
@@ -605,20 +605,17 @@ void dump_jbd_unknown (FILE *out, uint64_t start, uint64_t end)
  * dump_slots()
  *
  */
-void dump_slots (FILE *out, char *buf, uint32_t len)
+void dump_slots (FILE *out, struct ocfs2_slot_map *sm, int num_slots)
 {
-	int16_t *slots = (int16_t *)buf;
-	uint32_t i;
-	uint32_t num_slots = (len / sizeof(uint16_t));
+	int i;
 	
 	fprintf (out, "\t%5s   %5s\n", "Slot#", "Node#");
 	
 	for (i = 0; i < num_slots; ++i) {
-		uint16_t slot = le16_to_cpu(slots[i]);
-		if (slot == (uint16_t)OCFS2_INVALID_SLOT)
+		if (sm->sm_slots[i] == (uint16_t)OCFS2_INVALID_SLOT)
 			continue;
 
-		fprintf (out, "\t%5d   %5u\n", i, slot);
+		fprintf (out, "\t%5d   %5u\n", i, sm->sm_slots[i]);
 	}
 
 	return ;
diff --git a/debugfs.ocfs2/include/dump.h b/debugfs.ocfs2/include/dump.h
index f3cf8f9..a094b7c 100644
--- a/debugfs.ocfs2/include/dump.h
+++ b/debugfs.ocfs2/include/dump.h
@@ -48,7 +48,7 @@ void dump_jbd_superblock (FILE *out, journal_superblock_t *jsb);
 void dump_jbd_block (FILE *out, journal_header_t *header, uint64_t blknum);
 void dump_jbd_metadata (FILE *out, int type, char *buf, uint64_t blknum);
 void dump_jbd_unknown (FILE *out, uint64_t start, uint64_t end);
-void dump_slots (FILE *out, char *buf, uint32_t len);
+void dump_slots (FILE *out, struct ocfs2_slot_map *sm, int num_slots);
 void dump_fast_symlink (FILE *out, char *link);
 void dump_hb (FILE *out, char *buf, uint32_t len);
 void dump_inode_path (FILE *out, uint64_t blkno, char *path);
diff --git a/libocfs2/checkhb.c b/libocfs2/checkhb.c
index 8431a65..e535ea3 100644
--- a/libocfs2/checkhb.c
+++ b/libocfs2/checkhb.c
@@ -40,38 +40,6 @@
 #include "ocfs2_fs.h"
 #include "ocfs1_fs_compat.h"
 
-static errcode_t ocfs2_read_slotmap (ocfs2_filesys *fs, uint8_t *node_nums)
-{
-	errcode_t ret = 0;
-	char *slotbuf = NULL;
-	int slotbuf_len;
-	char *slotmap = ocfs2_system_inodes[SLOT_MAP_SYSTEM_INODE].si_name;
-	uint32_t slotmap_len;
-	uint64_t slotmap_blkno;
-	int16_t *slots;
-	int i, j;
-	uint32_t num_nodes = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
-
-	slotmap_len = strlen(slotmap);
-
-	ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, slotmap, slotmap_len,
-			   NULL, &slotmap_blkno);
-	if (ret)
-		return ret;
-
-	ret =  ocfs2_read_whole_file(fs, slotmap_blkno, &slotbuf, &slotbuf_len);
-	if (!ret) {
-		slots = (int16_t *)slotbuf;
-		for (i = 0, j = 0; i < num_nodes; ++i)
-			if (le16_to_cpu(slots[i]) != (uint16_t)OCFS2_INVALID_SLOT)
-				node_nums[j++] = le16_to_cpu(slots[i]);
-	}
-
-	if (slotbuf)
-		ocfs2_free(&slotbuf);
-
-	return ret;
-}
 
 /*
  * ocfs2_check_heartbeats() check if the list of ocfs2 devices are
@@ -93,7 +61,7 @@ errcode_t ocfs2_check_heartbeats(struct list_head *dev_list, int ignore_local)
 	struct list_head *pos;
 	ocfs2_devices *dev = NULL;
 	char *device= NULL;
-	int open_flags;
+	int open_flags, i;
 
 	list_for_each(pos, dev_list) {
 		dev = list_entry(pos, ocfs2_devices, list);
@@ -122,31 +90,26 @@ errcode_t ocfs2_check_heartbeats(struct list_head *dev_list, int ignore_local)
 		}
 
 		/* get label/uuid for ocfs2 */
-		dev->max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
 		memcpy(dev->label, OCFS2_RAW_SB(fs->fs_super)->s_label,
 		       sizeof(dev->label));
 		memcpy(dev->uuid, OCFS2_RAW_SB(fs->fs_super)->s_uuid,
 		       sizeof(dev->uuid));
 
-		ret = ocfs2_malloc((sizeof(uint8_t) * dev->max_slots),
-				   &dev->node_nums);
-		if (ret)
-			goto bail;
-
-		memset(dev->node_nums, OCFS2_MAX_SLOTS,
-		       (sizeof(uint8_t) * dev->max_slots));
-
 		if (dev->hb_dev)
 			goto close;
 
 		/* read slotmap to get nodes on which the volume is mounted */
-		ret = ocfs2_read_slotmap(fs, dev->node_nums);
+		ret = ocfs2_load_slot_map(fs, &dev->map);
 		if (ret) {
 			dev->errcode = ret;
 			ret = 0;
 		} else {
-			if (dev->node_nums[0] != OCFS2_MAX_SLOTS)
-				dev->mount_flags |= OCFS2_MF_MOUNTED_CLUSTER;
+			for (i = 0; i < dev->map->md_num_slots; i++) {
+				if (dev->map->md_slots[i].sd_valid) {
+					dev->mount_flags |= OCFS2_MF_MOUNTED_CLUSTER;
+					break;
+				}
+			}
 		}
 close:
 		ocfs2_close(fs);
diff --git a/libocfs2/include/ocfs2.h b/libocfs2/include/ocfs2.h
index 35d40cc..8368f8b 100644
--- a/libocfs2/include/ocfs2.h
+++ b/libocfs2/include/ocfs2.h
@@ -198,6 +198,16 @@ struct _ocfs2_cached_inode {
 	ocfs2_bitmap *ci_chains;
 };
 
+struct ocfs2_slot_data {
+	int		sd_valid;
+	unsigned int	sd_node_num;
+};
+
+struct ocfs2_slot_map_data {
+	int			md_num_slots;
+	struct ocfs2_slot_data	*md_slots;
+};
+
 struct _ocfs2_devices {
 	struct list_head list;
 	char dev_name[100];
@@ -210,8 +220,7 @@ struct _ocfs2_devices {
 	uint32_t min_num;		/* minor number of the device */
 	errcode_t errcode;		/* error encountered reading device */
 	void *private;
-	uint16_t max_slots;
-	uint8_t *node_nums;		/* list of mounted nodes */
+	struct ocfs2_slot_map_data *map; /* Mounted nodes, must be freed */
 };
 
 typedef struct _fs_options fs_options;
@@ -546,7 +555,18 @@ errcode_t ocfs2_meta_lock(ocfs2_filesys *fs, ocfs2_cached_inode *inode,
 
 errcode_t ocfs2_meta_unlock(ocfs2_filesys *fs, ocfs2_cached_inode *ci);
 
-void ocfs2_swap_slot_map(int16_t *map, loff_t num_slots);
+/* Low level */
+void ocfs2_swap_slot_map(struct ocfs2_slot_map *sm, int num_slots);
+errcode_t ocfs2_read_slot_map(ocfs2_filesys *fs,
+			      struct ocfs2_slot_map **map_ret);
+errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
+			       struct ocfs2_slot_map *sm);
+
+/* High level */
+errcode_t ocfs2_load_slot_map(ocfs2_filesys *fs,
+			      struct ocfs2_slot_map_data **data_ret);
+errcode_t ocfs2_store_slot_map(ocfs2_filesys *fs,
+			       struct ocfs2_slot_map_data *md);
 
 enum ocfs2_lock_type ocfs2_get_lock_type(char c);
 
diff --git a/libocfs2/slot_map.c b/libocfs2/slot_map.c
index 349371b..8abfd4b 100644
--- a/libocfs2/slot_map.c
+++ b/libocfs2/slot_map.c
@@ -23,11 +23,147 @@
 
 #include "ocfs2.h"
 
-void ocfs2_swap_slot_map(int16_t *map, loff_t num_slots)
+void ocfs2_swap_slot_map(struct ocfs2_slot_map *sm, int num_slots)
 {
-	if (cpu_is_big_endian)
+	int i;
+
+	if (!cpu_is_big_endian)
 		return;
 
-	for ( ; num_slots; num_slots--, map++)
-		*map = bswap_16(*map);
+	for (i = 0; i < num_slots; i++)
+		sm->sm_slots[i] = bswap_16(sm->sm_slots[i]);
+}
+
+errcode_t ocfs2_read_slot_map(ocfs2_filesys *fs,
+			      struct ocfs2_slot_map **map_ret)
+{
+	errcode_t ret;
+	uint64_t blkno;
+	char *slot_map_buf;
+	struct ocfs2_slot_map *sm;
+	int bytes_needed, len;
+
+	ret = ocfs2_lookup_system_inode(fs, SLOT_MAP_SYSTEM_INODE, 0,
+					&blkno);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_read_whole_file(fs, blkno, &slot_map_buf, &len);
+	if (ret)
+		return ret;
+
+	bytes_needed = ocfs2_blocks_in_bytes(fs, OCFS2_RAW_SB(fs->fs_super)->s_max_slots * sizeof(__le16));
+	if (bytes_needed > len) {
+		ocfs2_free(&slot_map_buf);
+		return OCFS2_ET_SHORT_READ;
+	}
+
+	sm = (struct ocfs2_slot_map *)slot_map_buf;
+	ocfs2_swap_slot_map(sm, OCFS2_RAW_SB(fs->fs_super)->s_max_slots);
+
+	*map_ret = sm;
+
+	return 0;
+}
+
+errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
+			       struct ocfs2_slot_map *sm)
+{
+	errcode_t ret, tret;
+	ocfs2_cached_inode *ci;
+	uint64_t blkno, bytes;
+	uint32_t wrote;
+	int num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
+
+	ret = ocfs2_lookup_system_inode(fs, SLOT_MAP_SYSTEM_INODE, 0,
+					&blkno);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_read_cached_inode(fs, blkno, &ci);
+	if (ret)
+		return ret;
+
+	bytes = (uint64_t)num_slots * sizeof(__le16);
+
+	ocfs2_swap_slot_map(sm, num_slots);
+
+	ret = ocfs2_file_write(ci, sm, bytes, 0, &wrote);
+	tret = ocfs2_free_cached_inode(fs, ci);
+	if (ret)
+		return ret;
+	if (wrote != bytes)
+		return OCFS2_ET_SHORT_WRITE;
+
+	/*
+	 * The error from free_cached_inode() is only important if
+	 * there were no other problems.
+	 */
+	if (tret)
+		return tret;
+
+	return 0;
+}
+
+errcode_t ocfs2_load_slot_map(ocfs2_filesys *fs,
+			      struct ocfs2_slot_map_data **data_ret)
+{
+	errcode_t ret;
+	int i, num_slots;
+	struct ocfs2_slot_map *sm;
+	struct ocfs2_slot_map_data *md;
+
+	num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
+
+	ret = ocfs2_malloc0(sizeof(struct ocfs2_slot_map_data) +
+			    (sizeof(struct ocfs2_slot_data) * num_slots),
+			    &md);
+	if (ret)
+		return ret;
+
+	md->md_num_slots = num_slots;
+	md->md_slots = (struct ocfs2_slot_data *)((char *)md + sizeof(struct ocfs2_slot_map_data));
+
+	ret = ocfs2_read_slot_map(fs, &sm);
+	if (ret) {
+		ocfs2_free(&md);
+		return ret;
+	}
+
+	for (i = 0; i < num_slots; i++) {
+		if (sm->sm_slots[i] != (uint16_t)OCFS2_INVALID_SLOT) {
+			md->md_slots[i].sd_valid = 1;
+			md->md_slots[i].sd_node_num = sm->sm_slots[i];
+		}
+	}
+
+	*data_ret = md;
+	return 0;
+}
+
+errcode_t ocfs2_store_slot_map(ocfs2_filesys *fs,
+			       struct ocfs2_slot_map_data *md)
+{
+	errcode_t ret;
+	struct ocfs2_slot_map *sm;
+	int i, num_slots, bytes;
+
+	num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
+	bytes = num_slots * sizeof(__le16);
+
+	ret = ocfs2_malloc0(bytes, &sm);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < num_slots; i++) {
+		if (md->md_slots[i].sd_valid)
+			sm->sm_slots[i] = md->md_slots[i].sd_node_num;
+		else
+			sm->sm_slots[i] = OCFS2_INVALID_SLOT;
+	}
+
+	ret = ocfs2_write_slot_map(fs, sm);
+	ocfs2_free(&sm);
+
+	return ret;
 }
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 0ade0ab..60ad322 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -2044,24 +2044,23 @@ write_directory_data(State *s, DirData *dir)
 static void
 write_slot_map_data(State *s, SystemFileDiskRecord *slot_map_rec)
 {
-	int i, num;
-	int16_t *slot_map;
+	int i;
+	struct ocfs2_slot_map *sm;
+	char *map_buf;
 
-	/* we only use the 1st block of this file, the rest is zero'd
-	 * out. */
-	num = s->blocksize / sizeof(int16_t);
+	map_buf = do_malloc(s, slot_map_rec->extent_len);
+	memset(map_buf, 0, slot_map_rec->extent_len);
 
-	slot_map = do_malloc(s, slot_map_rec->extent_len);
-	memset(slot_map, 0, slot_map_rec->extent_len);
+	sm = (struct ocfs2_slot_map *)map_buf;
 
-	for(i = 0; i < num; i++)
-		slot_map[i] = -1;
+	for(i = 0; i < s->initial_slots; i++)
+		sm->sm_slots[i] = OCFS2_INVALID_SLOT;
 
-	ocfs2_swap_slot_map(slot_map, num);
-	do_pwrite(s, slot_map, slot_map_rec->extent_len,
+	ocfs2_swap_slot_map(sm, s->initial_slots);
+	do_pwrite(s, map_buf, slot_map_rec->extent_len,
 		  slot_map_rec->extent_off);
 
-	free(slot_map);
+	free(map_buf);
 }
 
 static void
diff --git a/mounted.ocfs2/mounted.c b/mounted.ocfs2/mounted.c
index 270a06c..bc196b6 100644
--- a/mounted.ocfs2/mounted.c
+++ b/mounted.ocfs2/mounted.c
@@ -52,18 +52,24 @@ static char *usage_string =
 
 static void ocfs2_print_nodes(ocfs2_devices *dev, char **names)
 {
-	int i;
-	uint8_t n;
-	uint8_t *nums = dev->node_nums;
+	int i, start = 1;
+	unsigned int node_num;
+        struct ocfs2_slot_map_data *map = dev->map;
 
-	for (i = 0; i < dev->max_slots && nums[i] != O2NM_MAX_NODES; ++i) {
-		if (i)
+	for (i = 0; i < map->md_num_slots; i++) {
+		if (!map->md_slots[i].sd_valid)
+			continue;
+
+		if (start)
+			start = 0;
+		else
 			printf(", ");
-		n = nums[i];
-		if (names && names[n] && *(names[n]))
-			printf("%s", names[n]);
+
+		node_num = map->md_slots[i].sd_node_num;
+		if (names && names[node_num] && *(names[node_num]))
+			printf("%s", names[node_num]);
 		else
-			printf("%d", n);
+			printf("%d", node_num);
 	}
 }
 
@@ -109,15 +115,12 @@ static void ocfs2_print_full_detect(struct list_head *dev_list)
 			fflush(stdout);
 			com_err("Unknown", dev->errcode, " ");
 		} else {
-			if (dev->hb_dev) {
-				printf("Heartbeat device\n");
-				continue;
-			}
-			if (dev->node_nums[0] == O2NM_MAX_NODES) {
-				printf("Not mounted\n");
-				continue;
-			}
-			ocfs2_print_nodes(dev, nodes);
+			if (dev->hb_dev)
+				printf("Heartbeat device");
+			else if (dev->mount_flags & OCFS2_MF_MOUNTED_CLUSTER)
+				ocfs2_print_nodes(dev, nodes);
+			else
+				printf("Not mounted");
 			printf("\n");
 		}
 	}
@@ -267,8 +270,8 @@ static errcode_t ocfs2_detect(char *device, int quick_detect)
 bail:
 	list_for_each_safe(pos1, pos2, &(dev_list)) {
 		dev = list_entry(pos1, ocfs2_devices, list);
-		if (dev->node_nums)
-			ocfs2_free(&dev->node_nums);
+		if (dev->map)
+			ocfs2_free(&dev->map);
 		list_del(&(dev->list));
 		ocfs2_free(&dev);
 	}
-- 
1.5.2.2




More information about the Ocfs2-tools-devel mailing list