[Sheepdog] [PATCH 2/2] shepherd: sort the output of vdi list
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Sat Jan 9 14:58:30 CET 2010
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
collie/store.c | 13 ++++++++++-
include/meta.h | 14 ++---------
shepherd/shepherd.c | 59 ++++++++++++++++++++++++++++++++++++++------------
3 files changed, 60 insertions(+), 26 deletions(-)
diff --git a/collie/store.c b/collie/store.c
index fce71ff..aa785b4 100644
--- a/collie/store.c
+++ b/collie/store.c
@@ -60,6 +60,8 @@ static int stat_sheep(uint64_t *store_size, uint64_t *store_free)
used += s.st_size;
}
+ closedir(dir);
+
*store_size = vs.f_frsize * vs.f_bfree;
*store_free = vs.f_frsize * vs.f_bfree - used;
@@ -325,6 +327,7 @@ out:
static int so_read_vdis(struct request *req)
{
+ struct sd_so_req *hdr = (struct sd_so_req *)&req->rq;
struct sd_so_rsp *rsp = (struct sd_so_rsp *)&req->rp;
DIR *dir, *vdir;
struct dirent *dent, *vdent;
@@ -373,6 +376,11 @@ static int so_read_vdis(struct request *req)
return SD_RES_NO_VDI;
while ((vdent = readdir(vdir))) {
+ if ((char *)sde - (char *)req->data >= hdr->data_length) {
+ closedir(vdir);
+ goto out;
+ }
+
if (!strcmp(vdent->d_name, ".") ||
!strcmp(vdent->d_name, ".."))
continue;
@@ -395,9 +403,12 @@ static int so_read_vdis(struct request *req)
sde->name_len = strlen(dent->d_name);
strcpy(sde->name, dent->d_name);
- sde = next_entry(sde);
+ sde++;
}
+ closedir(vdir);
}
+out:
+ closedir(dir);
rsp->data_length = (char *)sde - (char *)req->data;
dprintf("%d\n", rsp->data_length);
diff --git a/include/meta.h b/include/meta.h
index 801f31e..31568d0 100644
--- a/include/meta.h
+++ b/include/meta.h
@@ -51,6 +51,8 @@ static inline int is_data_obj(uint64_t oid)
#define FLAG_CURRENT 1
+#define MAX_VDINAME_LEN 1024
+
struct sheepdog_dir_entry {
uint64_t oid;
uint32_t tag;
@@ -59,19 +61,9 @@ struct sheepdog_dir_entry {
uint8_t flags;
uint32_t epoch;
uint32_t pad;
- char name[0];
+ char name[MAX_VDINAME_LEN];
};
-#define SD_DIR_ALIGN 8
-
-static inline struct sheepdog_dir_entry *next_entry(struct sheepdog_dir_entry *ent)
-{
- int len = offsetof(struct sheepdog_dir_entry, name)
- + roundup(ent->name_len, SD_DIR_ALIGN);
-
- return (struct sheepdog_dir_entry *)((char *)ent + len);
-}
-
#define MAX_DATA_OBJS (1 << 18)
#define MAX_CHILDREN 1024
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index e66c7e7..8c4aa9e 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -393,15 +393,44 @@ static int shutdown_sheepdog(void)
typedef void (*vdi_parser_func_t)(uint64_t oid, char *name, uint32_t tag, uint32_t flags,
struct sheepdog_inode *i, void *data);
+typedef int (*vdi_comp_func_t)(const void *p1, const void *p2);
+
+static int vdicomp_ctime(const void *p1, const void *p2)
+{
+ struct sheepdog_dir_entry *ent1 = (struct sheepdog_dir_entry *) p1;
+ struct sheepdog_dir_entry *ent2 = (struct sheepdog_dir_entry *) p2;
+
+ /* TODO: make a ctime field in struct sheepdog_dir_entry */
+ if (ent1->tag < ent2->tag)
+ return -1;
+
+ if (ent1->tag > ent2->tag)
+ return 1;
+
+ return 0;
+}
+
+static int vdicomp_name(const void *p1, const void *p2)
+{
+ struct sheepdog_dir_entry *ent1 = (struct sheepdog_dir_entry *) p1;
+ struct sheepdog_dir_entry *ent2 = (struct sheepdog_dir_entry *) p2;
+ int ret;
+
+ ret = strcmp(ent1->name, ent2->name);
+ if (ret)
+ return ret;
+
+ return -vdicomp_ctime(p1, p2);
+}
/*
* TODO: handle larger buffer
*/
-int parse_vdi(vdi_parser_func_t func, void *data)
+int parse_vdi(vdi_parser_func_t func, vdi_comp_func_t compare, void *data)
{
- struct sheepdog_dir_entry *prv, *ent;
+ struct sheepdog_dir_entry *ent, *endp;
char *buf;
- int rest, ret;
+ int nr_ent, ret;
struct sheepdog_inode i;
struct sd_so_req req;
@@ -422,9 +451,13 @@ int parse_vdi(vdi_parser_func_t func, void *data)
goto out;
}
+ nr_ent = ret / sizeof(struct sheepdog_dir_entry);
+ if (compare)
+ qsort(buf, nr_ent, sizeof(struct sheepdog_dir_entry), compare);
+
ent = (struct sheepdog_dir_entry *) buf;
- rest = ret;
- while (rest > 0) {
+ endp = ent + nr_ent;
+ while (ent < endp) {
if (!ent->name_len)
break;
@@ -434,9 +467,7 @@ int parse_vdi(vdi_parser_func_t func, void *data)
if (ret == sizeof(i))
func(ent->oid, ent->name, ent->tag, ent->flags, &i, data);
- prv = ent;
- ent = next_entry(prv);
- rest -= ((char *)ent - (char *)prv);
+ ent++;
}
out:
@@ -504,7 +535,7 @@ static int graphview_vdi(char *vdiname, int highlight)
/* print a header */
printf("digraph G \{\n");
- parse_vdi(print_graph_tree, &i);
+ parse_vdi(print_graph_tree, vdicomp_ctime, &i);
if (i.root == 0)
printf(" \"0\" [shape = \"ellipse\", label = \"root\"];\n");
@@ -559,7 +590,7 @@ static int treeview_vdi(char *vdiname, int highlight)
init_tree();
add_proc("", "root", 1, 1, 0);
- parse_vdi(print_vdi_tree, &i);
+ parse_vdi(print_vdi_tree, vdicomp_ctime, &i);
dump_tree();
@@ -802,7 +833,7 @@ static void print_obj(char *vdiname, unsigned index)
info.name = vdiname;
info.oid = 0;
- ret = parse_vdi(get_oid, &info);
+ ret = parse_vdi(get_oid, NULL, &info);
oid = info.oid;
@@ -863,7 +894,7 @@ rerun:
case FORMAT_LIST:
printf(" name tag size used shared creation time object id\n");
printf("-----------------------------------------------------------------------\n");
- ret = parse_vdi(print_vdi_list, name);
+ ret = parse_vdi(print_vdi_list, vdicomp_name, name);
break;
case FORMAT_TREE:
ret = treeview_vdi(name, highlight);
@@ -939,7 +970,7 @@ rerun:
printf("\n");
- parse_vdi(cal_total_vdi_size, &total_vdi_size);
+ parse_vdi(cal_total_vdi_size, NULL, &total_vdi_size);
printf("Total\t%" PRIu64 "G\t%" PRIu64 "G\t%3d%%, total virtual VDI Size\t%" PRIu64 "G\n",
total_size / 1024 / 1024 / 1024,
@@ -985,7 +1016,7 @@ rerun:
printf("Name |Vdi size |Allocated| Shared | Status\n");
printf("----------------+---------+---------+---------+------------\n");
- ret = parse_vdi(print_vm_list, &vli);
+ ret = parse_vdi(print_vm_list, vdicomp_name, &vli);
break;
}
default:
--
1.5.6.5
More information about the sheepdog
mailing list