Whamcloud - gitweb
fixing integer comparism bug
[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 /* copied from lov/lov_ea.c, just for debugging, will be removed later */
45 void mdt_dump_lmm(int level, struct lov_mds_md *lmm)
46 {
47         struct lov_ost_data_v1 *lod;
48         int i;
49         __s16 stripe_count = 
50                 le16_to_cpu(((struct lov_user_md*)lmm)->lmm_stripe_count);
51
52         CDEBUG_EX(level, "objid "LPX64", magic 0x%08X, pattern %#X\n",
53                le64_to_cpu(lmm->lmm_object_id), le32_to_cpu(lmm->lmm_magic),
54                le32_to_cpu(lmm->lmm_pattern));
55         CDEBUG_EX(level,"stripe_size=0x%x, stripe_count=0x%x\n",
56                le32_to_cpu(lmm->lmm_stripe_size),
57                le32_to_cpu(lmm->lmm_stripe_count));
58         LASSERT(stripe_count < (__s16)LOV_MAX_STRIPE_COUNT);
59         for (i = 0, lod = lmm->lmm_objects; i < stripe_count; i++, lod++) {
60                 CDEBUG_EX(level, "stripe %u idx %u subobj "LPX64"/"LPX64"\n",
61                        i, le32_to_cpu(lod->l_ost_idx),
62                        le64_to_cpu(lod->l_object_gr),
63                        le64_to_cpu(lod->l_object_id));
64         }
65 }
66
67 void mdt_shrink_reply(struct mdt_thread_info *info)
68 {
69         struct ptlrpc_request *req = mdt_info_req(info);
70         struct mdt_body *body;
71         struct lov_mds_md *lmm;
72         int cookie_size = 0;
73         int md_size = 0;
74
75         body = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY);
76
77         if (body && body->valid & OBD_MD_FLEASIZE) {
78                 md_size = body->eadatasize;
79         }
80         if (body && body->valid & OBD_MD_FLCOOKIE) {
81                 LASSERT(body->valid & OBD_MD_FLEASIZE);
82                 lmm = req_capsule_server_get(&info->mti_pill, &RMF_MDT_MD);
83                 cookie_size = le32_to_cpu(lmm->lmm_stripe_count) *
84                                 sizeof(struct llog_cookie);
85         }
86
87         CDEBUG(D_INFO, "Shrink to md_size %d cookie_size %d \n",
88                        md_size, cookie_size);
89
90         lustre_shrink_reply(req, 1, md_size, 1);
91         lustre_shrink_reply(req, md_size? 2:1, cookie_size, 0);
92 }
93
94
95 /* if object is dying, pack the lov/llog data,
96  * parameter info->mti_attr should be valid at this point! */
97 int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo,
98                            const struct md_attr *ma)
99 {
100         struct mdt_body       *repbody;
101         const struct lu_attr *la = &ma->ma_attr;
102         ENTRY;
103
104         repbody = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY);
105         
106         if (ma->ma_valid & MA_INODE)
107                 mdt_pack_attr2body(repbody, la, mdt_object_fid(mo));
108
109         if (ma->ma_valid & MA_LOV) {
110                 LASSERT(ma->ma_lmm_size);
111                 mdt_dump_lmm(D_INFO, ma->ma_lmm);
112                 repbody->eadatasize = ma->ma_lmm_size;
113                 if (S_ISREG(lu_object_attr(&mo->mot_obj.mo_lu)))
114                         repbody->valid |= OBD_MD_FLEASIZE;
115                 else if (S_ISDIR(lu_object_attr(&mo->mot_obj.mo_lu)))
116                         repbody->valid |= OBD_MD_FLDIREA;
117                 else 
118                         LBUG();
119         }
120         
121         if (ma->ma_cookie_size && (ma->ma_valid & MA_COOKIE))
122                 repbody->valid |= OBD_MD_FLCOOKIE;
123         
124         RETURN(0);
125 }
126
127 static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr,
128                                   struct md_attr *ma)
129 {
130         __u64 out;
131
132         out = 0;
133         if (in & ATTR_MODE)
134                 out |= LA_MODE;
135         if (in & ATTR_UID)
136                 out |= LA_UID;
137         if (in & ATTR_GID)
138                 out |= LA_GID;
139         if (in & ATTR_SIZE)
140                 out |= LA_SIZE;
141         if (in & ATTR_ATIME)
142                 out |= LA_ATIME;
143         if (in & ATTR_MTIME)
144                 out |= LA_MTIME;
145         if (in & ATTR_CTIME)
146                 out |= LA_CTIME;
147         if (in & ATTR_ATTR_FLAG)
148                 out |= LA_FLAGS;
149
150         if (in & ATTR_FROM_OPEN)
151                 rr->rr_flags |= MRF_SETATTR_LOCKED;
152
153         if (in & ATTR_ATIME_SET)
154                 ma->ma_attr_flags |= MD_ATIME_SET;
155
156         if (in & ATTR_CTIME_SET)
157                 ma->ma_attr_flags |= MD_CTIME_SET;
158
159         if (in & ATTR_MTIME_SET)
160                 ma->ma_attr_flags |= MD_MTIME_SET;
161
162         if (in & ATTR_RAW)
163                 ma->ma_attr_flags |= MD_ATTR_RAW;
164
165         in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|
166                 ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN|
167                 ATTR_ATIME_SET|ATTR_CTIME_SET|ATTR_MTIME_SET|
168                 ATTR_ATTR_FLAG|ATTR_RAW);
169         if (in != 0)
170                 CERROR("Unknown attr bits: %#llx\n", in);
171         return out;
172 }
173 /* unpacking */
174 static int mdt_setattr_unpack(struct mdt_thread_info *info)
175 {
176         struct mdt_rec_setattr  *rec;
177         struct md_attr          *ma = &info->mti_attr;
178         struct lu_attr          *la = &ma->ma_attr;
179         struct mdt_reint_record *rr = &info->mti_rr;
180         struct req_capsule      *pill = &info->mti_pill;
181         ENTRY;
182
183         rec = req_capsule_client_get(pill, &RMF_REC_SETATTR);
184
185         if (rec == NULL)
186                 RETURN(-EFAULT);
187
188         rr->rr_fid1 = &rec->sa_fid;
189         la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma);
190         la->la_mode  = rec->sa_mode;
191         la->la_uid   = rec->sa_uid;
192         la->la_gid   = rec->sa_gid;
193         la->la_size  = rec->sa_size;
194         la->la_flags = rec->sa_attr_flags;
195         la->la_ctime = rec->sa_ctime;
196         la->la_atime = rec->sa_atime;
197         la->la_mtime = rec->sa_mtime;
198         ma->ma_valid = MA_INODE;
199
200         if (req_capsule_field_present(pill, &RMF_EADATA)) {
201                 ma->ma_lmm = req_capsule_client_get(pill, &RMF_EADATA);
202                 ma->ma_lmm_size = req_capsule_get_size(pill, &RMF_EADATA,
203                                                        RCL_CLIENT);
204                 ma->ma_valid |= MA_LOV;
205         }
206         if (req_capsule_field_present(pill, &RMF_LOGCOOKIES)) {
207                 ma->ma_cookie = req_capsule_client_get(pill,
208                                                        &RMF_LOGCOOKIES);
209                 ma->ma_cookie_size = req_capsule_get_size(pill,
210                                                           &RMF_LOGCOOKIES,
211                                                           RCL_CLIENT);
212                 ma->ma_valid |= MA_COOKIE;
213         }
214
215         RETURN(0);
216 }
217
218 static int mdt_create_unpack(struct mdt_thread_info *info)
219 {
220         struct mdt_rec_create   *rec;
221         struct lu_attr          *attr = &info->mti_attr.ma_attr;
222         struct mdt_reint_record *rr = &info->mti_rr;
223         struct req_capsule      *pill = &info->mti_pill;
224         int                     result = 0;
225         ENTRY;
226
227         rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
228         if (rec != NULL) {
229                 rr->rr_fid1 = &rec->cr_fid1;
230                 rr->rr_fid2 = &rec->cr_fid2;
231                 attr->la_mode = rec->cr_mode;
232                 attr->la_rdev  = rec->cr_rdev;
233                 attr->la_uid   = rec->cr_fsuid;
234                 attr->la_gid   = rec->cr_fsgid;
235                 attr->la_ctime = rec->cr_time;
236                 attr->la_mtime = rec->cr_time;
237                 attr->la_atime = rec->cr_time;
238                 attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID |
239                                  LA_CTIME | LA_MTIME | LA_ATIME; 
240                 info->mti_spec.sp_cr_flags = rec->cr_flags;
241
242                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
243                 if (rr->rr_name) {
244                         if (req_capsule_field_present(pill, &RMF_SYMTGT)) {
245                                 const char *tgt;
246                                 tgt = req_capsule_client_get(pill,
247                                                              &RMF_SYMTGT);
248                                 if (tgt == NULL)
249                                         result = -EFAULT;
250                                 info->mti_spec.u.sp_symname = tgt;
251                         }
252                 } else
253                         result = -EFAULT;
254         } else
255                 result = -EFAULT;
256         RETURN(result);
257 }
258
259 static int mdt_link_unpack(struct mdt_thread_info *info)
260 {
261         struct mdt_rec_link     *rec;
262         struct lu_attr          *attr = &info->mti_attr.ma_attr;
263         struct mdt_reint_record *rr = &info->mti_rr;
264         struct req_capsule      *pill = &info->mti_pill;
265         int                      result = 0;
266         ENTRY;
267
268         rec = req_capsule_client_get(pill, &RMF_REC_LINK);
269         if (rec != NULL) {
270                 attr->la_uid = rec->lk_fsuid;
271                 attr->la_gid = rec->lk_fsgid;
272                 rr->rr_fid1 = &rec->lk_fid1;
273                 rr->rr_fid2 = &rec->lk_fid2;
274                 attr->la_ctime = rec->lk_time;
275                 attr->la_mtime = rec->lk_time;
276                 attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME;
277                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
278                 if (rr->rr_name == NULL)
279                         result = -EFAULT;
280         } else
281                 result = -EFAULT;
282         RETURN(result);
283 }
284
285 static int mdt_unlink_unpack(struct mdt_thread_info *info)
286 {
287         struct mdt_rec_unlink   *rec;
288         struct lu_attr          *attr = &info->mti_attr.ma_attr;
289         struct mdt_reint_record *rr = &info->mti_rr;
290         struct req_capsule      *pill = &info->mti_pill;
291         int                      result = 0;
292         ENTRY;
293
294         rec = req_capsule_client_get(pill, &RMF_REC_UNLINK);
295         if (rec != NULL) {
296                 attr->la_uid = rec->ul_fsuid;
297                 attr->la_gid = rec->ul_fsgid;
298                 rr->rr_fid1 = &rec->ul_fid1;
299                 rr->rr_fid2 = &rec->ul_fid2;
300                 attr->la_ctime = rec->ul_time;
301                 attr->la_mtime = rec->ul_time;
302                 attr->la_mode  = rec->ul_mode;
303
304                 attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME | LA_MODE;
305                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
306                 if (rr->rr_name == NULL)
307                         result = -EFAULT;
308         } else
309                 result = -EFAULT;
310         RETURN(result);
311 }
312
313 static int mdt_rename_unpack(struct mdt_thread_info *info)
314 {
315         struct mdt_rec_rename   *rec;
316         struct lu_attr          *attr = &info->mti_attr.ma_attr;
317         struct mdt_reint_record *rr = &info->mti_rr;
318         struct req_capsule      *pill = &info->mti_pill;
319         int                      result = 0;
320         ENTRY;
321
322         rec = req_capsule_client_get(pill, &RMF_REC_RENAME);
323         if (rec != NULL) {
324                 attr->la_uid = rec->rn_fsuid;
325                 attr->la_gid = rec->rn_fsgid;
326                 rr->rr_fid1 = &rec->rn_fid1;
327                 rr->rr_fid2 = &rec->rn_fid2;
328                 attr->la_ctime = rec->rn_time;
329                 attr->la_mtime = rec->rn_time;
330                 attr->la_valid = LA_UID | LA_GID | LA_CTIME | LA_MTIME;
331                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
332                 rr->rr_tgt = req_capsule_client_get(pill, &RMF_SYMTGT);
333                 if (rr->rr_name == NULL || rr->rr_tgt == NULL)
334                         result = -EFAULT;
335         } else
336                 result = -EFAULT;
337         RETURN(result);
338 }
339
340 static int mdt_open_unpack(struct mdt_thread_info *info)
341 {
342         struct mdt_rec_create   *rec;
343         struct lu_attr          *attr = &info->mti_attr.ma_attr;
344         struct req_capsule      *pill = &info->mti_pill;
345         struct mdt_reint_record *rr   = &info->mti_rr;
346         int                     result;
347         ENTRY;
348
349         rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
350         if (rec != NULL) {
351                 rr->rr_fid1   = &rec->cr_fid1;
352                 rr->rr_fid2   = &rec->cr_fid2;
353                 attr->la_mode = rec->cr_mode;
354                 attr->la_rdev  = rec->cr_rdev;
355                 attr->la_uid   = rec->cr_fsuid;
356                 attr->la_gid   = rec->cr_fsgid;
357                 attr->la_ctime = rec->cr_time;
358                 attr->la_mtime = rec->cr_time;
359                 attr->la_atime = rec->cr_time;
360                 attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID | LA_CTIME
361                                  | LA_MTIME | LA_ATIME;
362                 info->mti_spec.sp_cr_flags = rec->cr_flags;
363                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
364                 if (rr->rr_name == NULL)
365                         /*XXX: what about open by FID? */
366                         result = -EFAULT;
367                 else
368                         result = 0;
369         } else
370                 result = -EFAULT;
371
372         if (req_capsule_field_present(pill, &RMF_EADATA)) {
373                 struct md_create_spec *sp = &info->mti_spec;
374                 sp->u.sp_ea.eadata = req_capsule_client_get(pill,
375                                                             &RMF_EADATA);
376                 sp->u.sp_ea.eadatalen = req_capsule_get_size(pill,
377                                                              &RMF_EADATA,
378                                                              RCL_CLIENT);
379         }
380
381         RETURN(result);
382 }
383
384 typedef int (*reint_unpacker)(struct mdt_thread_info *info);
385
386 static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
387         [REINT_SETATTR]  = mdt_setattr_unpack,
388         [REINT_CREATE]   = mdt_create_unpack,
389         [REINT_LINK]     = mdt_link_unpack,
390         [REINT_UNLINK]   = mdt_unlink_unpack,
391         [REINT_RENAME]   = mdt_rename_unpack,
392         [REINT_OPEN]     = mdt_open_unpack
393 };
394
395 int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
396 {
397         int rc;
398
399         ENTRY;
400
401         if (op < REINT_MAX && mdt_reint_unpackers[op] != NULL) {
402                 info->mti_rr.rr_opcode = op;
403                 rc = mdt_reint_unpackers[op](info);
404         } else {
405                 CERROR("Unexpected opcode %d\n", op);
406                 rc = -EFAULT;
407         }
408         RETURN(rc);
409 }