static INT CompareVersions( __in ULONG MajorVersion1, __in ULONG MinorVersion1, __in ULONG MajorVersion2, __in ULONG MinorVersion2 ) { INT result = intcmp(MajorVersion1, MajorVersion2); if (result == 0) result = intcmp(MinorVersion1, MinorVersion2); return result; }
static int __cdecl PhpAccessEntryCompare( _In_ const void *elem1, _In_ const void *elem2 ) { PPH_ACCESS_ENTRY entry1 = (PPH_ACCESS_ENTRY)elem1; PPH_ACCESS_ENTRY entry2 = (PPH_ACCESS_ENTRY)elem2; return intcmp(PhCountBits(entry2->Access), PhCountBits(entry1->Access)); }
static int epoll_event_cmp(const struct epoll_event *_a, struct epoll_event *_b) { struct event_info *a, *b; a = (struct event_info *)_a->data.ptr; b = (struct event_info *)_b->data.ptr; /* we need sort event_info array in reverse order */ return intcmp(b->prio, a->prio); }
static int binop(void) { const char *opnd1, *opnd2; struct t_op const *op; opnd1 = *t_wp; (void) t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL); op = t_wp_op; if ((opnd2 = nargc > 0 ? (--nargc, *++t_wp) : NULL) == NULL) syntax(op->op_text, "argument expected"); switch (op->op_num) { case STREQ: return strcmp(opnd1, opnd2) == 0; case STRNE: return strcmp(opnd1, opnd2) != 0; case STRLT: return strcmp(opnd1, opnd2) < 0; case STRGT: return strcmp(opnd1, opnd2) > 0; case INTEQ: return intcmp(opnd1, opnd2) == 0; case INTNE: return intcmp(opnd1, opnd2) != 0; case INTGE: return intcmp(opnd1, opnd2) >= 0; case INTGT: return intcmp(opnd1, opnd2) > 0; case INTLE: return intcmp(opnd1, opnd2) <= 0; case INTLT: return intcmp(opnd1, opnd2) < 0; case FILNT: return newerf (opnd1, opnd2); case FILOT: return olderf (opnd1, opnd2); case FILEQ: return equalf (opnd1, opnd2); default: abort(); /* NOTREACHED */ } }
static int binop(enum token n) { const char *opnd1, *op, *opnd2; opnd1 = *t_wp; op = nargc > 0 ? (--nargc, *++t_wp) : NULL; if ((opnd2 = nargc > 0 ? (--nargc, *++t_wp) : NULL) == NULL) syntax(op, "argument expected"); switch (n) { case STREQ: return strcmp(opnd1, opnd2) == 0; case STRNE: return strcmp(opnd1, opnd2) != 0; case STRLT: return strcmp(opnd1, opnd2) < 0; case STRGT: return strcmp(opnd1, opnd2) > 0; case INTEQ: return intcmp(opnd1, opnd2) == 0; case INTNE: return intcmp(opnd1, opnd2) != 0; case INTGE: return intcmp(opnd1, opnd2) >= 0; case INTGT: return intcmp(opnd1, opnd2) > 0; case INTLE: return intcmp(opnd1, opnd2) <= 0; case INTLT: return intcmp(opnd1, opnd2) < 0; case FILNT: return newerf (opnd1, opnd2); case FILOT: return olderf (opnd1, opnd2); case FILEQ: return equalf (opnd1, opnd2); default: abort(); /* NOTREACHED */ } }
static int event_cmp(const struct event_info *e1, const struct event_info *e2) { return intcmp(e1->fd, e2->fd); }
static int vdisk_cmp(const struct vdisk *d1, const struct vdisk *d2) { return intcmp(d1->hash, d2->hash); }
static int vdi_state_cmp(const struct vdi_state_entry *a, const struct vdi_state_entry *b) { return intcmp(a->vid, b->vid); }
/* * Initialize the data vdi * * @vid: the vdi where the allocator resides */ int oalloc_init(uint32_t vid) { struct strbuf buf = STRBUF_INIT; struct sd_inode *inode = xmalloc(sizeof(struct sd_inode)); struct header hd = { .nr_free = 1, }; struct free_desc fd = { .start = 1, /* Use first object as the meta object */ .count = MAX_DATA_OBJS - 1, }; int ret; strbuf_add(&buf, &hd, sizeof(hd)); strbuf_add(&buf, &fd, sizeof(fd)); ret = sd_read_object(vid_to_vdi_oid(vid), (char *)inode, sizeof(*inode), 0); if (ret != SD_RES_SUCCESS) { sd_err("failed to read inode, %" PRIx32", %s", vid, sd_strerror(ret)); goto out; } ret = sd_write_object(vid_to_data_oid(vid, 0), buf.buf, buf.len, 0, true); if (ret != SD_RES_SUCCESS) { sd_err("failed to create meta object for %" PRIx32", %s", vid, sd_strerror(ret)); goto out; } sd_inode_set_vid(inode, 0, vid); ret = sd_inode_write_vid(inode, 0, vid, vid, 0, false, false); if (ret != SD_RES_SUCCESS) { sd_err("failed to update inode, %" PRIx32", %s", vid, sd_strerror(ret)); goto out; } out: strbuf_release(&buf); free(inode); return ret; } /* * Allocate the objects and update the free list. * * Callers are expected to call oalloc_new_finish() to update the inode bitmap * after filling up the data. * * @vid: the vdi where the allocator resides * @start: start index of the objects to allocate * @count: number of the objects to allocate */ int oalloc_new_prepare(uint32_t vid, uint64_t *start, uint64_t count) { char *meta = xvalloc(SD_DATA_OBJ_SIZE); struct header *hd; struct free_desc *fd; uint64_t oid = vid_to_data_oid(vid, 0), i; int ret; ret = sd_read_object(oid, meta, SD_DATA_OBJ_SIZE, 0); if (ret != SD_RES_SUCCESS) { sd_err("failed to read meta %" PRIx64 ", %s", oid, sd_strerror(ret)); goto out; } hd = (struct header *)meta; fd = (struct free_desc *)(meta + oalloc_meta_length(hd)) - 1; sd_debug("used %"PRIu64", nr_free %"PRIu64, hd->used, hd->nr_free); for (i = 0; i < hd->nr_free; i++, fd--) { sd_debug("start %"PRIu64", count %"PRIu64, fd->start, fd->count); if (fd->count > count) break; } if (i == hd->nr_free) { ret = SD_RES_NO_SPACE; goto out; } *start = fd->start; fd->start += count; fd->count -= count; hd->used += count; /* Update the meta object */ ret = sd_write_object(oid, meta, oalloc_meta_length(hd), 0, false); if (ret != SD_RES_SUCCESS) sd_err("failed to update meta %"PRIx64 ", %s", oid, sd_strerror(ret)); out: free(meta); return ret; } /* * Update the inode map of the vid * * @vid: the vdi where the allocator resides * @start: start index of the objects to update * @count: number of the objects to update */ int oalloc_new_finish(uint32_t vid, uint64_t start, uint64_t count) { struct sd_inode *inode = xmalloc(sizeof(struct sd_inode)); int ret; ret = sd_read_object(vid_to_vdi_oid(vid), (char *)inode, sizeof(*inode), 0); if (ret != SD_RES_SUCCESS) { sd_err("failed to read inode, %" PRIx64 ", %s", vid_to_vdi_oid(vid), sd_strerror(ret)); goto out; } sd_debug("start %"PRIu64" end %"PRIu64, start, start + count - 1); sd_inode_set_vid_range(inode, start, (start + count - 1), vid); ret = sd_inode_write(inode, 0, false, false); if (ret != SD_RES_SUCCESS) { sd_err("failed to update inode, %" PRIx64", %s", vid_to_vdi_oid(vid), sd_strerror(ret)); goto out; } out: free(inode); return ret; } static int free_desc_cmp(struct free_desc *a, struct free_desc *b) { return -intcmp(a->start, b->start); } static inline int update_and_merge_free_desc(char *meta, uint64_t start, uint64_t count, uint32_t vid) { struct header *hd = (struct header *)meta; struct free_desc *tail, *fd = HEADER_TO_FREE_DESC(hd); uint64_t i, j; /* Try our best to merge it in place, or append it to tail */ for (i = 0; i < hd->nr_free; i++) { if (start + count == fd->start) { fd->start = start; fd->count += count; break; } else if(fd->start + fd->count == start) { fd->count +=count; break; } fd++; } if (i == hd->nr_free) { if (hd->nr_free >= MAX_FREE_DESC) return SD_RES_NO_SPACE; tail = (struct free_desc *)(meta + oalloc_meta_length(hd)); tail->start = start; tail->count = count; hd->nr_free++; } hd->used -= count; xqsort(HEADER_TO_FREE_DESC(hd), hd->nr_free, free_desc_cmp); /* Merge as hard as we can */ j = hd->nr_free - 1; tail = (struct free_desc *)(meta + oalloc_meta_length(hd)) - 1; for (i = 0; i < j; i++, tail--) { struct free_desc *front = tail - 1; sd_debug("start %"PRIu64", count %"PRIu64, tail->start, tail->count); if (tail->start + tail->count > front->start) sd_emerg("bad free descriptor found at %"PRIx32, vid); if (tail->start + tail->count == front->start) { front->start = tail->start; front->count += tail->count; memmove(tail, tail + 1, sizeof(*tail) * i); hd->nr_free--; } } return SD_RES_SUCCESS; } /* * Discard the allocated objects and update the free list of the allocator * * Caller should check the return value since it might fail. * * @vid: the vdi where the allocator resides * @start: start index of the objects to free * @count: number of the objects to free */ int oalloc_free(uint32_t vid, uint64_t start, uint64_t count) { char *meta = xvalloc(SD_DATA_OBJ_SIZE); struct header *hd; uint64_t oid = vid_to_data_oid(vid, 0), i; struct sd_inode *inode = xmalloc(sizeof(struct sd_inode)); int ret; ret = sd_read_object(vid_to_vdi_oid(vid), (char *)inode, sizeof(*inode), 0); if (ret != SD_RES_SUCCESS) { sd_err("failed to read inode, %" PRIx64 ", %s", vid_to_vdi_oid(vid), sd_strerror(ret)); goto out; } sd_debug("discard start %"PRIu64" end %"PRIu64, start, start + count - 1); sd_inode_set_vid_range(inode, start, (start + count - 1), 0); ret = sd_inode_write(inode, 0, false, false); if (ret != SD_RES_SUCCESS) { sd_err("failed to update inode, %" PRIx64", %s", vid_to_vdi_oid(vid), sd_strerror(ret)); goto out; } ret = sd_read_object(oid, meta, SD_DATA_OBJ_SIZE, 0); if (ret != SD_RES_SUCCESS) { sd_err("failed to read meta %" PRIx64 ", %s", oid, sd_strerror(ret)); goto out; } ret = update_and_merge_free_desc(meta, start, count, vid); if (ret != SD_RES_SUCCESS) goto out; /* XXX use aio to speed up remove of objects */ for (i = 0; i < count; i++) { struct sd_req hdr; int res; sd_init_req(&hdr, SD_OP_REMOVE_OBJ); hdr.obj.oid = vid_to_data_oid(vid, start + i); res = exec_local_req(&hdr, NULL); /* * return the error code if it does not * success or can't find obj. */ if (res != SD_RES_SUCCESS && res != SD_RES_NO_OBJ) ret = res; } hd = (struct header *)meta; ret = sd_write_object(oid, meta, oalloc_meta_length(hd), 0, false); if (ret != SD_RES_SUCCESS) { sd_err("failed to update meta %"PRIx64 ", %s", oid, sd_strerror(ret)); goto out; } sd_debug("used %"PRIu64", nr_free %"PRIu64, hd->used, hd->nr_free); out: free(meta); free(inode); return ret; }
/* AutoBool means: AF_TRUE: redefine AF_FALSE: dispatch AF_DEPENDS: depends */ static int compare_usages (usaged *u1, recID rd, usaged *u2, recID rb, Token deps[]) { int i, nd = 0, j; if (!u1) return AF_FALSE; for (i = 0; u1 [i].status != USE_END; i++) switch (u1 [i].status) { case USE_LTDEF: case USE_TCONST: if (u1 [i].u.t != u2 [i].u.t) return AF_TRUE; ncase USE_TYPEID: if (u1 [i].u.T != u2 [i].u.T) return AF_TRUE; ncase USE_FCALL: if (u1 [i].u.t == u2 [i].u.t) continue; switch (is_another_autof (u1 [i].u.t)) { case AF_TRUE: return AF_TRUE; case AF_FALSE: continue; default: for (j = 0; j < nd; j++) if (deps [j] == u1 [i].u.t) break; if (j == nd) deps [nd++] = u1 [i].u.t; } ncase USE_VVAR: if (intcmp (u1 [i].u.s, u2 [i].u.s)) return AF_TRUE; ncase USE_MEMB: { Token p1 [64], p2 [64], *p; lookup_variable_member (rd, u1[i].u.t, p1, true, 0); lookup_variable_member (rb, u1[i].u.t, p2 + 2, true, 0); p2 [1] = is_ancestor (rd, rb, &p, true) == 2 ? POINTSAT : '.'; p2 [0] = p [0]; if (intcmp (p1, p2)) return AF_TRUE; } ncase USE_UPCAST: /* if different, will catch fcalls */ if (u1 [i].u.r != u2 [i].u.r) continue; { Token *p1, p2 [64], *p; is_ancestor (rd, u1 [i].u.r, &p1, true); if (rb != u1 [i].u.r) { is_ancestor (rb, u1 [i].u.r, &p, true); intcpy (p2 + 2, p); p2 [1] = is_ancestor (rd, rb, &p, true) == 2 ? POINTSAT : '.'; p2 [0] = p [0]; if (p2 [2] == -1) p2 [1] = -1; if (p [0] == -1) intcpy (p2, p2 + 2); } else { is_ancestor (rd, rb, &p, true); intcpy (p2, p); } if (intcmp (p1, p2)) return AF_TRUE; } } deps [nd] = -1; return nd ? AF_DEPENDS : AF_FALSE; }
static int intpcmp(const void *a, const void *b) { return intcmp(*(const int *)a, *(const int *)b); }
static int vdi_inode_cmp(const struct vdi_inode *a, const struct vdi_inode *b) { return intcmp(a->vid, b->vid); }