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 = 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_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 cmobd_prepare_mdc_data(&op_data, &rec->sa_id, NULL,
117 /* handling possible EAs. */
118 ea1 = lustre_msg_buf(msg, 1, 0);
119 ea1len = ea1 ? msg->buflens[1] : 0;
121 ea2 = lustre_msg_buf(msg, 2, 0);
122 ea2len = ea2 ? msg->buflens[2] : 0;
124 rc = md_setattr(cmobd->master_exp, &op_data, &iattr,
125 ea1, ea1len, ea2, ea2len, &req);
128 ptlrpc_req_finished(req);
132 static int cmobd_reint_create(struct obd_device *obd, void *record)
134 struct cm_obd *cmobd = &obd->u.cm;
135 struct ptlrpc_request *req = NULL;
136 struct mds_kml_pack_info *mkpi;
137 int rc = 0, namelen, datalen;
138 struct mds_rec_create *rec;
139 struct mdc_op_data op_data;
140 struct lustre_msg *msg;
141 struct mds_body *body;
142 struct lustre_id lid;
146 mkpi = (struct mds_kml_pack_info *)record;
147 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
149 rec = lustre_msg_buf(msg, 0, 0);
153 lid = rec->cr_replayid;
155 /* zeroing @rec->cr_replayid out in request, as master MDS should create
156 * own inode (with own store cookie). */
157 memset(&rec->cr_replayid, 0, sizeof(rec->cr_replayid));
159 /* converting local inode store cookie to remote lustre_id. */
160 rc = mds_read_mid(cmobd->cache_obd, &rec->cr_id,
161 &rec->cr_id, sizeof(rec->cr_id));
163 CERROR("Can't read master MDS store cookie "
164 "from local inode EA, err = %d.\n", rc);
168 /* getting name to be created and its length */
169 name = lustre_msg_string(msg, 1, 0);
170 namelen = name ? msg->buflens[1] - 1 : 0;
172 /* getting misc data (symlink) and its length */
173 data = (char *)lustre_msg_buf(msg, 2, 0);
174 datalen = data ? msg->buflens[2] : 0;
176 /* prepare mdc request data. */
177 cmobd_prepare_mdc_data(&op_data, &rec->cr_id, &rec->cr_replayid,
178 name, namelen, rec->cr_mode);
180 /* requesting to master to create object with passed attributes. */
181 rc = md_create(cmobd->master_exp, &op_data, data, datalen,
182 rec->cr_mode, current->fsuid, current->fsgid,
186 /* here we save store cookie from master MDS to local
188 body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
190 rc = mds_update_mid(cmobd->cache_obd, &lid,
191 &body->id1, sizeof(body->id1));
195 ptlrpc_req_finished(req);
199 static int cmobd_reint_unlink(struct obd_device *obd, void *record)
201 struct cm_obd *cmobd = &obd->u.cm;
202 struct ptlrpc_request *req = NULL;
203 struct mds_kml_pack_info *mkpi;
204 struct mdc_op_data op_data;
205 struct mds_rec_unlink *rec;
206 struct lustre_msg *msg;
211 mkpi = (struct mds_kml_pack_info *)record;
212 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
214 rec = lustre_msg_buf(msg, 0, 0);
218 /* converting local store cookie to remote lustre_id. */
219 rc = mds_read_mid(cmobd->cache_obd, &rec->ul_id1,
220 &rec->ul_id1, sizeof(rec->ul_id1));
222 CERROR("Can't read master MDS store cookie "
223 "from local inode EA, err = %d.\n", rc);
227 /* getting name to be created and its length */
228 name = lustre_msg_string(msg, 1, 0);
229 namelen = name ? msg->buflens[1] - 1 : 0;
231 /* prepare mdc request data. */
232 cmobd_prepare_mdc_data(&op_data, &rec->ul_id1, NULL,
233 name, namelen, rec->ul_mode);
235 rc = md_unlink(cmobd->master_exp, &op_data, &req);
238 ptlrpc_req_finished(req);
242 static int cmobd_reint_link(struct obd_device *obd, void *record)
244 struct cm_obd *cmobd = &obd->u.cm;
245 struct ptlrpc_request *req = NULL;
246 struct mds_kml_pack_info *mkpi;
247 struct mdc_op_data op_data;
248 struct mds_rec_link *rec;
249 struct lustre_msg *msg;
254 mkpi = (struct mds_kml_pack_info *)record;
255 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
257 rec = lustre_msg_buf(msg, 0, 0);
261 /* converting local store cookie for both ids to remote lustre_id. */
262 rc = mds_read_mid(cmobd->cache_obd, &rec->lk_id1,
263 &rec->lk_id1, sizeof(rec->lk_id1));
265 CERROR("Can't read master MDS store cookie "
266 "from local inode EA, err = %d.\n", rc);
270 rc = mds_read_mid(cmobd->cache_obd, &rec->lk_id2,
271 &rec->lk_id2, sizeof(rec->lk_id2));
273 CERROR("Can't read master MDS store cookie "
274 "from local inode EA, err = %d.\n", rc);
278 /* getting name to be created and its length */
279 name = lustre_msg_string(msg, 1, 0);
280 namelen = name ? msg->buflens[1] - 1: 0;
282 /* prepare mdc request data. */
283 cmobd_prepare_mdc_data(&op_data, &rec->lk_id1, &rec->lk_id2,
286 rc = md_link(cmobd->master_exp, &op_data, &req);
289 ptlrpc_req_finished(req);
293 static int cmobd_reint_rename(struct obd_device *obd, void *record)
295 struct cm_obd *cmobd = &obd->u.cm;
296 struct ptlrpc_request *req = NULL;
297 struct mds_kml_pack_info *mkpi;
298 struct mdc_op_data op_data;
299 struct mds_rec_rename *rec;
300 int rc = 0, oldlen, newlen;
301 struct lustre_msg *msg;
305 mkpi = (struct mds_kml_pack_info *)record;
306 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
308 rec = lustre_msg_buf(msg, 0, 0);
312 /* converting local store cookie for both ids to remote lustre_id. */
313 rc = mds_read_mid(cmobd->cache_obd, &rec->rn_id1,
314 &rec->rn_id1, sizeof(rec->rn_id1));
316 CERROR("Can't read master MDS store cookie "
317 "from local inode EA, err = %d.\n", rc);
321 rc = mds_read_mid(cmobd->cache_obd, &rec->rn_id2,
322 &rec->rn_id2, sizeof(rec->rn_id2));
324 CERROR("Can't read master MDS store cookie "
325 "from local inode EA, err = %d.\n", rc);
329 /* getting old name and its length */
330 old = lustre_msg_string(msg, 1, 0);
331 oldlen = old ? msg->buflens[1] - 1 : 0;
333 /* getting new len and its length */
334 new = lustre_msg_string(msg, 2, 0);
335 newlen = new ? msg->buflens[2] - 1: 0;
337 /* prepare mdc request data. */
338 cmobd_prepare_mdc_data(&op_data, &rec->rn_id1, &rec->rn_id1,
341 rc = md_rename(cmobd->master_exp, &op_data, old, oldlen,
345 ptlrpc_req_finished(req);
349 typedef int (*cmobd_reint_rec_func_t)(struct obd_device *, void *);
351 static cmobd_reint_rec_func_t mds_reint_handler[REINT_MAX + 1] = {
352 [REINT_SETATTR] cmobd_reint_setattr,
353 [REINT_CREATE] cmobd_reint_create,
354 [REINT_LINK] cmobd_reint_link,
355 [REINT_UNLINK] cmobd_reint_unlink,
356 [REINT_RENAME] cmobd_reint_rename,
359 int cmobd_reint_mds(struct obd_device *obd, void *record, int dummy)
361 struct mds_kml_pack_info *mkpi;
362 struct lustre_msg *msg;
365 mkpi = (struct mds_kml_pack_info *)record;
366 msg = (struct lustre_msg *)(record + sizeof(*mkpi));
368 opcode = *(__u32 *)lustre_msg_buf(msg, 0, 0);
370 if (opcode > REINT_MAX || opcode <= 0) {
371 CERROR("Invalid mds reint opcode %u\n",
376 return mds_reint_handler[opcode](obd, record);