// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { unsigned char FB[]="MESSAGE WRITTEN THROUGH FRAMEBUFFER!!"; fb_init(); // initialize framebuffer device (2015.11.02) cprintf("\nUsing Framebuffer still presents some problems :(\n\n"); cprintf("\nSuggestion: review the way it is used in console.c\n\n"); fb_write(FB, sizeof(FB)); // Framebuffer maybe could be used before this moment (2015.11.02) see_mylock(MYLOCK); kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { monitor_clear (); // Print basic system information. cprintf ("Ensidia\n\n"); cprintf ("Copyright (c) 2013-2014 Fotis Koutoulakis\n"); cprintf ("Based on xv6 by Russ Cox et al, at MIT CSAIL\n"); kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xng kernel\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl, gfp_t gfp) { unsigned int i, size; #if defined(CONFIG_PROVE_LOCKING) unsigned int nr_pcpus = 2; #else unsigned int nr_pcpus = num_possible_cpus(); #endif nr_pcpus = min_t(unsigned int, nr_pcpus, 64UL); size = roundup_pow_of_two(nr_pcpus * ht->p.locks_mul); /* Never allocate more than 0.5 locks per bucket */ size = min_t(unsigned int, size, tbl->size >> 1); if (tbl->nest) size = min(size, 1U << tbl->nest); if (sizeof(spinlock_t) != 0) { if (gfpflags_allow_blocking(gfp)) tbl->locks = kvmalloc(size * sizeof(spinlock_t), gfp); else tbl->locks = kmalloc_array(size, sizeof(spinlock_t), gfp); if (!tbl->locks) return -ENOMEM; for (i = 0; i < size; i++) spin_lock_init(&tbl->locks[i]); } tbl->locks_mask = size - 1; return 0; }
/*int main(void){*/ void kmain(void){ // vga_init(); // puts((uint8_t*)"Hello kernel world!\n"); /*do some work here, like initialize timer or paging*/ kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); // gdt_descriptor(); // puts((uint8_t*)"GDT initialized...\n"); // idt_descriptor(); // puts((uint8_t*)"IDT initialized...\n"); // cprintf("IDT initialized...\n"); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
ib_status_t ib_kvstore_riak_set_bucket_property_str( ib_kvstore_t *kvstore, const char *property, const char *value) { assert(kvstore); assert(property); assert(value); const char *post_fmt = "{\"props\":{\"%s\":\"%s\"}}"; membuffer_t request; ib_status_t rc; membuffer_init(kvstore, &request); request.read = 0; request.size = strlen(property) + /* Property length. */ strlen(value) + /* Value length. */ strlen(post_fmt) - 4; /* post_fmt - %s and %s. */ /* Note: size+1 so we can use sprintf below. */ request.buffer = kvmalloc(kvstore, request.size+1); if (!request.buffer) { return IB_EALLOC; } sprintf(request.buffer, post_fmt, property, value); rc = ib_kvstore_riak_set_bucket_property(kvstore, &request); cleanup_membuffer(&request); return rc; }
static int hgcm_call_preprocess_linaddr( const struct vmmdev_hgcm_function_parameter *src_parm, void **bounce_buf_ret, size_t *extra) { void *buf, *bounce_buf; bool copy_in; u32 len; int ret; buf = (void *)src_parm->u.pointer.u.linear_addr; len = src_parm->u.pointer.size; copy_in = src_parm->type != VMMDEV_HGCM_PARM_TYPE_LINADDR_OUT; if (len > VBG_MAX_HGCM_USER_PARM) return -E2BIG; bounce_buf = kvmalloc(len, GFP_KERNEL); if (!bounce_buf) return -ENOMEM; if (copy_in) { ret = copy_from_user(bounce_buf, (void __user *)buf, len); if (ret) return -EFAULT; } else { memset(bounce_buf, 0, len); } *bounce_buf_ret = bounce_buf; hgcm_call_add_pagelist_size(bounce_buf, len, extra); return 0; }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(mpbcpu()); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors (must come before kinit) kinit(); // initialize memory allocator userinit(); // first user process (must come after kinit) // Finish setting up this processor in mpmain. mpmain(); }
/** * aa_simple_write_to_buffer - common routine for getting policy from user * @op: operation doing the user buffer copy * @userbuf: user buffer to copy data from (NOT NULL) * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size) * @copy_size: size of data to copy from user buffer * @pos: position write is at in the file (NOT NULL) * * Returns: kernel buffer containing copy of user buffer data or an * ERR_PTR on failure. */ static char *aa_simple_write_to_buffer(int op, const char __user *userbuf, size_t alloc_size, size_t copy_size, loff_t *pos) { char *data; BUG_ON(copy_size > alloc_size); if (*pos != 0) /* only writes from pos 0, that is complete writes */ return ERR_PTR(-ESPIPE); /* * Don't allow profile load/replace/remove from profiles that don't * have CAP_MAC_ADMIN */ if (!aa_may_manage_policy(op)) return ERR_PTR(-EACCES); /* freed by caller to simple_write_to_buffer */ data = kvmalloc(alloc_size); if (data == NULL) return ERR_PTR(-ENOMEM); if (copy_from_user(data, userbuf, copy_size)) { kvfree(data); return ERR_PTR(-EFAULT); } return data; }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // detect other processors lapicinit(); // interrupt controller seginit(); // segment descriptors cprintf("\ncpu%d: starting xv6\n\n", cpunum()); picinit(); // another interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // console hardware uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); // finish this processor's setup init_semaphores_on_boot(); }
int ib_kvstore_riak_ping(ib_kvstore_t *kvstore) { assert(kvstore); ib_kvstore_riak_server_t *riak; ib_status_t rc; membuffer_t resp; riak_headers_t headers; char *url; riak = (ib_kvstore_riak_server_t *)kvstore->server; int result; url = kvmalloc(kvstore, riak->riak_url_len + 7); if (!url) { return 0; } sprintf(url, "%s/ping", riak->riak_url); rc = riak_get(kvstore, riak, url, &resp, &headers); if (rc != IB_OK) { result = 0; } else { result = (resp.read == 2 && resp.buffer[0] == 'O' && resp.buffer[1] == 'K'); } kvfree(kvstore, url); cleanup_membuffer(&resp); cleanup_riak_headers(&headers); return result; }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator // kmem. freelist added cprintf("%x \n", end); kvmalloc(); // kernel page table #ifdef CONFIG_MULTI_PROCESS mpinit(); // collect info about this machine #endif lapicinit(); seginit(); // set up segments picinit(); // interrupt controller: Programmable Interrupt Controller #ifdef CONFIG_MULTI_PROCESS ioapicinit(); // another interrupt controller #endif consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table iinit(); // inode cache ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer #ifdef CONFIG_MULTI_PROCESS startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() #endif userinit(); // first user process // Finish setting up this processor in mpmain. mpmain(); }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port pinit(); // process table tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk if(!ismp) timerinit(); // uniprocessor timer startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); }
static struct fdtable * alloc_fdtable(unsigned int nr) { struct fdtable *fdt; void *data; /* * Figure out how many fds we actually want to support in this fdtable. * Allocation steps are keyed to the size of the fdarray, since it * grows far faster than any of the other dynamic data. We try to fit * the fdarray into comfortable page-tuned chunks: starting at 1024B * and growing in powers of two from there on. */ nr /= (1024 / sizeof(struct file *)); nr = roundup_pow_of_two(nr + 1); nr *= (1024 / sizeof(struct file *)); /* * Note that this can drive nr *below* what we had passed if sysctl_nr_open * had been set lower between the check in expand_files() and here. Deal * with that in caller, it's cheaper that way. * * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise * bitmaps handling below becomes unpleasant, to put it mildly... */ if (unlikely(nr > sysctl_nr_open)) nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL_ACCOUNT); if (!fdt) goto out; fdt->max_fds = nr; data = kvmalloc_array(nr, sizeof(struct file *), GFP_KERNEL_ACCOUNT); if (!data) goto out_fdt; fdt->fd = data; data = kvmalloc(max_t(size_t, 2 * nr / BITS_PER_BYTE + BITBIT_SIZE(nr), L1_CACHE_BYTES), GFP_KERNEL_ACCOUNT); if (!data) goto out_arr; fdt->open_fds = data; data += nr / BITS_PER_BYTE; fdt->close_on_exec = data; data += nr / BITS_PER_BYTE; fdt->full_fds_bits = data; return fdt; out_arr: kvfree(fdt->fd); out_fdt: kfree(fdt); out: return NULL; }
/** * unpack_table - unpack a dfa table (one of accept, default, base, next check) * @blob: data to unpack (NOT NULL) * @bsize: size of blob * * Returns: pointer to table else NULL on failure * * NOTE: must be freed by kvfree (not kmalloc) */ static struct table_header *unpack_table(char *blob, size_t bsize) { struct table_header *table = NULL; struct table_header th; size_t tsize; if (bsize < sizeof(struct table_header)) goto out; /* loaded td_id's start at 1, subtract 1 now to avoid doing * it every time we use td_id as an index */ th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1; th.td_flags = be16_to_cpu(*(u16 *) (blob + 2)); th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8)); blob += sizeof(struct table_header); if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || th.td_flags == YYTD_DATA8)) goto out; tsize = table_size(th.td_lolen, th.td_flags); if (bsize < tsize) goto out; table = kvmalloc(tsize); if (table) { *table = th; if (th.td_flags == YYTD_DATA8) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, u8, byte_to_byte); else if (th.td_flags == YYTD_DATA16) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, u16, be16_to_cpu); else if (th.td_flags == YYTD_DATA32) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, u32, be32_to_cpu); else goto fail; } out: /* if table was vmalloced make sure the page tables are synced * before it is used, as it goes live to all cpus. */ if (is_vmalloc_addr(table)) vm_unmap_aliases(); return table; fail: kvfree(table); return NULL; }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // collect info about this machine lapicinit(); seginit(); // set up segments cprintf("\ncpu%d: starting xv6\n\n", cpu->id); picinit(); // interrupt controller ioapicinit(); // another interrupt controller consoleinit(); // I/O devices & their interrupts uartinit(); // serial port initGraphMode(); initDom(); tryOnce(); toggleOn(); pinit(); // process table toggleOn(); tvinit(); // trap vectors toggleOn(); binit(); // buffer cache toggleOn(); fileinit(); // file table toggleOn(); iinit(); // inode cache toggleOn(); ideinit(); // disk toggleOn(); if(!ismp) timerinit(); // uniprocessor timer toggleOn(); startothers(); // start other processors toggleOn(); kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() toggleOn(); txt_initLock(); mouseEnable(); initProcessMsgMap(); userinit(); // first user process toggleOn(); endToggle(); // Finish setting up this processor in mpmain. mpmain(); }
/** * Convert @a response and @a headers into a @a value. * * This copies the response buffer and related headers * into the given @a value. * * @param[in] kvstore Key-value store. * @param[in] riak kvstore->server object, extracted. * @param[in] response The response from the server. * @param[in] headers Riak headers captured during the get. * @param[out] value The value to be populated. * * @returns * - IB_OK success. * - IB_EALLOC memory allocation. */ static ib_status_t http_to_kvstore_value( ib_kvstore_t *kvstore, ib_kvstore_riak_server_t *riak, membuffer_t *response, riak_headers_t *headers, ib_kvstore_value_t *value) { assert(kvstore); assert(riak); assert(response); assert(headers); assert(value); /* Copy value. */ value->value = kvmalloc(kvstore, response->read); if (value->value == NULL) { return IB_EALLOC; } memcpy(value->value, response->buffer, response->read); value->value_length = response->read; /* Copy Content-Type as a string. */ value->type_length = strlen(headers->content_type); value->type = kvmalloc(kvstore, value->type_length + 1); if (value->type == NULL) { kvfree(kvstore, value->value); return IB_EALLOC; } strcpy(value->type, headers->content_type); value->expiration = headers->expiration; value->creation.tv_sec = headers->creation.tv_sec; value->creation.tv_usec = headers->creation.tv_usec; return IB_OK; }
/** * vmemdup_user - duplicate memory region from user space * * @src: source address in user space * @len: number of bytes to copy * * Returns an ERR_PTR() on failure. Result may be not * physically contiguous. Use kvfree() to free. */ void *vmemdup_user(const void __user *src, size_t len) { void *p; p = kvmalloc(len, GFP_USER); if (!p) return ERR_PTR(-ENOMEM); if (copy_from_user(p, src, len)) { kvfree(p); return ERR_PTR(-EFAULT); } return p; }
static struct table_header *unpack_table(char *blob, size_t bsize) { struct table_header *table = NULL; struct table_header th; size_t tsize; if (bsize < sizeof(struct table_header)) goto out; th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1; th.td_flags = be16_to_cpu(*(u16 *) (blob + 2)); th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8)); blob += sizeof(struct table_header); if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || th.td_flags == YYTD_DATA8)) goto out; tsize = table_size(th.td_lolen, th.td_flags); if (bsize < tsize) goto out; table = kvmalloc(tsize); if (table) { *table = th; if (th.td_flags == YYTD_DATA8) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, u8, byte_to_byte); else if (th.td_flags == YYTD_DATA16) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, u16, be16_to_cpu); else if (th.td_flags == YYTD_DATA32) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, u32, be32_to_cpu); else goto fail; } out: if (is_vmalloc_addr(table)) vm_unmap_aliases(); return table; fail: kvfree(table); return NULL; }
void ib_kvstore_riak_set_etag(ib_kvstore_t *kvstore, char *etag) { ib_kvstore_riak_server_t *riak; riak = (ib_kvstore_riak_server_t *)kvstore->server; if (riak->etag) { kvfree(kvstore, riak->etag); } if (etag) { riak->etag = kvmalloc(kvstore, strlen(etag)+1); if (riak->etag) { strcpy(riak->etag, etag); } } else { riak->etag = NULL; } }
void ib_kvstore_riak_set_vclock(ib_kvstore_t *kvstore, char *vclock) { ib_kvstore_riak_server_t *riak; riak = (ib_kvstore_riak_server_t *)kvstore->server; if (riak->vclock) { kvfree(kvstore, riak->vclock); } if (vclock) { riak->vclock = kvmalloc(kvstore, strlen(vclock)+1); if (riak->vclock) { strcpy(riak->vclock, vclock); } } else { riak->vclock = NULL; } }
// Os procedimentos de inicialização começam a executar o // código .C a partir daqui. // Aloca uma pilha real e troca para ela, primeiro fazendo // algumas configurações necessárias par o alocador de memória funcionar. int main(void) { kinit1(end, P2V(4*1024*1024)); // alocador de páginas de memória física kvmalloc(); // tabela de páginas do kernel mpinit(); // detecta outros processadores lapicinit(); // controlador de interrupções seginit(); // descritores de segmentos picinit(); // desabilita pic ioapicinit(); // outro controlador de interrupções consoleinit(); // console hardware uartinit(); // porta serial pinit(); // tabela de processos tvinit(); // vetores trap binit(); // buffer cache fileinit(); // tabela de arquivo ideinit(); // disco startothers(); // inicia outros processadores kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // deve vir após startothers() userinit(); // primeiro processo no modo usuário mpmain(); // encerra esta configuração de processadores }
/** * Conditional copy. * * @param[in] kvstore Key-value store. * @param[in] header The header to check for. * @param[in] ptr The header line. * @param[in] ptr_len The pointer length. * @param[out] dest A copy of the header value is written here. * @returns * - IB_OK on success. * - IB_EINVAL if the header is not found in ptr. * - IB_EALLOC Allocation error. */ static ib_status_t cond_copy_header( ib_kvstore_t *kvstore, const char *header, const char *ptr, size_t ptr_len, char **dest) { size_t header_len = strlen(header); size_t value_sz; /* If header cannot prefix ptr (because header is too long)... */ if (ptr_len <= header_len) { return IB_EINVAL; } /* If header is not prefixed by ptr... */ if (strncmp(ptr, header, header_len)) { return IB_EINVAL; } value_sz = ptr_len - header_len + 1; *dest = kvmalloc(kvstore, value_sz); if (*dest == NULL) { return IB_EALLOC; } strncpy(*dest, ptr + header_len, value_sz); /* If we are given a header with \r\n at the end of it, terminate the * string early. This is always the case with Curl. */ if (value_sz >= 3 && (*dest)[value_sz-3] == '\r') { (*dest)[value_sz-3] = '\0'; } return IB_OK; }
ib_status_t ib_kvstore_riak_set_bucket_property_int( ib_kvstore_t *kvstore, const char *property, int value) { assert(kvstore); assert(property); const char *post_fmt = "{\"props\":{\"%s\":%d}}"; membuffer_t request; const int digits = 6; size_t size; ib_status_t rc; if (value < 0) { return IB_EINVAL; } /* Digits is greater than 6, so we can't represent it in our buffer. */ if (value > 999999) { return IB_EINVAL; } membuffer_init(kvstore, &request); request.read = 0; size = strlen(property) + digits + strlen(post_fmt)-4; request.buffer = kvmalloc(kvstore, size+1); if (!request.buffer) { return IB_EALLOC; } request.size = sprintf(request.buffer, post_fmt, property, value); rc = ib_kvstore_riak_set_bucket_property(kvstore, &request); cleanup_membuffer(&request); return rc; }
// Bootstrap processor starts running C code here. // Allocate a real stack and switch to it, first // doing some setup required for memory allocator to work. int main(void) { kinit1(end, P2V(4*1024*1024)); // phys page allocator kvmalloc(); // kernel page table mpinit(); // detect other processors lapicinit(); // interrupt controller seginit(); // segment descriptors picinit(); // disable pic ioapicinit(); // another interrupt controller consoleinit(); // console hardware uartinit(); // serial port pinit(); // process table shminit(); // shared memory tvinit(); // trap vectors binit(); // buffer cache fileinit(); // file table ideinit(); // disk startothers(); // start other processors kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers() userinit(); // first user process mpmain(); // finish this processor's setup }
/** * This function manages writing returned data from curl into a buffer. * * @param[in] ptr The buffer. * @param[in] size The size of each memory buffer. * @param[in] nmemb The number of memory buffers. * @param[out] userdata A membuffer_t pointer. * @returns The length of bytes written. * * @see http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTWRITEFUNCTION */ static size_t membuffer_writefunction( char *ptr, size_t size, size_t nmemb, void *userdata) { membuffer_t *mb = (membuffer_t *)userdata; ib_kvstore_t *kvstore = mb->kvstore; /* Resize mb. */ if (size * nmemb > mb->size - mb->read) { size_t new_size = size * nmemb + mb->size + 4096; char *buffer_tmp = kvmalloc(kvstore, new_size); if (!buffer_tmp) { return 0; } /* Avoid situations where buffer is null. */ if (mb->buffer) { if (mb->read > 0) { memcpy(buffer_tmp, mb->buffer, mb->read); } kvfree(kvstore, mb->buffer); } mb->buffer = buffer_tmp; mb->size = new_size; } memcpy(mb->buffer + mb->read, ptr, size * nmemb); mb->read += size * nmemb; return size * nmemb; }
/** * Allocates new string using kvstore->malloc representing a riak key url. * * Caller should free this with kvstore->free. * * @param[in] kvstore Key-value store. * @param[in] riak The riak server data already pulled out of kvstore. * @param[in] key The key to be converted into a URL. * * @returns NULL on failure. */ static char * build_key_url( ib_kvstore_t *kvstore, ib_kvstore_riak_server_t *riak, const ib_kvstore_key_t *key) { assert(kvstore); assert(riak); assert(key); char *url; size_t url_len; /* bucket + /keys/ + key */ url_len = riak->bucket_url_len + 6 + key->length; url = kvmalloc(kvstore, url_len + 1); if (!url) { return NULL; } snprintf(url, url_len, "%s/keys/%s", riak->bucket_url, (char *)key->key); return url; }
/** * frame_vector_create() - allocate & initialize structure for pinned pfns * @nr_frames: number of pfns slots we should reserve * * Allocate and initialize struct pinned_pfns to be able to hold @nr_pfns * pfns. */ struct frame_vector *frame_vector_create(unsigned int nr_frames) { struct frame_vector *vec; int size = sizeof(struct frame_vector) + sizeof(void *) * nr_frames; if (WARN_ON_ONCE(nr_frames == 0)) return NULL; /* * This is absurdly high. It's here just to avoid strange effects when * arithmetics overflows. */ if (WARN_ON_ONCE(nr_frames > INT_MAX / sizeof(void *) / 2)) return NULL; /* * Avoid higher order allocations, use vmalloc instead. It should * be rare anyway. */ vec = kvmalloc(size, GFP_KERNEL); if (!vec) return NULL; vec->nr_allocated = nr_frames; vec->nr_frames = 0; return vec; }
/** * Internal helper function to do the work for * ib_kvstore_riak_set_bucket_property_int and * ib_kvstore_riak_set_bucket_property_str. */ static ib_status_t ib_kvstore_riak_set_bucket_property( ib_kvstore_t *kvstore, membuffer_t *request) { assert(kvstore); assert(request); assert(request->buffer); /* Constants for this function, alone. */ const char *props_path = "/props"; ib_kvstore_riak_server_t *riak; CURLcode curl_rc; struct curl_slist *header_list = NULL; size_t url_length; char *url; membuffer_t response; riak_headers_t headers; ib_status_t rc = IB_OK; riak_headers_init(kvstore, &headers); membuffer_init(kvstore, &response); riak = (ib_kvstore_riak_server_t *)kvstore->server; url_length = riak->bucket_url_len + strlen(props_path); url = kvmalloc(kvstore, url_length + 1); if (!url) { rc = IB_EALLOC; goto exit; } snprintf(url, url_length+1, "%s%s", riak->bucket_url, props_path); /* Set url. */ curl_rc = curl_easy_setopt(riak->curl, CURLOPT_URL, url); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Use PUT action. */ curl_rc = curl_easy_setopt(riak->curl, CURLOPT_UPLOAD, 1); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Set request data. */ curl_rc = curl_easy_setopt(riak->curl, CURLOPT_READDATA, request); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Set request data size. */ curl_rc = curl_easy_setopt(riak->curl, CURLOPT_INFILESIZE, request->size); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Define how to read the request. */ curl_rc = curl_easy_setopt( riak->curl, CURLOPT_READFUNCTION, membuffer_readfunction); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Define how to write the response. */ curl_rc = curl_easy_setopt( riak->curl, CURLOPT_WRITEFUNCTION, membuffer_writefunction); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Set the response buffer. */ curl_rc = curl_easy_setopt(riak->curl, CURLOPT_WRITEDATA, &response); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* How are headers captures. */ curl_rc = curl_easy_setopt( riak->curl, CURLOPT_HEADERFUNCTION, &riak_header_capture); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Where are headers captures. */ curl_rc = curl_easy_setopt(riak->curl, CURLOPT_WRITEHEADER, &headers); if (curl_rc) { rc = IB_EOTHER; goto exit; } header_list = curl_slist_append(header_list, "Content-Type: application/json"); if (!header_list) { rc = IB_EOTHER; goto exit; } curl_rc = curl_easy_setopt(riak->curl, CURLOPT_HTTPHEADER, header_list); if (curl_rc) { rc = IB_EOTHER; goto exit; } /* Perform the transaction. */ curl_rc = curl_easy_perform(riak->curl); if (curl_rc) { rc = IB_EOTHER; goto exit; } exit: if (header_list) { curl_slist_free_all(header_list); } cleanup_membuffer(&response); cleanup_riak_headers(&headers); curl_easy_reset(riak->curl); kvfree(kvstore, url); return rc; }
static void *sfq_alloc(size_t sz) { return kvmalloc(sz, GFP_KERNEL); }
static ib_status_t kvget( ib_kvstore_t *kvstore, const ib_kvstore_key_t *key, ib_kvstore_value_t ***values, size_t *values_length, ib_kvstore_cbdata_t *cbdata) { ib_status_t rc; ib_kvstore_riak_server_t *riak; char *url; membuffer_t response; riak_headers_t riak_headers; membuffer_init(kvstore, &response); riak_headers_init(kvstore, &riak_headers); riak = (ib_kvstore_riak_server_t *)kvstore->server; url = build_key_url(kvstore, riak, key); rc = riak_get(kvstore, riak, url, &response, &riak_headers); if (rc != IB_OK) { goto exit; } if (riak_headers.status == 200) { *values_length = 1; /* Build 1-element array. */ *values = kvmalloc(kvstore, sizeof(**values)); if (*values == NULL) { rc = IB_EALLOC; goto exit; } /* Allocate kvstore value. */ (*values)[0] = kvmalloc(kvstore, sizeof(*((*values)[0]))); if (*values[0] == NULL) { rc = IB_EALLOC; goto exit; } rc = http_to_kvstore_value( kvstore, riak, &response, &riak_headers, (*values)[0]); goto exit; } /* Multiple choices. */ else if (riak_headers.status == 300) { /* Current line. */ char *cur; *values_length = 0; /* Count the siblings returned in the buffer. */ for (size_t i = 0; i + 1 < response.read && response.buffer[i] != '\0'; ++i) { /* Every sibling etag is preceded by a '\n' */ if (response.buffer[i] == '\n' && isalnum(response.buffer[i+1])) { ++(*values_length); } } /* Build a *values_length element array. */ *values = kvmalloc(kvstore, sizeof(**values) * *values_length); if (*values == NULL) { rc = IB_EALLOC; goto exit; } /* For each sibling, fetch it to be merged. */ /* Skip the first line which is always "Siblings:\n". */ cur = index(response.buffer, '\n') + 1; for (size_t i = 0; i < *values_length; ++i) { /* URL containing ?vtag=<ETag> from response. */ char *vtag_url; const char *vtag = "?vtag="; char *eol = index(cur, '\n'); *eol = '\0'; membuffer_t tmp_buf; riak_headers_t tmp_headers; /* Init and Re-init. */ membuffer_init(kvstore, &tmp_buf); riak_headers_init(kvstore, &tmp_headers); vtag_url = kvmalloc( kvstore, strlen(url) + strlen(vtag) + strlen(cur) + 1); if (!vtag_url) { rc = IB_EALLOC; goto exit; } sprintf(vtag_url, "%s%s%s", url, vtag, cur); rc = riak_get(kvstore, riak, vtag_url, &tmp_buf, &tmp_headers); if (rc != IB_OK) { /* Nop - just skip this and decrement the results. */ --(*values_length); cleanup_membuffer(&tmp_buf); kvfree(kvstore, vtag_url); continue; } (*values)[i] = kvmalloc(kvstore, sizeof(*(*values)[i])); if ((*values)[i] == NULL) { /* On failure, free allocated keys. */ for(size_t j = 0; j < i; j++) { ib_kvstore_free_value(kvstore, (*values)[i]); } kvfree(kvstore, vtag_url); rc = IB_EALLOC; goto exit; } /* Convert the retrieved buffer data into a kvstore value. */ rc = http_to_kvstore_value( kvstore, riak, &tmp_buf, &tmp_headers, (*values)[i]); cleanup_membuffer(&tmp_buf); cleanup_riak_headers(&tmp_headers); kvfree(kvstore, vtag_url); cur = eol+1; } } else if (riak_headers.status == 404) { *values_length = 0; *values = NULL; goto exit; rc = IB_ENOENT; } /* Before cleanly existing, set the riak etag and vclock to that of * the representative request, not the individual etag ones. */ if (riak_headers.etag) { ib_kvstore_riak_set_etag(kvstore, riak_headers.etag); } if (riak_headers.x_riak_vclock) { ib_kvstore_riak_set_vclock(kvstore, riak_headers.x_riak_vclock); } exit: cleanup_membuffer(&response); cleanup_riak_headers(&riak_headers); curl_easy_reset(riak->curl); kvfree(kvstore, url); return rc; }