Whamcloud - gitweb
1. modified the code to #colibri coding guideline.
[fs/lustre-release.git] / lustre / mdt / mdt_lib.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/mdt/mdt_lib.c
5  *  Lustre Metadata Target (mdt) request unpacking helper.
6  *
7  *  Copyright (c) 2006 Cluster File Systems, Inc.
8  *   Author: Peter Braam <braam@clusterfs.com>
9  *   Author: Andreas Dilger <adilger@clusterfs.com>
10  *   Author: Phil Schwan <phil@clusterfs.com>
11  *   Author: Mike Shaver <shaver@clusterfs.com>
12  *   Author: Nikita Danilov <nikita@clusterfs.com>
13  *   Author: Huang Hua <huanghua@clusterfs.com>
14  *
15  *
16  *   This file is part of the Lustre file system, http://www.lustre.org
17  *   Lustre is a trademark of Cluster File Systems, Inc.
18  *
19  *   You may have signed or agreed to another license before downloading
20  *   this software.  If so, you are bound by the terms and conditions
21  *   of that agreement, and the following does not apply to you.  See the
22  *   LICENSE file included with this distribution for more information.
23  *
24  *   If you did not agree to a different license, then this copy of Lustre
25  *   is open source software; you can redistribute it and/or modify it
26  *   under the terms of version 2 of the GNU General Public License as
27  *   published by the Free Software Foundation.
28  *
29  *   In either case, Lustre is distributed in the hope that it will be
30  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
31  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  *   license text for more details.
33  */
34
35
36 #ifndef EXPORT_SYMTAB
37 # define EXPORT_SYMTAB
38 #endif
39 #define DEBUG_SUBSYSTEM S_MDS
40
41 #include "mdt_internal.h"
42
43
44 /* unpacking */
45 static int mdt_setattr_unpack(struct mdt_thread_info *info,
46                               struct ptlrpc_request *req, 
47                               int offset)
48 {
49         struct lu_attr *attr = &info->mti_attr;
50         struct mdt_reint_record *r = &info->mti_rr;
51         struct mdt_rec_setattr *rec;
52         ENTRY;
53
54         rec = lustre_swab_reqbuf(req, offset, sizeof(*rec),
55                                  lustre_swab_mdt_rec_setattr);
56         if (rec == NULL)
57                 RETURN(-EFAULT);
58
59         r->rr_uc.luc_fsuid = rec->sa_fsuid;
60         r->rr_uc.luc_fsgid = rec->sa_fsgid;
61         r->rr_uc.luc_cap = rec->sa_cap;
62         r->rr_uc.luc_suppgid1 = rec->sa_suppgid;
63         r->rr_uc.luc_suppgid2 = -1;
64         r->rr_fid1 = &rec->sa_fid;
65 /*FIXME        attr->la_valid = rec->sa_valid; */
66         attr->la_mode = rec->sa_mode;
67         attr->la_uid = rec->sa_uid;
68         attr->la_gid = rec->sa_gid;
69         attr->la_size = rec->sa_size;
70         attr->la_atime = rec->sa_atime;
71         attr->la_mtime = rec->sa_mtime;
72         attr->la_ctime = rec->sa_ctime;
73 /*FIXME        attr->la_attr_flags = rec->sa_attr_flags;*/
74
75         LASSERT_REQSWAB (req, offset + 1);
76         if (req->rq_reqmsg->bufcount > offset + 1) {
77                 r->rr_eadata = lustre_msg_buf (req->rq_reqmsg,
78                                                offset + 1, 0);
79                 if (r->rr_eadata == NULL)
80                         RETURN(-EFAULT);
81                 r->rr_eadatalen = req->rq_reqmsg->buflens[offset + 1];
82         }
83
84         if (req->rq_reqmsg->bufcount > offset + 2) {
85                 r->rr_logcookies = lustre_msg_buf(req->rq_reqmsg, offset + 2,0);
86                 if (r->rr_logcookies == NULL)
87                         RETURN(-EFAULT);
88
89                 r->rr_cookielen = req->rq_reqmsg->buflens[offset + 2];
90         }
91
92         RETURN(0);
93 }
94
95 static int mdt_create_unpack(struct mdt_thread_info *info,
96                              struct ptlrpc_request *req, 
97                              int offset)
98 {
99         struct mdt_rec_create *rec;
100         struct mdt_reint_record *r = &info->mti_rr;
101         ENTRY;
102
103         rec = lustre_swab_reqbuf (req, offset, sizeof (*rec),
104                                   lustre_swab_mdt_rec_create);
105         if (rec == NULL)
106                 RETURN(-EFAULT);
107
108         r->rr_uc.luc_fsuid = rec->cr_fsuid;
109         r->rr_uc.luc_fsgid = rec->cr_fsgid;
110         r->rr_uc.luc_cap = rec->cr_cap;
111         r->rr_uc.luc_suppgid1 = rec->cr_suppgid;
112         r->rr_uc.luc_suppgid2 = -1;
113         r->rr_fid1 = &rec->cr_fid;
114         r->rr_fid2 = &rec->cr_replayfid;
115         r->rr_mode = rec->cr_mode;
116         r->rr_rdev = rec->cr_rdev;
117         r->rr_time = rec->cr_time;
118         r->rr_flags = rec->cr_flags;
119
120         LASSERT_REQSWAB (req, offset + 1);
121         r->rr_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0);
122         if (r->rr_name == NULL)
123                 RETURN(-EFAULT);
124         r->rr_namelen = req->rq_reqmsg->buflens[offset + 1];
125
126         LASSERT_REQSWAB (req, offset + 2);
127         if (req->rq_reqmsg->bufcount > offset + 2) {
128                 /* NB for now, we only seem to pass NULL terminated symlink
129                  * target strings here.  If this ever changes, we'll have
130                  * to stop checking for a buffer filled completely with a
131                  * NULL terminated string here, and make the callers check
132                  * depending on what they expect.  We should probably stash
133                  * it in r->rr_eadata in that case, so it's obvious... -eeb
134                  */
135                 r->rr_tgt = lustre_msg_string(req->rq_reqmsg, offset + 2, 0);
136                 if (r->rr_tgt == NULL)
137                         RETURN(-EFAULT);
138                 r->rr_tgtlen = req->rq_reqmsg->buflens[offset + 2];
139         }
140         RETURN(0);
141 }
142
143 static int mdt_link_unpack(struct mdt_thread_info *info,
144                            struct ptlrpc_request *req, 
145                            int offset)
146 {
147         struct mdt_rec_link *rec;
148         struct mdt_reint_record *r = &info->mti_rr;
149         ENTRY;
150
151         rec = lustre_swab_reqbuf (req, offset, sizeof (*rec),
152                                   lustre_swab_mdt_rec_link);
153         if (rec == NULL)
154                 RETURN(-EFAULT);
155
156         r->rr_uc.luc_fsuid = rec->lk_fsuid;
157         r->rr_uc.luc_fsgid = rec->lk_fsgid;
158         r->rr_uc.luc_cap = rec->lk_cap;
159         r->rr_uc.luc_suppgid1 = rec->lk_suppgid1;
160         r->rr_uc.luc_suppgid2 = rec->lk_suppgid2;
161         r->rr_fid1 = &rec->lk_fid1;
162         r->rr_fid2 = &rec->lk_fid2;
163         r->rr_time = rec->lk_time;
164
165         LASSERT_REQSWAB (req, offset + 1);
166         r->rr_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0);
167         if (r->rr_name == NULL)
168                 RETURN(-EFAULT);
169         r->rr_namelen = req->rq_reqmsg->buflens[offset + 1];
170         RETURN(0);
171 }
172
173 static int mdt_unlink_unpack(struct mdt_thread_info *info,
174                              struct ptlrpc_request *req, 
175                              int offset)
176 {
177         struct mdt_rec_unlink *rec;
178         struct mdt_reint_record *r = &info->mti_rr;
179         ENTRY;
180
181         rec = lustre_swab_reqbuf (req, offset, sizeof (*rec),
182                                   lustre_swab_mdt_rec_unlink);
183         if (rec == NULL)
184                 RETURN(-EFAULT);
185
186         r->rr_uc.luc_fsuid = rec->ul_fsuid;
187         r->rr_uc.luc_fsgid = rec->ul_fsgid;
188         r->rr_uc.luc_cap = rec->ul_cap;
189         r->rr_uc.luc_suppgid1 = rec->ul_suppgid;
190         r->rr_uc.luc_suppgid2 = -1;
191         r->rr_mode = rec->ul_mode;
192         r->rr_fid1 = &rec->ul_fid1;
193         r->rr_fid2 = &rec->ul_fid2;
194         r->rr_time = rec->ul_time;
195
196         LASSERT_REQSWAB (req, offset + 1);
197         r->rr_name = lustre_msg_string(req->rq_reqmsg, offset + 1, 0);
198         if (r->rr_name == NULL)
199                 RETURN(-EFAULT);
200         r->rr_namelen = req->rq_reqmsg->buflens[offset + 1];
201         RETURN(0);
202 }
203
204 static int mdt_rename_unpack(struct mdt_thread_info *info,
205                              struct ptlrpc_request *req, 
206                              int offset)
207 {
208         struct mdt_rec_rename *rec;
209         struct mdt_reint_record *r = &info->mti_rr;
210         ENTRY;
211
212         rec = lustre_swab_reqbuf (req, offset, sizeof (*rec),
213                                   lustre_swab_mdt_rec_rename);
214         if (rec == NULL)
215                 RETURN(-EFAULT);
216
217         r->rr_uc.luc_fsuid = rec->rn_fsuid;
218         r->rr_uc.luc_fsgid = rec->rn_fsgid;
219         r->rr_uc.luc_cap = rec->rn_cap;
220         r->rr_uc.luc_suppgid1 = rec->rn_suppgid1;
221         r->rr_uc.luc_suppgid2 = rec->rn_suppgid2;
222         r->rr_fid1 = &rec->rn_fid1;
223         r->rr_fid2 = &rec->rn_fid2;
224         r->rr_time = rec->rn_time;
225
226         LASSERT_REQSWAB (req, offset + 1);
227         r->rr_name = lustre_msg_string(req->rq_reqmsg, offset + 1, 0);
228         if (r->rr_name == NULL)
229                 RETURN(-EFAULT);
230         r->rr_namelen = req->rq_reqmsg->buflens[offset + 1];
231
232         LASSERT_REQSWAB (req, offset + 2);
233         r->rr_tgt = lustre_msg_string(req->rq_reqmsg, offset + 2, 0);
234         if (r->rr_tgt == NULL)
235                 RETURN(-EFAULT);
236         r->rr_tgtlen = req->rq_reqmsg->buflens[offset + 2];
237         RETURN(0);
238 }
239
240 static int mdt_open_unpack(struct mdt_thread_info *info,
241                            struct ptlrpc_request *req, 
242                            int offset)
243 {
244         struct mdt_rec_create *rec;
245         struct mdt_reint_record *r = &info->mti_rr;
246         ENTRY;
247
248         rec = lustre_swab_reqbuf (req, offset, sizeof (*rec),
249                                   lustre_swab_mdt_rec_create);
250         if (rec == NULL)
251                 RETURN(-EFAULT);
252
253         r->rr_uc.luc_fsuid = rec->cr_fsuid;
254         r->rr_uc.luc_fsgid = rec->cr_fsgid;
255         r->rr_uc.luc_cap = rec->cr_cap;
256         r->rr_uc.luc_suppgid1 = rec->cr_suppgid;
257         r->rr_uc.luc_suppgid2 = -1;
258         r->rr_fid1 = &rec->cr_fid;
259         r->rr_fid2 = &rec->cr_replayfid;
260         r->rr_mode = rec->cr_mode;
261         r->rr_rdev = rec->cr_rdev;
262         r->rr_time = rec->cr_time;
263         r->rr_flags = rec->cr_flags;
264
265         LASSERT_REQSWAB (req, offset + 1);
266         r->rr_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0);
267         if (r->rr_name == NULL)
268                 RETURN(-EFAULT);
269         r->rr_namelen = req->rq_reqmsg->buflens[offset + 1];
270
271         LASSERT_REQSWAB (req, offset + 2);
272         if (req->rq_reqmsg->bufcount > offset + 2) {
273                 r->rr_eadata = lustre_msg_buf(req->rq_reqmsg, offset + 2, 0);
274                 if (r->rr_eadata == NULL)
275                         RETURN(-EFAULT);
276                 r->rr_eadatalen = req->rq_reqmsg->buflens[offset + 2];
277         }
278         RETURN(0);
279 }
280
281 typedef int (*reint_unpacker)(struct mdt_thread_info *info,
282                               struct ptlrpc_request *req, 
283                               int offset);
284
285 static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
286         [REINT_SETATTR]  = mdt_setattr_unpack,
287         [REINT_CREATE] = mdt_create_unpack,
288         [REINT_LINK] = mdt_link_unpack,
289         [REINT_UNLINK] = mdt_unlink_unpack,
290         [REINT_RENAME] = mdt_rename_unpack,
291         [REINT_OPEN] = mdt_open_unpack
292 };
293
294 int mdt_reint_unpack(struct mdt_thread_info *info,
295                      struct ptlrpc_request *req, 
296                      int offset)
297 {
298         mdt_reint_t opcode;
299         mdt_reint_t *opcodep;
300         int rc;
301         ENTRY;
302
303         /* NB don't lustre_swab_reqbuf() here.  We're just taking a peek
304          * and we want to leave it to the specific unpacker once we've
305          * identified the message type */
306         opcodep = lustre_msg_buf (req->rq_reqmsg, offset, sizeof (*opcodep));
307         if (opcodep == NULL)
308                 RETURN(-EFAULT);
309
310         opcode = *opcodep;
311         if (lustre_msg_swabbed (req->rq_reqmsg))
312                 __swab32s (&opcode);
313
314         if (opcode >= REINT_MAX || mdt_reint_unpackers[opcode] == NULL) {
315                 CERROR("Unexpected opcode %d\n", opcode);
316                 RETURN(-EFAULT);
317         }
318
319         info->mti_rr.rr_opcode = opcode;
320         rc = mdt_reint_unpackers[opcode](info, req, offset);
321
322         RETURN(rc);
323 }