1/* 2 * GPL HEADER START 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 only, 8 * as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License version 2 for more details (a copy is included 14 * in the LICENSE file that accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License 17 * version 2 along with this program; If not, see 18 * http://www.gnu.org/licenses/gpl-2.0.htm 19 * 20 * GPL HEADER END 21 */ 22/* 23 * Copyright (c) 2013, Intel Corporation. 24 */ 25/* 26 * lustre/include/lustre_update.h 27 * 28 * Author: Di Wang <di.wang@intel.com> 29 */ 30 31#ifndef _LUSTRE_UPDATE_H 32#define _LUSTRE_UPDATE_H 33 34#define UPDATE_BUFFER_SIZE 8192 35struct update_request { 36 struct dt_device *ur_dt; 37 struct list_head ur_list; /* attached itself to thandle */ 38 int ur_flags; 39 int ur_rc; /* request result */ 40 int ur_batchid; /* Current batch(trans) id */ 41 struct update_buf *ur_buf; /* Holding the update req */ 42}; 43 44static inline unsigned long update_size(struct update *update) 45{ 46 unsigned long size; 47 int i; 48 49 size = cfs_size_round(offsetof(struct update, u_bufs[0])); 50 for (i = 0; i < UPDATE_BUF_COUNT; i++) 51 size += cfs_size_round(update->u_lens[i]); 52 53 return size; 54} 55 56static inline void *update_param_buf(struct update *update, int index, 57 int *size) 58{ 59 int i; 60 void *ptr; 61 62 if (index >= UPDATE_BUF_COUNT) 63 return NULL; 64 65 ptr = (char *)update + cfs_size_round(offsetof(struct update, 66 u_bufs[0])); 67 for (i = 0; i < index; i++) { 68 LASSERT(update->u_lens[i] > 0); 69 ptr += cfs_size_round(update->u_lens[i]); 70 } 71 72 if (size != NULL) 73 *size = update->u_lens[index]; 74 75 return ptr; 76} 77 78static inline unsigned long update_buf_size(struct update_buf *buf) 79{ 80 unsigned long size; 81 int i = 0; 82 83 size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0])); 84 for (i = 0; i < buf->ub_count; i++) { 85 struct update *update; 86 87 update = (struct update *)((char *)buf + size); 88 size += update_size(update); 89 } 90 LASSERT(size <= UPDATE_BUFFER_SIZE); 91 return size; 92} 93 94static inline void *update_buf_get(struct update_buf *buf, int index, int *size) 95{ 96 int count = buf->ub_count; 97 void *ptr; 98 int i = 0; 99 100 if (index >= count) 101 return NULL; 102 103 ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf, 104 ub_bufs[0])); 105 for (i = 0; i < index; i++) 106 ptr += update_size((struct update *)ptr); 107 108 if (size != NULL) 109 *size = update_size((struct update *)ptr); 110 111 return ptr; 112} 113 114static inline void update_init_reply_buf(struct update_reply *reply, int count) 115{ 116 reply->ur_version = UPDATE_REPLY_V1; 117 reply->ur_count = count; 118} 119 120static inline void *update_get_buf_internal(struct update_reply *reply, 121 int index, int *size) 122{ 123 char *ptr; 124 int count = reply->ur_count; 125 int i; 126 127 if (index >= count) 128 return NULL; 129 130 ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply, 131 ur_lens[count])); 132 for (i = 0; i < index; i++) { 133 LASSERT(reply->ur_lens[i] > 0); 134 ptr += cfs_size_round(reply->ur_lens[i]); 135 } 136 137 if (size != NULL) 138 *size = reply->ur_lens[index]; 139 140 return ptr; 141} 142 143static inline void update_insert_reply(struct update_reply *reply, void *data, 144 int data_len, int index, int rc) 145{ 146 char *ptr; 147 148 ptr = update_get_buf_internal(reply, index, NULL); 149 LASSERT(ptr != NULL); 150 151 *(int *)ptr = cpu_to_le32(rc); 152 ptr += sizeof(int); 153 if (data_len > 0) { 154 LASSERT(data != NULL); 155 memcpy(ptr, data, data_len); 156 } 157 reply->ur_lens[index] = data_len + sizeof(int); 158} 159 160static inline int update_get_reply_buf(struct update_reply *reply, void **buf, 161 int index) 162{ 163 char *ptr; 164 int size = 0; 165 int result; 166 167 ptr = update_get_buf_internal(reply, index, &size); 168 result = *(int *)ptr; 169 170 if (result < 0) 171 return result; 172 173 LASSERT((ptr != NULL && size >= sizeof(int))); 174 *buf = ptr + sizeof(int); 175 return size - sizeof(int); 176} 177 178static inline int update_get_reply_result(struct update_reply *reply, 179 void **buf, int index) 180{ 181 void *ptr; 182 int size; 183 184 ptr = update_get_buf_internal(reply, index, &size); 185 LASSERT(ptr != NULL && size > sizeof(int)); 186 return *(int *)ptr; 187} 188 189#endif 190