static void encode_layoutstats(struct xdr_stream *xdr, struct nfs42_layoutstat_args *args, struct nfs42_layoutstat_devinfo *devinfo, struct compound_hdr *hdr) { __be32 *p; encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); p = reserve_space(xdr, 8 + 8); p = xdr_encode_hyper(p, devinfo->offset); p = xdr_encode_hyper(p, devinfo->length); encode_nfs4_stateid(xdr, &args->stateid); p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); p = xdr_encode_hyper(p, devinfo->read_count); p = xdr_encode_hyper(p, devinfo->read_bytes); p = xdr_encode_hyper(p, devinfo->write_count); p = xdr_encode_hyper(p, devinfo->write_bytes); p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, NFS4_DEVICEID4_SIZE); /* Encode layoutupdate4 */ *p++ = cpu_to_be32(devinfo->layout_type); if (devinfo->layoutstats_encode != NULL) devinfo->layoutstats_encode(xdr, args, devinfo); else encode_uint32(xdr, 0); }
void serialize_string( char *str, struct buffer *b ) { reserve_space( b, sizeof(char) * strlen(str) ); memcpy( ((char *) b->data) + b->next, str, sizeof(char) * strlen(str) ); b->next += (sizeof(char) * strlen(str)); }
void serialize_short( short x, struct buffer *b ) { //x = htonl(x); reserve_space( b, sizeof(short) ); memcpy( ((char *) b->data) + b->next, &x, sizeof(short) ); b->next += sizeof(short); }
void MemoryStream::Write(PLcdata data, PLuint size) { if (data && (size != 0)) { if (iPos + size > iCapacity) reserve_space(size); memcpy(&pData[iPos], data, size); iPos += size; if (iPos > iLen) iLen = iPos; } }
void MemoryStream::Write(MemoryStream& stream) { if (&stream != this) { PLuint size = stream.Size(); if (iPos + size > iCapacity) reserve_space(size); memcpy(&pData[iPos], stream.Data(), size); iPos += size; if (iPos > iLen) iLen = iPos; } }
static void encode_clone(struct xdr_stream *xdr, struct nfs42_clone_args *args, struct compound_hdr *hdr) { __be32 *p; encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr); encode_nfs4_stateid(xdr, &args->src_stateid); encode_nfs4_stateid(xdr, &args->dst_stateid); p = reserve_space(xdr, 3*8); p = xdr_encode_hyper(p, args->src_offset); p = xdr_encode_hyper(p, args->dst_offset); xdr_encode_hyper(p, args->count); }
PLuint MemoryStream::Set(PLuint pos, PLcdata data, PLuint size) { if (data && (size != 0)) { if (pos + size > iCapacity) reserve_space(size); memcpy(&pData[pos], data, size); if (pos == iPos) { iPos += size; if (iPos > iLen) iLen = iPos; } return size; } return 0; }
/** * make_reservation - reserve journal space. * @c: UBIFS file-system description object * @jhead: journal head * @len: how many bytes to reserve * * This function makes space reservation in journal head @jhead. The function * takes the commit lock and locks the journal head, and the caller has to * unlock the head and finish the reservation with 'finish_reservation()'. * Returns zero in case of success and a negative error code in case of * failure. * * Note, the journal head may be unlocked as soon as the data is written, while * the commit lock has to be released after the data has been added to the * TNC. */ static int make_reservation(struct ubifs_info *c, int jhead, int len) { int err, cmt_retries = 0, nospc_retries = 0; ubifs_assert(len <= c->dark_wm); again: down_read(&c->commit_sem); err = reserve_space(c, jhead, len); if (!err) return 0; up_read(&c->commit_sem); if (err == -ENOSPC) { /* * GC could not make any progress. We should try to commit * once because it could make some dirty space and GC would * make progress, so make the error -EAGAIN so that the below * will commit and re-try. */ if (nospc_retries++ < 2) { dbg_jrn("no space, retry"); err = -EAGAIN; } /* * This means that the budgeting is incorrect. We always have * to be able to write to the media, because all operations are * budgeted. Deletions are not budgeted, though, but we reserve * an extra LEB for them. */ } if (err != -EAGAIN) goto out; /* * -EAGAIN means that the journal is full or too large, or the above * code wants to do one commit. Do this and re-try. */ if (cmt_retries > 128) { /* * This should not happen unless the journal size limitations * are too tough. */ ubifs_err("stuck in space allocation"); err = -ENOSPC; goto out; } else if (cmt_retries > 32) ubifs_warn("too many space allocation re-tries (%d)", cmt_retries); dbg_jrn("-EAGAIN, commit and retry (retried %d times)", cmt_retries); cmt_retries += 1; err = ubifs_run_commit(c); if (err) return err; goto again; out: ubifs_err("cannot reserve %d bytes in jhead %d, error %d", len, jhead, err); if (err == -ENOSPC) { /* This are some budgeting problems, print useful information */ down_write(&c->commit_sem); spin_lock(&c->space_lock); dbg_dump_stack(); dbg_dump_budg(c); spin_unlock(&c->space_lock); dbg_dump_lprops(c); cmt_retries = dbg_check_lprops(c); up_write(&c->commit_sem); } return err; }
static void parse_rx_slots(VCHIQ_STATE_T *state) { VCHIQ_CHANNEL_T *remote = state->remote; VCHIQ_CHANNEL_T *local = state->local; while (remote->ctrl.process != remote->ctrl.insert) { VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)(remote->ctrl.data + (remote->ctrl.process & VCHIQ_CHANNEL_MASK)); VCHIQ_SERVICE_T *service = NULL; unsigned int stride = calc_stride(header->size); int type = VCHIQ_MSG_TYPE(header->fourcc); VCHIQ_TRACE("%d: prs %d (%d,%d)", state->id, type, VCHIQ_MSG_DSTPORT(header->fourcc), VCHIQ_MSG_SRCPORT(header->fourcc)); switch (type) { case VCHIQ_MSG_OPEN: vcos_assert(VCHIQ_MSG_DSTPORT(header->fourcc) == 0); if (vcos_verify(header->size == 4)) { VCHIQ_HEADER_T *reply; unsigned short remoteport = VCHIQ_MSG_SRCPORT(header->fourcc); int target; service = get_listening_service(local, *(int *)header->data); local_mutex_acquire(&local->ctrl.mutex); target = local->ctrl.insert + sizeof(VCHIQ_HEADER_T); reply = reserve_space(local, target); if (!reply) { local_mutex_release(&local->ctrl.mutex); return; /* Bail out */ } if (service && (service->srvstate == VCHIQ_SRVSTATE_LISTENING)) { /* A matching, listening service exists - attempt the OPEN */ VCHIQ_STATUS_T status; vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPEN); /* Proceed as if the connection will be accepted */ status = service->base.callback(VCHIQ_SERVICE_OPENED, NULL, &service->base, NULL); if (status == VCHIQ_SUCCESS) { /* The open was accepted - acknowledge it */ reply->fourcc = VCHIQ_MAKE_MSG(VCHIQ_MSG_OPENACK, service->localport, remoteport); service->remoteport = remoteport; } else { vchiq_set_service_state(service, VCHIQ_SRVSTATE_LISTENING); if (status == VCHIQ_RETRY) return; /* Bail out if not ready */ /* The open was rejected - send a close */ reply->fourcc = VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, remoteport); } } else { /* No matching, available service - send a CLOSE */ reply->fourcc = VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, remoteport); } reply->size = 0; local->ctrl.insert = target; local_mutex_release(&local->ctrl.mutex); remote_event_signal(&remote->trigger); } break; case VCHIQ_MSG_OPENACK: { unsigned int localport = VCHIQ_MSG_DSTPORT(header->fourcc); unsigned int remoteport = VCHIQ_MSG_SRCPORT(header->fourcc); service = &local->services[localport]; if (vcos_verify((localport < VCHIQ_MAX_SERVICES) && (service->srvstate == VCHIQ_SRVSTATE_OPENING))) { service->remoteport = remoteport; vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPEN); local_event_signal(&service->remove_event); } } break; case VCHIQ_MSG_CLOSE: { unsigned int localport = VCHIQ_MSG_DSTPORT(header->fourcc); unsigned int remoteport = VCHIQ_MSG_SRCPORT(header->fourcc); service = &local->services[localport]; vcos_assert(header->size == 0); /* There should be no data */ if (vcos_verify(localport < VCHIQ_MAX_SERVICES)) { switch (service->srvstate) { case VCHIQ_SRVSTATE_OPEN: if (service->remoteport != remoteport) break; /* Return the close */ if (queue_message(state, VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, service->localport, service->remoteport), NULL, 0, 0) == VCHIQ_RETRY) return; /* Bail out if not ready */ vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT); /* Drop through... */ case VCHIQ_SRVSTATE_CLOSESENT: if (service->remoteport != remoteport) break; vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSING); /* Drop through... */ case VCHIQ_SRVSTATE_CLOSING: if (service->remoteport == remoteport) { /* Start the close procedure */ if (vchiq_close_service_internal(service) == VCHIQ_RETRY) return; /* Bail out if not ready */ } break; case VCHIQ_SRVSTATE_OPENING: /* A client is mid-open - this is a rejection, so just fail the open */ vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSEWAIT); local_event_signal(&service->remove_event); break; default: break; } } } break; case VCHIQ_MSG_DATA: { unsigned int localport = VCHIQ_MSG_DSTPORT(header->fourcc); unsigned int remoteport = VCHIQ_MSG_SRCPORT(header->fourcc); service = &local->services[localport]; if (vcos_verify((localport < VCHIQ_MAX_SERVICES) && (service->remoteport == remoteport)) && (service->srvstate == VCHIQ_SRVSTATE_OPEN)) { if (service->base.callback(VCHIQ_MESSAGE_AVAILABLE, header, &service->base, NULL) == VCHIQ_RETRY) return; /* Bail out if not ready */ header = NULL; /* Don't invalidate this message - defer till vchiq_release */ } } break; case VCHIQ_MSG_CONNECT: vcos_event_signal(&state->connect); break; case VCHIQ_MSG_INVALID: default: break; } remote->ctrl.process += stride; if (header != NULL) { /* Invalidate it */ header->fourcc = VCHIQ_FOURCC_INVALID; /* Notify the other end there is some space */ remote_event_signal(&remote->ctrl.remove_event); } } }
static VCHIQ_STATUS_T queue_message(VCHIQ_STATE_T *state, int fourcc, const VCHIQ_ELEMENT_T *elements, int count, int size) { VCHIQ_CHANNEL_T *local; VCHIQ_HEADER_T *header; unsigned int stride; unsigned int pos; VCHIQ_TRACE("%d: qm %d", state->id, VCHIQ_MSG_TYPE(fourcc)); local = state->local; stride = calc_stride(size); vcos_assert(stride < VCHIQ_CHANNEL_SIZE); local_mutex_acquire(&local->ctrl.mutex); pos = local->ctrl.insert; /* Remember for rewind */ if ((local->ctrl.insert & VCHIQ_CHANNEL_MASK) + stride > VCHIQ_CHANNEL_SIZE) { int target = (local->ctrl.insert + VCHIQ_CHANNEL_SIZE) & ~VCHIQ_CHANNEL_MASK; header = (VCHIQ_HEADER_T *)reserve_space(local, target); if (!header) { local_mutex_release(&local->ctrl.mutex); return VCHIQ_RETRY; } header->fourcc = VCHIQ_FOURCC_INVALID; header->size = VCHIQ_CHANNEL_SIZE - sizeof(VCHIQ_HEADER_T) - (local->ctrl.insert & VCHIQ_CHANNEL_MASK); local->ctrl.insert = target; } /* write into slot */ header = (VCHIQ_HEADER_T *)reserve_space(local, local->ctrl.insert + stride); if (!header) { local->ctrl.insert = pos; local_mutex_release(&local->ctrl.mutex); return VCHIQ_RETRY; } header->fourcc = fourcc; header->size = size; VCHIQ_TRACE("%d: qm %d - %x", state->id, VCHIQ_MSG_TYPE(fourcc), header); if (VCHIQ_MSG_TYPE(fourcc) == VCHIQ_MSG_DATA) { int i; for (i = 0, pos = 0; i < (unsigned int)count; pos += elements[i++].size) if (elements[i].size) { if (vchiq_copy_from_user(header->data + pos, elements[i].data, (size_t) elements[i].size) != VCHIQ_SUCCESS) { header->fourcc = VCHIQ_FOURCC_INVALID; local_mutex_release(&local->ctrl.mutex); return VCHIQ_ERROR; } } } else if (size != 0) { vcos_assert((count == 1) && (size == elements[0].size)); memcpy(header->data, elements[0].data, elements[0].size); } local->ctrl.insert += stride; local_mutex_release(&local->ctrl.mutex); remote_event_signal(&state->remote->trigger); return VCHIQ_SUCCESS; }