4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.html
23 * Copyright (c) 2013, Intel Corporation.
26 * lustre/target/out_lib.c
28 * Author: Di Wang <di.wang@intel.com>
29 * Author: Fan, Yong <fan.yong@intel.com>
32 #define DEBUG_SUBSYSTEM S_CLASS
34 #include <lu_target.h>
35 #include <lustre_update.h>
38 struct update_request *out_find_update(struct thandle_update *tu,
39 struct dt_device *dt_dev)
41 struct update_request *update;
44 list_for_each_entry(update, &tu->tu_remote_update_list, ur_list) {
45 if (update->ur_dt == dt_dev)
51 EXPORT_SYMBOL(out_find_update);
53 void out_destroy_update_req(struct update_request *update)
58 LASSERT(list_empty(&update->ur_cb_items));
60 list_del(&update->ur_list);
61 if (update->ur_buf != NULL)
62 OBD_FREE_LARGE(update->ur_buf, UPDATE_BUFFER_SIZE);
66 EXPORT_SYMBOL(out_destroy_update_req);
68 struct update_request *out_create_update_req(struct dt_device *dt)
70 struct update_request *update;
72 OBD_ALLOC_PTR(update);
74 return ERR_PTR(-ENOMEM);
76 OBD_ALLOC_LARGE(update->ur_buf, UPDATE_BUFFER_SIZE);
77 if (update->ur_buf == NULL) {
80 return ERR_PTR(-ENOMEM);
83 INIT_LIST_HEAD(&update->ur_list);
85 update->ur_buf->ub_magic = UPDATE_BUFFER_MAGIC;
86 update->ur_buf->ub_count = 0;
87 INIT_LIST_HEAD(&update->ur_cb_items);
91 EXPORT_SYMBOL(out_create_update_req);
94 * Find or create one loc in th_dev/dev_obj_update for the update,
95 * Because only one thread can access this thandle, no need
98 struct update_request *out_find_create_update_loc(struct thandle *th,
101 struct dt_device *dt_dev = lu2dt_dev(dt->do_lu.lo_dev);
102 struct thandle_update *tu = th->th_update;
103 struct update_request *update;
109 RETURN(ERR_PTR(-ENOMEM));
111 INIT_LIST_HEAD(&tu->tu_remote_update_list);
112 tu->tu_sent_after_local_trans = 0;
116 update = out_find_update(tu, dt_dev);
120 update = out_create_update_req(dt_dev);
124 list_add_tail(&update->ur_list, &tu->tu_remote_update_list);
126 if (!tu->tu_only_remote_trans)
131 EXPORT_SYMBOL(out_find_create_update_loc);
133 int out_prep_update_req(const struct lu_env *env, struct obd_import *imp,
134 const struct update_buf *ubuf, int ubuf_len,
135 struct ptlrpc_request **reqp)
137 struct ptlrpc_request *req;
138 struct update_buf *tmp;
142 req = ptlrpc_request_alloc(imp, &RQF_UPDATE_OBJ);
146 req_capsule_set_size(&req->rq_pill, &RMF_UPDATE, RCL_CLIENT,
149 rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, UPDATE_OBJ);
151 ptlrpc_req_finished(req);
155 req_capsule_set_size(&req->rq_pill, &RMF_UPDATE_REPLY, RCL_SERVER,
158 tmp = req_capsule_client_get(&req->rq_pill, &RMF_UPDATE);
159 memcpy(tmp, ubuf, ubuf_len);
160 ptlrpc_request_set_replen(req);
161 req->rq_request_portal = OUT_PORTAL;
162 req->rq_reply_portal = OSC_REPLY_PORTAL;
167 EXPORT_SYMBOL(out_prep_update_req);
169 int out_remote_sync(const struct lu_env *env, struct obd_import *imp,
170 struct update_request *update,
171 struct ptlrpc_request **reqp)
173 struct ptlrpc_request *req = NULL;
177 rc = out_prep_update_req(env, imp, update->ur_buf,
178 UPDATE_BUFFER_SIZE, &req);
182 /* Note: some dt index api might return non-zero result here, like
183 * osd_index_ea_lookup, so we should only check rc < 0 here */
184 rc = ptlrpc_queue_wait(req);
186 ptlrpc_req_finished(req);
195 ptlrpc_req_finished(req);
200 EXPORT_SYMBOL(out_remote_sync);
202 int out_insert_update(const struct lu_env *env, struct update_request *update,
203 int op, const struct lu_fid *fid, int count,
204 int *lens, const char **bufs)
206 struct update_buf *ubuf = update->ur_buf;
207 struct update *obj_update;
213 obj_update = (struct update *)((char *)ubuf + update_buf_size(ubuf));
215 /* Check update size to make sure it can fit into the buffer */
216 update_length = cfs_size_round(offsetof(struct update,
218 for (i = 0; i < count; i++)
219 update_length += cfs_size_round(lens[i]);
221 if (cfs_size_round(update_buf_size(ubuf)) + update_length >
222 UPDATE_BUFFER_SIZE || ubuf->ub_count >= UPDATE_MAX_OPS)
225 if (count > UPDATE_BUF_COUNT)
228 /* fill the update into the update buffer */
229 fid_cpu_to_le(&obj_update->u_fid, fid);
230 obj_update->u_type = cpu_to_le32(op);
231 obj_update->u_batchid = update->ur_batchid;
232 for (i = 0; i < count; i++)
233 obj_update->u_lens[i] = cpu_to_le32(lens[i]);
235 ptr = (char *)obj_update +
236 cfs_size_round(offsetof(struct update, u_bufs[0]));
237 for (i = 0; i < count; i++)
238 LOGL(bufs[i], lens[i], ptr);
242 CDEBUG(D_INFO, "%s: %p "DFID" idx %d: op %d params %d:%lu\n",
243 update->ur_dt->dd_lu_dev.ld_obd->obd_name, ubuf, PFID(fid),
244 ubuf->ub_count, op, count, update_buf_size(ubuf));
248 EXPORT_SYMBOL(out_insert_update);