blob: 84defce0f6231a263b12000c0fa6d202331064e2 [file] [log] [blame]
/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is included
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
* http://www.gnu.org/licenses/gpl-2.0.htm
*
* GPL HEADER END
*/
/*
* Copyright (c) 2013, Intel Corporation.
*/
/*
* lustre/include/lustre_update.h
*
* Author: Di Wang <di.wang@intel.com>
*/
#ifndef _LUSTRE_UPDATE_H
#define _LUSTRE_UPDATE_H
#define UPDATE_BUFFER_SIZE 8192
struct update_request {
struct dt_device *ur_dt;
struct list_head ur_list; /* attached itself to thandle */
int ur_flags;
int ur_rc; /* request result */
int ur_batchid; /* Current batch(trans) id */
struct update_buf *ur_buf; /* Holding the update req */
};
static inline unsigned long update_size(struct update *update)
{
unsigned long size;
int i;
size = cfs_size_round(offsetof(struct update, u_bufs[0]));
for (i = 0; i < UPDATE_BUF_COUNT; i++)
size += cfs_size_round(update->u_lens[i]);
return size;
}
static inline void *update_param_buf(struct update *update, int index,
int *size)
{
int i;
void *ptr;
if (index >= UPDATE_BUF_COUNT)
return NULL;
ptr = (char *)update + cfs_size_round(offsetof(struct update,
u_bufs[0]));
for (i = 0; i < index; i++) {
LASSERT(update->u_lens[i] > 0);
ptr += cfs_size_round(update->u_lens[i]);
}
if (size != NULL)
*size = update->u_lens[index];
return ptr;
}
static inline unsigned long update_buf_size(struct update_buf *buf)
{
unsigned long size;
int i = 0;
size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
for (i = 0; i < buf->ub_count; i++) {
struct update *update;
update = (struct update *)((char *)buf + size);
size += update_size(update);
}
LASSERT(size <= UPDATE_BUFFER_SIZE);
return size;
}
static inline void *update_buf_get(struct update_buf *buf, int index, int *size)
{
int count = buf->ub_count;
void *ptr;
int i = 0;
if (index >= count)
return NULL;
ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf,
ub_bufs[0]));
for (i = 0; i < index; i++)
ptr += update_size((struct update *)ptr);
if (size != NULL)
*size = update_size((struct update *)ptr);
return ptr;
}
static inline void update_init_reply_buf(struct update_reply *reply, int count)
{
reply->ur_version = UPDATE_REPLY_V1;
reply->ur_count = count;
}
static inline void *update_get_buf_internal(struct update_reply *reply,
int index, int *size)
{
char *ptr;
int count = reply->ur_count;
int i;
if (index >= count)
return NULL;
ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply,
ur_lens[count]));
for (i = 0; i < index; i++) {
LASSERT(reply->ur_lens[i] > 0);
ptr += cfs_size_round(reply->ur_lens[i]);
}
if (size != NULL)
*size = reply->ur_lens[index];
return ptr;
}
static inline void update_insert_reply(struct update_reply *reply, void *data,
int data_len, int index, int rc)
{
char *ptr;
ptr = update_get_buf_internal(reply, index, NULL);
LASSERT(ptr != NULL);
*(int *)ptr = cpu_to_le32(rc);
ptr += sizeof(int);
if (data_len > 0) {
LASSERT(data != NULL);
memcpy(ptr, data, data_len);
}
reply->ur_lens[index] = data_len + sizeof(int);
}
static inline int update_get_reply_buf(struct update_reply *reply, void **buf,
int index)
{
char *ptr;
int size = 0;
int result;
ptr = update_get_buf_internal(reply, index, &size);
result = *(int *)ptr;
if (result < 0)
return result;
LASSERT((ptr != NULL && size >= sizeof(int)));
*buf = ptr + sizeof(int);
return size - sizeof(int);
}
static inline int update_get_reply_result(struct update_reply *reply,
void **buf, int index)
{
void *ptr;
int size;
ptr = update_get_buf_internal(reply, index, &size);
LASSERT(ptr != NULL && size > sizeof(int));
return *(int *)ptr;
}
#endif