1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2003 Cluster File Systems, Inc.
6 * This file is part of the Lustre file system, http://www.lustre.org
7 * Lustre is a trademark of Cluster File Systems, Inc.
9 * You may have signed or agreed to another license before downloading
10 * this software. If so, you are bound by the terms and conditions
11 * of that agreement, and the following does not apply to you. See the
12 * LICENSE file included with this distribution for more information.
14 * If you did not agree to a different license, then this copy of Lustre
15 * is open source software; you can redistribute it and/or modify it
16 * under the terms of version 2 of the GNU General Public License as
17 * published by the Free Software Foundation.
19 * In either case, Lustre is distributed in the hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
21 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * license text for more details.
25 #define DEBUG_SUBSYSTEM S_MDC
28 # include <liblustre.h>
30 #include <lustre/lustre_idl.h>
31 #include <lustre_net.h>
32 #include "mdc_internal.h"
35 /* some liblustre hackings here */
41 void mdc_readdir_pack(struct ptlrpc_request *req, int offset, __u64 pg_off,
42 __u32 size, struct ll_fid *fid)
46 b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
47 b->fsuid = current->fsuid;
48 b->fsgid = current->fsgid;
49 b->capability = current->cap_effective;
51 b->size = pg_off; /* !! */
53 b->nlink = size; /* !! */
56 static void mdc_pack_body(struct mds_body *b)
60 b->fsuid = current->fsuid;
61 b->fsgid = current->fsgid;
62 b->capability = current->cap_effective;
65 void mdc_pack_req_body(struct ptlrpc_request *req, int offset,
66 __u64 valid, struct ll_fid *fid, int ea_size, int flags)
68 struct mds_body *b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
73 b->eadatasize = ea_size;
78 /* packing of MDS records */
79 void mdc_create_pack(struct ptlrpc_request *req, int offset,
80 struct mdc_op_data *op_data, const void *data, int datalen,
81 __u32 mode, __u32 uid, __u32 gid, __u32 cap_effective,
84 struct mds_rec_create *rec;
86 rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*rec));
88 rec->cr_opcode = REINT_CREATE;
91 rec->cr_cap = cap_effective;
92 rec->cr_fid = op_data->fid1;
93 memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid));
96 rec->cr_time = op_data->mod_time;
97 rec->cr_suppgid = op_data->suppgids[0];
99 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, op_data->namelen + 1);
100 LOGL0(op_data->name, op_data->namelen, tmp);
103 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2, datalen);
104 memcpy (tmp, data, datalen);
108 static __u32 mds_pack_open_flags(__u32 flags)
111 (flags & (FMODE_READ | FMODE_WRITE |
112 MDS_OPEN_DELAY_CREATE | MDS_OPEN_HAS_EA |
113 MDS_OPEN_HAS_OBJS | MDS_OPEN_OWNEROVERRIDE |
115 ((flags & O_CREAT) ? MDS_OPEN_CREAT : 0) |
116 ((flags & O_EXCL) ? MDS_OPEN_EXCL : 0) |
117 ((flags & O_TRUNC) ? MDS_OPEN_TRUNC : 0) |
118 ((flags & O_APPEND) ? MDS_OPEN_APPEND : 0) |
119 ((flags & O_SYNC) ? MDS_OPEN_SYNC : 0) |
120 ((flags & O_DIRECTORY) ? MDS_OPEN_DIRECTORY : 0) |
121 ((flags & O_JOIN_FILE) ? MDS_OPEN_JOIN_FILE : 0) |
123 ((flags & FMODE_EXEC) ? MDS_FMODE_EXEC : 0) |
128 /* packing of MDS records */
129 void mdc_join_pack(struct ptlrpc_request *req, int offset,
130 struct mdc_op_data *op_data, __u64 head_size)
132 struct mds_rec_join *rec;
134 rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*rec));
135 LASSERT(rec != NULL);
136 rec->jr_fid = op_data->fid2;
137 rec->jr_headsize = head_size;
140 void mdc_open_pack(struct ptlrpc_request *req, int offset,
141 struct mdc_op_data *op_data, __u32 mode, __u64 rdev,
142 __u32 flags, const void *lmm, int lmmlen)
144 struct mds_rec_create *rec;
146 rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*rec));
148 /* XXX do something about time, uid, gid */
149 rec->cr_opcode = REINT_OPEN;
150 rec->cr_fsuid = current->fsuid;
151 rec->cr_fsgid = current->fsgid;
152 rec->cr_cap = current->cap_effective;
153 rec->cr_fid = op_data->fid1;
154 memset(&rec->cr_replayfid, 0, sizeof(rec->cr_replayfid));
156 rec->cr_flags = mds_pack_open_flags(flags);
158 rec->cr_time = op_data->mod_time;
159 rec->cr_suppgid = op_data->suppgids[0];
162 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1,
163 op_data->namelen + 1);
164 LOGL0(op_data->name, op_data->namelen, tmp);
168 rec->cr_flags |= MDS_OPEN_HAS_EA;
170 /*XXX a hack for liblustre to set EA (LL_IOC_LOV_SETSTRIPE) */
171 rec->cr_replayfid = op_data->fid2;
173 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2, lmmlen);
174 memcpy (tmp, lmm, lmmlen);
178 void mdc_setattr_pack(struct ptlrpc_request *req, int offset,
179 struct mdc_op_data *data, struct iattr *iattr, void *ea,
180 int ealen, void *ea2, int ea2len)
182 struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset,
184 rec->sa_opcode = REINT_SETATTR;
185 rec->sa_fsuid = current->fsuid;
186 rec->sa_fsgid = current->fsgid;
187 rec->sa_cap = current->cap_effective;
188 rec->sa_fid = data->fid1;
189 rec->sa_suppgid = -1;
192 rec->sa_valid = iattr->ia_valid;
193 rec->sa_mode = iattr->ia_mode;
194 rec->sa_uid = iattr->ia_uid;
195 rec->sa_gid = iattr->ia_gid;
196 rec->sa_size = iattr->ia_size;
197 rec->sa_atime = LTIME_S(iattr->ia_atime);
198 rec->sa_mtime = LTIME_S(iattr->ia_mtime);
199 rec->sa_ctime = LTIME_S(iattr->ia_ctime);
201 ((struct ll_iattr_struct *)iattr)->ia_attr_flags;
202 if ((iattr->ia_valid & ATTR_GID) && in_group_p(iattr->ia_gid))
203 rec->sa_suppgid = iattr->ia_gid;
205 rec->sa_suppgid = data->suppgids[0];
211 memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 1, ealen), ea, ealen);
216 memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 2, ea2len), ea2, ea2len);
219 void mdc_unlink_pack(struct ptlrpc_request *req, int offset,
220 struct mdc_op_data *data)
222 struct mds_rec_unlink *rec;
225 rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*rec));
226 LASSERT (rec != NULL);
228 rec->ul_opcode = REINT_UNLINK;
229 rec->ul_fsuid = current->fsuid;
230 rec->ul_fsgid = current->fsgid;
231 rec->ul_cap = current->cap_effective;
232 rec->ul_mode = data->create_mode;
233 rec->ul_suppgid = data->suppgids[0];
234 rec->ul_fid1 = data->fid1;
235 rec->ul_fid2 = data->fid2;
236 rec->ul_time = data->mod_time;
238 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, data->namelen + 1);
239 LASSERT (tmp != NULL);
240 LOGL0(data->name, data->namelen, tmp);
243 void mdc_link_pack(struct ptlrpc_request *req, int offset,
244 struct mdc_op_data *data)
246 struct mds_rec_link *rec;
249 rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*rec));
251 rec->lk_opcode = REINT_LINK;
252 rec->lk_fsuid = current->fsuid;
253 rec->lk_fsgid = current->fsgid;
254 rec->lk_cap = current->cap_effective;
255 rec->lk_suppgid1 = data->suppgids[0];
256 rec->lk_suppgid2 = data->suppgids[1];
257 rec->lk_fid1 = data->fid1;
258 rec->lk_fid2 = data->fid2;
259 rec->lk_time = data->mod_time;
261 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, data->namelen + 1);
262 LOGL0(data->name, data->namelen, tmp);
265 void mdc_rename_pack(struct ptlrpc_request *req, int offset,
266 struct mdc_op_data *data,
267 const char *old, int oldlen, const char *new, int newlen)
269 struct mds_rec_rename *rec;
272 rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof (*rec));
274 /* XXX do something about time, uid, gid */
275 rec->rn_opcode = REINT_RENAME;
276 rec->rn_fsuid = current->fsuid;
277 rec->rn_fsgid = current->fsgid;
278 rec->rn_cap = current->cap_effective;
279 rec->rn_suppgid1 = data->suppgids[0];
280 rec->rn_suppgid2 = data->suppgids[1];
281 rec->rn_fid1 = data->fid1;
282 rec->rn_fid2 = data->fid2;
283 rec->rn_time = data->mod_time;
285 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1, oldlen + 1);
286 LOGL0(old, oldlen, tmp);
289 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 2, newlen + 1);
290 LOGL0(new, newlen, tmp);
294 void mdc_getattr_pack(struct ptlrpc_request *req, int offset, int valid,
295 int flags, struct mdc_op_data *data)
298 b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
300 b->fsuid = current->fsuid;
301 b->fsgid = current->fsgid;
302 b->capability = current->cap_effective;
304 b->flags = flags | MDS_BFLAG_EXT_FLAGS;
305 b->suppgid = data->suppgids[0];
307 b->fid1 = data->fid1;
308 b->fid2 = data->fid2;
311 tmp = lustre_msg_buf(req->rq_reqmsg, offset + 1,
313 LOGL0(data->name, data->namelen, tmp);
317 void mdc_close_pack(struct ptlrpc_request *req, int offset, struct obdo *oa,
318 int valid, struct obd_client_handle *och)
320 struct mds_body *body;
322 body = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*body));
324 mdc_pack_fid(&body->fid1, oa->o_id, 0, oa->o_mode);
325 memcpy(&body->handle, &och->och_fh, sizeof(body->handle));
326 if (oa->o_valid & OBD_MD_FLATIME) {
327 body->atime = oa->o_atime;
328 body->valid |= OBD_MD_FLATIME;
330 if (oa->o_valid & OBD_MD_FLMTIME) {
331 body->mtime = oa->o_mtime;
332 body->valid |= OBD_MD_FLMTIME;
334 if (oa->o_valid & OBD_MD_FLCTIME) {
335 body->ctime = oa->o_ctime;
336 body->valid |= OBD_MD_FLCTIME;
338 if (oa->o_valid & OBD_MD_FLSIZE) {
339 body->size = oa->o_size;
340 body->valid |= OBD_MD_FLSIZE;
342 if (oa->o_valid & OBD_MD_FLBLOCKS) {
343 body->blocks = oa->o_blocks;
344 body->valid |= OBD_MD_FLBLOCKS;
346 if (oa->o_valid & OBD_MD_FLFLAGS) {
347 body->flags = oa->o_flags;
348 body->valid |= OBD_MD_FLFLAGS;
352 struct mdc_cache_waiter {
353 struct list_head mcw_entry;
354 wait_queue_head_t mcw_waitq;
357 static int mdc_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw)
361 spin_lock(&cli->cl_loi_list_lock);
362 rc = list_empty(&mcw->mcw_entry);
363 spin_unlock(&cli->cl_loi_list_lock);
367 /* We record requests in flight in cli->cl_r_in_flight here.
368 * There is only one write rpc possible in mdc anyway. If this to change
369 * in the future - the code may need to be revisited. */
370 void mdc_enter_request(struct client_obd *cli)
372 struct mdc_cache_waiter mcw;
373 struct l_wait_info lwi = { 0 };
375 spin_lock(&cli->cl_loi_list_lock);
376 if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
377 list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters);
378 init_waitqueue_head(&mcw.mcw_waitq);
379 spin_unlock(&cli->cl_loi_list_lock);
380 l_wait_event(mcw.mcw_waitq, mdc_req_avail(cli, &mcw), &lwi);
382 cli->cl_r_in_flight++;
383 spin_unlock(&cli->cl_loi_list_lock);
387 void mdc_exit_request(struct client_obd *cli)
389 struct list_head *l, *tmp;
390 struct mdc_cache_waiter *mcw;
392 spin_lock(&cli->cl_loi_list_lock);
393 cli->cl_r_in_flight--;
394 list_for_each_safe(l, tmp, &cli->cl_cache_waiters) {
396 if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
397 /* No free request slots anymore */
401 mcw = list_entry(l, struct mdc_cache_waiter, mcw_entry);
402 list_del_init(&mcw->mcw_entry);
403 cli->cl_r_in_flight++;
404 wake_up(&mcw->mcw_waitq);
406 /* Empty waiting list? Decrease reqs in-flight number */
408 spin_unlock(&cli->cl_loi_list_lock);