[Ocfs2-tools-devel] [PATCH 2/7] ocfs2-tools: Remove open-coded slot
map access.
Joel Becker
joel.becker at oracle.com
Sat Jan 12 23:18:03 PST 2008
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 | 16 ++---
debugfs.ocfs2/dump.c | 11 +--
debugfs.ocfs2/include/dump.h | 2 +-
include/ocfs2/ocfs2.h | 28 +++++++-
libocfs2/checkhb.c | 53 ++-------------
libocfs2/slot_map.c | 146 ++++++++++++++++++++++++++++++++++++++++-
mkfs.ocfs2/mkfs.c | 23 +++----
mounted.ocfs2/mounted.c | 43 +++++++------
8 files changed, 221 insertions(+), 101 deletions(-)
diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
index ed93759..e021861 100644
--- a/debugfs.ocfs2/commands.c
+++ b/debugfs.ocfs2/commands.c
@@ -607,7 +607,7 @@ static void do_open (char **args)
}
flags = gbls.allow_write ? OCFS2_FLAG_RW : OCFS2_FLAG_RO;
- flags |= OCFS2_FLAG_HEARTBEAT_DEV_OK;
+ flags |= OCFS2_FLAG_HEARTBEAT_DEV_OK;
ret = ocfs2_open(dev, flags, superblock, block_size, &gbls.fs);
if (ret) {
gbls.fs = NULL;
@@ -1203,27 +1203,25 @@ static void do_slotmap (char **args)
{
FILE *out;
errcode_t ret;
- char *buf = NULL;
- uint32_t len;
+ int num_slots = OCFS2_RAW_SB(gbls.fs->fs_super)->s_max_slots;
+ 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, num_slots, &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, num_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 91c34d3..7f89412 100644
--- a/debugfs.ocfs2/dump.c
+++ b/debugfs.ocfs2/dump.c
@@ -607,20 +607,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/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 390666d..bff79ec 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -180,6 +180,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];
@@ -192,8 +202,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;
@@ -528,7 +537,20 @@ 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,
+ int num_slots,
+ struct ocfs2_slot_map **map_ret);
+errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
+ int num_slots,
+ 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/checkhb.c b/libocfs2/checkhb.c
index f4ff19e..4d48bd6 100644
--- a/libocfs2/checkhb.c
+++ b/libocfs2/checkhb.c
@@ -41,38 +41,6 @@
#include "ocfs2/ocfs2.h"
#include "ocfs2-kernel/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
@@ -94,7 +62,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);
@@ -123,31 +91,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/slot_map.c b/libocfs2/slot_map.c
index 616df50..397a7d0 100644
--- a/libocfs2/slot_map.c
+++ b/libocfs2/slot_map.c
@@ -24,11 +24,149 @@
#include "ocfs2/byteorder.h"
#include "ocfs2/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,
+ int num_slots,
+ 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,
+ num_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, num_slots);
+
+ *map_ret = sm;
+
+ return 0;
+}
+
+errcode_t ocfs2_write_slot_map(ocfs2_filesys *fs,
+ int num_slots,
+ struct ocfs2_slot_map *sm)
+{
+ errcode_t ret, tret;
+ ocfs2_cached_inode *ci;
+ uint64_t blkno, bytes;
+ uint32_t wrote;
+
+ 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, num_slots, &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, num_slots, 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 87a4f98..2b5550f 100644
--- a/mounted.ocfs2/mounted.c
+++ b/mounted.ocfs2/mounted.c
@@ -50,18 +50,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);
}
}
@@ -107,15 +113,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");
}
}
@@ -265,8 +268,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