Whamcloud - gitweb
b=14230
[fs/lustre-release.git] / lustre / cmm / mdc_object.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/cmm/mdc_object.c
5  *  Lustre Cluster Metadata Manager (cmm)
6  *
7  *  Copyright (c) 2006 Cluster File Systems, Inc.
8  *   Author: Mike Pershin <tappro@clusterfs.com>
9  *
10  *   This file is part of the Lustre file system, http://www.lustre.org
11  *   Lustre is a trademark of Cluster File Systems, Inc.
12  *
13  *   You may have signed or agreed to another license before downloading
14  *   this software.  If so, you are bound by the terms and conditions
15  *   of that agreement, and the following does not apply to you.  See the
16  *   LICENSE file included with this distribution for more information.
17  *
18  *   If you did not agree to a different license, then this copy of Lustre
19  *   is open source software; you can redistribute it and/or modify it
20  *   under the terms of version 2 of the GNU General Public License as
21  *   published by the Free Software Foundation.
22  *
23  *   In either case, Lustre is distributed in the hope that it will be
24  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *   license text for more details.
27  */
28
29 #ifndef EXPORT_SYMTAB
30 # define EXPORT_SYMTAB
31 #endif
32
33 #define DEBUG_SUBSYSTEM S_MDS
34 #include <obd_support.h>
35 #include <lustre_lib.h>
36 #include <obd_class.h>
37 #include <lustre_mdc.h>
38 #include "cmm_internal.h"
39 #include "mdc_internal.h"
40
41 static struct md_object_operations mdc_mo_ops;
42 static struct md_dir_operations mdc_dir_ops;
43 static struct lu_object_operations mdc_obj_ops;
44
45 extern struct lu_context_key mdc_thread_key;
46
47 struct lu_object *mdc_object_alloc(const struct lu_env *env,
48                                    const struct lu_object_header *hdr,
49                                    struct lu_device *ld)
50 {
51         struct mdc_object *mco;
52         ENTRY;
53
54         OBD_ALLOC_PTR(mco);
55         if (mco != NULL) {
56                 struct lu_object *lo;
57
58                 lo = &mco->mco_obj.mo_lu;
59                 lu_object_init(lo, NULL, ld);
60                 mco->mco_obj.mo_ops = &mdc_mo_ops;
61                 mco->mco_obj.mo_dir_ops = &mdc_dir_ops;
62                 lo->lo_ops = &mdc_obj_ops;
63                 RETURN(lo);
64         } else
65                 RETURN(NULL);
66 }
67
68 static void mdc_object_free(const struct lu_env *env, struct lu_object *lo)
69 {
70         struct mdc_object *mco = lu2mdc_obj(lo);
71         lu_object_fini(lo);
72         OBD_FREE_PTR(mco);
73 }
74
75 static int mdc_object_init(const struct lu_env *env, struct lu_object *lo)
76 {
77         ENTRY;
78         lo->lo_header->loh_attr |= LOHA_REMOTE;
79         RETURN(0);
80 }
81
82 static int mdc_object_print(const struct lu_env *env, void *cookie,
83                             lu_printer_t p, const struct lu_object *lo)
84 {
85         return (*p)(env, cookie, LUSTRE_CMM_MDC_NAME"-object@%p", lo);
86 }
87
88 static struct lu_object_operations mdc_obj_ops = {
89         .loo_object_init    = mdc_object_init,
90         .loo_object_free    = mdc_object_free,
91         .loo_object_print   = mdc_object_print,
92 };
93
94 /* md_object_operations */
95 static
96 struct mdc_thread_info *mdc_info_get(const struct lu_env *env)
97 {
98         struct mdc_thread_info *mci;
99
100         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
101         LASSERT(mci);
102         return mci;
103 }
104
105 static
106 struct mdc_thread_info *mdc_info_init(const struct lu_env *env)
107 {
108         struct mdc_thread_info *mci = mdc_info_get(env);
109         memset(mci, 0, sizeof(*mci));
110         return mci;
111 }
112
113 static void mdc_body2attr(struct mdt_body *body, struct md_attr *ma)
114 {
115         struct lu_attr *la = &ma->ma_attr;
116         /* update time */
117         if (body->valid & OBD_MD_FLCTIME && body->ctime >= la->la_ctime) {
118                 la->la_ctime = body->ctime;
119                 if (body->valid & OBD_MD_FLMTIME)
120                         la->la_mtime = body->mtime;
121         }
122
123         if (body->valid & OBD_MD_FLMODE)
124                 la->la_mode = body->mode;
125         if (body->valid & OBD_MD_FLSIZE)
126                 la->la_size = body->size;
127         if (body->valid & OBD_MD_FLBLOCKS)
128                 la->la_blocks = body->blocks;
129         if (body->valid & OBD_MD_FLUID)
130                 la->la_uid = body->uid;
131         if (body->valid & OBD_MD_FLGID)
132                 la->la_gid = body->gid;
133         if (body->valid & OBD_MD_FLFLAGS)
134                 la->la_flags = body->flags;
135         if (body->valid & OBD_MD_FLNLINK)
136                 la->la_nlink = body->nlink;
137         if (body->valid & OBD_MD_FLRDEV)
138                 la->la_rdev = body->rdev;
139
140         la->la_valid = body->valid;
141         ma->ma_valid = MA_INODE;
142 }
143
144 static int mdc_req2attr_update(const struct lu_env *env,
145                                struct md_attr *ma)
146 {
147         struct mdc_thread_info *mci;
148         struct ptlrpc_request *req;
149         struct mdt_body *body;
150         struct lov_mds_md *lov;
151         struct llog_cookie *cookie;
152
153         ENTRY;
154         mci = mdc_info_get(env);
155         req = mci->mci_req;
156         LASSERT(req);
157         body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
158         LASSERT(body);
159         mdc_body2attr(body, ma);
160
161         if (body->valid & OBD_MD_FLMDSCAPA) {
162                 struct lustre_capa *capa;
163
164                 /* create for cross-ref will fetch mds capa from remote obj */
165                 capa = req_capsule_server_get(&req->rq_pill, &RMF_CAPA1);
166                 LASSERT(capa != NULL);
167                 LASSERT(ma->ma_capa != NULL);
168                 *ma->ma_capa = *capa;
169         }
170                 
171         if (!(body->valid & OBD_MD_FLEASIZE))
172                 RETURN(0);
173
174         if (body->eadatasize == 0) {
175                 CERROR("OBD_MD_FLEASIZE is set but eadatasize is zero\n");
176                 RETURN(-EPROTO);
177         }
178
179         lov = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD,
180                                            body->eadatasize);
181         if (lov == NULL)
182                 RETURN(-EPROTO);
183
184         LASSERT(ma->ma_lmm != NULL);
185         LASSERT(ma->ma_lmm_size >= body->eadatasize); 
186         ma->ma_lmm_size = body->eadatasize;
187         memcpy(ma->ma_lmm, lov, ma->ma_lmm_size);
188         ma->ma_valid |= MA_LOV;
189
190         if (!(body->valid & OBD_MD_FLCOOKIE))
191                 RETURN(0);
192
193         if (body->aclsize == 0) {
194                 CERROR("OBD_MD_FLCOOKIE is set but cookie size is zero\n");
195                 RETURN(-EPROTO);
196         }
197
198         cookie = req_capsule_server_sized_get(&req->rq_pill, &RMF_ACL,
199                                               body->aclsize);
200         if (cookie == NULL)
201                 RETURN(-EPROTO);
202
203         LASSERT(ma->ma_cookie != NULL);
204         LASSERT(ma->ma_cookie_size == body->aclsize);
205         memcpy(ma->ma_cookie, cookie, ma->ma_cookie_size);
206         ma->ma_valid |= MA_COOKIE;
207         RETURN(0);
208 }
209
210 static int mdc_attr_get(const struct lu_env *env, struct md_object *mo,
211                         struct md_attr *ma)
212 {
213         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
214         struct mdc_thread_info *mci;
215         int rc;
216         ENTRY;
217
218         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
219         LASSERT(mci);
220
221         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
222
223         rc = md_getattr(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
224                         NULL, OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID |
225                         OBD_MD_FLFLAGS | OBD_MD_FLCROSSREF, 0, &mci->mci_req);
226         if (rc == 0) {
227                 /* get attr from request */
228                 rc = mdc_req2attr_update(env, ma);
229         }
230
231         ptlrpc_req_finished(mci->mci_req);
232
233         RETURN(rc);
234 }
235
236 static inline struct timespec *mdc_attr_time(struct timespec *t, __u64 seconds)
237 {
238         t->tv_sec = seconds;
239         t->tv_nsec = 0;
240         return t;
241 }
242
243 /*
244  * XXX: It is only used for set ctime when rename's source on remote MDS.
245  */
246 static int mdc_attr_set(const struct lu_env *env, struct md_object *mo,
247                         const struct md_attr *ma)
248 {
249         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
250         const struct lu_attr *la = &ma->ma_attr;
251         struct mdc_thread_info *mci;
252         struct md_ucred *uc = md_ucred(env);
253         int rc;
254         ENTRY;
255
256         LASSERT(ma->ma_attr.la_valid & LA_CTIME);
257
258         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
259         LASSERT(mci);
260
261         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
262
263         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo->mo_lu);
264         mdc_attr_time(&mci->mci_opdata.op_attr.ia_ctime, la->la_ctime);
265         mci->mci_opdata.op_attr.ia_mode = la->la_mode;
266         mci->mci_opdata.op_attr.ia_valid = ATTR_CTIME_SET;
267         if (uc &&
268             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
269                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
270                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
271                 mci->mci_opdata.op_cap = uc->mu_cap;
272                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
273                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
274                         mci->mci_opdata.op_suppgids[1] = uc->mu_suppgids[1];
275                 } else {
276                         mci->mci_opdata.op_suppgids[0] =
277                                 mci->mci_opdata.op_suppgids[1] = -1;
278                 }
279         } else {
280                 mci->mci_opdata.op_fsuid = la->la_uid;
281                 mci->mci_opdata.op_fsgid = la->la_gid;
282                 mci->mci_opdata.op_cap = current->cap_effective;
283                 mci->mci_opdata.op_suppgids[0] =
284                                 mci->mci_opdata.op_suppgids[1] = -1;
285         }
286
287         rc = md_setattr(mc->mc_desc.cl_exp, &mci->mci_opdata,
288                         NULL, 0, NULL, 0, &mci->mci_req, NULL);
289
290         ptlrpc_req_finished(mci->mci_req);
291
292         RETURN(rc);
293 }
294
295 static int mdc_object_create(const struct lu_env *env,
296                              struct md_object *mo,
297                              const struct md_op_spec *spec,
298                              struct md_attr *ma)
299 {
300         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
301         struct lu_attr *la = &ma->ma_attr;
302         struct mdc_thread_info *mci;
303         const void *symname;
304         struct md_ucred *uc = md_ucred(env);
305         int rc, symlen;
306         uid_t uid;
307         gid_t gid;
308         __u32 cap;
309         ENTRY;
310
311         LASSERT(S_ISDIR(la->la_mode));
312         LASSERT(spec->u.sp_pfid != NULL);
313
314         mci = mdc_info_init(env);
315         mci->mci_opdata.op_bias = MDS_CROSS_REF;
316         mci->mci_opdata.op_fid2 = *lu_object_fid(&mo->mo_lu);
317         
318         /* Parent fid is needed to create dotdot on the remote node. */
319         mci->mci_opdata.op_fid1 = *(spec->u.sp_pfid);
320         mci->mci_opdata.op_mod_time = la->la_ctime;
321         if (uc &&
322             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
323                 uid = uc->mu_fsuid;
324                 if (la->la_mode & S_ISGID)
325                         gid = la->la_gid;
326                 else
327                         gid = uc->mu_fsgid;
328                 cap = uc->mu_cap;
329                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD))
330                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
331                 else
332                         mci->mci_opdata.op_suppgids[0] = -1;
333         } else {
334                 uid = la->la_uid;
335                 gid = la->la_gid;
336                 cap = 0;
337                 mci->mci_opdata.op_suppgids[0] = -1;
338         }
339
340         /* get data from spec */
341         if (spec->sp_cr_flags & MDS_CREATE_SLAVE_OBJ) {
342                 symname = spec->u.sp_ea.eadata;
343                 symlen = spec->u.sp_ea.eadatalen;
344                 mci->mci_opdata.op_fid1 = *(spec->u.sp_ea.fid);
345                 mci->mci_opdata.op_flags |= MDS_CREATE_SLAVE_OBJ;
346 #ifdef CONFIG_FS_POSIX_ACL
347         } else if (spec->sp_cr_flags & MDS_CREATE_RMT_ACL) {
348                 symname = spec->u.sp_ea.eadata;
349                 symlen = spec->u.sp_ea.eadatalen;
350                 mci->mci_opdata.op_fid1 = *(spec->u.sp_ea.fid);
351                 mci->mci_opdata.op_flags |= MDS_CREATE_RMT_ACL;
352 #endif
353         } else {
354                 symname = spec->u.sp_symname;
355                 symlen = symname ? strlen(symname) + 1 : 0;
356         }
357
358         rc = md_create(mc->mc_desc.cl_exp, &mci->mci_opdata,
359                        symname, symlen, la->la_mode, uid, gid,
360                        cap, la->la_rdev, &mci->mci_req);
361
362         if (rc == 0) {
363                 /* get attr from request */
364                 rc = mdc_req2attr_update(env, ma);
365         }
366
367         ptlrpc_req_finished(mci->mci_req);
368
369         RETURN(rc);
370 }
371
372 static int mdc_ref_add(const struct lu_env *env, struct md_object *mo,
373                        const struct md_attr *ma)
374 {
375         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
376         const struct lu_attr *la = &ma->ma_attr;
377         struct mdc_thread_info *mci;
378         struct md_ucred *uc = md_ucred(env);
379         int rc;
380         ENTRY;
381
382         mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
383         LASSERT(mci);
384
385         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
386         mci->mci_opdata.op_bias = MDS_CROSS_REF;
387         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo->mo_lu);
388         mci->mci_opdata.op_mod_time = la->la_ctime;
389         if (uc &&
390             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
391                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
392                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
393                 mci->mci_opdata.op_cap = uc->mu_cap;
394                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
395                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
396                         mci->mci_opdata.op_suppgids[1] = uc->mu_suppgids[1];
397                 } else {
398                         mci->mci_opdata.op_suppgids[0] =
399                                 mci->mci_opdata.op_suppgids[1] = -1;
400                 }
401         } else {
402                 mci->mci_opdata.op_fsuid = la->la_uid;
403                 mci->mci_opdata.op_fsgid = la->la_gid;
404                 mci->mci_opdata.op_cap = current->cap_effective;
405                 mci->mci_opdata.op_suppgids[0] =
406                                 mci->mci_opdata.op_suppgids[1] = -1;
407         }
408
409
410         rc = md_link(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
411
412         ptlrpc_req_finished(mci->mci_req);
413
414         RETURN(rc);
415 }
416
417 static int mdc_ref_del(const struct lu_env *env, struct md_object *mo,
418                        struct md_attr *ma)
419 {
420         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
421         struct lu_attr *la = &ma->ma_attr;
422         struct mdc_thread_info *mci;
423         struct md_ucred *uc = md_ucred(env);
424         int rc;
425         ENTRY;
426
427         mci = mdc_info_init(env);
428         mci->mci_opdata.op_bias = MDS_CROSS_REF;
429         if (ma->ma_attr_flags & MDS_VTX_BYPASS)
430                 mci->mci_opdata.op_bias |= MDS_VTX_BYPASS;
431         else
432                 mci->mci_opdata.op_bias &= ~MDS_VTX_BYPASS;
433         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo->mo_lu);
434         mci->mci_opdata.op_mode = la->la_mode;
435         mci->mci_opdata.op_mod_time = la->la_ctime;
436         if (uc &&
437             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
438                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
439                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
440                 mci->mci_opdata.op_cap = uc->mu_cap;
441                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD))
442                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
443                 else
444                         mci->mci_opdata.op_suppgids[0] = -1;
445         } else {
446                 mci->mci_opdata.op_fsuid = la->la_uid;
447                 mci->mci_opdata.op_fsgid = la->la_gid;
448                 mci->mci_opdata.op_cap = current->cap_effective;
449                 mci->mci_opdata.op_suppgids[0] = -1;
450         }
451
452         rc = md_unlink(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
453         if (rc == 0) {
454                 /* get attr from request */
455                 rc = mdc_req2attr_update(env, ma);
456         }
457
458         ptlrpc_req_finished(mci->mci_req);
459
460         RETURN(rc);
461 }
462
463 #ifdef HAVE_SPLIT_SUPPORT
464 int mdc_send_page(struct cmm_device *cm, const struct lu_env *env,
465                   struct md_object *mo, struct page *page, __u32 offset)
466 {
467         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
468         int rc;
469         ENTRY;
470
471         rc = mdc_sendpage(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
472                           page, offset);
473         CDEBUG(rc ? D_ERROR : D_INFO, "send page %p  offset %d fid "DFID
474                " rc %d \n", page, offset, PFID(lu_object_fid(&mo->mo_lu)), rc);
475         RETURN(rc);
476 }
477 #endif
478
479 static struct md_object_operations mdc_mo_ops = {
480         .moo_attr_get       = mdc_attr_get,
481         .moo_attr_set       = mdc_attr_set,
482         .moo_object_create  = mdc_object_create,
483         .moo_ref_add        = mdc_ref_add,
484         .moo_ref_del        = mdc_ref_del,
485 };
486
487 /* md_dir_operations */
488 static int mdc_rename_tgt(const struct lu_env *env, struct md_object *mo_p,
489                           struct md_object *mo_t, const struct lu_fid *lf,
490                           const struct lu_name *lname, struct md_attr *ma)
491 {
492         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo_p));
493         struct lu_attr *la = &ma->ma_attr;
494         struct mdc_thread_info *mci;
495         struct md_ucred *uc = md_ucred(env);
496         int rc;
497         ENTRY;
498
499         mci = mdc_info_init(env);
500         mci->mci_opdata.op_bias = MDS_CROSS_REF;
501         if (ma->ma_attr_flags & MDS_VTX_BYPASS)
502                 mci->mci_opdata.op_bias |= MDS_VTX_BYPASS;
503         else
504                 mci->mci_opdata.op_bias &= ~MDS_VTX_BYPASS;
505         mci->mci_opdata.op_fid1 = *lu_object_fid(&mo_p->mo_lu);
506         mci->mci_opdata.op_fid2 = *lf;
507         mci->mci_opdata.op_mode = la->la_mode;
508         mci->mci_opdata.op_mod_time = la->la_ctime;
509         if (uc &&
510             ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
511                 mci->mci_opdata.op_fsuid = uc->mu_fsuid;
512                 mci->mci_opdata.op_fsgid = uc->mu_fsgid;
513                 mci->mci_opdata.op_cap = uc->mu_cap;
514                 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
515                         mci->mci_opdata.op_suppgids[0] = uc->mu_suppgids[0];
516                         mci->mci_opdata.op_suppgids[1] = uc->mu_suppgids[1];
517                 } else {
518                         mci->mci_opdata.op_suppgids[0] =
519                                 mci->mci_opdata.op_suppgids[1] = -1;
520                 }
521         } else {
522                 mci->mci_opdata.op_fsuid = la->la_uid;
523                 mci->mci_opdata.op_fsgid = la->la_gid;
524                 mci->mci_opdata.op_cap = current->cap_effective;
525                 mci->mci_opdata.op_suppgids[0] =
526                                 mci->mci_opdata.op_suppgids[1] = -1;
527         }
528
529         rc = md_rename(mc->mc_desc.cl_exp, &mci->mci_opdata, NULL, 0,
530                        lname->ln_name, lname->ln_namelen, &mci->mci_req);
531         if (rc == 0) {
532                 /* get attr from request */
533                 mdc_req2attr_update(env, ma);
534         }
535
536         ptlrpc_req_finished(mci->mci_req);
537
538         RETURN(rc);
539 }
540 /* 
541  * Return resulting fid in sfid
542  * 0: fids are not relatives
543  * fid: fid at which search stopped
544  */
545 static int mdc_is_subdir(const struct lu_env *env, struct md_object *mo,
546                          const struct lu_fid *fid, struct lu_fid *sfid)
547 {
548         struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
549         struct mdc_thread_info *mci;
550         struct mdt_body *body;
551         int rc;
552         ENTRY;
553
554         mci = mdc_info_init(env);
555
556         rc = md_is_subdir(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
557                           fid, &mci->mci_req);
558         if (rc == 0 || rc == -EREMOTE) {
559                 body = req_capsule_server_get(&mci->mci_req->rq_pill,
560                                               &RMF_MDT_BODY);
561                 LASSERT(body->valid & OBD_MD_FLID);
562         
563                 CDEBUG(D_INFO, "Remote mdo_is_subdir(), new src "DFID"\n",
564                        PFID(&body->fid1));
565                 *sfid = body->fid1;
566         }
567         ptlrpc_req_finished(mci->mci_req);
568         RETURN(rc);
569 }
570
571 static struct md_dir_operations mdc_dir_ops = {
572         .mdo_is_subdir   = mdc_is_subdir,
573         .mdo_rename_tgt  = mdc_rename_tgt
574 };