1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001-2003 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.sf.net/projects/lustre/
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #define DEBUG_SUBSYSTEM S_CMOBD
24 #include <linux/config.h>
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/obd_class.h>
28 #include <linux/lustre_net.h>
29 #include <linux/lustre_mds.h>
30 #include <linux/lustre_smfs.h>
32 #include "cm_internal.h"
34 /* converts mds_rec_setattr to struct iattr. */
35 static inline void cmobd_rec2iattr(struct mds_rec_setattr *rec,
38 iattr->ia_uid = rec->sa_uid;
39 iattr->ia_gid = rec->sa_gid;
40 iattr->ia_mode = rec->sa_mode;
41 iattr->ia_size = rec->sa_size;
42 iattr->ia_valid = rec->sa_valid;
43 LTIME_S(iattr->ia_atime) = rec->sa_atime;
44 LTIME_S(iattr->ia_mtime) = rec->sa_mtime;
45 LTIME_S(iattr->ia_ctime) = rec->sa_ctime;
46 iattr->ia_attr_flags = rec->sa_attr_flags;
50 cmobd_prepare_mdc_data(struct mdc_op_data *data, struct lustre_id *id1,
51 struct lustre_id *id2, const char *name,
52 int namelen, __u32 mode)
57 memset(data, 0, sizeof(*data));
63 memset(&data->id2, 0, sizeof(data->id2));
67 data->namelen = namelen;
68 data->create_mode = mode;
69 data->mod_time = LTIME_S(CURRENT_TIME);
72 /* If mdc_setattr() is called with an 'iattr', then it is a normal RPC that
73 * should take the normal semaphore and go to the normal portal.
75 * If it is called with iattr->ia_valid & ATTR_FROM_OPEN, then it is a magic
76 * open-path setattr that should take the setattr semaphore and go to the
78 static int cmobd_reint_setattr(struct obd_device *obd, void *record)
80 struct cm_obd *cmobd = &obd->u.cm;
81 struct ptlrpc_request *req = NULL;
82 struct mds_kml_pack_info *mkpi;
83 struct mds_rec_setattr *rec;
84 struct mdc_op_data *op_data;
85 struct lustre_msg *msg;
92 mkpi = (struct mds_kml_pack_info *)record;
93 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
95 rec = lustre_msg_buf(msg, 0, 0);
99 /* converting setattr rec to struct iattr. */
100 cmobd_rec2iattr(rec, &iattr);
102 /* FIXME-UMKA: here should be handling of setattr() from open. Bug
103 * #249. Will be fixed later. */
105 /* converting localstore cookie to remote lustre_id. */
106 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->sa_id,
107 &rec->sa_id, sizeof(rec->sa_id));
109 CERROR("Can't read master MDS store cookie "
110 "from local inode EA, err = %d.\n", rc);
114 OBD_ALLOC(op_data, sizeof(*op_data));
117 cmobd_prepare_mdc_data(op_data, &rec->sa_id, NULL,
120 /* handling possible EAs. */
121 ea1 = lustre_msg_buf(msg, 1, 0);
122 ea1len = ea1 ? msg->buflens[1] : 0;
124 ea2 = lustre_msg_buf(msg, 2, 0);
125 ea2len = ea2 ? msg->buflens[2] : 0;
127 rc = md_setattr(cmobd->master_exp, op_data, &iattr,
128 ea1, ea1len, ea2, ea2len, &req);
129 OBD_FREE(op_data, sizeof(*op_data));
132 ptlrpc_req_finished(req);
136 static int cmobd_reint_create(struct obd_device *obd, void *record)
138 struct cm_obd *cmobd = &obd->u.cm;
139 struct ptlrpc_request *req = NULL;
140 struct mds_kml_pack_info *mkpi;
141 int rc = 0, namelen, datalen;
142 struct mds_rec_create *rec;
143 struct mdc_op_data *op_data;
144 struct lustre_msg *msg;
145 struct mds_body *body;
146 struct lustre_id lid;
150 mkpi = (struct mds_kml_pack_info *)record;
151 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
153 rec = lustre_msg_buf(msg, 0, 0);
157 lid = rec->cr_replayid;
159 /* zeroing @rec->cr_replayid out in request, as master MDS should create
160 * own inode (with own store cookie). */
161 memset(&rec->cr_replayid, 0, sizeof(rec->cr_replayid));
163 /* converting local inode store cookie to remote lustre_id. */
164 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->cr_id,
165 &rec->cr_id, sizeof(rec->cr_id));
167 CERROR("Can't read master MDS store cookie "
168 "from local inode EA, err = %d.\n", rc);
172 /* getting name to be created and its length */
173 name = lustre_msg_string(msg, 1, 0);
174 namelen = name ? msg->buflens[1] - 1 : 0;
176 /* getting misc data (symlink) and its length */
177 data = (char *)lustre_msg_buf(msg, 2, 0);
178 datalen = data ? msg->buflens[2] : 0;
180 OBD_ALLOC(op_data, sizeof(*op_data));
184 /* prepare mdc request data. */
185 cmobd_prepare_mdc_data(op_data, &rec->cr_id, &rec->cr_replayid,
186 name, namelen, rec->cr_mode);
188 /* requesting to master to create object with passed attributes. */
189 rc = md_create(cmobd->master_exp, op_data, data, datalen,
190 rec->cr_mode, current->fsuid, current->fsgid,
192 OBD_FREE(op_data, sizeof(*op_data));
195 /* here we save store cookie from master MDS to local
197 body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
199 rc = mds_update_mid(cmobd->cache_exp->exp_obd, &lid,
200 &body->id1, sizeof(body->id1));
204 ptlrpc_req_finished(req);
208 static int cmobd_reint_unlink(struct obd_device *obd, void *record)
210 struct cm_obd *cmobd = &obd->u.cm;
211 struct ptlrpc_request *req = NULL;
212 struct mds_kml_pack_info *mkpi;
213 struct mdc_op_data *op_data;
214 struct mds_rec_unlink *rec;
215 struct lustre_msg *msg;
220 mkpi = (struct mds_kml_pack_info *)record;
221 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
223 rec = lustre_msg_buf(msg, 0, 0);
227 /* converting local store cookie to remote lustre_id. */
228 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->ul_id1,
229 &rec->ul_id1, sizeof(rec->ul_id1));
231 CERROR("Can't read master MDS store cookie "
232 "from local inode EA, err = %d.\n", rc);
236 /* getting name to be created and its length */
237 name = lustre_msg_string(msg, 1, 0);
238 namelen = name ? msg->buflens[1] - 1 : 0;
240 OBD_ALLOC(op_data, sizeof(*op_data));
244 /* prepare mdc request data. */
245 cmobd_prepare_mdc_data(op_data, &rec->ul_id1, NULL,
246 name, namelen, rec->ul_mode);
248 rc = md_unlink(cmobd->master_exp, op_data, &req);
249 OBD_FREE(op_data, sizeof(*op_data));
252 ptlrpc_req_finished(req);
256 static int cmobd_reint_link(struct obd_device *obd, void *record)
258 struct cm_obd *cmobd = &obd->u.cm;
259 struct ptlrpc_request *req = NULL;
260 struct mds_kml_pack_info *mkpi;
261 struct mdc_op_data *op_data;
262 struct mds_rec_link *rec;
263 struct lustre_msg *msg;
268 mkpi = (struct mds_kml_pack_info *)record;
269 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
271 rec = lustre_msg_buf(msg, 0, 0);
275 /* converting local store cookie for both ids to remote lustre_id. */
276 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->lk_id1,
277 &rec->lk_id1, sizeof(rec->lk_id1));
279 CERROR("Can't read master MDS store cookie "
280 "from local inode EA, err = %d.\n", rc);
284 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->lk_id2,
285 &rec->lk_id2, sizeof(rec->lk_id2));
287 CERROR("Can't read master MDS store cookie "
288 "from local inode EA, err = %d.\n", rc);
292 /* getting name to be created and its length */
293 name = lustre_msg_string(msg, 1, 0);
294 namelen = name ? msg->buflens[1] - 1: 0;
296 OBD_ALLOC(op_data, sizeof(*op_data));
300 /* prepare mdc request data. */
301 cmobd_prepare_mdc_data(op_data, &rec->lk_id1, &rec->lk_id2,
304 rc = md_link(cmobd->master_exp, op_data, &req);
305 OBD_FREE(op_data, sizeof(*op_data));
308 ptlrpc_req_finished(req);
312 static int cmobd_reint_rename(struct obd_device *obd, void *record)
314 struct cm_obd *cmobd = &obd->u.cm;
315 struct ptlrpc_request *req = NULL;
316 struct mds_kml_pack_info *mkpi;
317 struct mdc_op_data *op_data;
318 struct mds_rec_rename *rec;
319 int rc = 0, oldlen, newlen;
320 struct lustre_msg *msg;
324 mkpi = (struct mds_kml_pack_info *)record;
325 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
327 rec = lustre_msg_buf(msg, 0, 0);
331 /* converting local store cookie for both ids to remote lustre_id. */
332 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->rn_id1,
333 &rec->rn_id1, sizeof(rec->rn_id1));
335 CERROR("Can't read master MDS store cookie "
336 "from local inode EA, err = %d.\n", rc);
340 rc = mds_read_mid(cmobd->cache_exp->exp_obd, &rec->rn_id2,
341 &rec->rn_id2, sizeof(rec->rn_id2));
343 CERROR("Can't read master MDS store cookie "
344 "from local inode EA, err = %d.\n", rc);
348 /* getting old name and its length */
349 old = lustre_msg_string(msg, 1, 0);
350 oldlen = old ? msg->buflens[1] - 1 : 0;
352 /* getting new len and its length */
353 new = lustre_msg_string(msg, 2, 0);
354 newlen = new ? msg->buflens[2] - 1: 0;
356 OBD_ALLOC(op_data, sizeof(*op_data));
360 /* prepare mdc request data. */
361 cmobd_prepare_mdc_data(op_data, &rec->rn_id1, &rec->rn_id1,
364 rc = md_rename(cmobd->master_exp, op_data, old, oldlen,
366 OBD_FREE(op_data, sizeof(*op_data));
369 ptlrpc_req_finished(req);
373 typedef int (*cmobd_reint_rec_func_t)(struct obd_device *, void *);
375 static cmobd_reint_rec_func_t mds_reint_handler[REINT_MAX + 1] = {
376 [REINT_SETATTR] cmobd_reint_setattr,
377 [REINT_CREATE] cmobd_reint_create,
378 [REINT_LINK] cmobd_reint_link,
379 [REINT_UNLINK] cmobd_reint_unlink,
380 [REINT_RENAME] cmobd_reint_rename,
383 int cmobd_reint_mds(struct obd_device *obd, void *record, int dummy)
385 struct mds_kml_pack_info *mkpi;
386 struct lustre_msg *msg;
389 mkpi = (struct mds_kml_pack_info *)record;
390 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
392 opcode = *(__u32 *)lustre_msg_buf(msg, 0, 0);
394 if (opcode > REINT_MAX || opcode <= 0) {
395 CERROR("Invalid mds reint opcode %u\n",
400 return mds_reint_handler[opcode](obd, record);