int set_word_bits(uint32 *word, uint32 start, uint32 end, int bit) { if(end >= WORD_LEN || start > end) { _debug("Index out of range\n"); return OUT_OF_RANGE_ERR; } uint32 len = end - start + 1; unsigned long long setter = 1; // 00010000... setter = (setter << len) - 1; // 00001111... sstter = setter << start; // 00111...100 if(!bit) { setter = ~setter; *word = *word & ((uint32)setter); } else { *word = *word | ((uint32)setter); } return 0; }
std::string InstantMessaging::receive (const std::string& message, const std::string& /*author*/, const std::string& /*id*/) { // We just receive a TEXT message. Before sent it to the recipient, we must assure that the message is complete. // We should use a queue to push these messages in _debug ("New message : %s", message.c_str ()); // TODO Security check // TODO String cleaning // Archive the message // TODO Deactivate this for the momment, this is an extra feature. // this->saveMessage (message, author, id); return message; }
static void loadSaveDatafromVmu(unsigned int id) { char path[16]; unsigned char buf[MAX_VM_SIZE]; int size = MAX_VM_SIZE; int res; const char *load_title = "Select a VMU to load from"; sprintf(path, "%x", id); ZeroMemory(buf, sizeof(buf)); int files = vm_SearchFile(path, &res); if (!files) { return; } if (files == 1 && load_from_vmu(res, path, buf, &size)) { loadSaveData(id, buf); checked_vm = res; return; } for (;;) { if (!vmu_select(&res, load_title)) return; if (!load_from_vmu(res, path, buf, &size)) { _debug("Failed!"); } else { loadSaveData(id, buf); checked_vm = res; return; } } }
/* * give up the callback registered for a vnode on the file server when the * inode is being cleared */ void afs_give_up_callback(struct afs_vnode *vnode) { struct afs_server *server = vnode->server; DECLARE_WAITQUEUE(myself, current); _enter("%d", vnode->cb_promised); _debug("GIVE UP INODE %p", &vnode->vfs_inode); if (!vnode->cb_promised) { _leave(" [not promised]"); return; } ASSERT(server != NULL); spin_lock(&server->cb_lock); if (vnode->cb_promised && afs_breakring_space(server) == 0) { add_wait_queue(&server->cb_break_waitq, &myself); for (;;) { set_current_state(TASK_UNINTERRUPTIBLE); if (!vnode->cb_promised || afs_breakring_space(server) != 0) break; spin_unlock(&server->cb_lock); schedule(); spin_lock(&server->cb_lock); } remove_wait_queue(&server->cb_break_waitq, &myself); __set_current_state(TASK_RUNNING); } /* of course, it's always possible for the server to break this vnode's * callback first... */ if (vnode->cb_promised) afs_do_give_up_callback(server, vnode); spin_unlock(&server->cb_lock); _leave(""); }
// Parses the given PAC file. // // reads the given PAC file and evaluates it in the JavaScript context created // by pacparser_init. int // 0 (=Failure) or 1 (=Success) pacparser_parse_pac_file(const char *pacfile) { char *script = NULL; if ((script = read_file_into_str(pacfile)) == NULL) { print_error("pacparser.c: pacparser_parse_pac: %s: %s: %s\n", "Could not read the pacfile: ", pacfile, strerror(errno)); return 0; } int result = pacparser_parse_pac_string(script); if (script != NULL) free(script); if (_debug()) { if(result) print_error("DEBUG: Parsed the PAC file: %s\n", pacfile); else print_error("DEBUG: Could not parse the PAC file: %s\n", pacfile); } return result; }
/** * fscache_object_lookup_negative - Note negative cookie lookup * @object: Object pointing to cookie to mark * * Note negative lookup, permitting those waiting to read data from an already * existing backing object to continue as there's no data for them to read. */ void fscache_object_lookup_negative(struct fscache_object *object) { struct fscache_cookie *cookie = object->cookie; _enter("{OBJ%x,%s}", object->debug_id, object->state->name); if (!test_and_set_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags)) { fscache_stat(&fscache_n_object_lookups_negative); /* Allow write requests to begin stacking up and read requests to begin * returning ENODATA. */ set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); clear_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); _debug("wake up lookup %p", &cookie->flags); clear_bit_unlock(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags); wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP); } _leave(""); }
/* * finish off updating the recorded status of a file after an operation failed */ static void afs_vnode_status_update_failed(struct afs_vnode *vnode, int ret) { _enter("{%x:%u},%d", vnode->fid.vid, vnode->fid.vnode, ret); spin_lock(&vnode->lock); clear_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); if (ret == -ENOENT) { /* the file was deleted on the server */ _debug("got NOENT from server - marking file deleted"); afs_vnode_deleted_remotely(vnode); } vnode->update_cnt--; ASSERTCMP(vnode->update_cnt, >=, 0); spin_unlock(&vnode->lock); wake_up_all(&vnode->update_waitq); _leave(""); }
/* * allow the fileserver to request callback state (re-)initialisation */ void afs_init_callback_state(struct afs_server *server) { struct afs_vnode *vnode; _enter("{%p}", server); spin_lock(&server->cb_lock); /* kill all the promises on record from this server */ while (!RB_EMPTY_ROOT(&server->cb_promises)) { vnode = rb_entry(server->cb_promises.rb_node, struct afs_vnode, cb_promise); _debug("UNPROMISE { vid=%x:%u uq=%u}", vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); rb_erase(&vnode->cb_promise, &server->cb_promises); vnode->cb_promised = false; } spin_unlock(&server->cb_lock); _leave(""); }
/* * fill in a volume location record, consulting the cache and the VL server * both */ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl, struct key *key) { struct afs_cache_vlocation vldb; int ret; _enter(""); ASSERTCMP(vl->valid, ==, 0); memset(&vldb, 0, sizeof(vldb)); /* see if we have an in-cache copy (will set vl->valid if there is) */ #ifdef AFS_CACHING_SUPPORT cachefs_acquire_cookie(cell->cache, &afs_volume_cache_index_def, vlocation, &vl->cache); #endif if (vl->valid) { /* try to update a known volume in the cell VL databases by * ID as the name may have changed */ _debug("found in cache"); ret = afs_vlocation_update_record(vl, key, &vldb); } else { /* try to look up an unknown volume in the cell VL databases by * name */ ret = afs_vlocation_access_vl_by_name(vl, key, &vldb); if (ret < 0) { printk("kAFS: failed to locate '%s' in cell '%s'\n", vl->vldb.name, vl->cell->name); return ret; } } afs_vlocation_apply_update(vl, &vldb); _leave(" = 0"); return 0; }
static void connect_cb(struct uloop_fd *f, unsigned int events) { if (ufd.eof || ufd.error) { _debug("connection to sysrepo failed"); uloop_timeout_set(&reconnect_timer, 1000); return; } ___debug("connection with sysrepo established"); uloop_fd_delete(&ufd); usfd.stream.string_data = true; usfd.stream.notify_read = read_cb; usfd.stream.notify_state = state_cb; usfd.stream.notify_write = write_cb; ustream_fd_init(&usfd, ufd.fd); usfd.stream.write_error = 0; u_tcp_printf("%07d\n%s\n", strlen(CUSTOM_XML_HELO) + 1, CUSTOM_XML_HELO); u_tcp_printf("%07d\n%s\n", strlen(CUSTOM_XML_SET_DATASTORE) + 1, CUSTOM_XML_SET_DATASTORE); }
/* * get a client UUID */ static int __init afs_get_client_UUID(void) { struct timespec ts; u64 uuidtime; u16 clockseq; int ret; /* read the MAC address of one of the external interfaces and construct * a UUID from it */ ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node)); if (ret < 0) return ret; getnstimeofday(&ts); uuidtime = (u64) ts.tv_sec * 1000 * 1000 * 10; uuidtime += ts.tv_nsec / 100; uuidtime += AFS_UUID_TO_UNIX_TIME; afs_uuid.time_low = uuidtime; afs_uuid.time_mid = uuidtime >> 32; afs_uuid.time_hi_and_version = (uuidtime >> 48) & AFS_UUID_TIMEHI_MASK; afs_uuid.time_hi_and_version |= AFS_UUID_VERSION_TIME; get_random_bytes(&clockseq, 2); afs_uuid.clock_seq_low = clockseq; afs_uuid.clock_seq_hi_and_reserved = (clockseq >> 8) & AFS_UUID_CLOCKHI_MASK; afs_uuid.clock_seq_hi_and_reserved |= AFS_UUID_VARIANT_STD; _debug("AFS UUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", afs_uuid.time_low, afs_uuid.time_mid, afs_uuid.time_hi_and_version, afs_uuid.clock_seq_hi_and_reserved, afs_uuid.clock_seq_low, afs_uuid.node[0], afs_uuid.node[1], afs_uuid.node[2], afs_uuid.node[3], afs_uuid.node[4], afs_uuid.node[5]); return 0; }
std::string SIPAccount::getContactHeader (const std::string& address, const std::string& port) const { char contact[PJSIP_MAX_URL_SIZE]; const char * beginquote, * endquote; std::string scheme; std::string transport; // if IPV6, should be set to [] beginquote = endquote = ""; // UDP does not require the transport specification if (_transportType == PJSIP_TRANSPORT_TLS) { scheme = "sips:"; transport = ";transport=" + std::string (pjsip_transport_get_type_name (_transportType)); } else { scheme = "sip:"; transport = ""; } _debug ("Display Name: %s", _displayName.c_str()); int len = pj_ansi_snprintf (contact, PJSIP_MAX_URL_SIZE, "%s%s<%s%s%s%s%s%s:%d%s>", _displayName.c_str(), (_displayName.empty() ? "" : " "), scheme.c_str(), _username.c_str(), (_username.empty() ? "":"@"), beginquote, address.c_str(), endquote, atoi (port.c_str()), transport.c_str()); return std::string (contact, len); }
/* * clear an AFS inode */ void afs_evict_inode(struct inode *inode) { struct afs_vnode *vnode; vnode = AFS_FS_I(inode); _enter("{%x:%u.%d}", vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); _debug("CLEAR INODE %p", inode); ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode); truncate_inode_pages_final(&inode->i_data); clear_inode(inode); if (vnode->cb_interest) { afs_put_cb_interest(afs_i2net(inode), vnode->cb_interest); vnode->cb_interest = NULL; } while (!list_empty(&vnode->wb_keys)) { struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next, struct afs_wb_key, vnode_link); list_del(&wbk->vnode_link); afs_put_wb_key(wbk); } #ifdef CONFIG_AFS_FSCACHE fscache_relinquish_cookie(vnode->cache, 0); vnode->cache = NULL; #endif afs_put_permits(vnode->permit_cache); _leave(""); }
/* * allocate a call with flat request and reply buffers */ struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, size_t request_size, size_t reply_size) { struct afs_call *call; call = kzalloc(sizeof(*call), GFP_NOFS); if (!call) goto nomem_call; _debug("CALL %p{%s} [%d]", call, type->name, atomic_read(&afs_outstanding_calls)); atomic_inc(&afs_outstanding_calls); call->type = type; call->request_size = request_size; call->reply_max = reply_size; if (request_size) { call->request = kmalloc(request_size, GFP_NOFS); if (!call->request) goto nomem_free; } if (reply_size) { call->buffer = kmalloc(reply_size, GFP_NOFS); if (!call->buffer) goto nomem_free; } init_waitqueue_head(&call->waitq); skb_queue_head_init(&call->rx_queue); return call; nomem_free: afs_free_call(call); nomem_call: return NULL; }
static int saveSaveData(unsigned int id, unsigned char *buf) { Header *List; SaveHeader *head = (SaveHeader *)buf; DataHeader *data = (DataHeader*)((char*)buf + sizeof(SaveHeader)); unsigned int files = 0; for (List=Head; List; List=List->next) { if (id == List->id) { unsigned int allocsize = List->size + sizeof(DataHeader); DataHeader *tmp = (DataHeader*)((char*)data + allocsize); data->pos = List->pos; data->size = List->size; unsigned char *s = (unsigned char *)(List + 1); unsigned char *d = (unsigned char *)(data + 1); unsigned int n = List->size; while (n--) *d++ = *s++; data = tmp; ++files; } } if (files) { head->id = id; head->files = files; } _debug("\n%s (0x%x)\n",__func__, files); return files; }
/* * fetch file data from the volume * - TODO implement caching and server failover */ int afs_vnode_fetch_data(struct afs_vnode *vnode, struct afs_rxfs_fetch_descriptor *desc) { struct afs_server *server; int ret; _enter("%s,{%u,%u,%u}", vnode->volume->vlocation->vldb.name, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); /* this op will fetch the status */ spin_lock(&vnode->lock); vnode->update_cnt++; spin_unlock(&vnode->lock); /* merge in AFS status fetches and clear outstanding callback on this * vnode */ do { /* pick a server to query */ ret = afs_volume_pick_fileserver(vnode->volume, &server); if (ret < 0) return ret; _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr)); ret = afs_rxfs_fetch_file_data(server, vnode, desc, NULL); } while (!afs_volume_release_fileserver(vnode->volume, server, ret)); /* adjust the flags */ afs_vnode_finalise_status_update(vnode, server, ret); _leave(" = %d", ret); return ret; } /* end afs_vnode_fetch_data() */
/* * Allocate a key to use as a placeholder for anonymous user security. */ static int afs_alloc_anon_key(struct afs_cell *cell) { struct key *key; char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp; /* Create a key to represent an anonymous user. */ memcpy(keyname, "afs@", 4); dp = keyname + 4; cp = cell->name; do { *dp++ = tolower(*cp); } while (*cp++); key = rxrpc_get_null_key(keyname); if (IS_ERR(key)) return PTR_ERR(key); cell->anonymous_key = key; _debug("anon key %p{%x}", cell->anonymous_key, key_serial(cell->anonymous_key)); return 0; }
/* * actually break a callback */ static void afs_break_callback(struct afs_server *server, struct afs_vnode *vnode) { _enter(""); set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); if (vnode->cb_promised) { spin_lock(&vnode->lock); _debug("break callback"); spin_lock(&server->cb_lock); if (vnode->cb_promised) { rb_erase(&vnode->cb_promise, &server->cb_promises); vnode->cb_promised = false; } spin_unlock(&server->cb_lock); queue_work(afs_callback_update_worker, &vnode->cb_broken_work); spin_unlock(&vnode->lock); } }
/* * allow the fileserver to break callback promises */ void afs_break_callbacks(struct afs_server *server, size_t count, struct afs_callback callbacks[]) { _enter("%p,%zu,", server, count); ASSERT(server != NULL); ASSERTCMP(count, <=, AFSCBMAX); for (; count > 0; callbacks++, count--) { _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", callbacks->fid.vid, callbacks->fid.vnode, callbacks->fid.unique, callbacks->version, callbacks->expiry, callbacks->type ); afs_break_one_callback(server, &callbacks->fid); } _leave(""); return; }
/* * Pass back notification of a new call. The call is added to the * to-be-accepted list. This means that the next call to be accepted might not * be the last call seen awaiting acceptance, but unless we leave this on the * front of the queue and block all other messages until someone gives us a * user_ID for it, there's not a lot we can do. */ static int rxrpc_recvmsg_new_call(struct rxrpc_sock *rx, struct rxrpc_call *call, struct msghdr *msg, int flags) { int tmp = 0, ret; ret = put_cmsg(msg, SOL_RXRPC, RXRPC_NEW_CALL, 0, &tmp); if (ret == 0 && !(flags & MSG_PEEK)) { _debug("to be accepted"); write_lock_bh(&rx->recvmsg_lock); list_del_init(&call->recvmsg_link); write_unlock_bh(&rx->recvmsg_lock); rxrpc_get_call(call, rxrpc_call_got); write_lock(&rx->call_lock); list_add_tail(&call->accept_link, &rx->to_be_accepted); write_unlock(&rx->call_lock); } trace_rxrpc_recvmsg(call, rxrpc_recvmsg_to_be_accepted, 1, 0, 0, ret); return ret; }
/* * queue a packet for recvmsg to pass to userspace * - the caller must hold a lock on call->lock * - must not be called with interrupts disabled (sk_filter() disables BH's) * - eats the packet whether successful or not * - there must be just one reference to the packet, which the caller passes to * this function */ int rxrpc_queue_rcv_skb(struct rxrpc_call *call, struct sk_buff *skb, bool force, bool terminal) { struct rxrpc_skb_priv *sp; struct rxrpc_sock *rx = call->socket; struct sock *sk; int ret; _enter(",,%d,%d", force, terminal); ASSERT(!irqs_disabled()); sp = rxrpc_skb(skb); ASSERTCMP(sp->call, ==, call); /* if we've already posted the terminal message for a call, then we * don't post any more */ if (test_bit(RXRPC_CALL_TERMINAL_MSG, &call->flags)) { _debug("already terminated"); ASSERTCMP(call->state, >=, RXRPC_CALL_COMPLETE); rxrpc_free_skb(skb); return 0; }
/* * kill all the pages in the given range */ static void afs_kill_pages(struct address_space *mapping, pgoff_t first, pgoff_t last) { struct afs_vnode *vnode = AFS_FS_I(mapping->host); struct pagevec pv; unsigned count, loop; _enter("{%x:%u},%lx-%lx", vnode->fid.vid, vnode->fid.vnode, first, last); pagevec_init(&pv); do { _debug("kill %lx-%lx", first, last); count = last - first + 1; if (count > PAGEVEC_SIZE) count = PAGEVEC_SIZE; pv.nr = find_get_pages_contig(mapping, first, count, pv.pages); ASSERTCMP(pv.nr, ==, count); for (loop = 0; loop < count; loop++) { struct page *page = pv.pages[loop]; ClearPageUptodate(page); SetPageError(page); end_page_writeback(page); if (page->index >= first) first = page->index + 1; lock_page(page); generic_error_remove_page(mapping, page); } __pagevec_release(&pv); } while (first <= last); _leave(""); }
struct key *afs_request_key(struct afs_cell *cell) { struct key *key; _enter("{%x}", key_serial(cell->anonymous_key)); _debug("key %s", cell->anonymous_key->description); key = request_key(&key_type_rxrpc, cell->anonymous_key->description, NULL); if (IS_ERR(key)) { if (PTR_ERR(key) != -ENOKEY) { _leave(" = %ld", PTR_ERR(key)); return key; } _leave(" = {%x} [anon]", key_serial(cell->anonymous_key)); return key_get(cell->anonymous_key); } else { _leave(" = {%x} [auth]", key_serial(key)); return key; } }
void AudioRecord::recData (SFLDataFormat* buffer, int nSamples) { if (recordingEnabled_) { if (fp == 0) { _debug ("AudioRecord: Can't record data, a file has not yet been opened!"); return; } if (sndFormat_ == INT16) { // TODO change INT16 to SINT16 if (fwrite (buffer, sizeof (SFLDataFormat), nSamples, fp) != (unsigned int) nSamples) _warn ("AudioRecord: Could not record data! "); else { fflush (fp); byteCounter_ += (unsigned long) (nSamples*sizeof (SFLDataFormat)); } } } return; }
void KernelStart(char* cmd_args[], unsigned int pmem_size, UserContext* uctxt ) { TracePrintf(0, "Start the kernel\n"); // Initialize vector table mapping from interrupt/exception/trap to a handler fun init_trap_vector(); // REG_VECTOR_BASE point to vector table WriteRegister(REG_VECTOR_BASE, (uint32)interrupt_vector); // Memory management, linked list of frames of free memory available_frames = list_init(); PAGE_SIZE = GET_PAGE_NUMBER(pmem_size); init_kernel_page_table(); user_page_table = init_user_page_table(); if(!kernel_page_table || !user_page_table) { _debug("Cannot allocate memory for page tables.\n"); return; } // Build page tables using REG_PTBR0/1 REG_PTLR0/1 WriteRegister(REG_PTBR0, (uint32)kernel_page_table); WriteRegister(REG_PTLR0, GET_PAGE_NUMBER(VMEM_0_SIZE)); WriteRegister(REG_PTBR1, (uint32)user_page_table); WriteRegister(REG_PTLR1, GET_PAGE_NUMBER(VMEM_1_SIZE)); // Enable virtual memroy WriteRegister(REG_VM_ENABLE, _ENABLE); // Create idle proc Cooking(user_page_table, uctxt); // Load init process (in checkpoint 3) TracePrintf(0, "Leave the kernel\n"); return; }
/* * Redirty all the pages in a given range. */ static void afs_redirty_pages(struct writeback_control *wbc, struct address_space *mapping, pgoff_t first, pgoff_t last) { struct afs_vnode *vnode = AFS_FS_I(mapping->host); struct pagevec pv; unsigned count, loop; _enter("{%x:%u},%lx-%lx", vnode->fid.vid, vnode->fid.vnode, first, last); pagevec_init(&pv); do { _debug("redirty %lx-%lx", first, last); count = last - first + 1; if (count > PAGEVEC_SIZE) count = PAGEVEC_SIZE; pv.nr = find_get_pages_contig(mapping, first, count, pv.pages); ASSERTCMP(pv.nr, ==, count); for (loop = 0; loop < count; loop++) { struct page *page = pv.pages[loop]; redirty_page_for_writepage(wbc, page); end_page_writeback(page); if (page->index >= first) first = page->index + 1; } __pagevec_release(&pv); } while (first <= last); _leave(""); }
int rxrpc_queue_rcv_skb(struct rxrpc_call *call, struct sk_buff *skb, bool force, bool terminal) { struct rxrpc_skb_priv *sp; struct rxrpc_sock *rx = call->socket; struct sock *sk; int skb_len, ret; _enter(",,%d,%d", force, terminal); ASSERT(!irqs_disabled()); sp = rxrpc_skb(skb); ASSERTCMP(sp->call, ==, call); if (test_bit(RXRPC_CALL_TERMINAL_MSG, &call->flags)) { _debug("already terminated"); ASSERTCMP(call->state, >=, RXRPC_CALL_COMPLETE); skb->destructor = NULL; sp->call = NULL; rxrpc_put_call(call); rxrpc_free_skb(skb); return 0; }
void TrafficLight_carPass(int sig) { switch (sig) { case 1: //사람 검출 _carYellow(3000); //3s _carRed(4000, 10, 100, 100); //5s break; case 0: //red green 의 연결 신호 _carGreen(5000); //5s break; case 8: _ledOn(5000); //5s break; case 9: _debug(5); //깜빡임 반복횟수 break; default: break; }//switch }
void vTrapInstallHandlers( void ) { if( 0 == _install_trap_handler ( portMMU_TRAP, vMMUTrap ) ) { _debug(); } if( 0 == _install_trap_handler ( portIPT_TRAP, vInternalProtectionTrap ) ) { _debug(); } if( 0 == _install_trap_handler ( portIE_TRAP, vInstructionErrorTrap ) ) { _debug(); } if( 0 == _install_trap_handler ( portCM_TRAP, vContextManagementTrap ) ) { _debug(); } if( 0 == _install_trap_handler ( portSBP_TRAP, vSystemBusAndPeripheralsTrap ) ) { _debug(); } if( 0 == _install_trap_handler ( portASSERT_TRAP, vAssertionTrap ) ) { _debug(); } if( 0 == _install_trap_handler ( portNMI_TRAP, vNonMaskableInterruptTrap ) ) { _debug(); } }
/* * deliver request data to a CB.CallBack call */ static int afs_deliver_cb_callback(struct afs_call *call, struct sk_buff *skb, bool last) { struct afs_callback *cb; struct afs_server *server; struct in_addr addr; __be32 *bp; u32 tmp; int ret, loop; _enter("{%u},{%u},%d", call->unmarshall, skb->len, last); switch (call->unmarshall) { case 0: call->offset = 0; call->unmarshall++; /* extract the FID array and its count in two steps */ case 1: _debug("extract FID count"); ret = afs_extract_data(call, skb, last, &call->tmp, 4); switch (ret) { case 0: break; case -EAGAIN: return 0; default: return ret; } call->count = ntohl(call->tmp); _debug("FID count: %u", call->count); if (call->count > AFSCBMAX) return -EBADMSG; call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); if (!call->buffer) return -ENOMEM; call->offset = 0; call->unmarshall++; case 2: _debug("extract FID array"); ret = afs_extract_data(call, skb, last, call->buffer, call->count * 3 * 4); switch (ret) { case 0: break; case -EAGAIN: return 0; default: return ret; } _debug("unmarshall FID array"); call->request = kcalloc(call->count, sizeof(struct afs_callback), GFP_KERNEL); if (!call->request) return -ENOMEM; cb = call->request; bp = call->buffer; for (loop = call->count; loop > 0; loop--, cb++) { cb->fid.vid = ntohl(*bp++); cb->fid.vnode = ntohl(*bp++); cb->fid.unique = ntohl(*bp++); cb->type = AFSCM_CB_UNTYPED; } call->offset = 0; call->unmarshall++; /* extract the callback array and its count in two steps */ case 3: _debug("extract CB count"); ret = afs_extract_data(call, skb, last, &call->tmp, 4); switch (ret) { case 0: break; case -EAGAIN: return 0; default: return ret; } tmp = ntohl(call->tmp); _debug("CB count: %u", tmp); if (tmp != call->count && tmp != 0) return -EBADMSG; call->offset = 0; call->unmarshall++; if (tmp == 0) goto empty_cb_array; case 4: _debug("extract CB array"); ret = afs_extract_data(call, skb, last, call->request, call->count * 3 * 4); switch (ret) { case 0: break; case -EAGAIN: return 0; default: return ret; } _debug("unmarshall CB array"); cb = call->request; bp = call->buffer; for (loop = call->count; loop > 0; loop--, cb++) { cb->version = ntohl(*bp++); cb->expiry = ntohl(*bp++); cb->type = ntohl(*bp++); } empty_cb_array: call->offset = 0; call->unmarshall++; case 5: _debug("trailer"); if (skb->len != 0) return -EBADMSG; break; } if (!last) return 0; call->state = AFS_CALL_REPLYING; /* we'll need the file server record as that tells us which set of * vnodes to operate upon */ memcpy(&addr, &ip_hdr(skb)->saddr, 4); server = afs_find_server(&addr); if (!server) return -ENOTCONN; call->server = server; INIT_WORK(&call->work, SRXAFSCB_CallBack); schedule_work(&call->work); return 0; }