Whamcloud - gitweb
LU-3536 lod: Separate thandle to different layers.
[fs/lustre-release.git] / lustre / lod / lod_sub_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,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License version 2 for more details.  A copy is
14  * included in the COPYING file that accompanied this code.
15
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2014, Intel Corporation.
24  */
25 /*
26  * lustre/lod/lod_sub_object.c
27  *
28  * LOD sub object methods
29  *
30  * This file implements sub-object methods for LOD.
31  *
32  * LOD is Logic volume layer in the MDS stack, which will handle striping
33  * and distribute the update to different OSP/OSD. After directing the updates
34  * to one specific OSD/OSP, it also needs to do some thing before calling
35  * OSD/OSP API, for example recording updates for cross-MDT operation, get
36  * the next level transaction etc.
37  *
38  * Author: Di Wang <di.wang@intel.com>
39  */
40
41 #define DEBUG_SUBSYSTEM S_MDS
42
43 #include <obd.h>
44 #include <obd_class.h>
45 #include <lustre_ver.h>
46 #include <obd_support.h>
47 #include <lprocfs_status.h>
48
49 #include <lustre_fid.h>
50 #include <lustre_param.h>
51 #include <md_object.h>
52 #include <lustre_linkea.h>
53
54 #include "lod_internal.h"
55
56 struct thandle *lod_sub_get_thandle(const struct lu_env *env,
57                                     struct thandle *th,
58                                     const struct dt_object *sub_obj)
59 {
60         struct lod_device       *lod = dt2lod_dev(th->th_dev);
61         struct top_thandle      *tth;
62         struct thandle          *sub_th;
63         int                     type = LU_SEQ_RANGE_ANY;
64         __u32                   mdt_index;
65         int                     rc;
66         ENTRY;
67
68         if (th->th_top == NULL)
69                 RETURN(th);
70
71         tth = container_of(th, struct top_thandle, tt_super);
72         LASSERT(tth->tt_magic == TOP_THANDLE_MAGIC);
73         /* local object must be mdt object, Note: during ost object
74          * creation, FID is not assigned until osp_object_create(),
75          * so if the FID of sub_obj is zero, it means OST object. */
76         if (!dt_object_remote(sub_obj) ||
77             fid_is_zero(lu_object_fid(&sub_obj->do_lu)))
78                 RETURN(tth->tt_master_sub_thandle);
79
80         rc = lod_fld_lookup(env, lod, lu_object_fid(&sub_obj->do_lu),
81                             &mdt_index, &type);
82         if (rc < 0)
83                 RETURN(ERR_PTR(rc));
84
85         if (type == LU_SEQ_RANGE_OST)
86                 RETURN(tth->tt_master_sub_thandle);
87
88         sub_th = thandle_get_sub(env, th, sub_obj);
89
90         RETURN(sub_th);
91 }
92
93 /**
94  * Declare sub-object creation.
95  *
96  * Get transaction of next layer and declare the creation of the object.
97  *
98  * \param[in] env       execution environment
99  * \param[in] dt        the object being created
100  * \param[in] attr      the attributes of the object being created
101  * \param[in] hint      the hint of the creation
102  * \param[in] dof       the object format of the creation
103  * \param[th] th        the transaction handle
104  *
105  * \retval              0 if the declaration succeeds
106  * \retval              negative errno if the declaration fails.
107  */
108 int lod_sub_object_declare_create(const struct lu_env *env,
109                                   struct dt_object *dt,
110                                   struct lu_attr *attr,
111                                   struct dt_allocation_hint *hint,
112                                   struct dt_object_format *dof,
113                                   struct thandle *th)
114 {
115         struct thandle *sub_th;
116
117         sub_th = lod_sub_get_thandle(env, th, dt);
118         if (IS_ERR(sub_th))
119                 return PTR_ERR(sub_th);
120
121         return dt_declare_create(env, dt, attr, hint, dof, sub_th);
122 }
123
124 /**
125  * Create sub-object.
126  *
127  * Get transaction of next layer, record updates if it belongs to cross-MDT
128  * operation, and create the object.
129  *
130  * \param[in] env       execution environment
131  * \param[in] dt        the object being created
132  * \param[in] attr      the attributes of the object being created
133  * \param[in] hint      the hint of the creation
134  * \param[in] dof       the object format of the creation
135  * \param[th] th        the transaction handle
136  *
137  * \retval              0 if the creation succeeds
138  * \retval              negative errno if the creation fails.
139  */
140 int lod_sub_object_create(const struct lu_env *env, struct dt_object *dt,
141                           struct lu_attr *attr,
142                           struct dt_allocation_hint *hint,
143                           struct dt_object_format *dof,
144                           struct thandle *th)
145 {
146         struct thandle     *sub_th;
147         int                 rc;
148         ENTRY;
149
150         sub_th = lod_sub_get_thandle(env, th, dt);
151         if (IS_ERR(sub_th))
152                 RETURN(PTR_ERR(sub_th));
153
154         rc = dt_create(env, dt, attr, hint, dof, sub_th);
155
156         RETURN(rc);
157 }
158
159 /**
160  * Declare adding reference for the sub-object
161  *
162  * Get transaction of next layer and declare the reference adding.
163  *
164  * \param[in] env       execution environment
165  * \param[in] dt        dt object to add reference
166  * \param[in] th        transaction handle
167  *
168  * \retval              0 if the declaration succeeds.
169  * \retval              negative errno if the declaration fails.
170  */
171 int lod_sub_object_declare_ref_add(const struct lu_env *env,
172                                    struct dt_object *dt,
173                                    struct thandle *th)
174 {
175         struct thandle  *sub_th;
176         int             rc;
177         ENTRY;
178
179         sub_th = lod_sub_get_thandle(env, th, dt);
180         if (IS_ERR(sub_th))
181                 RETURN(PTR_ERR(sub_th));
182
183         rc = dt_declare_ref_add(env, dt, sub_th);
184
185         RETURN(rc);
186 }
187
188 /**
189  * Add reference for the sub-object
190  *
191  * Get transaction of next layer, record updates if it belongs to cross-MDT
192  * operation and add reference of the object.
193  *
194  * \param[in] env       execution environment
195  * \param[in] dt        dt object to add reference
196  * \param[in] th        transaction handle
197  *
198  * \retval              0 if it succeeds.
199  * \retval              negative errno if it fails.
200  */
201 int lod_sub_object_ref_add(const struct lu_env *env, struct dt_object *dt,
202                            struct thandle *th)
203 {
204         struct thandle  *sub_th;
205         int             rc;
206         ENTRY;
207
208         sub_th = lod_sub_get_thandle(env, th, dt);
209         if (IS_ERR(sub_th))
210                 RETURN(PTR_ERR(sub_th));
211
212         rc = dt_ref_add(env, dt, sub_th);
213
214         RETURN(rc);
215 }
216
217 /**
218  * Declare deleting reference for the sub-object
219  *
220  * Get transaction of next layer and declare the reference deleting.
221  *
222  * \param[in] env       execution environment
223  * \param[in] dt        dt object to delete reference
224  * \param[in] th        transaction handle
225  *
226  * \retval              0 if the declaration succeeds.
227  * \retval              negative errno if the declaration fails.
228  */
229 int lod_sub_object_declare_ref_del(const struct lu_env *env,
230                                    struct dt_object *dt,
231                                    struct thandle *th)
232 {
233         struct thandle  *sub_th;
234         int             rc;
235         ENTRY;
236
237         sub_th = lod_sub_get_thandle(env, th, dt);
238         if (IS_ERR(sub_th))
239                 RETURN(PTR_ERR(sub_th));
240
241         rc = dt_declare_ref_del(env, dt, sub_th);
242
243         RETURN(rc);
244 }
245
246 /**
247  * Delete reference for the sub-object
248  *
249  * Get transaction of next layer, record updates if it belongs to cross-MDT
250  * operation and delete reference of the object.
251  *
252  * \param[in] env       execution environment
253  * \param[in] dt        dt object to delete reference
254  * \param[in] th        transaction handle
255  *
256  * \retval              0 if it succeeds.
257  * \retval              negative errno if it fails.
258  */
259 int lod_sub_object_ref_del(const struct lu_env *env, struct dt_object *dt,
260                            struct thandle *th)
261 {
262         struct thandle  *sub_th;
263         int             rc;
264         ENTRY;
265
266         sub_th = lod_sub_get_thandle(env, th, dt);
267         if (IS_ERR(sub_th))
268                 RETURN(PTR_ERR(sub_th));
269
270         rc = dt_ref_del(env, dt, sub_th);
271
272         RETURN(rc);
273 }
274
275 /**
276  * Declare destroying sub-object
277  *
278  * Get transaction of next layer and declare the sub-object destroy.
279  *
280  * \param[in] env       execution environment
281  * \param[in] dt        dt object to be destroyed
282  * \param[in] th        transaction handle
283  *
284  * \retval              0 if the declaration succeeds.
285  * \retval              negative errno if the declaration fails.
286  */
287 int lod_sub_object_declare_destroy(const struct lu_env *env,
288                                    struct dt_object *dt,
289                                    struct thandle *th)
290 {
291         struct thandle  *sub_th;
292         int             rc;
293         ENTRY;
294
295         sub_th = lod_sub_get_thandle(env, th, dt);
296         if (IS_ERR(sub_th))
297                 RETURN(PTR_ERR(sub_th));
298
299         rc = dt_declare_destroy(env, dt, sub_th);
300
301         RETURN(rc);
302 }
303
304 /**
305  * Destroy sub-object
306  *
307  * Get transaction of next layer, record updates if it belongs to cross-MDT
308  * operation and destroy the object.
309  *
310  * \param[in] env       execution environment
311  * \param[in] dt        dt object to be destroyed
312  * \param[in] th        transaction handle
313  *
314  * \retval              0 if the destroy succeeds.
315  * \retval              negative errno if the destroy fails.
316  */
317 int lod_sub_object_destroy(const struct lu_env *env, struct dt_object *dt,
318                            struct thandle *th)
319 {
320         struct thandle  *sub_th;
321         int             rc;
322         ENTRY;
323
324         sub_th = lod_sub_get_thandle(env, th, dt);
325         if (IS_ERR(sub_th))
326                 RETURN(PTR_ERR(sub_th));
327
328         rc = dt_destroy(env, dt, sub_th);
329
330         RETURN(rc);
331 }
332
333 /**
334  * Declare sub-object index insert
335  *
336  * Get transaction of next layer and declare index insert.
337  *
338  * \param[in] env       execution environment
339  * \param[in] dt        object for which to insert index
340  * \param[in] rec       record of the index which will be inserted
341  * \param[in] key       key of the index which will be inserted
342  * \param[in] th        the transaction handle
343  *
344  * \retval              0 if the declaration succeeds.
345  * \retval              negative errno if the declaration fails.
346  */
347 int lod_sub_object_declare_insert(const struct lu_env *env,
348                                   struct dt_object *dt,
349                                   const struct dt_rec *rec,
350                                   const struct dt_key *key,
351                                   struct thandle *th)
352 {
353         struct thandle *sub_th;
354
355         sub_th = lod_sub_get_thandle(env, th, dt);
356         if (IS_ERR(sub_th))
357                 return PTR_ERR(sub_th);
358
359         return dt_declare_insert(env, dt, rec, key, sub_th);
360 }
361
362 /**
363  * Insert index of sub object
364  *
365  * Get transaction of next layer, record updates if it belongs to cross-MDT
366  * operation, and insert the index.
367  *
368  * \param[in] env       execution environment
369  * \param[in] dt        object for which to insert index
370  * \param[in] rec       record of the index to be inserted
371  * \param[in] key       key of the index to be inserted
372  * \param[in] th        the transaction handle
373  * \param[in] ign       whether ignore quota
374  *
375  * \retval              0 if the insertion succeeds.
376  * \retval              negative errno if the insertion fails.
377  */
378 int lod_sub_object_index_insert(const struct lu_env *env, struct dt_object *dt,
379                                 const struct dt_rec *rec,
380                                 const struct dt_key *key, struct thandle *th,
381                                 int ign)
382 {
383         struct thandle *sub_th;
384
385         sub_th = lod_sub_get_thandle(env, th, dt);
386         if (IS_ERR(sub_th))
387                 return PTR_ERR(sub_th);
388
389         return dt_insert(env, dt, rec, key, sub_th, ign);
390 }
391
392 /**
393  * Declare sub-object index delete
394  *
395  * Get transaction of next layer and declare index deletion.
396  *
397  * \param[in] env       execution environment
398  * \param[in] dt        object for which to delete index
399  * \param[in] key       key of the index which will be deleted
400  * \param[in] th        the transaction handle
401  *
402  * \retval              0 if the declaration succeeds.
403  * \retval              negative errno if the declaration fails.
404  */
405 int lod_sub_object_declare_delete(const struct lu_env *env,
406                                   struct dt_object *dt,
407                                   const struct dt_key *key,
408                                   struct thandle *th)
409 {
410         struct thandle *sub_th;
411
412         sub_th = lod_sub_get_thandle(env, th, dt);
413         if (IS_ERR(sub_th))
414                 return PTR_ERR(sub_th);
415
416         return dt_declare_delete(env, dt, key, sub_th);
417 }
418
419 /**
420  * Delete index of sub object
421  *
422  * Get transaction of next layer, record updates if it belongs to cross-MDT
423  * operation, and delete the index.
424  *
425  * \param[in] env       execution environment
426  * \param[in] dt        object for which to delete index
427  * \param[in] key       key of the index to be deleted
428  * \param[in] th        the transaction handle
429  *
430  * \retval              0 if the deletion succeeds.
431  * \retval              negative errno if the deletion fails.
432  */
433 int lod_sub_object_delete(const struct lu_env *env, struct dt_object *dt,
434                           const struct dt_key *name, struct thandle *th)
435 {
436         struct thandle  *sub_th;
437         int             rc;
438         ENTRY;
439
440         sub_th = lod_sub_get_thandle(env, th, dt);
441         if (IS_ERR(sub_th))
442                 RETURN(PTR_ERR(sub_th));
443
444         rc = dt_delete(env, dt, name, sub_th);
445         RETURN(rc);
446 }
447
448 /**
449  * Declare xattr_set
450  *
451  * Get transaction of next layer, and declare xattr set.
452  *
453  * \param[in] env       execution environment
454  * \param[in] dt        object on which to set xattr
455  * \param[in] buf       xattr to be set
456  * \param[in] name      name of the xattr
457  * \param[in] fl        flag for setting xattr
458  *
459  * \retval              0 if the declaration succeeds.
460  * \retval              negative errno if the declaration fails.
461  */
462 int lod_sub_object_declare_xattr_set(const struct lu_env *env,
463                                      struct dt_object *dt,
464                                      const struct lu_buf *buf,
465                                      const char *name, int fl,
466                                      struct thandle *th)
467 {
468         struct thandle  *sub_th;
469         int             rc;
470         ENTRY;
471
472         sub_th = lod_sub_get_thandle(env, th, dt);
473         if (IS_ERR(sub_th))
474                 RETURN(PTR_ERR(sub_th));
475
476         rc = dt_declare_xattr_set(env, dt, buf, name, fl, sub_th);
477
478         RETURN(rc);
479 }
480
481 /**
482  * Set xattr
483  *
484  * Get transaction of next layer, record updates if it belongs to cross-MDT
485  * operation, and set xattr to the object.
486  *
487  * \param[in] env       execution environment
488  * \param[in] dt        object on which to set xattr
489  * \param[in] buf       xattr to be set
490  * \param[in] name      name of the xattr
491  * \param[in] fl        flag for setting xattr
492  * \param[in] th        transaction handle
493  *
494  * \retval              0 if the xattr setting succeeds.
495  * \retval              negative errno if xattr setting fails.
496  */
497 int lod_sub_object_xattr_set(const struct lu_env *env, struct dt_object *dt,
498                              const struct lu_buf *buf, const char *name, int fl,
499                              struct thandle *th)
500 {
501         struct thandle  *sub_th;
502         int             rc;
503         ENTRY;
504
505         sub_th = lod_sub_get_thandle(env, th, dt);
506         if (IS_ERR(sub_th))
507                 RETURN(PTR_ERR(sub_th));
508
509         rc = dt_xattr_set(env, dt, buf, name, fl, sub_th);
510
511         RETURN(rc);
512 }
513
514 /**
515  * Declare attr_set
516  *
517  * Get transaction of next layer, and declare attr set.
518  *
519  * \param[in] env       execution environment
520  * \param[in] dt        object on which to set attr
521  * \param[in] attr      attributes to be set
522  * \param[in] th        transaction handle
523  *
524  * \retval              0 if the declaration succeeds.
525  * \retval              negative errno if the declaration fails.
526  */
527 int lod_sub_object_declare_attr_set(const struct lu_env *env,
528                                     struct dt_object *dt,
529                                     const struct lu_attr *attr,
530                                     struct thandle *th)
531 {
532         struct thandle  *sub_th;
533         int             rc;
534         ENTRY;
535
536         sub_th = lod_sub_get_thandle(env, th, dt);
537         if (IS_ERR(sub_th))
538                 RETURN(PTR_ERR(sub_th));
539
540         rc = dt_declare_attr_set(env, dt, attr, sub_th);
541
542         RETURN(rc);
543 }
544
545 /**
546  * attributes set
547  *
548  * Get transaction of next layer, record updates if it belongs to cross-MDT
549  * operation, and set attributes to the object.
550  *
551  * \param[in] env       execution environment
552  * \param[in] dt        object on which to set attr
553  * \param[in] attr      attrbutes to be set
554  * \param[in] th        transaction handle
555  *
556  * \retval              0 if attributes setting succeeds.
557  * \retval              negative errno if the attributes setting fails.
558  */
559 int lod_sub_object_attr_set(const struct lu_env *env,
560                             struct dt_object *dt,
561                             const struct lu_attr *attr,
562                             struct thandle *th)
563 {
564         struct thandle     *sub_th;
565         int                 rc;
566         ENTRY;
567
568         sub_th = lod_sub_get_thandle(env, th, dt);
569         if (IS_ERR(sub_th))
570                 RETURN(PTR_ERR(sub_th));
571
572         rc = dt_attr_set(env, dt, attr, sub_th);
573
574         RETURN(rc);
575 }
576
577 /**
578  * Declare xattr_del
579  *
580  * Get transaction of next layer, and declare xattr deletion.
581  *
582  * \param[in] env       execution environment
583  * \param[in] dt        object on which to delete xattr
584  * \param[in] name      name of the xattr to be deleted
585  * \param[in] th        transaction handle
586  *
587  * \retval              0 if the declaration succeeds.
588  * \retval              negative errno if the declaration fails.
589  */
590 int lod_sub_object_declare_xattr_del(const struct lu_env *env,
591                                      struct dt_object *dt,
592                                      const char *name,
593                                      struct thandle *th)
594 {
595         struct thandle  *sub_th;
596         int             rc;
597         ENTRY;
598
599         sub_th = lod_sub_get_thandle(env, th, dt);
600         if (IS_ERR(sub_th))
601                 RETURN(PTR_ERR(sub_th));
602
603         rc = dt_declare_xattr_del(env, dt, name, sub_th);
604
605         RETURN(rc);
606 }
607
608 /**
609  * xattribute deletion
610  *
611  * Get transaction of next layer, record update if it belongs to cross-MDT
612  * operation and delete xattr.
613  *
614  * \param[in] env       execution environment
615  * \param[in] dt        object on which to delete xattr
616  * \param[in] name      name of the xattr to be deleted
617  * \param[in] th        transaction handle
618  *
619  * \retval              0 if the deletion succeeds.
620  * \retval              negative errno if the deletion fails.
621  */
622 int lod_sub_object_xattr_del(const struct lu_env *env,
623                              struct dt_object *dt,
624                              const char *name,
625                              struct thandle *th)
626 {
627         struct thandle  *sub_th;
628         int             rc;
629         ENTRY;
630
631         sub_th = lod_sub_get_thandle(env, th, dt);
632         if (IS_ERR(sub_th))
633                 RETURN(PTR_ERR(sub_th));
634
635         rc = dt_xattr_del(env, dt, name, sub_th);
636
637         RETURN(rc);
638 }
639
640 /**
641  * Declare buffer write
642  *
643  * Get transaction of next layer and declare buffer write.
644  *
645  * \param[in] env       execution environment
646  * \param[in] dt        object to be written
647  * \param[in] buf       buffer to write which includes an embedded size field
648  * \param[in] pos       offet in the object to start writing at
649  * \param[in] th        transaction handle
650  *
651  * \retval              0 if the insertion succeeds.
652  * \retval              negative errno if the insertion fails.
653  */
654 int lod_sub_object_declare_write(const struct lu_env *env,
655                                  struct dt_object *dt,
656                                  const struct lu_buf *buf, loff_t pos,
657                                  struct thandle *th)
658 {
659         struct thandle  *sub_th;
660         int             rc;
661         ENTRY;
662
663         sub_th = lod_sub_get_thandle(env, th, dt);
664         if (IS_ERR(sub_th))
665                 RETURN(PTR_ERR(sub_th));
666
667         rc = dt_declare_write(env, dt, buf, pos, sub_th);
668
669         RETURN(rc);
670 }
671
672 /**
673  * Write buffer to sub object
674  *
675  * Get transaction of next layer, records buffer write if it belongs to
676  * Cross-MDT operation, and write buffer.
677  *
678  * \param[in] env       execution environment
679  * \param[in] dt        object to be written
680  * \param[in] buf       buffer to write which includes an embedded size field
681  * \param[in] pos       offet in the object to start writing at
682  * \param[in] th        transaction handle
683  * \param[in] rq        enforcement for this write
684  *
685  * \retval              the buffer size in bytes if it succeeds.
686  * \retval              negative errno if it fails.
687  */
688 ssize_t lod_sub_object_write(const struct lu_env *env, struct dt_object *dt,
689                              const struct lu_buf *buf, loff_t *pos,
690                              struct thandle *th, int rq)
691 {
692         struct thandle  *sub_th;
693         ssize_t         rc;
694         ENTRY;
695
696         sub_th = lod_sub_get_thandle(env, th, dt);
697         if (IS_ERR(sub_th))
698                 RETURN(PTR_ERR(sub_th));
699
700         rc = dt_write(env, dt, buf, pos, sub_th, rq);
701         RETURN(rc);
702 }