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 *th,
39 struct dt_device *dt_dev)
41 struct update_request *update;
43 list_for_each_entry(update, &th->th_remote_update_list, ur_list) {
44 if (update->ur_dt == dt_dev)
50 EXPORT_SYMBOL(out_find_update);
52 void out_destroy_update_req(struct update_request *update)
57 LASSERT(list_empty(&update->ur_cb_items));
59 list_del(&update->ur_list);
60 if (update->ur_buf != NULL)
61 OBD_FREE_LARGE(update->ur_buf, UPDATE_BUFFER_SIZE);
65 EXPORT_SYMBOL(out_destroy_update_req);
67 struct update_request *out_create_update_req(struct dt_device *dt)
69 struct update_request *update;
71 OBD_ALLOC_PTR(update);
73 return ERR_PTR(-ENOMEM);
75 OBD_ALLOC_LARGE(update->ur_buf, UPDATE_BUFFER_SIZE);
76 if (update->ur_buf == NULL) {
79 return ERR_PTR(-ENOMEM);
82 INIT_LIST_HEAD(&update->ur_list);
84 update->ur_buf->ub_magic = UPDATE_BUFFER_MAGIC;
85 update->ur_buf->ub_count = 0;
86 INIT_LIST_HEAD(&update->ur_cb_items);
90 EXPORT_SYMBOL(out_create_update_req);
93 * Find one loc in th_dev/dev_obj_update for the update,
94 * Because only one thread can access this thandle, no need
97 struct update_request *out_find_create_update_loc(struct thandle *th,
100 struct dt_device *dt_dev = lu2dt_dev(dt->do_lu.lo_dev);
101 struct update_request *update;
104 update = out_find_update(th, dt_dev);
108 update = out_create_update_req(dt_dev);
112 list_add_tail(&update->ur_list, &th->th_remote_update_list);
116 EXPORT_SYMBOL(out_find_create_update_loc);
118 int out_prep_update_req(const struct lu_env *env, struct obd_import *imp,
119 const struct update_buf *ubuf, int ubuf_len,
120 struct ptlrpc_request **reqp)
122 struct ptlrpc_request *req;
123 struct update_buf *tmp;
127 req = ptlrpc_request_alloc(imp, &RQF_UPDATE_OBJ);
131 req_capsule_set_size(&req->rq_pill, &RMF_UPDATE, RCL_CLIENT,
134 rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, UPDATE_OBJ);
136 ptlrpc_req_finished(req);
140 req_capsule_set_size(&req->rq_pill, &RMF_UPDATE_REPLY, RCL_SERVER,
143 tmp = req_capsule_client_get(&req->rq_pill, &RMF_UPDATE);
144 memcpy(tmp, ubuf, ubuf_len);
145 ptlrpc_request_set_replen(req);
146 req->rq_request_portal = OUT_PORTAL;
147 req->rq_reply_portal = OSC_REPLY_PORTAL;
152 EXPORT_SYMBOL(out_prep_update_req);
154 int out_remote_sync(const struct lu_env *env, struct obd_import *imp,
155 struct update_request *update,
156 struct ptlrpc_request **reqp)
158 struct ptlrpc_request *req = NULL;
162 rc = out_prep_update_req(env, imp, update->ur_buf,
163 UPDATE_BUFFER_SIZE, &req);
167 /* Note: some dt index api might return non-zero result here, like
168 * osd_index_ea_lookup, so we should only check rc < 0 here */
169 rc = ptlrpc_queue_wait(req);
171 ptlrpc_req_finished(req);
180 ptlrpc_req_finished(req);
185 EXPORT_SYMBOL(out_remote_sync);
187 int out_insert_update(const struct lu_env *env, struct update_request *update,
188 int op, const struct lu_fid *fid, int count,
189 int *lens, const char **bufs)
191 struct update_buf *ubuf = update->ur_buf;
192 struct update *obj_update;
198 obj_update = (struct update *)((char *)ubuf +
199 cfs_size_round(update_buf_size(ubuf)));
201 /* Check update size to make sure it can fit into the buffer */
202 update_length = cfs_size_round(offsetof(struct update,
204 for (i = 0; i < count; i++)
205 update_length += cfs_size_round(lens[i]);
207 if (cfs_size_round(update_buf_size(ubuf)) + update_length >
208 UPDATE_BUFFER_SIZE || ubuf->ub_count >= UPDATE_MAX_OPS)
211 if (count > UPDATE_BUF_COUNT)
214 /* fill the update into the update buffer */
215 fid_cpu_to_le(&obj_update->u_fid, fid);
216 obj_update->u_type = cpu_to_le32(op);
217 obj_update->u_batchid = update->ur_batchid;
218 for (i = 0; i < count; i++)
219 obj_update->u_lens[i] = cpu_to_le32(lens[i]);
221 ptr = (char *)obj_update +
222 cfs_size_round(offsetof(struct update, u_bufs[0]));
223 for (i = 0; i < count; i++)
224 LOGL(bufs[i], lens[i], ptr);
228 CDEBUG(D_INFO, "%s: %p "DFID" idx %d: op %d params %d:%lu\n",
229 update->ur_dt->dd_lu_dev.ld_obd->obd_name, ubuf, PFID(fid),
230 ubuf->ub_count, op, count, update_buf_size(ubuf));
234 EXPORT_SYMBOL(out_insert_update);