Whamcloud - gitweb
xattr support in md/dt stack
[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 /* if object is dying, pack the lov/llog data,
44  * parameter info->mti_attr should be valid at this point! */
45 int mdt_handle_last_unlink(struct mdt_thread_info *info,
46                            struct mdt_object *mo, const struct req_format *fmt)
47 {
48         struct mdt_body *body;
49         struct lu_attr  *la = &info->mti_attr.ma_attr;
50         int              rc = 0;
51         ENTRY;
52
53         body = req_capsule_server_get(&info->mti_pill,
54                                       &RMF_MDT_BODY);
55         mdt_pack_attr2body(body, la, mdt_object_fid(mo));
56
57         /* if last unlinked object reference so client should destroy ost
58          * objects*/
59         if (S_ISREG(la->la_mode) &&
60             la->la_nlink == 0 && mo->mot_header.loh_ref == 1) {
61                 struct lov_mds_md  *lmm;
62
63                 /* reply should contains more data,
64                  * * so we need to extend it */
65                 req_capsule_extend(&info->mti_pill, fmt);
66
67                 lmm = req_capsule_server_get(&info->mti_pill,
68                                 &RMF_MDT_MD);
69
70
71                 /*TODO: lmm data & llog cookie
72                  * rc = mo_xattr_get(info->mti_ctxt, mdt_object_child(o),
73                  * lmm, info->mti_mdt->mdt_max_mdsize,
74                  * MDS_LOV_MD_NAME);
75                  * if (rc >= 0) {
76                  * if (S_ISDIR(info->mti_attr.la_mode))
77                  * body->valid |= OBD_MD_FLDIREA;
78                  * else
79                  * body->valid |= OBD_MD_FLEASIZE;
80                  * body->eadatasize = rc;
81                  * rc = 0;
82                  * }
83                  */
84         }
85
86         RETURN(rc);
87 }
88
89 /* unpacking */
90 static int mdt_setattr_unpack(struct mdt_thread_info *info)
91 {
92         struct mdt_rec_setattr  *rec;
93         struct lu_attr          *attr = &info->mti_attr.ma_attr;
94         struct mdt_reint_record *rr = &info->mti_rr;
95         struct req_capsule      *pill = &info->mti_pill;
96         ENTRY;
97
98         rec = req_capsule_client_get(pill, &RMF_REC_SETATTR);
99
100         if (rec == NULL)
101                 RETURN(-EFAULT);
102
103         rr->rr_fid1 = &rec->sa_fid;
104         attr->la_valid = rec->sa_valid;
105         attr->la_mode  = rec->sa_mode;
106         attr->la_uid   = rec->sa_uid;
107         attr->la_gid   = rec->sa_gid;
108         attr->la_size  = rec->sa_size;
109         attr->la_flags = rec->sa_attr_flags;
110         attr->la_ctime = rec->sa_ctime;
111         attr->la_atime = rec->sa_atime;
112         attr->la_mtime = rec->sa_mtime;
113
114         if (req_capsule_field_present(pill, &RMF_EADATA)) {
115                 rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
116                 rr->rr_eadatalen = req_capsule_get_size(pill,
117                                                         &RMF_EADATA,
118                                                         RCL_CLIENT);
119         }
120         if (req_capsule_field_present(pill, &RMF_LOGCOOKIES)) {
121                 rr->rr_logcookies = req_capsule_client_get(pill,
122                                                            &RMF_LOGCOOKIES);
123                 rr->rr_logcookielen = req_capsule_get_size(pill,
124                                                            &RMF_LOGCOOKIES,
125                                                            RCL_CLIENT);
126         }
127
128         RETURN(0);
129 }
130
131 static int mdt_create_unpack(struct mdt_thread_info *info)
132 {
133         struct mdt_rec_create   *rec;
134         struct lu_attr          *attr = &info->mti_attr.ma_attr;
135         struct mdt_reint_record *rr = &info->mti_rr;
136         struct req_capsule      *pill = &info->mti_pill;
137         int                     result = 0;
138         ENTRY;
139
140         rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
141         if (rec != NULL) {
142                 rr->rr_fid1 = &rec->cr_fid1;
143                 rr->rr_fid2 = &rec->cr_fid2;
144                 attr->la_mode = rec->cr_mode;
145                 attr->la_rdev  = rec->cr_rdev;
146                 attr->la_uid   = rec->cr_fsuid;
147                 attr->la_gid   = rec->cr_fsgid;
148                 attr->la_flags = rec->cr_flags;
149                 attr->la_ctime = rec->cr_time;
150                 attr->la_mtime = rec->cr_time;
151                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
152                 if (rr->rr_name) {
153                         if (req_capsule_field_present(pill, &RMF_SYMTGT)) {
154                                 rr->rr_tgt = req_capsule_client_get(pill,
155                                                                 &RMF_SYMTGT);
156                                 if (rr->rr_tgt == NULL)
157                                         result = -EFAULT;
158                         }
159                 } else
160                         result = -EFAULT;
161         } else
162                 result = -EFAULT;
163         RETURN(result);
164 }
165
166 static int mdt_link_unpack(struct mdt_thread_info *info)
167 {
168         struct mdt_rec_link     *rec;
169         struct lu_attr          *attr = &info->mti_attr.ma_attr;
170         struct mdt_reint_record *rr = &info->mti_rr;
171         struct req_capsule      *pill = &info->mti_pill;
172         int                      result = 0;
173         ENTRY;
174
175         rec = req_capsule_client_get(pill, &RMF_REC_LINK);
176         if (rec != NULL) {
177                 attr->la_uid = rec->lk_fsuid;
178                 attr->la_gid = rec->lk_fsgid;
179                 rr->rr_fid1 = &rec->lk_fid1;
180                 rr->rr_fid2 = &rec->lk_fid2;
181                 attr->la_ctime = rec->lk_time;
182                 attr->la_mtime = rec->lk_time;
183
184                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
185                 if (rr->rr_name == NULL)
186                         result = -EFAULT;
187         } else
188                 result = -EFAULT;
189         RETURN(result);
190 }
191
192 static int mdt_unlink_unpack(struct mdt_thread_info *info)
193 {
194         struct mdt_rec_unlink   *rec;
195         struct lu_attr          *attr = &info->mti_attr.ma_attr;
196         struct mdt_reint_record *rr = &info->mti_rr;
197         struct req_capsule      *pill = &info->mti_pill;
198         int                      result = 0;
199         ENTRY;
200
201         rec = req_capsule_client_get(pill, &RMF_REC_UNLINK);
202         if (rec != NULL) {
203                 attr->la_uid = rec->ul_fsuid;
204                 attr->la_gid = rec->ul_fsgid;
205                 rr->rr_fid1 = &rec->ul_fid1;
206                 rr->rr_fid2 = &rec->ul_fid2;
207                 attr->la_ctime = rec->ul_time;
208                 attr->la_mtime = rec->ul_time;
209                 attr->la_mode  = rec->ul_mode;
210
211                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
212                 if (rr->rr_name == NULL)
213                         result = -EFAULT;
214         } else
215                 result = -EFAULT;
216         RETURN(result);
217 }
218
219 static int mdt_rename_unpack(struct mdt_thread_info *info)
220 {
221         struct mdt_rec_rename   *rec;
222         struct lu_attr          *attr = &info->mti_attr.ma_attr;
223         struct mdt_reint_record *rr = &info->mti_rr;
224         struct req_capsule      *pill = &info->mti_pill;
225         int                      result = 0;
226         ENTRY;
227
228         rec = req_capsule_client_get(pill, &RMF_REC_RENAME);
229         if (rec != NULL) {
230                 attr->la_uid = rec->rn_fsuid;
231                 attr->la_gid = rec->rn_fsgid;
232                 rr->rr_fid1 = &rec->rn_fid1;
233                 rr->rr_fid2 = &rec->rn_fid2;
234                 attr->la_ctime = rec->rn_time;
235                 attr->la_mtime = rec->rn_time;
236
237                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
238                 rr->rr_tgt = req_capsule_client_get(pill, &RMF_SYMTGT);
239                 if (rr->rr_name == NULL || rr->rr_tgt == NULL)
240                         result = -EFAULT;
241         } else
242                 result = -EFAULT;
243         RETURN(result);
244 }
245
246 static int mdt_open_unpack(struct mdt_thread_info *info)
247 {
248         struct mdt_rec_create   *rec;
249         struct lu_attr          *attr = &info->mti_attr.ma_attr;
250         struct req_capsule      *pill = &info->mti_pill;
251         struct mdt_reint_record *rr   = &info->mti_rr;
252         int                     result;
253         ENTRY;
254
255         rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
256         if (rec != NULL) {
257                 rr->rr_fid1   = &rec->cr_fid1;
258                 rr->rr_fid2   = &rec->cr_fid2;
259                 attr->la_mode = rec->cr_mode;
260                 attr->la_flags  = rec->cr_flags;
261
262                 rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
263                 if (rr->rr_name == NULL)
264                         result = -EFAULT;
265                 else
266                         result = 0;
267         } else
268                 result = -EFAULT;
269
270         RETURN(result);
271 }
272
273 typedef int (*reint_unpacker)(struct mdt_thread_info *info);
274
275 static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
276         [REINT_SETATTR]  = mdt_setattr_unpack,
277         [REINT_CREATE]   = mdt_create_unpack,
278         [REINT_LINK]     = mdt_link_unpack,
279         [REINT_UNLINK]   = mdt_unlink_unpack,
280         [REINT_RENAME]   = mdt_rename_unpack,
281         [REINT_OPEN]     = mdt_open_unpack
282 };
283
284 int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
285 {
286         int rc;
287
288         ENTRY;
289
290         if (op < REINT_MAX && mdt_reint_unpackers[op] != NULL) {
291                 info->mti_rr.rr_opcode = op;
292                 rc = mdt_reint_unpackers[op](info);
293         } else {
294                 CERROR("Unexpected opcode %d\n", op);
295                 rc = -EFAULT;
296         }
297         RETURN(rc);
298 }