Whamcloud - gitweb
LU-1347 build: remove the vim/emacs modelines
[fs/lustre-release.git] / lustre / cmm / mdc_object.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/cmm/mdc_object.c
35  *
36  * Lustre Cluster Metadata Manager (cmm)
37  *
38  * Author: Mike Pershin <tappro@clusterfs.com>
39  */
40
41 #ifndef EXPORT_SYMTAB
42 # define EXPORT_SYMTAB
43 #endif
44
45 #define DEBUG_SUBSYSTEM S_MDS
46 #include <obd_support.h>
47 #include <lustre_lib.h>
48 #include <obd_class.h>
49 #include <lustre_mdc.h>
50 #include "cmm_internal.h"
51 #include "mdc_internal.h"
52
53 static const struct md_object_operations mdc_mo_ops;
54 static const struct md_dir_operations mdc_dir_ops;
55 static const struct lu_object_operations mdc_obj_ops;
56
57 extern struct lu_context_key mdc_thread_key;
58 /**
59  * \addtogroup cmm_mdc
60  * @{
61  */
62 /**
63  * Allocate new mdc object.
64  */
65 struct lu_object *mdc_object_alloc(const struct lu_env *env,
66                                    const struct lu_object_header *hdr,
67                                    struct lu_device *ld)
68 {
69         struct mdc_object *mco;
70         ENTRY;
71
72         OBD_ALLOC_PTR(mco);
73         if (mco != NULL) {
74                 struct lu_object *lo;
75
76                 lo = &mco->mco_obj.mo_lu;
77                 lu_object_init(lo, NULL, ld);
78                 mco->mco_obj.mo_ops = &mdc_mo_ops;
79                 mco->mco_obj.mo_dir_ops = &mdc_dir_ops;
80                 lo->lo_ops = &mdc_obj_ops;
81                 RETURN(lo);
82         } else
83                 RETURN(NULL);
84 }
85
86 /** Free current mdc object */
87 static void mdc_object_free(const struct lu_env *env, struct lu_object *lo)
88 {
89         struct mdc_object *mco = lu2mdc_obj(lo);
90         lu_object_fini(lo);
91         OBD_FREE_PTR(mco);
92 }
93
94 /**
95  * Initialize mdc object. All of them have loh_attr::LOHA_REMOTE set.
96  */
97 static int mdc_object_init(const struct lu_env *env, struct lu_object *lo,
98                            const struct lu_object_conf *unused)
99 {
100         ENTRY;
101         lo->lo_header->loh_attr |= LOHA_REMOTE;
102         RETURN(0);
103 }
104
105 /**
106  * Instance of lu_object_operations for mdc.
107  */
108 static const struct lu_object_operations mdc_obj_ops = {
109         .loo_object_init    = mdc_object_init,
110         .loo_object_free    = mdc_object_free,
111 };
112
113 /**
114  * \name The set of md_object_operations.
115  * @{
116  */
117 /**
118  * Get mdc_thread_info from lu_context
119  */
120 static
121 struct mdc_thread_info *mdc_info_get(const struct lu_env *env)
122 {
123         struct mdc_thread_info *mci;
124
125         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
126         LASSERT(mci);
127         return mci;
128 }
129
130 /**
131  * Initialize mdc_thread_info.
132  */
133 static
134 struct mdc_thread_info *mdc_info_init(const struct lu_env *env)
135 {
136         struct mdc_thread_info *mci = mdc_info_get(env);
137         memset(mci, 0, sizeof(*mci));
138         return mci;
139 }
140
141 /**
142  * Convert attributes from mdt_body to the md_attr.
143  */
144 static void mdc_body2attr(struct mdt_body *body, struct md_attr *ma)
145 {
146         struct lu_attr *la = &ma->ma_attr;
147         /* update time */
148         if (body->valid & OBD_MD_FLCTIME && body->ctime >= la->la_ctime) {
149                 la->la_ctime = body->ctime;
150                 if (body->valid & OBD_MD_FLMTIME)
151                         la->la_mtime = body->mtime;
152         }
153
154         if (body->valid & OBD_MD_FLMODE)
155                 la->la_mode = body->mode;
156         if (body->valid & OBD_MD_FLSIZE)
157                 la->la_size = body->size;
158         if (body->valid & OBD_MD_FLBLOCKS)
159                 la->la_blocks = body->blocks;
160         if (body->valid & OBD_MD_FLUID)
161                 la->la_uid = body->uid;
162         if (body->valid & OBD_MD_FLGID)
163                 la->la_gid = body->gid;
164         if (body->valid & OBD_MD_FLFLAGS)
165                 la->la_flags = body->flags;
166         if (body->valid & OBD_MD_FLNLINK)
167                 la->la_nlink = body->nlink;
168         if (body->valid & OBD_MD_FLRDEV)
169                 la->la_rdev = body->rdev;
170
171         la->la_valid = body->valid;
172         ma->ma_valid = MA_INODE;
173 }
174
175 /**
176  * Fill the md_attr \a ma with attributes from request.
177  */
178 static int mdc_req2attr_update(const struct lu_env *env,
179                                struct md_attr *ma)
180 {
181         struct mdc_thread_info *mci;
182         struct ptlrpc_request *req;
183         struct mdt_body *body;
184         struct lov_mds_md *md;
185         struct llog_cookie *cookie;
186         void *acl;
187
188         ENTRY;
189         mci = mdc_info_get(env);
190         req = mci->mci_req;
191         LASSERT(req);
192         body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
193         LASSERT(body);
194         mdc_body2attr(body, ma);
195
196         if (body->valid & OBD_MD_FLMDSCAPA) {
197                 struct lustre_capa *capa;
198
199                 /* create for cross-ref will fetch mds capa from remote obj */
200                 capa = req_capsule_server_get(&req->rq_pill, &RMF_CAPA1);
201                 LASSERT(capa != NULL);
202                 LASSERT(ma->ma_capa != NULL);
203                 *ma->ma_capa = *capa;
204         }
205
206         if ((body->valid & OBD_MD_FLEASIZE) || (body->valid & OBD_MD_FLDIREA)) {
207                 if (body->eadatasize == 0) {
208                         CERROR("No size defined for easize field\n");
209                         RETURN(-EPROTO);
210                 }
211
212                 md = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD,
213                                                   body->eadatasize);
214                 if (md == NULL)
215                         RETURN(-EPROTO);
216
217                 LASSERT(ma->ma_lmm != NULL);
218                 LASSERT(ma->ma_lmm_size >= body->eadatasize);
219                 ma->ma_lmm_size = body->eadatasize;
220                 memcpy(ma->ma_lmm, md, ma->ma_lmm_size);
221                 ma->ma_valid |= MA_LOV;
222         }
223
224         if (body->valid & OBD_MD_FLCOOKIE) {
225                 /*
226                  * ACL and cookie share the same body->aclsize, we need
227                  * to make sure that they both never come here.
228                  */
229                 LASSERT(!(body->valid & OBD_MD_FLACL));
230
231                 if (body->aclsize == 0) {
232                         CERROR("No size defined for cookie field\n");
233                         RETURN(-EPROTO);
234                 }
235
236                 cookie = req_capsule_server_sized_get(&req->rq_pill,
237                                                       &RMF_LOGCOOKIES,
238                                                       body->aclsize);
239                 if (cookie == NULL)
240                         RETURN(-EPROTO);
241
242                 LASSERT(ma->ma_cookie != NULL);
243                 LASSERT(ma->ma_cookie_size == body->aclsize);
244                 memcpy(ma->ma_cookie, cookie, ma->ma_cookie_size);
245                 ma->ma_valid |= MA_COOKIE;
246         }
247
248 #ifdef CONFIG_FS_POSIX_ACL
249         if (body->valid & OBD_MD_FLACL) {
250                 if (body->aclsize == 0) {
251                         CERROR("No size defined for acl field\n");
252                         RETURN(-EPROTO);
253                 }
254
255                 acl = req_capsule_server_sized_get(&req->rq_pill,
256                                                    &RMF_ACL,
257                                                    body->aclsize);
258                 if (acl == NULL)
259                         RETURN(-EPROTO);
260
261                 LASSERT(ma->ma_acl != NULL);
262                 LASSERT(ma->ma_acl_size == body->aclsize);
263                 memcpy(ma->ma_acl, acl, ma->ma_acl_size);
264                 ma->ma_valid |= MA_ACL_DEF;
265         }
266 #endif
267
268         RETURN(0);
269 }
270
271 /**
272  * The md_object_operations::moo_attr_get() in mdc.
273  */
274 static int mdc_attr_get(const struct lu_env *env, struct md_object *mo,
275                         struct md_attr *ma)
276 {
277         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
278         struct mdc_thread_info *mci;
279         int rc;
280         ENTRY;
281
282         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
283         LASSERT(mci);
284
285         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
286
287         memcpy(&mci->mci_opdata.op_fid1, lu_object_fid(&mo->mo_lu),
288                sizeof (struct lu_fid));
289         mci->mci_opdata.op_valid = OBD_MD_FLMODE | OBD_MD_FLUID |
290                                    OBD_MD_FLGID | OBD_MD_FLFLAGS |
291                                    OBD_MD_FLCROSSREF;
292
293         rc = md_getattr(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
294         if (rc == 0) {
295                 /* get attr from request */
296                 rc = mdc_req2attr_update(env, ma);
297         }
298
299         ptlrpc_req_finished(mci->mci_req);
300
301         RETURN(rc);
302 }
303
304 /**
305  * Helper to init timspec \a t.
306  */
307 static inline struct timespec *mdc_attr_time(struct timespec *t, obd_time seconds)
308 {
309         t->tv_sec = seconds;
310         t->tv_nsec = 0;
311         return t;
312 }
313
314 /**
315  * The md_object_operations::moo_attr_set() in mdc.
316  *
317  * \note It is only used for set ctime when rename's source on remote MDS.
318  */
319 static int mdc_attr_set(const struct lu_env *env, struct md_object *mo,
320                         const struct md_attr *ma)
321 {
322         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
323         const struct lu_attr *la = &ma->ma_attr;
324         struct mdc_thread_info *mci;
325         struct md_ucred *uc = md_ucred(env);
326         int rc;
327         ENTRY;
328
329         LASSERT(ma->ma_attr.la_valid & LA_CTIME);
330
331         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
332         LASSERT(mci);
333
334         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
335
336         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo->mo_lu);
337         mdc_attr_time(&mci->mci_opdata.op_attr.ia_ctime, la->la_ctime);
338         mci->mci_opdata.op_attr.ia_mode = la->la_mode;
339         mci->mci_opdata.op_attr.ia_valid = ATTR_CTIME_SET;
340         if (uc &&
341             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
342                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
343                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
344                 mci->mci_opdata.op_cap = uc->mu_cap;
345                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
346                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
347                         mci->mci_opdata.op_suppgids[1] = uc->mu_suppgids[1];
348                 } else {
349                         mci->mci_opdata.op_suppgids[0] =
350                                 mci->mci_opdata.op_suppgids[1] = -1;
351                 }
352         } else {
353                 mci->mci_opdata.op_fsuid = la->la_uid;
354                 mci->mci_opdata.op_fsgid = la->la_gid;
355                 mci->mci_opdata.op_cap = cfs_curproc_cap_pack();
356                 mci->mci_opdata.op_suppgids[0] =
357                                 mci->mci_opdata.op_suppgids[1] = -1;
358         }
359
360         rc = md_setattr(mc->mc_desc.cl_exp, &mci->mci_opdata,
361                         NULL, 0, NULL, 0, &mci->mci_req, NULL);
362
363         ptlrpc_req_finished(mci->mci_req);
364
365         RETURN(rc);
366 }
367
368 /**
369  * The md_object_operations::moo_object_create() in mdc.
370  */
371 static int mdc_object_create(const struct lu_env *env,
372                              struct md_object *mo,
373                              const struct md_op_spec *spec,
374                              struct md_attr *ma)
375 {
376         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
377         struct lu_attr *la = &ma->ma_attr;
378         struct mdc_thread_info *mci;
379         const void *symname;
380         struct md_ucred *uc = md_ucred(env);
381         int rc, symlen;
382         uid_t uid;
383         gid_t gid;
384         cfs_cap_t cap;
385         ENTRY;
386
387         LASSERT(S_ISDIR(la->la_mode));
388         LASSERT(spec->u.sp_pfid != NULL);
389
390         mci = mdc_info_init(env);
391         mci->mci_opdata.op_bias = MDS_CROSS_REF;
392         mci->mci_opdata.op_fid2 = *lu_object_fid(&mo->mo_lu);
393
394         /* Parent fid is needed to create dotdot on the remote node. */
395         mci->mci_opdata.op_fid1 = *(spec->u.sp_pfid);
396         mci->mci_opdata.op_mod_time = la->la_ctime;
397         if (uc &&
398             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
399                 uid = uc->mu_fsuid;
400                 if (la->la_mode & S_ISGID)
401                         gid = la->la_gid;
402                 else
403                         gid = uc->mu_fsgid;
404                 cap = uc->mu_cap;
405                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD))
406                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
407                 else
408                         mci->mci_opdata.op_suppgids[0] = -1;
409         } else {
410                 uid = la->la_uid;
411                 gid = la->la_gid;
412                 cap = 0;
413                 mci->mci_opdata.op_suppgids[0] = -1;
414         }
415
416         /* get data from spec */
417         if (spec->sp_cr_flags & MDS_CREATE_SLAVE_OBJ) {
418                 symname = spec->u.sp_ea.eadata;
419                 symlen = spec->u.sp_ea.eadatalen;
420                 mci->mci_opdata.op_fid1 = *(spec->u.sp_ea.fid);
421                 mci->mci_opdata.op_flags |= MDS_CREATE_SLAVE_OBJ;
422 #ifdef CONFIG_FS_POSIX_ACL
423         } else if (spec->sp_cr_flags & MDS_CREATE_RMT_ACL) {
424                 symname = spec->u.sp_ea.eadata;
425                 symlen = spec->u.sp_ea.eadatalen;
426                 mci->mci_opdata.op_fid1 = *(spec->u.sp_ea.fid);
427                 mci->mci_opdata.op_flags |= MDS_CREATE_RMT_ACL;
428 #endif
429         } else {
430                 symname = spec->u.sp_symname;
431                 symlen = symname ? strlen(symname) + 1 : 0;
432         }
433
434         rc = md_create(mc->mc_desc.cl_exp, &mci->mci_opdata,
435                        symname, symlen, la->la_mode, uid, gid,
436                        cap, la->la_rdev, &mci->mci_req);
437
438         if (rc == 0) {
439                 /* get attr from request */
440                 rc = mdc_req2attr_update(env, ma);
441         }
442
443         ptlrpc_req_finished(mci->mci_req);
444
445         RETURN(rc);
446 }
447
448 /**
449  * The md_object_operations::moo_ref_add() in mdc.
450  */
451 static int mdc_ref_add(const struct lu_env *env, struct md_object *mo,
452                        const struct md_attr *ma)
453 {
454         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
455         const struct lu_attr *la = &ma->ma_attr;
456         struct mdc_thread_info *mci;
457         struct md_ucred *uc = md_ucred(env);
458         int rc;
459         ENTRY;
460
461         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
462         LASSERT(mci);
463
464         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
465         mci->mci_opdata.op_bias = MDS_CROSS_REF;
466         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo->mo_lu);
467         mci->mci_opdata.op_mod_time = la->la_ctime;
468         if (uc &&
469             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
470                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
471                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
472                 mci->mci_opdata.op_cap = uc->mu_cap;
473                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
474                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
475                         mci->mci_opdata.op_suppgids[1] = uc->mu_suppgids[1];
476                 } else {
477                         mci->mci_opdata.op_suppgids[0] =
478                                 mci->mci_opdata.op_suppgids[1] = -1;
479                 }
480         } else {
481                 mci->mci_opdata.op_fsuid = la->la_uid;
482                 mci->mci_opdata.op_fsgid = la->la_gid;
483                 mci->mci_opdata.op_cap = cfs_curproc_cap_pack();
484                 mci->mci_opdata.op_suppgids[0] =
485                                 mci->mci_opdata.op_suppgids[1] = -1;
486         }
487
488
489         rc = md_link(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
490
491         ptlrpc_req_finished(mci->mci_req);
492
493         RETURN(rc);
494 }
495
496 /**
497  * The md_object_operations::moo_ref_del() in mdc.
498  */
499 static int mdc_ref_del(const struct lu_env *env, struct md_object *mo,
500                        struct md_attr *ma)
501 {
502         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
503         struct lu_attr *la = &ma->ma_attr;
504         struct mdc_thread_info *mci;
505         struct md_ucred *uc = md_ucred(env);
506         int rc;
507         ENTRY;
508
509         mci = mdc_info_init(env);
510         mci->mci_opdata.op_bias = MDS_CROSS_REF;
511         if (ma->ma_attr_flags & MDS_VTX_BYPASS)
512                 mci->mci_opdata.op_bias |= MDS_VTX_BYPASS;
513         else
514                 mci->mci_opdata.op_bias &= ~MDS_VTX_BYPASS;
515         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo->mo_lu);
516         mci->mci_opdata.op_mode = la->la_mode;
517         mci->mci_opdata.op_mod_time = la->la_ctime;
518         if (uc &&
519             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
520                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
521                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
522                 mci->mci_opdata.op_cap = uc->mu_cap;
523                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD))
524                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
525                 else
526                         mci->mci_opdata.op_suppgids[0] = -1;
527         } else {
528                 mci->mci_opdata.op_fsuid = la->la_uid;
529                 mci->mci_opdata.op_fsgid = la->la_gid;
530                 mci->mci_opdata.op_cap = cfs_curproc_cap_pack();
531                 mci->mci_opdata.op_suppgids[0] = -1;
532         }
533
534         rc = md_unlink(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
535         if (rc == 0) {
536                 /* get attr from request */
537                 rc = mdc_req2attr_update(env, ma);
538         }
539
540         ptlrpc_req_finished(mci->mci_req);
541
542         RETURN(rc);
543 }
544
545 #ifdef HAVE_SPLIT_SUPPORT
546 /** Send page with directory entries to another MDS. */
547 int mdc_send_page(struct cmm_device *cm, const struct lu_env *env,
548                   struct md_object *mo, struct page *page, __u32 offset)
549 {
550         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
551         int rc;
552         ENTRY;
553
554         rc = mdc_sendpage(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
555                           page, offset);
556         CDEBUG(rc ? D_ERROR : D_INFO, "send page %p  offset %d fid "DFID
557                " rc %d \n", page, offset, PFID(lu_object_fid(&mo->mo_lu)), rc);
558         RETURN(rc);
559 }
560 #endif
561
562 /**
563  * Instance of md_object_operations for mdc.
564  */
565 static const struct md_object_operations mdc_mo_ops = {
566         .moo_attr_get       = mdc_attr_get,
567         .moo_attr_set       = mdc_attr_set,
568         .moo_object_create  = mdc_object_create,
569         .moo_ref_add        = mdc_ref_add,
570         .moo_ref_del        = mdc_ref_del,
571 };
572 /** @} */
573
574 /**
575  * \name The set of md_dir_operations.
576  * @{
577  */
578 /**
579  * The md_dir_operations::mdo_rename_tgt in mdc.
580  */
581 static int mdc_rename_tgt(const struct lu_env *env, struct md_object *mo_p,
582                           struct md_object *mo_t, const struct lu_fid *lf,
583                           const struct lu_name *lname, struct md_attr *ma)
584 {
585         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo_p));
586         struct lu_attr *la = &ma->ma_attr;
587         struct mdc_thread_info *mci;
588         struct md_ucred *uc = md_ucred(env);
589         int rc;
590         ENTRY;
591
592         mci = mdc_info_init(env);
593         mci->mci_opdata.op_bias = MDS_CROSS_REF;
594         if (ma->ma_attr_flags & MDS_VTX_BYPASS)
595                 mci->mci_opdata.op_bias |= MDS_VTX_BYPASS;
596         else
597                 mci->mci_opdata.op_bias &= ~MDS_VTX_BYPASS;
598         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo_p->mo_lu);
599         mci->mci_opdata.op_fid2 = *lf;
600         mci->mci_opdata.op_mode = la->la_mode;
601         mci->mci_opdata.op_mod_time = la->la_ctime;
602         if (uc &&
603             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
604                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
605                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
606                 mci->mci_opdata.op_cap = uc->mu_cap;
607                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
608                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
609                         mci->mci_opdata.op_suppgids[1] = uc->mu_suppgids[1];
610                 } else {
611                         mci->mci_opdata.op_suppgids[0] =
612                                 mci->mci_opdata.op_suppgids[1] = -1;
613                 }
614         } else {
615                 mci->mci_opdata.op_fsuid = la->la_uid;
616                 mci->mci_opdata.op_fsgid = la->la_gid;
617                 mci->mci_opdata.op_cap = cfs_curproc_cap_pack();
618                 mci->mci_opdata.op_suppgids[0] =
619                                 mci->mci_opdata.op_suppgids[1] = -1;
620         }
621
622         rc = md_rename(mc->mc_desc.cl_exp, &mci->mci_opdata, NULL, 0,
623                        lname->ln_name, lname->ln_namelen, &mci->mci_req);
624         if (rc == 0) {
625                 /* get attr from request */
626                 mdc_req2attr_update(env, ma);
627         }
628
629         ptlrpc_req_finished(mci->mci_req);
630
631         RETURN(rc);
632 }
633 /**
634  * Check the fids are not relatives.
635  * The md_dir_operations::mdo_is_subdir() in mdc.
636  *
637  * Return resulting fid in sfid.
638  * \retval \a sfid = 0 fids are not relatives
639  * \retval \a sfid = FID at which search stopped
640  */
641 static int mdc_is_subdir(const struct lu_env *env, struct md_object *mo,
642                          const struct lu_fid *fid, struct lu_fid *sfid)
643 {
644         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
645         struct mdc_thread_info *mci;
646         struct mdt_body *body;
647         int rc;
648         ENTRY;
649
650         mci = mdc_info_init(env);
651
652         rc = md_is_subdir(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
653                           fid, &mci->mci_req);
654         if (rc == 0 || rc == -EREMOTE) {
655                 body = req_capsule_server_get(&mci->mci_req->rq_pill,
656                                               &RMF_MDT_BODY);
657                 LASSERT(body->valid & OBD_MD_FLID);
658
659                 CDEBUG(D_INFO, "Remote mdo_is_subdir(), new src "DFID"\n",
660                        PFID(&body->fid1));
661                 *sfid = body->fid1;
662         }
663         ptlrpc_req_finished(mci->mci_req);
664         RETURN(rc);
665 }
666
667 /** Instance of md_dir_operations for mdc. */
668 static const struct md_dir_operations mdc_dir_ops = {
669         .mdo_is_subdir   = mdc_is_subdir,
670         .mdo_rename_tgt  = mdc_rename_tgt
671 };
672 /** @} */