Whamcloud - gitweb
6a265ddc9c49ee43083f921c700107d65adcf5e4
[fs/lustre-release.git] / lustre / osp / osp_md_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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2013, Intel Corporation.
24  */
25 /*
26  * lustre/osp/osp_md_object.c
27  *
28  * Lustre MDT Proxy Device
29  *
30  * Author: Di Wang <di.wang@intel.com>
31  */
32
33 #define DEBUG_SUBSYSTEM S_MDS
34
35 #include <lustre_log.h>
36 #include "osp_internal.h"
37
38 static const char dot[] = ".";
39 static const char dotdot[] = "..";
40
41 int osp_md_declare_object_create(const struct lu_env *env,
42                                  struct dt_object *dt,
43                                  struct lu_attr *attr,
44                                  struct dt_allocation_hint *hint,
45                                  struct dt_object_format *dof,
46                                  struct thandle *th)
47 {
48         struct osp_thread_info          *osi = osp_env_info(env);
49         struct dt_update_request        *update;
50         struct lu_fid                   *fid1;
51         int                             sizes[2] = {sizeof(struct obdo), 0};
52         char                            *bufs[2] = {NULL, NULL};
53         int                             buf_count;
54         int                             rc;
55
56         update = out_find_create_update_loc(th, dt);
57         if (IS_ERR(update)) {
58                 CERROR("%s: Get OSP update buf failed: rc = %d\n",
59                        dt->do_lu.lo_dev->ld_obd->obd_name,
60                        (int)PTR_ERR(update));
61                 return PTR_ERR(update);
62         }
63
64         osi->osi_obdo.o_valid = 0;
65         obdo_from_la(&osi->osi_obdo, attr, attr->la_valid);
66         lustre_set_wire_obdo(NULL, &osi->osi_obdo, &osi->osi_obdo);
67         obdo_cpu_to_le(&osi->osi_obdo, &osi->osi_obdo);
68
69         bufs[0] = (char *)&osi->osi_obdo;
70         buf_count = 1;
71         fid1 = (struct lu_fid *)lu_object_fid(&dt->do_lu);
72         if (hint != NULL && hint->dah_parent) {
73                 struct lu_fid *fid2;
74                 struct lu_fid *tmp_fid = &osi->osi_fid;
75
76                 fid2 = (struct lu_fid *)lu_object_fid(&hint->dah_parent->do_lu);
77                 fid_cpu_to_le(tmp_fid, fid2);
78                 sizes[1] = sizeof(*tmp_fid);
79                 bufs[1] = (char *)tmp_fid;
80                 buf_count++;
81         }
82
83         if (lu_object_exists(&dt->do_lu)) {
84                 /* If the object already exists, we needs to destroy
85                  * this orphan object first.
86                  *
87                  * The scenario might happen in this case
88                  *
89                  * 1. client send remote create to MDT0.
90                  * 2. MDT0 send create update to MDT1.
91                  * 3. MDT1 finished create synchronously.
92                  * 4. MDT0 failed and reboot.
93                  * 5. client resend remote create to MDT0.
94                  * 6. MDT0 tries to resend create update to MDT1,
95                  *    but find the object already exists
96                  */
97                 CDEBUG(D_HA, "%s: object "DFID" exists, destroy this orphan\n",
98                        dt->do_lu.lo_dev->ld_obd->obd_name, PFID(fid1));
99
100                 rc = out_insert_update(env, update, OUT_REF_DEL, fid1, 0,
101                                        NULL, NULL);
102                 if (rc != 0)
103                         GOTO(out, rc);
104
105                 if (S_ISDIR(lu_object_attr(&dt->do_lu))) {
106                         /* decrease for ".." */
107                         rc = out_insert_update(env, update, OUT_REF_DEL, fid1,
108                                                0, NULL, NULL);
109                         if (rc != 0)
110                                 GOTO(out, rc);
111                 }
112
113                 rc = out_insert_update(env, update, OUT_DESTROY, fid1, 0, NULL,
114                                        NULL);
115                 if (rc != 0)
116                         GOTO(out, rc);
117
118                 dt->do_lu.lo_header->loh_attr &= ~LOHA_EXISTS;
119                 /* Increase batchid to add this orphan object deletion
120                  * to separate transaction */
121                 update_inc_batchid(update);
122         }
123
124         rc = out_insert_update(env, update, OUT_CREATE, fid1, buf_count, sizes,
125                                (const char **)bufs);
126 out:
127         if (rc)
128                 CERROR("%s: Insert update error: rc = %d\n",
129                        dt->do_lu.lo_dev->ld_obd->obd_name, rc);
130
131         return rc;
132 }
133
134 int osp_md_object_create(const struct lu_env *env, struct dt_object *dt,
135                          struct lu_attr *attr, struct dt_allocation_hint *hint,
136                          struct dt_object_format *dof, struct thandle *th)
137 {
138         struct osp_object  *obj = dt2osp_obj(dt);
139
140         CDEBUG(D_INFO, "create object "DFID"\n",
141                PFID(&dt->do_lu.lo_header->loh_fid));
142
143         /* Because the create update RPC will be sent during declare phase,
144          * if creation reaches here, it means the object has been created
145          * successfully */
146         dt->do_lu.lo_header->loh_attr |= LOHA_EXISTS | (attr->la_mode & S_IFMT);
147         obj->opo_empty = 1;
148
149         return 0;
150 }
151
152 static int osp_md_declare_object_ref_del(const struct lu_env *env,
153                                          struct dt_object *dt,
154                                          struct thandle *th)
155 {
156         struct dt_update_request        *update;
157         struct lu_fid                   *fid;
158         int                             rc;
159
160         update = out_find_create_update_loc(th, dt);
161         if (IS_ERR(update)) {
162                 CERROR("%s: Get OSP update buf failed: rc = %d\n",
163                        dt->do_lu.lo_dev->ld_obd->obd_name,
164                       (int)PTR_ERR(update));
165                 return PTR_ERR(update);
166         }
167
168         fid = (struct lu_fid *)lu_object_fid(&dt->do_lu);
169
170         rc = out_insert_update(env, update, OUT_REF_DEL, fid, 0, NULL, NULL);
171
172         return rc;
173 }
174
175 static int osp_md_object_ref_del(const struct lu_env *env,
176                                  struct dt_object *dt,
177                                  struct thandle *th)
178 {
179         CDEBUG(D_INFO, "ref del object "DFID"\n",
180                PFID(&dt->do_lu.lo_header->loh_fid));
181
182         return 0;
183 }
184
185 static int osp_md_declare_ref_add(const struct lu_env *env,
186                                   struct dt_object *dt, struct thandle *th)
187 {
188         struct dt_update_request        *update;
189         struct lu_fid                   *fid;
190         int                             rc;
191
192         update = out_find_create_update_loc(th, dt);
193         if (IS_ERR(update)) {
194                 CERROR("%s: Get OSP update buf failed: rc = %d\n",
195                        dt->do_lu.lo_dev->ld_obd->obd_name,
196                        (int)PTR_ERR(update));
197                 return PTR_ERR(update);
198         }
199
200         fid = (struct lu_fid *)lu_object_fid(&dt->do_lu);
201
202         rc = out_insert_update(env, update, OUT_REF_ADD, fid, 0, NULL, NULL);
203
204         return rc;
205 }
206
207 static int osp_md_object_ref_add(const struct lu_env *env,
208                                  struct dt_object *dt,
209                                  struct thandle *th)
210 {
211         CDEBUG(D_INFO, "ref add object "DFID"\n",
212                PFID(&dt->do_lu.lo_header->loh_fid));
213
214         return 0;
215 }
216
217 static void osp_md_ah_init(const struct lu_env *env,
218                            struct dt_allocation_hint *ah,
219                            struct dt_object *parent,
220                            struct dt_object *child,
221                            umode_t child_mode)
222 {
223         LASSERT(ah);
224
225         memset(ah, 0, sizeof(*ah));
226         ah->dah_parent = parent;
227         ah->dah_mode = child_mode;
228 }
229
230 int osp_md_declare_attr_set(const struct lu_env *env, struct dt_object *dt,
231                             const struct lu_attr *attr, struct thandle *th)
232 {
233         struct osp_thread_info          *osi = osp_env_info(env);
234         struct dt_update_request        *update;
235         struct lu_fid                   *fid;
236         int                             size = sizeof(struct obdo);
237         char                            *buf;
238         int                             rc;
239
240         update = out_find_create_update_loc(th, dt);
241         if (IS_ERR(update)) {
242                 CERROR("%s: Get OSP update buf failed: %d\n",
243                        dt->do_lu.lo_dev->ld_obd->obd_name,
244                        (int)PTR_ERR(update));
245                 return PTR_ERR(update);
246         }
247
248         osi->osi_obdo.o_valid = 0;
249         obdo_from_la(&osi->osi_obdo, (struct lu_attr *)attr,
250                      attr->la_valid);
251         lustre_set_wire_obdo(NULL, &osi->osi_obdo, &osi->osi_obdo);
252         obdo_cpu_to_le(&osi->osi_obdo, &osi->osi_obdo);
253
254         buf = (char *)&osi->osi_obdo;
255         fid = (struct lu_fid *)lu_object_fid(&dt->do_lu);
256
257         rc = out_insert_update(env, update, OUT_ATTR_SET, fid, 1, &size,
258                                (const char **)&buf);
259
260         return rc;
261 }
262
263 int osp_md_attr_set(const struct lu_env *env, struct dt_object *dt,
264                     const struct lu_attr *attr, struct thandle *th,
265                     struct lustre_capa *capa)
266 {
267         CDEBUG(D_INFO, "attr set object "DFID"\n",
268                PFID(&dt->do_lu.lo_header->loh_fid));
269
270         RETURN(0);
271 }
272
273 static void osp_md_object_read_lock(const struct lu_env *env,
274                                     struct dt_object *dt, unsigned role)
275 {
276         struct osp_object  *obj = dt2osp_obj(dt);
277
278         LASSERT(obj->opo_owner != env);
279         down_read_nested(&obj->opo_sem, role);
280
281         LASSERT(obj->opo_owner == NULL);
282 }
283
284 static void osp_md_object_write_lock(const struct lu_env *env,
285                                      struct dt_object *dt, unsigned role)
286 {
287         struct osp_object *obj = dt2osp_obj(dt);
288
289         down_write_nested(&obj->opo_sem, role);
290
291         LASSERT(obj->opo_owner == NULL);
292         obj->opo_owner = env;
293 }
294
295 static void osp_md_object_read_unlock(const struct lu_env *env,
296                                       struct dt_object *dt)
297 {
298         struct osp_object *obj = dt2osp_obj(dt);
299
300         up_read(&obj->opo_sem);
301 }
302
303 static void osp_md_object_write_unlock(const struct lu_env *env,
304                                        struct dt_object *dt)
305 {
306         struct osp_object *obj = dt2osp_obj(dt);
307
308         LASSERT(obj->opo_owner == env);
309         obj->opo_owner = NULL;
310         up_write(&obj->opo_sem);
311 }
312
313 static int osp_md_object_write_locked(const struct lu_env *env,
314                                       struct dt_object *dt)
315 {
316         struct osp_object *obj = dt2osp_obj(dt);
317
318         return obj->opo_owner == env;
319 }
320
321 static int osp_md_index_lookup(const struct lu_env *env, struct dt_object *dt,
322                                struct dt_rec *rec, const struct dt_key *key,
323                                struct lustre_capa *capa)
324 {
325         struct lu_buf           *lbuf   = &osp_env_info(env)->osi_lb2;
326         struct osp_device       *osp    = lu2osp_dev(dt->do_lu.lo_dev);
327         struct dt_device        *dt_dev = &osp->opd_dt_dev;
328         struct dt_update_request   *update;
329         struct object_update_reply *reply;
330         struct ptlrpc_request      *req = NULL;
331         int                        size = strlen((char *)key) + 1;
332         struct lu_fid              *fid;
333         int                        rc;
334         ENTRY;
335
336         /* Because it needs send the update buffer right away,
337          * just create an update buffer, instead of attaching the
338          * update_remote list of the thandle.
339          */
340         update = out_create_update_req(dt_dev);
341         if (IS_ERR(update))
342                 RETURN(PTR_ERR(update));
343
344         rc = out_insert_update(env, update, OUT_INDEX_LOOKUP,
345                                lu_object_fid(&dt->do_lu),
346                                1, &size, (const char **)&key);
347         if (rc) {
348                 CERROR("%s: Insert update error: rc = %d\n",
349                        dt_dev->dd_lu_dev.ld_obd->obd_name, rc);
350                 GOTO(out, rc);
351         }
352
353         rc = out_remote_sync(env, osp->opd_obd->u.cli.cl_import, update, &req);
354         if (rc < 0)
355                 GOTO(out, rc);
356
357         reply = req_capsule_server_sized_get(&req->rq_pill,
358                                              &RMF_OUT_UPDATE_REPLY,
359                                              OUT_UPDATE_REPLY_SIZE);
360         if (reply->ourp_magic != UPDATE_REPLY_MAGIC) {
361                 CERROR("%s: Wrong version %x expected %x: rc = %d\n",
362                        dt_dev->dd_lu_dev.ld_obd->obd_name,
363                        reply->ourp_magic, UPDATE_REPLY_MAGIC, -EPROTO);
364                 GOTO(out, rc = -EPROTO);
365         }
366
367         rc = object_update_result_data_get(reply, lbuf, 0);
368         if (rc < 0)
369                 GOTO(out, rc = size);
370
371         if (lbuf->lb_len != sizeof(*fid)) {
372                 CERROR("%s: lookup "DFID" %s wrong size %d\n",
373                        dt_dev->dd_lu_dev.ld_obd->obd_name,
374                        PFID(lu_object_fid(&dt->do_lu)), (char *)key,
375                        (int)lbuf->lb_len);
376                 GOTO(out, rc = -EINVAL);
377         }
378
379         fid = lbuf->lb_buf;
380         fid_le_to_cpu(fid, fid);
381         if (!fid_is_sane(fid)) {
382                 CERROR("%s: lookup "DFID" %s invalid fid "DFID"\n",
383                        dt_dev->dd_lu_dev.ld_obd->obd_name,
384                        PFID(lu_object_fid(&dt->do_lu)), (char *)key, PFID(fid));
385                 GOTO(out, rc = -EINVAL);
386         }
387
388         memcpy(rec, fid, sizeof(*fid));
389
390         GOTO(out, rc = 1);
391
392 out:
393         if (req != NULL)
394                 ptlrpc_req_finished(req);
395
396         out_destroy_update_req(update);
397
398         return rc;
399 }
400
401 static int osp_md_declare_insert(const struct lu_env *env,
402                                  struct dt_object *dt,
403                                  const struct dt_rec *rec,
404                                  const struct dt_key *key,
405                                  struct thandle *th)
406 {
407         struct dt_update_request *update;
408         struct lu_fid            *fid;
409         struct lu_fid            *rec_fid = (struct lu_fid *)rec;
410         int                      size[2] = {strlen((char *)key) + 1,
411                                                   sizeof(*rec_fid)};
412         const char               *bufs[2] = {(char *)key, (char *)rec_fid};
413         int                      rc;
414
415         update = out_find_create_update_loc(th, dt);
416         if (IS_ERR(update)) {
417                 CERROR("%s: Get OSP update buf failed: rc = %d\n",
418                        dt->do_lu.lo_dev->ld_obd->obd_name,
419                        (int)PTR_ERR(update));
420                 return PTR_ERR(update);
421         }
422
423         fid = (struct lu_fid *)lu_object_fid(&dt->do_lu);
424
425         CDEBUG(D_INFO, "%s: insert index of "DFID" %s: "DFID"\n",
426                dt->do_lu.lo_dev->ld_obd->obd_name,
427                PFID(fid), (char *)key, PFID(rec_fid));
428
429         fid_cpu_to_le(rec_fid, rec_fid);
430
431         rc = out_insert_update(env, update, OUT_INDEX_INSERT, fid,
432                                ARRAY_SIZE(size), size, bufs);
433         return rc;
434 }
435
436 static int osp_md_index_insert(const struct lu_env *env,
437                                struct dt_object *dt,
438                                const struct dt_rec *rec,
439                                const struct dt_key *key,
440                                struct thandle *th,
441                                struct lustre_capa *capa,
442                                int ignore_quota)
443 {
444         return 0;
445 }
446
447 static int osp_md_declare_delete(const struct lu_env *env,
448                                  struct dt_object *dt,
449                                  const struct dt_key *key,
450                                  struct thandle *th)
451 {
452         struct dt_update_request *update;
453         struct lu_fid *fid;
454         int size = strlen((char *)key) + 1;
455         int rc;
456
457         update = out_find_create_update_loc(th, dt);
458         if (IS_ERR(update)) {
459                 CERROR("%s: Get OSP update buf failed: rc = %d\n",
460                        dt->do_lu.lo_dev->ld_obd->obd_name,
461                        (int)PTR_ERR(update));
462                 return PTR_ERR(update);
463         }
464
465         fid = (struct lu_fid *)lu_object_fid(&dt->do_lu);
466
467         rc = out_insert_update(env, update, OUT_INDEX_DELETE, fid, 1, &size,
468                                (const char **)&key);
469
470         return rc;
471 }
472
473 static int osp_md_index_delete(const struct lu_env *env,
474                                struct dt_object *dt,
475                                const struct dt_key *key,
476                                struct thandle *th,
477                                struct lustre_capa *capa)
478 {
479         CDEBUG(D_INFO, "index delete "DFID" %s\n",
480                PFID(&dt->do_lu.lo_header->loh_fid), (char *)key);
481
482         return 0;
483 }
484
485 /**
486  * Creates or initializes iterator context.
487  *
488  * Note: for OSP, these index iterate api is only used to check
489  * whether the directory is empty now (see mdd_dir_is_empty).
490  * Since dir_empty will be return by OUT_ATTR_GET(see osp_attr_get/
491  * out_attr_get). So the implementation of these iterator is simplied
492  * to make mdd_dir_is_empty happy. The real iterator should be
493  * implemented, if we need it one day.
494  */
495 static struct dt_it *osp_it_init(const struct lu_env *env,
496                                  struct dt_object *dt,
497                                  __u32 attr,
498                                 struct lustre_capa *capa)
499 {
500         lu_object_get(&dt->do_lu);
501         return (struct dt_it *)dt;
502 }
503
504 static void osp_it_fini(const struct lu_env *env, struct dt_it *di)
505 {
506         struct dt_object *dt = (struct dt_object *)di;
507         lu_object_put(env, &dt->do_lu);
508 }
509
510 static int osp_it_get(const struct lu_env *env,
511                       struct dt_it *di, const struct dt_key *key)
512 {
513         return 1;
514 }
515
516 static void osp_it_put(const struct lu_env *env, struct dt_it *di)
517 {
518         return;
519 }
520
521 static int osp_it_next(const struct lu_env *env, struct dt_it *di)
522 {
523         struct dt_object *dt = (struct dt_object *)di;
524         struct osp_object *o = dt2osp_obj(dt);
525
526         if (o->opo_empty)
527                 return 1;
528
529         return 0;
530 }
531
532 static struct dt_key *osp_it_key(const struct lu_env *env,
533                                  const struct dt_it *di)
534 {
535         LBUG();
536         return NULL;
537 }
538
539 static int osp_it_key_size(const struct lu_env *env, const struct dt_it *di)
540 {
541         LBUG();
542         return 0;
543 }
544
545 static int osp_it_rec(const struct lu_env *env, const struct dt_it *di,
546                       struct dt_rec *lde, __u32 attr)
547 {
548         LBUG();
549         return 0;
550 }
551
552 static __u64 osp_it_store(const struct lu_env *env, const struct dt_it *di)
553 {
554         LBUG();
555         return 0;
556 }
557
558 static int osp_it_load(const struct lu_env *env, const struct dt_it *di,
559                        __u64 hash)
560 {
561         LBUG();
562         return 0;
563 }
564
565 static int osp_it_key_rec(const struct lu_env *env, const struct dt_it *di,
566                           void *key_rec)
567 {
568         LBUG();
569         return 0;
570 }
571
572 static const struct dt_index_operations osp_md_index_ops = {
573         .dio_lookup         = osp_md_index_lookup,
574         .dio_declare_insert = osp_md_declare_insert,
575         .dio_insert         = osp_md_index_insert,
576         .dio_declare_delete = osp_md_declare_delete,
577         .dio_delete         = osp_md_index_delete,
578         .dio_it     = {
579                 .init     = osp_it_init,
580                 .fini     = osp_it_fini,
581                 .get      = osp_it_get,
582                 .put      = osp_it_put,
583                 .next     = osp_it_next,
584                 .key      = osp_it_key,
585                 .key_size = osp_it_key_size,
586                 .rec      = osp_it_rec,
587                 .store    = osp_it_store,
588                 .load     = osp_it_load,
589                 .key_rec  = osp_it_key_rec,
590         }
591 };
592
593 static int osp_md_index_try(const struct lu_env *env,
594                             struct dt_object *dt,
595                             const struct dt_index_features *feat)
596 {
597         dt->do_index_ops = &osp_md_index_ops;
598         return 0;
599 }
600
601 static int osp_md_object_lock(const struct lu_env *env,
602                               struct dt_object *dt,
603                               struct lustre_handle *lh,
604                               struct ldlm_enqueue_info *einfo,
605                               ldlm_policy_data_t *policy)
606 {
607         struct osp_thread_info  *info = osp_env_info(env);
608         struct ldlm_res_id      *res_id = &info->osi_resid;
609         struct dt_device        *dt_dev = lu2dt_dev(dt->do_lu.lo_dev);
610         struct osp_device       *osp = dt2osp_dev(dt_dev);
611         struct ptlrpc_request   *req;
612         int                     rc = 0;
613         __u64                   flags = 0;
614         ldlm_mode_t             mode;
615
616         fid_build_reg_res_name(lu_object_fid(&dt->do_lu), res_id);
617
618         mode = ldlm_lock_match(osp->opd_obd->obd_namespace,
619                                LDLM_FL_BLOCK_GRANTED, res_id,
620                                einfo->ei_type, policy,
621                                einfo->ei_mode, lh, 0);
622         if (mode > 0)
623                 return ELDLM_OK;
624
625         req = ldlm_enqueue_pack(osp->opd_exp, 0);
626         if (IS_ERR(req))
627                 RETURN(PTR_ERR(req));
628
629         rc = ldlm_cli_enqueue(osp->opd_exp, &req, einfo, res_id,
630                               (const ldlm_policy_data_t *)policy,
631                               &flags, NULL, 0, LVB_T_NONE, lh, 0);
632
633         ptlrpc_req_finished(req);
634
635         return rc == ELDLM_OK ? 0 : -EIO;
636 }
637
638 static int osp_md_object_unlock(const struct lu_env *env,
639                                 struct dt_object *dt,
640                                 struct ldlm_enqueue_info *einfo,
641                                 ldlm_policy_data_t *policy)
642 {
643         struct lustre_handle    *lockh = einfo->ei_cbdata;
644
645         /* unlock finally */
646         ldlm_lock_decref(lockh, einfo->ei_mode);
647
648         return 0;
649 }
650
651 struct dt_object_operations osp_md_obj_ops = {
652         .do_read_lock         = osp_md_object_read_lock,
653         .do_write_lock        = osp_md_object_write_lock,
654         .do_read_unlock       = osp_md_object_read_unlock,
655         .do_write_unlock      = osp_md_object_write_unlock,
656         .do_write_locked      = osp_md_object_write_locked,
657         .do_declare_create    = osp_md_declare_object_create,
658         .do_create            = osp_md_object_create,
659         .do_declare_ref_add   = osp_md_declare_ref_add,
660         .do_ref_add           = osp_md_object_ref_add,
661         .do_declare_ref_del   = osp_md_declare_object_ref_del,
662         .do_ref_del           = osp_md_object_ref_del,
663         .do_declare_destroy   = osp_declare_object_destroy,
664         .do_destroy           = osp_object_destroy,
665         .do_ah_init           = osp_md_ah_init,
666         .do_attr_get          = osp_attr_get,
667         .do_declare_attr_set  = osp_md_declare_attr_set,
668         .do_attr_set          = osp_md_attr_set,
669         .do_xattr_get         = osp_xattr_get,
670         .do_declare_xattr_set = osp_declare_xattr_set,
671         .do_xattr_set         = osp_xattr_set,
672         .do_index_try         = osp_md_index_try,
673         .do_object_lock       = osp_md_object_lock,
674         .do_object_unlock     = osp_md_object_unlock,
675 };